Skip to content

[lexical-html][lexical-playground] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM#8368

Merged
etrepum merged 8 commits intofacebook:mainfrom
etrepum:domextension-override-sort
Apr 23, 2026
Merged

[lexical-html][lexical-playground] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM#8368
etrepum merged 8 commits intofacebook:mainfrom
etrepum:domextension-override-sort

Conversation

@etrepum
Copy link
Copy Markdown
Collaborator

@etrepum etrepum commented Apr 18, 2026

Description

Implement a natural topological ordering for DOMRenderExtension overrides based on class hierarchy as a follow-up to #8353

  • Wildcards ('*') have highest priority
  • Predicates ($isParagraphNode) have next priority
  • Subclasses have higher priority (e.g. ParagraphNode before ElementNode)
  • Extensions closer to the root have higher priority
  • Extensions depended on later have higher priority
  • Overrides defined later have higher priority

This should be the least surprising ordering and moving guards/wildcards to the highest priority allows for a more efficient getType based dispatch in more cases.

Demonstrates this ability in the playground with a TerseExportExtension that defines some $exportDOM overrides that are used to make the "Convert to HTML" output a bit more readable (mostly removes theme classes and style="white-space: pre" when not needed). Also makes the markdown and html views more robust by applying a transform to ensure that the CodeNode is always there when it's supposed to be.

New $decorateDOM override

Adds a $decorateDOM hook to DOMRenderExtension overrides that runs after a node is created or updated, after its children have been reconciled. It is intended for in-place DOM modifications (such as attributes) that would otherwise have to be duplicated across $createDOM and $updateDOM, or that need to observe fully-reconciled child DOM.

  • Signature: (nextNode, prevNode, dom, editor) => void. prevNode is null on create, and the previous node on update (when $updateDOM returned false).
  • Unlike other overrides, $decorateDOM has no $next argument — all applicable overrides are called unconditionally. The ordering is equivalent to an implicit $next call first, so less-specific overrides run before more-specific ones (base class, then subclass, then predicate, with wildcard last), which is the inverse of the $createDOM/$updateDOM chain since those can decide when to call $next.
  • Runs after the slot has been populated with children, so decorators can inspect the reconciled subtree if needed.

The dev-node-state-style example has been simplified to use $decorateDOM in place of the paired $createDOM/$updateDOM style-application logic.

Test plan

  • Unit tests were changed to match the new ordering (the named functions help with debugging potential test failures by giving them distinct names)
  • New DOMRenderExtension tests cover $decorateDOM behavior: create-vs-update prevNode, multi-override sequencing (base, subclass, wildcard), and verifying children are reconciled before decoration.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexical Ready Ready Preview, Comment Apr 23, 2026 4:35am
lexical-playground Ready Ready Preview, Comment Apr 23, 2026 4:35am

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 18, 2026
@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label Apr 18, 2026
@etrepum etrepum changed the title [lexical-html] Bug Fix: Implement a well-defined ordering for DOMRenderExtension overrides [lexical-html] Feature: Implement a well-defined ordering for DOMRenderExtension overrides Apr 18, 2026
@etrepum etrepum changed the title [lexical-html] Feature: Implement a well-defined ordering for DOMRenderExtension overrides [lexical-html] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM Apr 18, 2026
@etrepum etrepum changed the title [lexical-html] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM [lexical-html][lexical-playground] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM Apr 23, 2026
@etrepum etrepum added this pull request to the merge queue Apr 23, 2026
Merged via the queue into facebook:main with commit 207648e Apr 23, 2026
41 checks passed
@etrepum etrepum deleted the domextension-override-sort branch April 23, 2026 14:12
vishisht31 pushed a commit that referenced this pull request Apr 23, 2026
…ordering for DOMRenderExtension overrides and add $decorateDOM (#8368)
levensta added a commit to levensta/lexical that referenced this pull request Apr 24, 2026
commit 5d1bc33
Author: Sathvik Veerapaneni <98241593+Sathvik-Chowdary-Veerapaneni@users.noreply.github.com>
Date:   Thu Apr 23 13:12:21 2026 -0400

    [lexical-list] Bug Fix: Merge nested list into parent <li> during HTML export (facebook#8313)

    Co-authored-by: Bob Ippolito <bob@redivi.com>

commit 2c37dc2
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:14:14 2026 -0700

    [lexical-clipboard][lexical-rich-text][lexical-plain-text] Bug Fix: Drag-and-drop within the same block (facebook#8373)

    Co-authored-by: Claude <noreply@anthropic.com>

commit ca2aa31
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:12:43 2026 -0700

    [lexical][lexical-utils][lexical-list] Bug Fix: Clean up and test $insertNodeToNearestRootAtCaret edge cases (facebook#8384)

commit 207648e
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:11:52 2026 -0700

    [lexical-html][lexical-playground] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM (facebook#8368)

commit 1ca42f1
Author: Agyei Holy <agyeiholy978@gmail.com>
Date:   Wed Apr 22 15:39:37 2026 -0500

    [lexical][lexical-code-core][lexical-list][lexical-table][lexical-yjs] Refactor: make runtime style updates CSP-safe (facebook#8372)

commit ca0ce82
Author: Bob Ippolito <bob@redivi.com>
Date:   Wed Apr 22 12:57:28 2026 -0700

    [lexical-list] Bug Fix: Ensure that ListItemNode always has a ListItem parent (facebook#8382)

commit f4c44e1
Author: Sherry <potatowagon@meta.com>
Date:   Thu Apr 23 00:28:54 2026 +0530

    [lexical-markdown] Bug Fix: Code spans take precedence over inline formatting in shortcuts (facebook#8381)

commit 4a43cb0
Author: Sergey Gorbachev <grbchv.s@gmail.com>
Date:   Wed Apr 22 18:31:21 2026 +0300

    [lexical-playground] Feature: HTML conversion button (facebook#8379)
levensta added a commit to levensta/lexical that referenced this pull request Apr 24, 2026
commit 5d1bc33
Author: Sathvik Veerapaneni <98241593+Sathvik-Chowdary-Veerapaneni@users.noreply.github.com>
Date:   Thu Apr 23 13:12:21 2026 -0400

    [lexical-list] Bug Fix: Merge nested list into parent <li> during HTML export (facebook#8313)

    Co-authored-by: Bob Ippolito <bob@redivi.com>

commit 2c37dc2
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:14:14 2026 -0700

    [lexical-clipboard][lexical-rich-text][lexical-plain-text] Bug Fix: Drag-and-drop within the same block (facebook#8373)

    Co-authored-by: Claude <noreply@anthropic.com>

commit ca2aa31
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:12:43 2026 -0700

    [lexical][lexical-utils][lexical-list] Bug Fix: Clean up and test $insertNodeToNearestRootAtCaret edge cases (facebook#8384)

commit 207648e
Author: Bob Ippolito <bob@redivi.com>
Date:   Thu Apr 23 07:11:52 2026 -0700

    [lexical-html][lexical-playground] Feature: Implement a well-defined ordering for DOMRenderExtension overrides and add $decorateDOM (facebook#8368)

commit 1ca42f1
Author: Agyei Holy <agyeiholy978@gmail.com>
Date:   Wed Apr 22 15:39:37 2026 -0500

    [lexical][lexical-code-core][lexical-list][lexical-table][lexical-yjs] Refactor: make runtime style updates CSP-safe (facebook#8372)

commit ca0ce82
Author: Bob Ippolito <bob@redivi.com>
Date:   Wed Apr 22 12:57:28 2026 -0700

    [lexical-list] Bug Fix: Ensure that ListItemNode always has a ListItem parent (facebook#8382)

commit f4c44e1
Author: Sherry <potatowagon@meta.com>
Date:   Thu Apr 23 00:28:54 2026 +0530

    [lexical-markdown] Bug Fix: Code spans take precedence over inline formatting in shortcuts (facebook#8381)

commit 4a43cb0
Author: Sergey Gorbachev <grbchv.s@gmail.com>
Date:   Wed Apr 22 18:31:21 2026 +0300

    [lexical-playground] Feature: HTML conversion button (facebook#8379)
@etrepum etrepum mentioned this pull request Apr 27, 2026
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants