mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 16:06:32 +00:00
fix: show one signature separator when the signature brings its own
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
insertSignatureAboveQuote,
|
||||
signatureIdentityFor,
|
||||
signPlainTextReply,
|
||||
signatureHasOwnDelimiter,
|
||||
} from '../signature-utils';
|
||||
|
||||
describe('sanitizeSignatureHtml', () => {
|
||||
@@ -115,3 +116,23 @@ describe('signPlainTextReply', () => {
|
||||
expect(signPlainTextReply('Thanks', 'q', null, { position: 'above_quote', separator: true })).toBe('Thanks\n\nq');
|
||||
});
|
||||
});
|
||||
|
||||
describe('a signature with its own "-- " line', () => {
|
||||
const own = { textSignature: '-- \nUser A\nstw-test' };
|
||||
const plain = { textSignature: 'User A\nstw-test' };
|
||||
|
||||
it('is detected, also with a bare "--" or a leading blank line', () => {
|
||||
expect(signatureHasOwnDelimiter(own)).toBe(true);
|
||||
expect(signatureHasOwnDelimiter({ textSignature: '\n--\nUser A' })).toBe(true);
|
||||
expect(signatureHasOwnDelimiter(plain)).toBe(false);
|
||||
expect(signatureHasOwnDelimiter({ htmlSignature: '<p>-- </p><p>User A</p>' })).toBe(true);
|
||||
});
|
||||
|
||||
it('gets no second separator in plain text or HTML', () => {
|
||||
const delimiters = (text: string) => text.split('\n').filter((line) => /^--\s*$/.test(line)).length;
|
||||
expect(delimiters(appendPlainTextSignature('Hi', own, { separator: true }))).toBe(1);
|
||||
expect(appendPlainTextSignature('Hi', plain, { separator: true })).toBe('Hi\n\n-- \nUser A\nstw-test');
|
||||
expect(buildEmbeddedSignatureHtml(own, { separator: true })).not.toContain('="separator"');
|
||||
expect(buildEmbeddedSignatureHtml(plain, { separator: true })).toContain('="separator"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ import { htmlToPlainText } from './compose-html';
|
||||
import {
|
||||
buildEmbeddedSignatureHtml, containsEmbeddedSignature, getPlainTextSignature,
|
||||
plainTextBodyHasSignature, plainTextBodyWithoutSignature, spliceSignature,
|
||||
type SignatureSource,
|
||||
wantsSignatureSeparator, type SignatureSource,
|
||||
} from './signature-utils';
|
||||
|
||||
/**
|
||||
@@ -67,7 +67,9 @@ export function htmlComposeBodyToPlainText(
|
||||
const head = text.slice(0, at).replace(/\s+$/, '');
|
||||
const tail = text.slice(at + SIGNATURE_TOKEN.length).replace(/^\s+/, '');
|
||||
const signature = getPlainTextSignature(identity);
|
||||
const withSignature = signature ? `${head}${separatorText(options.separator)}${signature}` : head;
|
||||
const withSignature = signature
|
||||
? `${head}${separatorText(wantsSignatureSeparator(options.separator, identity))}${signature}`
|
||||
: head;
|
||||
return tail ? `${withSignature}\n\n${tail}` : withSignature;
|
||||
}
|
||||
|
||||
@@ -86,7 +88,7 @@ export function plainComposeBodyToHtml(
|
||||
const signature = getPlainTextSignature(identity);
|
||||
const embedded = signature ? buildEmbeddedSignatureHtml(identity, options) : '';
|
||||
if (embedded) {
|
||||
const marker = `${separatorText(options.separator)}${signature}`;
|
||||
const marker = `${separatorText(wantsSignatureSeparator(options.separator, identity))}${signature}`;
|
||||
const at = text.indexOf(marker);
|
||||
if (at !== -1) {
|
||||
const before = plainTextToComposerHtml(text.slice(0, at).replace(/^\n+/, ''));
|
||||
|
||||
@@ -90,6 +90,27 @@ export function signatureIdentityFor<T extends { textSignature?: string; htmlSig
|
||||
return primary && hasSignature(primary) ? primary : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the signature starts with its own "-- " delimiter line. Many do
|
||||
* (imported from other clients, or set on the server), and the composer's
|
||||
* own separator on top of it showed two delimiter lines (webmail
|
||||
* lib/signature-delimiter.ts).
|
||||
*/
|
||||
export function signatureHasOwnDelimiter(signature?: SignatureSource | null): boolean {
|
||||
const text = signature?.textSignature?.trim()
|
||||
? signature.textSignature
|
||||
: signature?.htmlSignature?.trim()
|
||||
? htmlToPlainText(sanitizeSignatureHtml(signature.htmlSignature))
|
||||
: '';
|
||||
const firstLine = text.replace(/\r\n?/g, '\n').replace(/^\s*\n/, '').split('\n')[0];
|
||||
return /^--[ \t ]*$/.test(firstLine);
|
||||
}
|
||||
|
||||
/** Whether to add the "-- " separator line in front of this signature. */
|
||||
export function wantsSignatureSeparator(enabled: boolean | undefined, signature?: SignatureSource | null): boolean {
|
||||
return enabled !== false && !signatureHasOwnDelimiter(signature);
|
||||
}
|
||||
|
||||
export function getPlainTextSignature(signature?: SignatureSource): string {
|
||||
if (signature?.textSignature?.trim()) {
|
||||
return normalizeSignatureLineBreaks(signature.textSignature);
|
||||
@@ -112,7 +133,7 @@ export function appendPlainTextSignature(
|
||||
return body;
|
||||
}
|
||||
|
||||
const sep = options.separator === false ? '\n\n' : '\n\n-- \n';
|
||||
const sep = wantsSignatureSeparator(options.separator, signature) ? '\n\n-- \n' : '\n\n';
|
||||
return `${body}${sep}${plainTextSignature}`;
|
||||
}
|
||||
|
||||
@@ -186,7 +207,7 @@ export function appendHtmlSignature(
|
||||
signature?: SignatureSource,
|
||||
options: { separator?: boolean } = {},
|
||||
): string {
|
||||
const sep = options.separator === false ? '<br><br>' : '<br><br>-- <br>';
|
||||
const sep = wantsSignatureSeparator(options.separator, signature) ? '<br><br>-- <br>' : '<br><br>';
|
||||
|
||||
if (signature?.htmlSignature?.trim()) {
|
||||
return `${htmlBody}${sep}${sanitizeSignatureHtml(signature.htmlSignature)}`;
|
||||
@@ -208,7 +229,7 @@ export function buildEmbeddedSignatureHtml(
|
||||
identity: SignatureSource,
|
||||
options: { separator: boolean },
|
||||
): string {
|
||||
const startMarker = options.separator
|
||||
const startMarker = wantsSignatureSeparator(options.separator, identity)
|
||||
? `<p ${SIGNATURE_RANGE_MARKER}="separator">-- </p>`
|
||||
: `<p ${SIGNATURE_RANGE_MARKER}="start"></p>`;
|
||||
const endMarker = `<p ${SIGNATURE_RANGE_MARKER}="end"><br></p>`;
|
||||
|
||||
@@ -67,7 +67,7 @@ import { shouldBlockEditorRemoteImages } from '../lib/editor-html';
|
||||
import {
|
||||
signatureIdentityFor, buildEmbeddedSignatureHtml, containsEmbeddedSignature, spliceSignature,
|
||||
insertSignatureAboveQuote, getPlainTextSignature, appendPlainTextSignature,
|
||||
plainTextBodyHasSignature, plainTextBodyWithoutSignature, SIGNATURE_RANGE_MARKER,
|
||||
plainTextBodyHasSignature, plainTextBodyWithoutSignature, SIGNATURE_RANGE_MARKER, wantsSignatureSeparator,
|
||||
} from '../lib/signature-utils';
|
||||
import {
|
||||
getAutoFilledPlaceholders, getPlaceholdersFromTemplate, substitutePlaceholders, templateBodyToHtml,
|
||||
@@ -1083,7 +1083,7 @@ export default function ComposeScreen({ route, navigation }: Props) {
|
||||
const placeSignaturePlain = React.useCallback((body: string, identity: Identity): string => {
|
||||
const sig = getPlainTextSignature(identity);
|
||||
if (!sig) return body;
|
||||
const sep = signatureSeparatorEnabled ? '\n\n-- \n' : '\n\n';
|
||||
const sep = wantsSignatureSeparator(signatureSeparatorEnabled, identity) ? '\n\n-- \n' : '\n\n';
|
||||
if (isReplyLike && signaturePosition === 'above_quote') {
|
||||
const idx = body.indexOf('\n\n');
|
||||
const head = idx === -1 ? body : body.slice(0, idx);
|
||||
@@ -1139,7 +1139,7 @@ export default function ComposeScreen({ route, navigation }: Props) {
|
||||
stripped = plainTextBodyWithoutSignature(body, prev);
|
||||
} else if (prev) {
|
||||
const old = getPlainTextSignature(prev);
|
||||
const marker = `${signatureSeparatorEnabled ? '\n\n-- \n' : '\n\n'}${old}`;
|
||||
const marker = `${wantsSignatureSeparator(signatureSeparatorEnabled, prev) ? '\n\n-- \n' : '\n\n'}${old}`;
|
||||
if (old && body.includes(marker)) stripped = body.replace(marker, '');
|
||||
}
|
||||
return signatureIdentity ? placeSignaturePlain(stripped, signatureIdentity) : stripped;
|
||||
|
||||
Reference in New Issue
Block a user