-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[WIP][lexical][lexical-html] Feature: Extensible DOM create/update/export #7885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
etrepum
wants to merge
55
commits into
facebook:main
Choose a base branch
from
etrepum:extensible-dom-export
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
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
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
CLA Signed
This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
extended-tests
Run extended e2e tests on a PR
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).