[WIP][lexical][lexical-html] Feature: Extensible DOM create/update/export#7885
Draft
etrepum wants to merge 55 commits intofacebook:mainfrom
Draft
[WIP][lexical][lexical-html] Feature: Extensible DOM create/update/export#7885etrepum wants to merge 55 commits intofacebook:mainfrom
etrepum wants to merge 55 commits intofacebook:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@etrepum is attempting to deploy a commit to the Meta Open Source Team on Vercel. A member of the Team first needs to authorize it. |
…ortDOM in editor config
116c95a to
f3d97f9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Addresses the
createDOM/updateDOM/exportDOMpart of #7259 by parameterizing the DOM functionality from the reconciler and@lexical/htmlto use the editor config viaDOMRenderExtension. Part of the thinking here is that we may be able to leverage this work later to make the reconciler itself more flexible.Follow-up work (out of scope)
Does not yet consider the different types of import/export, e.g. export for clipboard vs. export for serialization.
The same sort of approach can probably also be used for other tree based import/export (json, markdown ast, etc.).
$getDOMSlotcould possibly be used for nodes other than just ElementNode. The motivating use case there would be able to inject "widget decorators" (in prosemirror terms) that sit before or after specific nodes to facilitate UI that is "outside" of the document. The sorts of things we do now with popovers.EditorDOMRenderConfig
This data structure moves responsibility for all DOM rendering (create/update) and export to a single configuration in the editor. These
$createDOM,$exportDOM,$updateDOM, etc. properties are all functions which are eventually responsible for calling their respective node methods (at least by default).The trick here is that we can wrap these implementations with middleware style functions that can be composed to override or otherwise run code that happens "around" the default implementations. This is very difficult to do with the existing infrastructure, especially when writing code that needs to target all nodes, all nodes with some specific NodeState, etc. Since they are middleware, they have the ability to call the
$next()function to get the result of the next implementation (e.g. "calling super" and then enhancing its result) or not (to completely override).DOMRenderExtension
This provides a mechanism to compile the EditorDOMRenderConfig using composable configuration, targeting either all nodes with
'*'or some subset of nodes by an array ofNodeClassor$isNodeClassguards. This first pass is a relatively blunt approach but we can build more specific extensions to consolidate this wrapping in the future for optimization reasons.Examples:
Enhancing TextNode export to remove the 'white-space' style unless it's necessary to support the encoding of the content:
Adding an arbitrary id property to any node (e.g. for supporting deep linking)
DOMImportExtension (WIP)
The flaws with importDOM are very apparent.
forChildhack which is something but you have to decide what to do with Lexical nodes and not DOM. You also can't really ignore a subtree from a parent.This implementation aims to solve these problems with a backwards incompatible API and by adding import context. Import context is a key:value store that cascades (each node has the opportunity to override any set of key:value pairs). Context keys can be created with
createImportState, fetched with$getImportContextValue, and set with$withImportContext(for calling$next()) or by returning an array of pairs innextContextand/orchildContextto influence the behavior of the next importer for that node or its children.Test plan
Currently it's primarily some minimal tests that show the legacy support works the same way that the legacy code does
Also ships a dev-node-state-style example that demonstrates one of the use cases (having NodeState apply styles to any node both in create and export).