[lexical-markdown] Bug Fix: don't emit a dangling closing tag when a selection slices a format to whitespace - #8961
Merged
etrepum merged 2 commits intoAug 8, 2026
Conversation
…selection slices a format to whitespace ## Description `exportTextFormat` decides whether a node carries a format from the node's whole text, via `checkHasFormat`, but decides whether to emit the tags from the `textContent` argument, which on the selection path is the node sliced down to the selected range. When a selection slices a formatted node down to whitespace the two disagree: the tag is pushed onto `unclosedTags` while the opening tag is thrown away by the whitespace early return, so the next node closes a tag that was never opened. Opening-tag registration is now skipped when the exported text is whitespace-only. The full-document path is unaffected, since there `checkHasFormat` already rejects whitespace-only nodes. ## Test plan ### Before expected ' b**' to be ' **b**' ### After 417 passed in the markdown suite; 5251 passed in the full unit run. The two remaining failures are pre-existing Windows shell failures in scripts/__tests__/unit/childProcess.test.ts.
luantaraschi
requested review from
acywatson,
etrepum,
fantactuka,
ivailop7 and
potatowagon
as code owners
August 7, 2026 16:49
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
etrepum
approved these changes
Aug 8, 2026
|
@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. |
Merged
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
exportTextFormatdecides two different things from two different strings, and a selection export can make them disagree.Whether the node carries a format comes from
checkHasFormat, which reads the node's whole text and rejects nodes that are entirely whitespace:Whether the tags are actually emitted comes from
isWhitespaceOnly, computed from thetextContentargument, which on the selection path is the node sliced down to the selected range:When a selection slices a formatted node down to whitespace, the first check passes and the second one fires. The tag is pushed onto
unclosedTagsbut the opening tag is thrown away by the early return, so the next node closes a tag that was never opened.Two bold text nodes,
'a 'and'b', with the selection running from offset 1 of the first through the second:The
**at the end has no opener, so the output is not valid markdown.The opening-tag registration is now skipped when the exported text is whitespace-only. The early return already discards those tags, so registering them had no effect other than corrupting the shared
unclosedTagslist. The following node then sees no pending**, opens its own, and closes it.This does not change the full-document path: there
textContentis the node's whole text, soisWhitespaceOnlycan only be true whencheckHasFormatalready returned false for every format.Test plan
Before
After
Full
vitest run: 5251 passed, 2 skipped. The two failures are inscripts/__tests__/unit/childProcess.test.tsand are about shell env forwarding on Windows. They reproduce on a cleanmainwith this change stashed, so they are not related to it.pnpm run prettierandpnpm run tscare clean.