diff --git a/packages/lexical/src/LexicalSelection.ts b/packages/lexical/src/LexicalSelection.ts index 24ae233c552..b4f70f95216 100644 --- a/packages/lexical/src/LexicalSelection.ts +++ b/packages/lexical/src/LexicalSelection.ts @@ -2473,18 +2473,6 @@ function $normalizeSelectionPointsForBoundaries( if (isCollapsed) { focus.set(anchor.key, anchor.offset, anchor.type); } - const editor = getActiveEditor(); - - if ( - editor.isComposing() && - editor._compositionKey !== anchor.key && - $isRangeSelection(lastSelection) - ) { - const lastAnchor = lastSelection.anchor; - const lastFocus = lastSelection.focus; - anchor.set(lastAnchor.key, lastAnchor.offset, lastAnchor.type, true); - focus.set(lastFocus.key, lastFocus.offset, lastFocus.type, true); - } } } @@ -2687,11 +2675,29 @@ export function $internalCreateRangeSelection( return null; } const [resolvedAnchorPoint, resolvedFocusPoint] = resolvedSelectionPoints; + let format = 0; + let style = ''; + if ($isRangeSelection(lastSelection)) { + const lastAnchor = lastSelection.anchor; + if (resolvedAnchorPoint.key === lastAnchor.key) { + format = lastSelection.format; + style = lastSelection.style; + } else { + const anchorNode = resolvedAnchorPoint.getNode(); + if ($isTextNode(anchorNode)) { + format = anchorNode.getFormat(); + style = anchorNode.getStyle(); + } else if ($isElementNode(anchorNode)) { + format = anchorNode.getTextFormat(); + style = anchorNode.getTextStyle(); + } + } + } return new RangeSelection( resolvedAnchorPoint, resolvedFocusPoint, - !$isRangeSelection(lastSelection) ? 0 : lastSelection.format, - !$isRangeSelection(lastSelection) ? '' : lastSelection.style, + format, + style, ); } diff --git a/packages/lexical/src/__tests__/unit/LexicalSelection.test.ts b/packages/lexical/src/__tests__/unit/LexicalSelection.test.ts index dddfd3bfdc3..7222a80784e 100644 --- a/packages/lexical/src/__tests__/unit/LexicalSelection.test.ts +++ b/packages/lexical/src/__tests__/unit/LexicalSelection.test.ts @@ -29,6 +29,7 @@ import { $setSelection, createEditor, ElementNode, + getDOMSelection, LexicalEditor, type LexicalNode, ParagraphNode, @@ -38,6 +39,7 @@ import { import {beforeEach, describe, expect, test} from 'vitest'; import {SerializedElementNode} from '../..'; +import {$internalCreateRangeSelection} from '../../LexicalSelection'; import { $assertRangeSelection, $createTestDecoratorNode, @@ -1675,3 +1677,49 @@ describe('Regression #8067', () => { }); }); }); + +describe('Regression #8098', () => { + initializeUnitTest((testEnv) => { + test('Do not apply format and style when moving to different node', async () => { + const {editor} = testEnv; + let normalTextKey: string; + + await editor.update( + () => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + const firstNode = $createTextNode('가다'); + firstNode.toggleFormat('bold'); + const lastNode = $createTextNode('라바'); + paragraph.append(firstNode, lastNode); + root.clear().append(paragraph); + firstNode.select(0, 0).format = 1; + normalTextKey = lastNode.getKey(); + }, + {discrete: true}, + ); + + const domSelection = getDOMSelection(editor._window ?? window); + const range = document.createRange(); + range.setStart(editor.getElementByKey(normalTextKey!)!.firstChild!, 1); + range.collapse(true); + domSelection?.removeAllRanges(); + domSelection?.addRange(range); + + await editor.update( + () => { + const selection = $internalCreateRangeSelection( + $getSelection(), + domSelection, + editor, + {type: 'selectionchange'} as Event, + ); + expect(selection).not.toBeNull(); + expect(selection!.format).toBe(0); + expect(selection!.style).toBe(''); + }, + {discrete: true}, + ); + }); + }); +});