Files
SRCmail/components/email/__tests__/signature-block.test.ts
T
198407ebf5 fix(composer): keep HTML signature styling in the editor and on send
Rich, table-based identity signatures lost all their inline CSS
(background/text colors, fonts, border-radius, bgcolor). The composer
embeds the signature into the TipTap editor, and parsing it into the
ProseMirror schema flattened it to a generic bordered table. That
normalized version was then shown while composing AND delivered to the
recipient, even though Identity settings stored and previewed it
correctly.

Hold the signature as a dedicated, non-editable atom node
(SignatureBlock) that keeps the verbatim HTML in an attribute and renders
it inside a Shadow Root, mirroring the existing QuotedHtml island. The
markup is never parsed into the schema, so the styling survives 1:1 both
in the in-editor preview and in the outgoing mail
(serializeEditorContent inlines the verbatim HTML, as it already does for
quoted originals). The signature stays a single unit: select it and
Backspace/Delete to remove it; identity switching still swaps it via the
existing data-signature-block markers.

Adds unit coverage (parse + serialize round-trip preserves inline styles).

Fixes #475

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 19:56:10 +02:00

39 lines
1.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import { SignatureBlock, buildSignatureBlock, SIGNATURE_BLOCK_MARKER } from '../signature-block';
import { serializeEditorContent } from '../quoted-html';
describe('signature-block', () => {
it('buildSignatureBlock wraps html in the marker div', () => {
expect(buildSignatureBlock('<b>x</b>')).toBe(`<div ${SIGNATURE_BLOCK_MARKER}><b>x</b></div>`);
});
it('preserves an inline-styled signature through parse + serialize (no schema flattening)', () => {
const styled =
'<table style="background:#0a0e16;border-radius:8px"><tbody><tr>' +
'<td style="color:#c6f24e;font-family:\'Courier New\'">MV</td>' +
'</tr></tbody></table>';
const editor = new Editor({
element: document.createElement('div'),
extensions: [StarterKit, SignatureBlock],
content: `<p>Hello</p>${buildSignatureBlock(styled)}`,
});
try {
const out = serializeEditorContent(editor);
// Original inline styling survives - it is NOT re-parsed into the schema.
expect(out).toContain('background:#0a0e16');
expect(out).toContain('border-radius:8px');
expect(out).toContain('color:#c6f24e');
expect(out).toContain(SIGNATURE_BLOCK_MARKER);
// Surrounding body is preserved.
expect(out).toContain('Hello');
// The signature did not get the editor's generic table styling.
expect(out).not.toContain('rgb(204, 204, 204)');
} finally {
editor.destroy();
}
});
});