diff --git a/packages/roosterjs-editor-plugins/lib/plugins/ImageEdit/ImageEdit.ts b/packages/roosterjs-editor-plugins/lib/plugins/ImageEdit/ImageEdit.ts
index 7173d0e0f49..92b48098683 100644
--- a/packages/roosterjs-editor-plugins/lib/plugins/ImageEdit/ImageEdit.ts
+++ b/packages/roosterjs-editor-plugins/lib/plugins/ImageEdit/ImageEdit.ts
@@ -218,6 +218,13 @@ export default class ImageEdit implements EditorPlugin {
this.setEditingImage(null);
}
break;
+ case PluginEventType.MouseUp:
+ // When mouse up, if the image and the shadow span exists, the editing mode is on.
+ // To make sure the selection did not jump to the shadow root, reselect the image.
+ if (this.image && this.shadowSpan) {
+ this.editor?.select(this.image);
+ }
+ break;
case PluginEventType.KeyDown:
this.setEditingImage(null);
break;
diff --git a/packages/roosterjs-editor-plugins/test/imageEdit/imageEditTest.ts b/packages/roosterjs-editor-plugins/test/imageEdit/imageEditTest.ts
index 72dd5b694c8..6a317d352f2 100644
--- a/packages/roosterjs-editor-plugins/test/imageEdit/imageEditTest.ts
+++ b/packages/roosterjs-editor-plugins/test/imageEdit/imageEditTest.ts
@@ -1,7 +1,13 @@
import * as TestHelper from '../TestHelper';
import ImageEditInfo from '../../lib/plugins/ImageEdit/types/ImageEditInfo';
-import { IEditor, ImageEditOperation, PluginEvent, PluginEventType } from 'roosterjs-editor-types';
import { ImageEdit } from '../../lib/ImageEdit';
+import {
+ IEditor,
+ ImageEditOperation,
+ PluginEvent,
+ PluginEventType,
+ SelectionRangeTypes,
+} from 'roosterjs-editor-types';
import {
getEditInfoFromImage,
saveEditInfo,
@@ -225,7 +231,7 @@ describe('ImageEdit | rotate and flip', () => {
});
});
-describe('ImageEdit | plugin events | quitting', () => {
+describe('ImageEdit | plugin events | ', () => {
let editor: IEditor;
const TEST_ID = 'imageEditTest';
let plugin: ImageEdit;
@@ -270,22 +276,34 @@ describe('ImageEdit | plugin events | quitting', () => {
target.dispatchEvent(event);
};
- it('image selection quit editing', () => {
- const IMG_ID = 'IMAGE_ID_QUIT';
+ const mouseUp = (target: HTMLElement, keyNumber: number) => {
+ const rect = target.getBoundingClientRect();
+ const event = new MouseEvent('mouseup', {
+ view: window,
+ bubbles: true,
+ cancelable: true,
+ clientX: rect.left,
+ clientY: rect.top,
+ shiftKey: false,
+ button: keyNumber,
+ });
+ target.dispatchEvent(event);
+ };
+
+ it('mouse up | keep image selected if click in a image', () => {
+ const IMG_ID = 'IMAGE_ID_MOUSE';
const SPAN_ID = 'SPAN_ID';
const content = ``;
editor.setContent(content);
const image = document.getElementById(IMG_ID) as HTMLImageElement;
editor.focus();
editor.select(image);
- expect(setEditingImageSpy).toHaveBeenCalled();
- expect(setEditingImageSpy).toHaveBeenCalledWith(
- image as any,
- ImageEditOperation.ResizeAndRotate as any
- );
+ mouseUp(image, 0);
+ const selection = editor.getSelectionRangeEx();
+ expect(selection.type).toBe(SelectionRangeTypes.ImageSelection);
});
- it('mousedown quit editing', () => {
+ it('quitting | mousedown quit editing', () => {
const IMG_ID = 'IMAGE_ID_MOUSE';
const SPAN_ID = 'SPAN_ID';
const content = ``;
@@ -294,12 +312,12 @@ describe('ImageEdit | plugin events | quitting', () => {
const span = document.getElementById(SPAN_ID) as HTMLImageElement;
editor.focus();
editor.select(image);
- mouseDown(span, 0);
+ mouseDown(span, 2);
expect(setEditingImageSpy).toHaveBeenCalled();
expect(setEditingImageSpy).toHaveBeenCalledWith(null);
});
- it('keydown quit editing', () => {
+ it('quitting | keydown quit editing', () => {
const IMG_ID = 'IMAGE_ID';
const content = ``;
editor.setContent(content);