Skip to content

Dispose lexical editor#928

Merged
samuelpecher merged 12 commits intomainfrom
dispose
Mar 30, 2026
Merged

Dispose lexical editor#928
samuelpecher merged 12 commits intomainfrom
dispose

Conversation

@samuelpecher
Copy link
Copy Markdown
Collaborator

@samuelpecher samuelpecher commented Mar 28, 2026

Called editor.dispose() on element disconnection, which properly tears down listeners and event handlers.

  • handled a bug which registered an undefined listener
  • reworked lexxy tools with dispose function to force handler removal
  • made lexxy tools custom elements idempotent
  • added tests including leak tests

According to the performance tests we have no more leaked listeners or nodes:

10 iter Listeners Nodes
main +4440 +12685
dispose 0 0

Probably removes the need for a lot of #717

Without calling `dispose()`, Lexxy leaks references to an entire Lexical
reference on a reconnection cycle, for example during turbo navigation
when the element is in a `turbo-permanent` tree. Disposable must happen
before removal of the bound contenteditable.
Prevented editor `dispose` since the return of
`setScrollableTablesActive` is null.

Since the editor is registered in a WeakMap, no need to go to the
trouble of registering a clean-up function.
Copilot AI review requested due to automatic review settings March 28, 2026 09:35

This comment was marked as outdated.

Removing tools before editor disposal run their tear-down and handler
deregistration, preventing them firing when the editor state changes one
last time on disconnect.

Fix tableHandler -> tableTools name problem
…itor

When removing an element, `disconnectedCallback` on child elements is
enqueued after the parent, so various handlers remain in place and fire
when the editor is disposed. Calling `remove()` does not fire the event
since the element is already gone from the DOM. Extracting to
`dispose()` allows synchronously removing the handlers and preventing
undesired updates.

Given the forced disposal of handlers, tools which are custom elements
don't require de-registration as they will be re-connected on
re-intertion.
As custom handlers are disposed appropriately, there's no need to remove
the elements from the DOM, which will simply re-connect when added back
to the DOM.

Clean-up toolbar-dropdown initialization

Made custom element tool idempotent (or at least closer). Find existing
elements or ensure a clean slate before creation
Null the toolbar reference to avoid turbo morphing wiping the toolbar
dom while keeping an outdated reference to it.

The lifecycle handling could do with a rethink, but this will be a step
forward.
Copilot AI review requested due to automatic review settings March 28, 2026 23:14

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/browser/tests/editor/leak.test.js
Comment thread src/elements/toolbar_dropdown.js
Comment thread src/elements/toolbar.js
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/elements/toolbar.js
@samuelpecher samuelpecher merged commit a45ca25 into main Mar 30, 2026
11 checks passed
@samuelpecher samuelpecher deleted the dispose branch March 30, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants