Skip to content

[lexical][lexical-selection] Bug Fix: Treat all TabNode as if they are in token mode - #7602

Merged
etrepum merged 4 commits into
facebook:mainfrom
etrepum:tabnode-as-token
Jun 3, 2025
Merged

etrepum merged 4 commits into
facebook:mainfrom
etrepum:tabnode-as-token

Conversation

@etrepum

@etrepum etrepum commented Jun 3, 2025 •

Copy link
Copy Markdown
Collaborator

Description

For legacy reasons TabNode is a 'normal' mode TextNode with the IS_UNMERGEABLE detail flag (used only in the reconciler's normalization), but the conditions in the rest of the core used node.isToken() to determine if the node should be modified or replaced without checking the IS_UNMERGEABLE flag.

To keep legacy serialization as-is, this PR changes the core to use $isTokenOrTab (new) and $isTokenOrSegmented functions instead of calling the TextNode.isToken method directly, and these functions both now check $isTabNode as part of their condition.

This also changes all property setters of __text to go through the setTextContent method (except for @lexical/selection's $sliceSelectedTextNodeContent which is used in an unusual "read-only" way), and adds an additional invariant to TabNode.spliceText to ensure that it is not modified by that either.

Closes #7601

Test plan

Unit tests to confirm that TabNode is not modified in the scenarios from #7601

@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label Jun 3, 2025
@vercel

vercel Bot commented Jun 3, 2025 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lexical ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 3, 2025 6:35pm
lexical-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 3, 2025 6:35pm

@facebook-github-bot facebook-github-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 Jun 3, 2025
@etrepum
etrepum added this pull request to the merge queue Jun 3, 2025
Merged via the queue into facebook:main with commit d923795 Jun 3, 2025
@etrepum etrepum mentioned this pull request Jun 4, 2025
fantactuka pushed a commit that referenced this pull request Aug 11, 2025
mayrang added a commit to mayrang/lexical that referenced this pull request May 30, 2026
…or Safari IME compat (facebook#8596)

In Safari, the MutationObserver delivers mid-IME-composition text writes straight onto the `TabNode`'s `\t` text node — Korean / Japanese / similar IMEs compose onto the existing text node, and Safari rewrites it to `\tㅁ`. `flushMutations` then calls `TabNode.setTextContent('\tㅁ')`, the `devInvariant` throws, and the throw cascades through `onError`, freezing the editor (composition, Backspace, Enter, English input all stop working until a hard refresh).

The throw existed since `TabNode` was introduced, but the only path that surfaced it before was selection-based typing across the node (fixed by treating the node as token-mode in facebook#7602). The MutationObserver / IME path was uncovered.

Drop the `devInvariant` check entirely. The body already normalizes to `\t` via `super.setTextContent('\t')`, so the throw never carried information the reconciler couldn't recover from — the next update re-renders the canonical `\t`. A unit test exercises the exact `setTextContent('\tㅁ')` shape `flushMutations` produces so the regression doesn't return.

This branch was successfully deployed

2 active deployments
Preview – lexical-playground — a5a6e30d Deployed Jun 3, 2025 by vercel[bot]
Preview – lexical — a5a6e30d Deployed Jun 3, 2025 by vercel[bot]
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.

Bug: Typing to a selection including TabNode and TextNode adds text to TabNode

3 participants