[0.12.0] Rework generateNodesFromDOM API
I will try to get around to writing up a more extensive explanation later. The main purposes of this are twofold:
- Improve the out-of-the-box experience for HTML serialization and deserialization in the storage format use-case (as opposed to the transfer/copy-paste use case).
One of the big issues here is that we can't support interpretation of html attributes like background-color or text-align in the core without creating a poor user experience during HTML copy+paste. The idea here is to transfer those semantics via custom attributes on HTML, so we can support HTML-as-a-storage-format (deserializing into an editor with the same configuration) at a higher fidelity while preserving control during copy/paste.
- Amend the public API to be less cluttered and provide a path for additional options
Ultimately, I'd like to experiment with bringing more of this logic out of the core library and into the editor configuration, possible with some defaults in the rich-text or utils modules. import/exportDOM makes sense on the nodes, but it is honestly pretty clunky to have to do that for just a simple use case like supporting a text style.
fixes #4243
Example:
const editor = createEditor();
const htmlString = '<body><p lexical-data-format-align="center" ><span lexical-data-style="background: red">Hello</span></body>' //$generateHtmlFromNodes(editor, selection | null);
const parser = new DOMParser();
const dom = parser.parseFromString(htmlString, textHtmlMimeType);
const nodes = $generateNodesFromDOM(editor, dom, { elementFormats: true, textStyles: true });
// ParagraphNode (format: CENTER)
// - TextNode (style: background: red)
const nodesWithoutStyle = $generateNodesFromDOM(editor, dom, { elementFormats: false, textStyles: false });
// ParagraphNode (align: undefined)
// - TextNode (style: undefined)
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| lexical | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Apr 2, 2023 11:36pm |
| lexical-playground | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Apr 2, 2023 11:36pm |
size-limit report 📦
| Path | Size | Loading time (3g) | Running time (snapdragon) | Total time |
|---|---|---|---|---|
| packages/lexical/dist/Lexical.js | 27.02 KB (+0.49% 🔺) | 541 ms (+0.49% 🔺) | 222 ms (-42.3% 🔽) | 762 ms |
| packages/lexical-rich-text/dist/LexicalRichText.js | 37.96 KB (+0.63% 🔺) | 760 ms (+0.63% 🔺) | 230 ms (-19.92% 🔽) | 989 ms |
| packages/lexical-plain-text/dist/LexicalPlainText.js | 37.94 KB (+0.63% 🔺) | 759 ms (+0.63% 🔺) | 319 ms (-43.35% 🔽) | 1.1 s |
I like the concept here.
QQ, why is convertDOMElementLexicalData() only for element nodes?
Could you add an example of new API usage?
LGTM
Amend the public API to be less cluttered and provide a path for additional options
I'm unsure how this PR addresses this but I like the long-term vision of moving all the conversion functionality outside of the Core
I was thinking because now generateNodesFromDOM will take an options object instead of just continuously adding more arguments.
I like the concept here.
QQ, why is
convertDOMElementLexicalData()only for element nodes?
Good question - it's because all ElementNode subclasses don't need this logic, so I couldn't very easily put it in the base class. Instead, I put it in a util to avoid repetition. Will look closer at this when I have time to take another pass.
Could you add an example of new API usage?
yes, I will
@acywatson Mind resolving the merge conflicts?
Closing this PR due to staleness! If there are new updates, please reopen the PR.