Skip to content

Commit a063cc6

Browse files
authored
fix(lexical): Text with underline format is stripped out on paste (#2555)
1 parent 815c6e6 commit a063cc6

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

packages/lexical-playground/__tests__/e2e/CopyAndPaste.spec.mjs

+59
Original file line numberDiff line numberDiff line change
@@ -2120,4 +2120,63 @@ test.describe('CopyAndPaste', () => {
21202120
`,
21212121
);
21222122
});
2123+
2124+
test('Paste content copied from google doc that contains bold italic underline formatting', async ({
2125+
page,
2126+
isPlainText,
2127+
}) => {
2128+
test.skip(isPlainText);
2129+
await focusEditor(page);
2130+
const htmlFromGoogle = `<meta charset='utf-8'><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-d6ac4fde-7fff-3941-b4d9-3903abcccdcb"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Bold</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Italic</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:underline;-webkit-text-decoration-skip:none;text-decoration-skip-ink:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">underline</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:italic;font-variant:normal;text-decoration:underline;-webkit-text-decoration-skip:none;text-decoration-skip-ink:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Bold Italic Underline</span></p></b><br class="Apple-interchange-newline">`;
2131+
const clipboardData = {
2132+
'text/html': htmlFromGoogle,
2133+
};
2134+
await pasteFromClipboard(page, clipboardData);
2135+
await assertHTML(
2136+
page,
2137+
html`
2138+
<p
2139+
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
2140+
dir="ltr">
2141+
<strong
2142+
class="PlaygroundEditorTheme__textBold"
2143+
data-lexical-text="true">
2144+
Bold
2145+
</strong>
2146+
</p>
2147+
<p
2148+
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
2149+
dir="ltr">
2150+
<em
2151+
class="PlaygroundEditorTheme__textItalic"
2152+
data-lexical-text="true">
2153+
Italic
2154+
</em>
2155+
</p>
2156+
<p
2157+
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
2158+
dir="ltr">
2159+
<span
2160+
class="PlaygroundEditorTheme__textUnderline"
2161+
data-lexical-text="true">
2162+
underline
2163+
</span>
2164+
</p>
2165+
<p
2166+
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
2167+
dir="ltr">
2168+
<strong
2169+
class="PlaygroundEditorTheme__textBold PlaygroundEditorTheme__textItalic
2170+
PlaygroundEditorTheme__textUnderline"
2171+
data-lexical-text="true">
2172+
Bold Italic Underline
2173+
</strong>
2174+
</p>
2175+
<p class="PlaygroundEditorTheme__paragraph">
2176+
<br />
2177+
<br />
2178+
</p>
2179+
`,
2180+
);
2181+
});
21232182
});

packages/lexical/src/nodes/LexicalTextNode.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,13 @@ function convertSpanElement(domNode: Node): DOMConversionOutput {
830830
const span = domNode as HTMLSpanElement;
831831
// Google Docs uses span tags + font-weight for bold text
832832
const hasBoldFontWeight = span.style.fontWeight === '700';
833-
// Google Docs uses span tags + text-decoration for strikethrough text
833+
// Google Docs uses span tags + text-decoration: line-through for strikethrough text
834834
const hasLinethroughTextDecoration =
835835
span.style.textDecoration === 'line-through';
836836
// Google Docs uses span tags + font-style for italic text
837837
const hasItalicFontStyle = span.style.fontStyle === 'italic';
838+
// Google Docs uses span tags + text-decoration: underline for underline text
839+
const hasUnderlineTextDecoration = span.style.textDecoration === 'underline';
838840

839841
return {
840842
forChild: (lexicalNode) => {
@@ -847,6 +849,9 @@ function convertSpanElement(domNode: Node): DOMConversionOutput {
847849
if ($isTextNode(lexicalNode) && hasItalicFontStyle) {
848850
lexicalNode.toggleFormat('italic');
849851
}
852+
if ($isTextNode(lexicalNode) && hasUnderlineTextDecoration) {
853+
lexicalNode.toggleFormat('underline');
854+
}
850855

851856
return lexicalNode;
852857
},

0 commit comments

Comments
 (0)