[lexical] Bug Fix: Preserve text alignment when pasting into non-empty paragraph#8310
Conversation
…y paragraph When pasting a block with explicit alignment (center, right, justify) into a non-empty paragraph, the alignment was lost because insertNodes only merged children without propagating the format property. Closes facebook#8101
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
etrepum
left a comment
There was a problem hiding this comment.
This fails ci-check and probably doesn't really fix the problem, the conditions where you actually want the paragraph alignment to carry over are not this simple.
The last abandoned attempt is here which was close but not quite correct #8102
|
Thanks for the review. I looked at #8102 — the Would you prefer I rework this using the |
|
It should really only carry over alignment when the paste destination is empty, or it's creating a new block. This was what was broken with #8102, it modified the alignment and created new paragraphs when it shouldn't have. You can validate what the behavior should be by trying out some other editors like google docs. |
|
Got it — I traced through the code and the empty paragraph case already works correctly (isMergeable returns false, pasted block keeps its format). For non-empty destinations, alignment staying as-is matches Google Docs behavior. I've reverted the setFormat change. Should I close this PR since the reported issue (#8101) describes behavior that's actually correct per editor conventions? |
…on-empty destinations
Empty paragraph destination: alignment carries over from pasted content. Non-empty paragraph destination: alignment stays unchanged (matches Google Docs).
|
After investigating further — the current behavior is actually correct:
I've reverted the code change and updated the PR to just add two tests documenting this behavior. If you'd rather close this PR entirely, happy to do that too. |
|
I think the thing that does not currently work as expected is that copying and pasting a partial paragraph (or the entire text of an existing paragraph) may not carry over the paragraph alignment and formatting when pasted into an empty paragraph. |
|
Found the root cause — Added an |
|
I don't know, try it and see what happens. Don't know without an audit of the code, the whole test run, and some QA |
…verride ParagraphNode.extractWithChild now returns true when the paragraph has non-default alignment, so the paragraph wrapper (and its format) is included in the clipboard during copy. This fixes the root cause of facebook#8101 where copying text from a centered paragraph lost alignment info.
|
Pushed the extractWithChild override — CI should confirm. The fix preserves the paragraph wrapper in the clipboard when alignment is non-default, so paste into an empty paragraph carries over the format. Added tests for both empty and non-empty destination cases. |
| extractWithChild( | ||
| child: LexicalNode, | ||
| selection: BaseSelection | null, | ||
| destination: 'clone' | 'html', | ||
| ): boolean { | ||
| const formatType = this.getFormatType(); | ||
| return formatType !== '' && formatType !== 'left' && formatType !== 'start'; | ||
| } |
There was a problem hiding this comment.
Interestingly in Google Docs the text/html representation of the nodes doesn't include the paragraph at all when there's a slice, so I'm not 100% sure that extractWithChild for html destinations is the best approach here for compatibility reasons. It does include that information in the json though, so maybe we should try something like destination === 'clone' instead which would be a bit less invasive for interoperability with other applications since that only affects the json output.
Review: Preserve Text Alignment When Pasting Into Non-Empty ParagraphReviewed by: Navi (AI review assistant for @potatowagon) SummarySimilar to #8438 but approaches the paste-alignment problem differently. This PR preserves the pasted block's alignment when merging into the destination block, only when the destination has no explicit format ( What I Verified
Relationship to #8438This PR and #8438 address the same issue with essentially the same approach. The code change in Verdict |
potatowagon
left a comment
There was a problem hiding this comment.
Review — Preserve Text Alignment When Pasting
Assessment: Superseded by #8438
What I verified:
-
Same issue as #8438: Both PRs fix the same alignment-preservation bug during paste operations. This PR takes a similar but slightly different approach.
-
Comparison with #8438: PR #8438 (by matingathani) has a cleaner implementation — a simple condition in one location with comprehensive tests. This PR (by Sathvik-Chowdary-Veerapaneni) also works correctly but adds more test scaffolding.
-
CI status: All checks pass (34 passing).
-
Recommendation: Since #8438 and #8310 address the same issue, only one should be merged. I'd lean toward #8438 for its simpler approach, but either works. The maintainers should pick one and close the other.
— via Navi on behalf of potatowagon
Description
When pasting a block with explicit alignment (center, right, justify) into a non-empty paragraph, the alignment was lost. The pasted text reverted to default left alignment.
The root cause is in
RangeSelection.insertNodes: when the first pasted block is mergeable, only its children are appended to the destination block — theformatproperty (which holds alignment) is discarded.Fixed by propagating the pasted block's format to the destination block before merging children, when the pasted block has explicit alignment.
Closes #8101
Test plan
Before
Copy a center-aligned paragraph → paste into a non-empty paragraph → alignment is lost.
After
Alignment is preserved on paste. Only applies when the pasted block has explicit alignment — pasting default-aligned content does not override the destination's existing alignment.
Added a unit test verifying center-aligned paste into a non-empty paragraph preserves the format.
All existing tests pass (2740 passed, 0 failed).