Bug: $generateNodesFromDOM does not apply styles properly
See original GitHub issueWhen using $generateNodesFromDOM to convert HTML to Lexical, styles such as underline
or align
are not being applied.
In the case of HTML with styles that changes tag name such as bold
(<strong>
) or Italic
(<em>
), the style looks well when converted to lexical using $generateNodesFromDOM.
However, for HTML with styles that only add className(e.g.editor-text-*
), such as underline
or strikethrough
, the styles don’t seem to be applied when converted to lexical.
I referenced the convert code(HTML -> Lexical - lexical doc).
Lexical version: 0.3.5
Steps To Reproduce
(* example HTML string - No style applied to text(STYLE TEST
))
<div class="editor-input" contenteditable="true" spellcheck="true" data-lexical-editor="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" role="textbox"><p class="editor-paragraph ltr" dir="ltr"><span data-lexical-text="true">STYLE TEST</span></p></div>
case 1. bold
- Select bold - it is applied to
<strong>
tag. - When convert it to lexical based on the html string obtained in step 1 and insert it, the bold style is well as shown below.
case 2. underline
-
Select underline - The tagname is not changed(still
<span>
) and onlyeditor-text-underline
is added to the classname. The underline is also visible in the editor. -
However, when convert it to lexical based on html obtained in step 1 and insert, converted without underline applied.
case 3. bold + italic
-
Select bold and italic. The tagname is
<strong>
, and italics only apply toeditor-text-italic
classname. -
However, when convert and insert it, only applied
bold(<strong>)
. (where is theeditor-text-italic
? 😢 )
Considering the above cases, when converting html string to lexical, style or classname is ignored and it seems to be applied only based on tagname.
Link to code example: HTML -> Lexical
const LoadHtmlPlugin = ({htmlString}: Props) => {
const [editor] = useLexicalComposerContext();
useEffect(() => {
editor.update(() => {
const parser = new DOMParser();
const dom = parser.parseFromString(htmlString, 'text/html');
const nodes = $generateNodesFromDOM(editor, dom);
// Select the root
$getRoot().select();
// Insert them at a selection.
const selection = $getSelection() as RangeSelection;
selection.insertNodes(nodes);
});
}, [editor]);
return null;
};
The current behavior
$generateNodesFromDOM does not apply styles properly
The expected behavior
If $generateNodesFromDOM is used, the style and className of the dom must be maintained.
Issue Analytics
- State:
- Created a year ago
- Reactions:18
- Comments:10 (2 by maintainers)
Top GitHub Comments
I’ve implemented a patch-function that adds missed tag conversion (for Lexical@0.6.3:
sub
,sup
,s
) andbackground-color
andcolor
styles transfer from the DOM node to the Lexical nodeUPD After some investigation I figured out that the way of determining of applied formats for the node wasn’t correct for each cases, so I found the another way and updated the code snippet above using this
I believe I have the same issue, and I do not believe it is just a styling concern.
It seems that $generateHtmlFromNodes correctly applies style classes to the HTML, for me it is something like this (snippet):
<span class="textUnderline">aaaa</span>
However as far as i can tell $generateNodesFromDOM does not have any logic to apply this in reverse (take the class and generate an underline node). So in my case where I am saving the output of $generateHtmlFromNodes and then reloading it via $generateNodesFromDOM I lose some subset of my styling on reload