-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Description
I propose Lexical gave the user a choice in how they want the inline TextNode formatting to be applied.
Currently, inline formatting is applied via inline styles taken from editorConfig.theme[formatType]. This leads to HTML elements that look like this:
<strong class="font-bold italic" data-lexical-text="true">Content</strong>Instead, I would like for the outputted HTML to resemble the final, valid HTML as close as possible:
<strong data-lexical-text="true"><em>Content</em></strong>Considerations:
- The parent element remains
TextNode. Formatting (tag nesting) is applied to the inner children of that element whenever applied. - Make this behavior config-dependent:
createEditor({
textFormatMode: 'inline' // default `'theme'` for backward compatibility
})Impact
- No impact on existing users since the behavior in question is opt-in and backward -compatible.
- Improved HTML output and smaller gap between the runtime and the output editor states.
Maintainer impact
This becomes dependent on config.textFormatMode:
| setTextThemeClassNames(innerTag, 0, format, innerDOM, textClassNames); |
Preserve getElementInnerTag as-is:
lexical/packages/lexical/src/nodes/LexicalTextNode.ts
Lines 125 to 133 in 12bdc8d
| function getElementInnerTag(node: TextNode, format: number): string { | |
| if (format & IS_BOLD) { | |
| return 'strong'; | |
| } | |
| if (format & IS_ITALIC) { | |
| return 'em'; | |
| } | |
| return 'span'; | |
| } |
Presently, it short-circuits due to early return for every format so you cannot get
<strong><em>nesting in case text format has bothIS_BOLDandIS_ITALIC.
This function will be used conditionally based on config.textFormatMode. If the mode is set to 'inline', instead the created dom for TextNode will be recursively wrapped in the HTML elements representing all the text formatting applied to the node.
Affected logic is here:
lexical/packages/lexical/src/nodes/LexicalTextNode.ts
Lines 489 to 490 in 12bdc8d
| const outerTag = getElementOuterTag(this, format); | |
| const innerTag = getElementInnerTag(this, format); |
And here:
lexical/packages/lexical/src/nodes/LexicalTextNode.ts
Lines 514 to 517 in 12bdc8d
| const prevOuterTag = getElementOuterTag(this, prevFormat); | |
| const nextOuterTag = getElementOuterTag(this, nextFormat); | |
| const prevInnerTag = getElementInnerTag(this, prevFormat); | |
| const nextInnerTag = getElementInnerTag(this, nextFormat); |
I don't mind the order of nesting to be fixed so
TextNodecan reliably produceouterTagbut have nestedinnerTags.