-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[lexical] Bug Fix: Handle MutationObserver/input event re-ordering when using contentEditable inside of an iframe #7045
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
size-limit report 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a tricky one, thanks for looking into this! 😮
@@ -290,7 +290,7 @@ function onSelectionChange( | |||
return; | |||
} | |||
} | |||
updateEditor(editor, () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we foresee any performance impact of sync update events? I presume that this makes it possible for multiple reconciliations to happen almost simultaneously
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No performance impact, the behavior only differs for nested updates in which case it’s inlined like dispatchCommand instead of deferred to after the current updateFn returns. It just runs code in the order you expect it to happen, doesn’t otherwise change semantics of reconciliation which still happens on the tick after the updating started (note that no tests had to change here).
Description
Sometimes when an iframe is used as the contentEditable then the MutationObserver can fire after the input event, even if the mutation actually did happen. This causes problems that were undiagnosed prior to the addition of
$validatePoint
in__DEV__
(part of #6759) because the Lexical selection would refer to DOM coordinates that were not yet valid in the Lexical document, because the DOM was mutated before getting the selection. When the mutation observer happens first this doesn't occur because either the mutation is applied and/or the selection code is skipped due togetIsProcessingMutations()
(see$internalCreateRangeSelection
). This is related to the optimization(?) in #794 that avoids explicitly flushing root mutations on input.This PR:
dev:monorepo
script so you can run it with the monorepo like the playground rather than with the npm installed lexical for easier development/debugging (maybe we add this to other examples?)updateEditorSync
instead ofupdateEditor
in the places that I visited along the way, for in-order executionevent
option toUpdateOptions
so that the reason for the update can be captured in a way that's accessible by the code in$internalCreateRangeSelection
that checks to see if it's from a mutation or from some specific set of events before deciding whether to use the DOM selection or not. We don't want to use the DOM selection before input because it might refer to DOM coordinates that do not exist in the lexical document yet.getWindow
foreditor._window
in the core package (just a general clean-up while investigating)Closes #7028
Test plan
I'm not exactly sure how to reasonably add tests for this
Before
Error when typing into the end of a TextNode in an iframe on Chrome or Firefox
After
No more errors