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>
39 lines
1.6 KiB
TypeScript
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();
|
|
}
|
|
});
|
|
});
|