diff --git a/packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts b/packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts index d25849d57613..1576c3013757 100644 --- a/packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts +++ b/packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts @@ -738,11 +738,11 @@ class SelectionPlugin implements PluginWithState { const newSelection = this.editor.getDOMSelection(); const domHelper = this.editor.getDOMHelper(); - //If am image selection changed to a wider range due a keyboard event, we should update the selection + // If an image selection changed to a wider range due to a keyboard event, we should update the selection const range = domHelper.getSelectionRange(); if (range) { const image = isSingleImageInSelection(range); - if (newSelection?.type == 'image' && !image) { + if (newSelection?.type == 'image' && !image && !range.collapsed) { const sel = this.editor.getDocument().defaultView?.getSelection(); const isReverted = sel ? sel.focusNode != range.endContainer || sel.focusOffset != range.endOffset diff --git a/packages/roosterjs-content-model-core/test/corePlugin/selection/SelectionPluginTest.ts b/packages/roosterjs-content-model-core/test/corePlugin/selection/SelectionPluginTest.ts index 42357b2f8e2f..9075f41c6d37 100644 --- a/packages/roosterjs-content-model-core/test/corePlugin/selection/SelectionPluginTest.ts +++ b/packages/roosterjs-content-model-core/test/corePlugin/selection/SelectionPluginTest.ts @@ -3698,6 +3698,38 @@ describe('SelectionPlugin selectionChange on image selected', () => { }); expect(getDOMSelectionSpy).toHaveBeenCalledTimes(1); }); + + it('onSelectionChange on image | 5, keeps image selection when range is collapsed', () => { + spyOn(isSingleImageInSelection, 'isSingleImageInSelection').and.returnValue(null); + + mockedRange = { startContainer: {}, collapsed: true } as any; + + const plugin = createSelectionPlugin({}); + const state = plugin.getState(); + const mockedOldSelection = { + type: 'image', + image: {} as any, + } as DOMSelection; + + state.selection = mockedOldSelection; + + plugin.initialize(editor); + + const onSelectionChange = addEventListenerSpy.calls.argsFor(0)[1] as Function; + const mockedNewSelection = { + type: 'image', + image: {} as any, + } as any; + + hasFocusSpy.and.returnValue(true); + isInShadowEditSpy.and.returnValue(false); + getDOMSelectionSpy.and.returnValue(mockedNewSelection); + + onSelectionChange(); + + expect(setDOMSelectionSpy).not.toHaveBeenCalled(); + expect(getDOMSelectionSpy).toHaveBeenCalledTimes(1); + }); }); describe('SelectionPlugin handle logical root change', () => {