roosterjs-content-model-plugins 9.35.0 → 9.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/edit/keyboardDelete.js +10 -5
  2. package/lib/edit/keyboardDelete.js.map +1 -1
  3. package/lib/imageEdit/ImageEditPlugin.d.ts +1 -1
  4. package/lib/imageEdit/ImageEditPlugin.js +11 -9
  5. package/lib/imageEdit/ImageEditPlugin.js.map +1 -1
  6. package/lib/imageEdit/utils/imageEditUtils.d.ts +0 -4
  7. package/lib/imageEdit/utils/imageEditUtils.js +1 -8
  8. package/lib/imageEdit/utils/imageEditUtils.js.map +1 -1
  9. package/lib/imageEdit/utils/updateWrapper.d.ts +1 -1
  10. package/lib/imageEdit/utils/updateWrapper.js +2 -2
  11. package/lib/imageEdit/utils/updateWrapper.js.map +1 -1
  12. package/lib-amd/edit/keyboardDelete.js +10 -5
  13. package/lib-amd/edit/keyboardDelete.js.map +1 -1
  14. package/lib-amd/imageEdit/ImageEditPlugin.d.ts +1 -1
  15. package/lib-amd/imageEdit/ImageEditPlugin.js +11 -9
  16. package/lib-amd/imageEdit/ImageEditPlugin.js.map +1 -1
  17. package/lib-amd/imageEdit/utils/imageEditUtils.d.ts +0 -4
  18. package/lib-amd/imageEdit/utils/imageEditUtils.js +1 -8
  19. package/lib-amd/imageEdit/utils/imageEditUtils.js.map +1 -1
  20. package/lib-amd/imageEdit/utils/updateWrapper.d.ts +1 -1
  21. package/lib-amd/imageEdit/utils/updateWrapper.js +2 -2
  22. package/lib-amd/imageEdit/utils/updateWrapper.js.map +1 -1
  23. package/lib-mjs/edit/keyboardDelete.js +10 -5
  24. package/lib-mjs/edit/keyboardDelete.js.map +1 -1
  25. package/lib-mjs/imageEdit/ImageEditPlugin.d.ts +1 -1
  26. package/lib-mjs/imageEdit/ImageEditPlugin.js +11 -9
  27. package/lib-mjs/imageEdit/ImageEditPlugin.js.map +1 -1
  28. package/lib-mjs/imageEdit/utils/imageEditUtils.d.ts +0 -4
  29. package/lib-mjs/imageEdit/utils/imageEditUtils.js +0 -6
  30. package/lib-mjs/imageEdit/utils/imageEditUtils.js.map +1 -1
  31. package/lib-mjs/imageEdit/utils/updateWrapper.d.ts +1 -1
  32. package/lib-mjs/imageEdit/utils/updateWrapper.js +3 -3
  33. package/lib-mjs/imageEdit/utils/updateWrapper.js.map +1 -1
  34. package/package.json +5 -5
@@ -18,10 +18,11 @@ var deleteCollapsedSelection_1 = require("./deleteSteps/deleteCollapsedSelection
18
18
  * @returns True if the event is handled by content model, otherwise false
19
19
  */
20
20
  function keyboardDelete(editor, rawEvent, handleExpandedSelection) {
21
+ var _a;
21
22
  if (handleExpandedSelection === void 0) { handleExpandedSelection = true; }
22
23
  var handled = false;
23
24
  var selection = editor.getDOMSelection();
24
- if (shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection)) {
25
+ if (shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection, (_a = editor.getEnvironment().isIOS) !== null && _a !== void 0 ? _a : false)) {
25
26
  editor.formatContentModel(function (model, context) {
26
27
  var result = (0, roosterjs_content_model_dom_1.deleteSelection)(model, getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac), context).deleteResult;
27
28
  handled = (0, handleKeyboardEventCommon_1.handleKeyboardEventResult)(editor, model, rawEvent, result, context);
@@ -58,7 +59,7 @@ function getDeleteSteps(rawEvent, isMac) {
58
59
  deleteParagraphStyle_1.deleteParagraphStyle,
59
60
  ];
60
61
  }
61
- function shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection) {
62
+ function shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection, isIOS) {
62
63
  var _a, _b;
63
64
  if (!selection) {
64
65
  return false; // Nothing to delete
@@ -84,15 +85,19 @@ function shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelecti
84
85
  // When selection is collapsed and is in middle of text node, no need to use Content Model to delete
85
86
  return !((0, roosterjs_content_model_dom_1.isNodeOfType)(startContainer, 'TEXT_NODE') &&
86
87
  !(0, roosterjs_content_model_dom_1.isModifierKey)(rawEvent) &&
87
- (canDeleteBefore(rawEvent, startContainer, startOffset) ||
88
+ (canDeleteBefore(rawEvent, startContainer, startOffset, isIOS) ||
88
89
  canDeleteAfter(rawEvent, startContainer, startOffset)));
89
90
  }
90
91
  }
91
- function canDeleteBefore(rawEvent, text, offset) {
92
+ function canDeleteBefore(rawEvent, text, offset, isIOS) {
92
93
  var _a, _b;
93
- if (rawEvent.key != 'Backspace' || offset <= 1) {
94
+ if (rawEvent.key != 'Backspace') {
94
95
  return false;
95
96
  }
97
+ if (offset <= 1) {
98
+ // For iOS, allow browser to handle deletion of first character on iOS to preserve auto-capitalization
99
+ return offset === 1 && isIOS;
100
+ }
96
101
  var length = (_b = (_a = text.nodeValue) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
97
102
  if (offset == length) {
98
103
  // At the end of text, need to check if next segment is deletable
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardDelete.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardDelete.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteAllSegmentBefore } from './deleteSteps/deleteAllSegmentBefore';\nimport { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';\nimport { deleteList } from './deleteSteps/deleteList';\nimport { deleteParagraphStyle } from './deleteSteps/deleteParagraphStyle';\nimport {\n ChangeSource,\n deleteSelection,\n isElementOfType,\n isLinkUndeletable,\n isModifierKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport {\n handleKeyboardEventResult,\n shouldDeleteAllSegmentsBefore,\n shouldDeleteWord,\n} from './handleKeyboardEventCommon';\nimport {\n backwardDeleteWordSelection,\n forwardDeleteWordSelection,\n} from './deleteSteps/deleteWordSelection';\nimport {\n backwardDeleteCollapsedSelection,\n forwardDeleteCollapsedSelection,\n} from './deleteSteps/deleteCollapsedSelection';\nimport type { DOMSelection, DeleteSelectionStep, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Do keyboard event handling for DELETE/BACKSPACE key\n * @param editor The editor object\n * @param rawEvent DOM keyboard event\n * @param handleExpandedSelection Whether to handle expanded selection within a text node by CM\n * @returns True if the event is handled by content model, otherwise false\n */\nexport function keyboardDelete(\n editor: IEditor,\n rawEvent: KeyboardEvent,\n handleExpandedSelection: boolean = true\n) {\n let handled = false;\n const selection = editor.getDOMSelection();\n\n if (shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection)) {\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(\n model,\n getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac),\n context\n ).deleteResult;\n\n handled = handleKeyboardEventResult(editor, model, rawEvent, result, context);\n return handled;\n },\n {\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n scrollCaretIntoView: true,\n apiName: rawEvent.key == 'Delete' ? 'handleDeleteKey' : 'handleBackspaceKey',\n }\n );\n }\n\n return handled;\n}\n\nfunction getDeleteSteps(rawEvent: KeyboardEvent, isMac: boolean): (DeleteSelectionStep | null)[] {\n const isForward = rawEvent.key == 'Delete';\n const deleteAllSegmentBeforeStep =\n shouldDeleteAllSegmentsBefore(rawEvent) && !isForward ? deleteAllSegmentBefore : null;\n const deleteWordSelection = shouldDeleteWord(rawEvent, isMac)\n ? isForward\n ? forwardDeleteWordSelection\n : backwardDeleteWordSelection\n : null;\n const deleteCollapsedSelection = isForward\n ? forwardDeleteCollapsedSelection\n : backwardDeleteCollapsedSelection;\n const deleteQuote = !isForward ? deleteEmptyQuote : null;\n return [\n deleteAllSegmentBeforeStep,\n deleteWordSelection,\n isForward ? null : deleteList,\n deleteCollapsedSelection,\n deleteQuote,\n deleteParagraphStyle,\n ];\n}\n\nfunction shouldDeleteWithContentModel(\n selection: DOMSelection | null,\n rawEvent: KeyboardEvent,\n handleExpandedSelection: boolean\n) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (selection.type != 'range') {\n return true;\n } else if (!selection.range.collapsed) {\n if (handleExpandedSelection) {\n return true; // Selection is not collapsed, need to delete all selections\n }\n\n const range = selection.range;\n const { startContainer, endContainer } = selection.range;\n const isInSameTextNode =\n startContainer === endContainer && isNodeOfType(startContainer, 'TEXT_NODE');\n return !(\n isInSameTextNode &&\n !isModifierKey(rawEvent) &&\n range.endOffset - range.startOffset < (startContainer.nodeValue?.length ?? 0)\n );\n } else {\n const range = selection.range;\n const startContainer = range.startContainer;\n const startOffset = range.startOffset;\n\n // When selection is collapsed and is in middle of text node, no need to use Content Model to delete\n return !(\n isNodeOfType(startContainer, 'TEXT_NODE') &&\n !isModifierKey(rawEvent) &&\n (canDeleteBefore(rawEvent, startContainer, startOffset) ||\n canDeleteAfter(rawEvent, startContainer, startOffset))\n );\n }\n}\n\nfunction canDeleteBefore(rawEvent: KeyboardEvent, text: Text, offset: number) {\n if (rawEvent.key != 'Backspace' || offset <= 1) {\n return false;\n }\n\n const length = text.nodeValue?.length ?? 0;\n\n if (offset == length) {\n // At the end of text, need to check if next segment is deletable\n const nextSibling = text.nextSibling;\n const isNextSiblingUndeletable =\n isNodeOfType(nextSibling, 'ELEMENT_NODE') &&\n isElementOfType(nextSibling, 'a') &&\n isLinkUndeletable(nextSibling) &&\n !nextSibling.firstChild;\n\n // If next sibling is undeletable, we cannot let browser handle it since it will remove the anchor\n // So we return false here to let Content Model handle it\n return !isNextSiblingUndeletable;\n } else {\n // In middle of text, we can safely let browser handle deletion\n return true;\n }\n}\n\nfunction canDeleteAfter(rawEvent: KeyboardEvent, text: Text, offset: number) {\n return rawEvent.key == 'Delete' && offset < (text.nodeValue?.length ?? 0) - 1;\n}\n"]}
1
+ {"version":3,"file":"keyboardDelete.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardDelete.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteAllSegmentBefore } from './deleteSteps/deleteAllSegmentBefore';\nimport { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';\nimport { deleteList } from './deleteSteps/deleteList';\nimport { deleteParagraphStyle } from './deleteSteps/deleteParagraphStyle';\nimport {\n ChangeSource,\n deleteSelection,\n isElementOfType,\n isLinkUndeletable,\n isModifierKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport {\n handleKeyboardEventResult,\n shouldDeleteAllSegmentsBefore,\n shouldDeleteWord,\n} from './handleKeyboardEventCommon';\nimport {\n backwardDeleteWordSelection,\n forwardDeleteWordSelection,\n} from './deleteSteps/deleteWordSelection';\nimport {\n backwardDeleteCollapsedSelection,\n forwardDeleteCollapsedSelection,\n} from './deleteSteps/deleteCollapsedSelection';\nimport type { DOMSelection, DeleteSelectionStep, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Do keyboard event handling for DELETE/BACKSPACE key\n * @param editor The editor object\n * @param rawEvent DOM keyboard event\n * @param handleExpandedSelection Whether to handle expanded selection within a text node by CM\n * @returns True if the event is handled by content model, otherwise false\n */\nexport function keyboardDelete(\n editor: IEditor,\n rawEvent: KeyboardEvent,\n handleExpandedSelection: boolean = true\n) {\n let handled = false;\n const selection = editor.getDOMSelection();\n\n if (\n shouldDeleteWithContentModel(\n selection,\n rawEvent,\n handleExpandedSelection,\n editor.getEnvironment().isIOS ?? false\n )\n ) {\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(\n model,\n getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac),\n context\n ).deleteResult;\n\n handled = handleKeyboardEventResult(editor, model, rawEvent, result, context);\n return handled;\n },\n {\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n scrollCaretIntoView: true,\n apiName: rawEvent.key == 'Delete' ? 'handleDeleteKey' : 'handleBackspaceKey',\n }\n );\n }\n\n return handled;\n}\n\nfunction getDeleteSteps(rawEvent: KeyboardEvent, isMac: boolean): (DeleteSelectionStep | null)[] {\n const isForward = rawEvent.key == 'Delete';\n const deleteAllSegmentBeforeStep =\n shouldDeleteAllSegmentsBefore(rawEvent) && !isForward ? deleteAllSegmentBefore : null;\n const deleteWordSelection = shouldDeleteWord(rawEvent, isMac)\n ? isForward\n ? forwardDeleteWordSelection\n : backwardDeleteWordSelection\n : null;\n const deleteCollapsedSelection = isForward\n ? forwardDeleteCollapsedSelection\n : backwardDeleteCollapsedSelection;\n const deleteQuote = !isForward ? deleteEmptyQuote : null;\n return [\n deleteAllSegmentBeforeStep,\n deleteWordSelection,\n isForward ? null : deleteList,\n deleteCollapsedSelection,\n deleteQuote,\n deleteParagraphStyle,\n ];\n}\n\nfunction shouldDeleteWithContentModel(\n selection: DOMSelection | null,\n rawEvent: KeyboardEvent,\n handleExpandedSelection: boolean,\n isIOS: boolean\n) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (selection.type != 'range') {\n return true;\n } else if (!selection.range.collapsed) {\n if (handleExpandedSelection) {\n return true; // Selection is not collapsed, need to delete all selections\n }\n\n const range = selection.range;\n const { startContainer, endContainer } = selection.range;\n const isInSameTextNode =\n startContainer === endContainer && isNodeOfType(startContainer, 'TEXT_NODE');\n return !(\n isInSameTextNode &&\n !isModifierKey(rawEvent) &&\n range.endOffset - range.startOffset < (startContainer.nodeValue?.length ?? 0)\n );\n } else {\n const range = selection.range;\n const startContainer = range.startContainer;\n const startOffset = range.startOffset;\n\n // When selection is collapsed and is in middle of text node, no need to use Content Model to delete\n return !(\n isNodeOfType(startContainer, 'TEXT_NODE') &&\n !isModifierKey(rawEvent) &&\n (canDeleteBefore(rawEvent, startContainer, startOffset, isIOS) ||\n canDeleteAfter(rawEvent, startContainer, startOffset))\n );\n }\n}\n\nfunction canDeleteBefore(rawEvent: KeyboardEvent, text: Text, offset: number, isIOS: boolean) {\n if (rawEvent.key != 'Backspace') {\n return false;\n }\n if (offset <= 1) {\n // For iOS, allow browser to handle deletion of first character on iOS to preserve auto-capitalization\n return offset === 1 && isIOS;\n }\n\n const length = text.nodeValue?.length ?? 0;\n\n if (offset == length) {\n // At the end of text, need to check if next segment is deletable\n const nextSibling = text.nextSibling;\n const isNextSiblingUndeletable =\n isNodeOfType(nextSibling, 'ELEMENT_NODE') &&\n isElementOfType(nextSibling, 'a') &&\n isLinkUndeletable(nextSibling) &&\n !nextSibling.firstChild;\n\n // If next sibling is undeletable, we cannot let browser handle it since it will remove the anchor\n // So we return false here to let Content Model handle it\n return !isNextSiblingUndeletable;\n } else {\n // In middle of text, we can safely let browser handle deletion\n return true;\n }\n}\n\nfunction canDeleteAfter(rawEvent: KeyboardEvent, text: Text, offset: number) {\n return rawEvent.key == 'Delete' && offset < (text.nodeValue?.length ?? 0) - 1;\n}\n"]}
@@ -68,7 +68,7 @@ export declare class ImageEditPlugin implements ImageEditor, EditorPlugin {
68
68
  private startEditing;
69
69
  private updateImageDimensionsIfZero;
70
70
  private startEditingInternal;
71
- startRotateAndResize(editor: IEditor, image: HTMLImageElement): void;
71
+ startRotateAndResize(editor: IEditor, image: HTMLImageElement, isRTL: boolean): void;
72
72
  private updateResizeHandleDirection;
73
73
  private updateRotateHandleState;
74
74
  isOperationAllowed(operation: ImageEditOperation): boolean;
@@ -267,6 +267,7 @@ var ImageEditPlugin = /** @class */ (function () {
267
267
  var _this = this;
268
268
  var editingImageModel;
269
269
  var selection = editor.getDOMSelection();
270
+ var isRTL = false;
270
271
  editor.formatContentModel(function (model, context) {
271
272
  var editingImage = (0, getSelectedImage_1.getSelectedImage)(model);
272
273
  var previousSelectedImage = isApiOperation
@@ -320,6 +321,7 @@ var ImageEditPlugin = /** @class */ (function () {
320
321
  _this.isCropMode = isCropMode;
321
322
  (0, roosterjs_content_model_dom_1.mutateSegment)(editingImage.paragraph, editingImage.image, function (image) {
322
323
  editingImageModel = image;
324
+ isRTL = editingImage.paragraph.format.direction == 'rtl';
323
325
  _this.imageEditInfo = (0, updateImageEditInfo_1.updateImageEditInfo)(image, selection.image);
324
326
  image.format.imageState = 'isEditing';
325
327
  });
@@ -336,10 +338,10 @@ var ImageEditPlugin = /** @class */ (function () {
336
338
  (0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') &&
337
339
  (0, roosterjs_content_model_dom_1.isElementOfType)(node, 'img')) {
338
340
  if (isCropMode) {
339
- _this.startCropMode(editor, node);
341
+ _this.startCropMode(editor, node, isRTL);
340
342
  }
341
343
  else {
342
- _this.startRotateAndResize(editor, node);
344
+ _this.startRotateAndResize(editor, node, isRTL);
343
345
  }
344
346
  }
345
347
  },
@@ -400,7 +402,7 @@ var ImageEditPlugin = /** @class */ (function () {
400
402
  ]);
401
403
  editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, "caret-color: transparent;");
402
404
  };
403
- ImageEditPlugin.prototype.startRotateAndResize = function (editor, image) {
405
+ ImageEditPlugin.prototype.startRotateAndResize = function (editor, image, isRTL) {
404
406
  var _this = this;
405
407
  var _a, _b;
406
408
  if (this.imageEditInfo) {
@@ -412,7 +414,7 @@ var ImageEditPlugin = /** @class */ (function () {
412
414
  _this.selectedImage &&
413
415
  _this.wrapper &&
414
416
  _this.clonedImage) {
415
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers);
417
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers, undefined /* croppers */, isRTL);
416
418
  _this.wasImageResized = true;
417
419
  }
418
420
  }, this.zoomScale, isMobileOrTable)), false), (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.RotateHandle, rotatorContext_1.Rotator, function () {
@@ -421,12 +423,12 @@ var ImageEditPlugin = /** @class */ (function () {
421
423
  _this.selectedImage &&
422
424
  _this.wrapper &&
423
425
  _this.clonedImage) {
424
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper);
426
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined /* resizers */, undefined /* croppers */, isRTL);
425
427
  _this.updateRotateHandleState(editor, _this.selectedImage, _this.wrapper, _this.rotators, (_a = _this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad, !!((_b = _this.options) === null || _b === void 0 ? void 0 : _b.disableSideResize));
426
428
  _this.updateResizeHandleDirection(_this.resizers, _this.imageEditInfo.angleRad);
427
429
  }
428
430
  }, this.zoomScale, isMobileOrTable)), false);
429
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers);
431
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers, undefined /* croppers */, isRTL);
430
432
  this.updateRotateHandleState(editor, this.selectedImage, this.wrapper, this.rotators, (_a = this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad, !!((_b = this.options) === null || _b === void 0 ? void 0 : _b.disableSideResize));
431
433
  }
432
434
  }
@@ -458,7 +460,7 @@ var ImageEditPlugin = /** @class */ (function () {
458
460
  ImageEditPlugin.prototype.canRegenerateImage = function (image) {
459
461
  return (0, canRegenerateImage_1.canRegenerateImage)(image);
460
462
  };
461
- ImageEditPlugin.prototype.startCropMode = function (editor, image) {
463
+ ImageEditPlugin.prototype.startCropMode = function (editor, image, isRTL) {
462
464
  var _this = this;
463
465
  if (this.imageEditInfo) {
464
466
  this.startEditing(editor, image, ['crop']);
@@ -468,11 +470,11 @@ var ImageEditPlugin = /** @class */ (function () {
468
470
  _this.selectedImage &&
469
471
  _this.wrapper &&
470
472
  _this.clonedImage) {
471
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined, _this.croppers);
473
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined /* resizers */, _this.croppers, isRTL);
472
474
  _this.isCropMode = true;
473
475
  }
474
476
  }, this.zoomScale, !!editor.getEnvironment().isMobileOrTablet)), false);
475
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined, this.croppers);
477
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined /* resizers */, this.croppers, isRTL);
476
478
  }
477
479
  }
478
480
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ImageEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/ImageEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyChange } from './utils/applyChange';\nimport { canRegenerateImage } from './utils/canRegenerateImage';\nimport { checkIfImageWasResized, isASmallImage } from './utils/imageEditUtils';\nimport { createImageWrapper } from './utils/createImageWrapper';\nimport { Cropper } from './Cropper/cropperContext';\nimport { EDITING_MARKER, findEditingImage } from './utils/findEditingImage';\nimport { filterInnerResizerHandles } from './utils/filterInnerResizerHandles';\nimport { getDropAndDragHelpers } from './utils/getDropAndDragHelpers';\nimport { getHTMLImageOptions } from './utils/getHTMLImageOptions';\nimport { getSelectedImage } from './utils/getSelectedImage';\nimport { getSelectedImageMetadata, updateImageEditInfo } from './utils/updateImageEditInfo';\nimport { ImageEditElementClass } from './types/ImageEditElementClass';\nimport { normalizeImageSelection } from './utils/normalizeImageSelection';\nimport { Resizer } from './Resizer/resizerContext';\nimport { Rotator } from './Rotator/rotatorContext';\nimport { updateHandleCursor } from './utils/updateHandleCursor';\nimport { updateRotateHandle } from './Rotator/updateRotateHandle';\nimport { updateWrapper } from './utils/updateWrapper';\nimport {\n ChangeSource,\n getSafeIdSelector,\n getSelectedParagraphs,\n isElementOfType,\n isNodeOfType,\n mutateBlock,\n mutateSegment,\n setImageState,\n unwrap,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHelper } from '../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport type { DragAndDropContext } from './types/DragAndDropContext';\nimport type { ImageHtmlOptions } from './types/ImageHtmlOptions';\nimport type { ImageEditOptions } from './types/ImageEditOptions';\nimport type {\n ContentChangedEvent,\n ContentModelImage,\n EditorPlugin,\n IEditor,\n ImageEditOperation,\n ImageEditor,\n ImageMetadataFormat,\n KeyDownEvent,\n MouseDownEvent,\n MouseUpEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst DefaultOptions: Partial<ImageEditOptions> = {\n borderColor: '#DB626C',\n minWidth: 10,\n minHeight: 10,\n preserveRatio: true,\n disableRotate: false,\n disableSideResize: false,\n onSelectState: ['resize', 'rotate'],\n};\n\nconst MouseRightButton = 2;\nconst DRAG_ID = '_dragging';\nconst IMAGE_EDIT_CLASS = 'imageEdit';\nconst IMAGE_EDIT_CLASS_CARET = 'imageEditCaretColor';\nconst IMAGE_EDIT_FORMAT_EVENT = 'ImageEditEvent';\n\n/**\n * ImageEdit plugin handles the following image editing features:\n * - Resize image\n * - Crop image\n * - Rotate image\n * - Flip image\n */\nexport class ImageEditPlugin implements ImageEditor, EditorPlugin {\n protected editor: IEditor | null = null;\n private shadowSpan: HTMLSpanElement | null = null;\n private selectedImage: HTMLImageElement | null = null;\n protected wrapper: HTMLSpanElement | null = null;\n protected imageEditInfo: ImageMetadataFormat | null = null;\n private imageHTMLOptions: ImageHtmlOptions | null = null;\n private dndHelpers: DragAndDropHelper<DragAndDropContext, any>[] = [];\n private clonedImage: HTMLImageElement | null = null;\n private lastSrc: string | null = null;\n private wasImageResized: boolean = false;\n private isCropMode: boolean = false;\n private resizers: HTMLDivElement[] = [];\n private rotators: HTMLDivElement[] = [];\n private croppers: HTMLDivElement[] = [];\n private zoomScale: number = 1;\n private disposer: (() => void) | null = null;\n protected isEditing = false;\n protected options: ImageEditOptions;\n\n constructor(options?: ImageEditOptions) {\n this.options = { ...DefaultOptions, ...options };\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ImageEdit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = editor.attachDomEvent({\n blur: {\n beforeDispatch: () => {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n true /* shouldSelectImage */\n );\n }\n },\n },\n dragstart: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target)) {\n target.id = target.id + DRAG_ID;\n }\n }\n },\n },\n dragend: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target) && target.id.includes(DRAG_ID)) {\n target.id = target.id.replace(DRAG_ID, '').trim();\n }\n }\n },\n },\n });\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n this.isEditing = false;\n this.cleanInfo();\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n switch (event.eventType) {\n case 'mouseDown':\n this.mouseDownHandler(this.editor, event);\n break;\n case 'mouseUp':\n this.mouseUpHandler(this.editor, event);\n break;\n case 'keyDown':\n this.keyDownHandler(this.editor, event);\n break;\n case 'contentChanged':\n this.contentChangedHandler(this.editor, event);\n break;\n case 'extractContentWithDom':\n this.removeImageEditing(event.clonedRoot);\n break;\n case 'beforeLogicalRootChange':\n this.handleBeforeLogicalRootChange();\n break;\n }\n }\n\n private handleBeforeLogicalRootChange() {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n false /* shouldSelectImage */\n );\n this.removeImageWrapper();\n this.cleanInfo();\n }\n }\n\n private removeImageEditing(clonedRoot: HTMLElement) {\n const images = clonedRoot.querySelectorAll('img');\n images.forEach(image => {\n if (image.dataset.editingInfo) {\n delete image.dataset.editingInfo;\n }\n });\n }\n\n private isImageSelection(target: Node): target is HTMLElement {\n return (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n (isElementOfType(target, 'img') ||\n !!(\n isElementOfType(target, 'span') &&\n target.firstElementChild &&\n isNodeOfType(target.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(target.firstElementChild, 'img')\n ))\n );\n }\n\n private mouseUpHandler(editor: IEditor, event: MouseUpEvent) {\n const selection = editor.getDOMSelection();\n if ((selection && selection.type == 'image') || this.isEditing) {\n const shouldSelectImage =\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button === MouseRightButton;\n this.applyFormatWithContentModel(editor, this.isCropMode, shouldSelectImage);\n }\n }\n\n private mouseDownHandler(editor: IEditor, event: MouseDownEvent) {\n if (\n this.isEditing &&\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button !== MouseRightButton &&\n !this.isCropMode\n ) {\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n this.shadowSpan === event.rawEvent.target\n );\n }\n }\n\n private onDropHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n editor.formatContentModel(model => {\n const imageDragged = findEditingImage(model, selection.image.id);\n const imageDropped = findEditingImage(\n model,\n selection.image.id.replace(DRAG_ID, '').trim()\n );\n if (imageDragged && imageDropped) {\n const draggedIndex = imageDragged.paragraph.segments.indexOf(\n imageDragged.image\n );\n mutateBlock(imageDragged.paragraph).segments.splice(draggedIndex, 1);\n const segment = imageDropped.image;\n const paragraph = imageDropped.paragraph;\n mutateSegment(paragraph, segment, image => {\n image.isSelected = true;\n image.isSelectedAsImageSelection = true;\n });\n\n return true;\n }\n return false;\n });\n }\n }\n\n private keyDownHandler(editor: IEditor, event: KeyDownEvent) {\n if (this.isEditing) {\n if (\n event.rawEvent.key === 'Escape' ||\n event.rawEvent.key === 'Delete' ||\n event.rawEvent.key === 'Backspace'\n ) {\n if (event.rawEvent.key === 'Escape') {\n this.removeImageWrapper();\n }\n this.cleanInfo();\n } else {\n if (event.rawEvent.key == 'Enter' && this.isCropMode) {\n event.rawEvent.preventDefault();\n }\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n true /** should selectImage */,\n false /* isApiOperation */\n );\n }\n }\n }\n\n private setContentHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.cleanInfo();\n setImageState(selection.image, '');\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private formatEventHandler(event: ContentChangedEvent) {\n if (this.isEditing && event.formatApiName !== IMAGE_EDIT_FORMAT_EVENT) {\n this.cleanInfo();\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private contentChangedHandler(editor: IEditor, event: ContentChangedEvent) {\n switch (event.source) {\n case ChangeSource.SetContent:\n this.setContentHandler(editor);\n break;\n case ChangeSource.Format:\n this.formatEventHandler(event);\n break;\n case ChangeSource.Drop:\n this.onDropHandler(editor);\n break;\n }\n }\n\n /**\n * EXPOSED FOR TESTING PURPOSE ONLY\n */\n protected applyFormatWithContentModel(\n editor: IEditor,\n isCropMode: boolean,\n shouldSelectImage: boolean,\n isApiOperation?: boolean\n ) {\n let editingImageModel: ContentModelImage | undefined;\n const selection = editor.getDOMSelection();\n\n editor.formatContentModel(\n (model, context) => {\n const editingImage = getSelectedImage(model);\n const previousSelectedImage = isApiOperation\n ? editingImage\n : findEditingImage(model);\n let result = false;\n\n // Skip adding undo snapshot for now. If we detect any changes later, we will reset it\n context.skipUndoSnapshot = 'SkipAll';\n\n if (\n shouldSelectImage ||\n previousSelectedImage?.image != editingImage?.image ||\n previousSelectedImage?.image.format.imageState == EDITING_MARKER ||\n isApiOperation\n ) {\n const { lastSrc, selectedImage, imageEditInfo, clonedImage } = this;\n if (\n (this.isEditing || isApiOperation) &&\n previousSelectedImage &&\n lastSrc &&\n selectedImage &&\n imageEditInfo &&\n clonedImage\n ) {\n mutateSegment(\n previousSelectedImage.paragraph,\n previousSelectedImage.image,\n image => {\n const changeState = applyChange(\n editor,\n selectedImage,\n image,\n imageEditInfo,\n lastSrc,\n this.wasImageResized || this.isCropMode,\n clonedImage\n );\n\n if (this.wasImageResized || changeState == 'FullyChanged') {\n context.skipUndoSnapshot = false;\n }\n\n image.isSelected = shouldSelectImage;\n image.isSelectedAsImageSelection = shouldSelectImage;\n image.format.imageState = undefined;\n\n if (selection?.type == 'range' && !selection.range.collapsed) {\n const selectedParagraphs = getSelectedParagraphs(model, true);\n const isImageInRange = selectedParagraphs.some(paragraph =>\n paragraph.segments.includes(image)\n );\n if (isImageInRange) {\n image.isSelected = true;\n }\n }\n }\n );\n\n if (shouldSelectImage) {\n normalizeImageSelection(previousSelectedImage);\n }\n\n this.cleanInfo();\n result = true;\n }\n\n this.isEditing = false;\n this.isCropMode = false;\n\n if (\n editingImage &&\n selection?.type == 'image' &&\n !shouldSelectImage &&\n !isApiOperation\n ) {\n this.isEditing = true;\n this.isCropMode = isCropMode;\n mutateSegment(editingImage.paragraph, editingImage.image, image => {\n editingImageModel = image;\n this.imageEditInfo = updateImageEditInfo(image, selection.image);\n image.format.imageState = 'isEditing';\n });\n\n result = true;\n }\n }\n\n return result;\n },\n {\n onNodeCreated: (model, node) => {\n if (\n !isApiOperation &&\n editingImageModel &&\n editingImageModel == model &&\n editingImageModel.format.imageState == EDITING_MARKER &&\n isNodeOfType(node, 'ELEMENT_NODE') &&\n isElementOfType(node, 'img')\n ) {\n if (isCropMode) {\n this.startCropMode(editor, node);\n } else {\n this.startRotateAndResize(editor, node);\n }\n }\n },\n apiName: IMAGE_EDIT_FORMAT_EVENT,\n },\n {\n tryGetFromCache: true,\n }\n );\n }\n\n private startEditing(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n\n if (\n (this.imageEditInfo.widthPx == 0 || this.imageEditInfo.heightPx == 0) &&\n !image.complete\n ) {\n // Image dimensions are zero and loading is incomplete, wait for image to load.\n image.onload = () => {\n this.updateImageDimensionsIfZero(image);\n this.startEditingInternal(editor, image, apiOperation);\n image.onload = null;\n image.onerror = null;\n };\n image.onerror = () => {\n image.onload = null;\n image.onerror = null;\n };\n } else {\n this.updateImageDimensionsIfZero(image);\n this.startEditingInternal(editor, image, apiOperation);\n }\n }\n\n private updateImageDimensionsIfZero(image: HTMLImageElement) {\n if (this.imageEditInfo?.widthPx === 0 || this.imageEditInfo?.heightPx === 0) {\n this.imageEditInfo.widthPx = image.clientWidth;\n this.imageEditInfo.heightPx = image.clientHeight;\n }\n }\n\n private startEditingInternal(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n this.imageHTMLOptions = getHTMLImageOptions(editor, this.options, this.imageEditInfo);\n this.lastSrc = image.getAttribute('src');\n\n const {\n resizers,\n rotators,\n wrapper,\n shadowSpan,\n imageClone,\n croppers,\n } = createImageWrapper(\n editor,\n image,\n this.options,\n this.imageEditInfo,\n this.imageHTMLOptions,\n apiOperation\n );\n this.shadowSpan = shadowSpan;\n this.selectedImage = image;\n this.wrapper = wrapper;\n this.clonedImage = imageClone;\n this.wasImageResized = checkIfImageWasResized(image);\n this.resizers = resizers;\n this.rotators = rotators;\n this.croppers = croppers;\n this.zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS, `outline-style:none!important;`, [\n `span:has(>img${getSafeIdSelector(this.selectedImage.id)})`,\n ]);\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, `caret-color: transparent;`);\n }\n\n public startRotateAndResize(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['resize', 'rotate']);\n if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {\n const isMobileOrTable = !!editor.getEnvironment().isMobileOrTablet;\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.ResizeHandle,\n Resizer,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n this.wasImageResized = true;\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.RotateHandle,\n Rotator,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad,\n !!this.options?.disableSideResize\n );\n this.updateResizeHandleDirection(\n this.resizers,\n this.imageEditInfo.angleRad\n );\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ];\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad,\n !!this.options?.disableSideResize\n );\n }\n }\n }\n\n private updateResizeHandleDirection(resizers: HTMLDivElement[], angleRad: number | undefined) {\n const resizeHandles = filterInnerResizerHandles(resizers);\n if (angleRad !== undefined) {\n updateHandleCursor(resizeHandles, angleRad);\n }\n }\n\n private updateRotateHandleState(\n editor: IEditor,\n image: HTMLImageElement,\n wrapper: HTMLSpanElement,\n rotators: HTMLDivElement[],\n angleRad: number | undefined,\n disableSideResize: boolean\n ) {\n const viewport = editor.getVisibleViewport();\n const smallImage = isASmallImage(image.width, image.height);\n if (viewport && rotators && rotators.length > 0) {\n const rotator = rotators[0];\n const rotatorHandle = rotator.firstElementChild;\n if (\n isNodeOfType(rotatorHandle, 'ELEMENT_NODE') &&\n isElementOfType(rotatorHandle, 'div')\n ) {\n updateRotateHandle(\n viewport,\n angleRad ?? 0,\n wrapper,\n rotator,\n rotatorHandle,\n smallImage,\n disableSideResize\n );\n }\n }\n }\n\n public isOperationAllowed(operation: ImageEditOperation): boolean {\n return (\n operation === 'resize' ||\n operation === 'rotate' ||\n operation === 'flip' ||\n operation === 'crop'\n );\n }\n\n public canRegenerateImage(image: HTMLImageElement): boolean {\n return canRegenerateImage(image);\n }\n\n private startCropMode(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['crop']);\n if (this.imageEditInfo && this.selectedImage && this.wrapper && this.clonedImage) {\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.CropHandle,\n Cropper,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n this.isCropMode = true;\n }\n },\n this.zoomScale,\n !!editor.getEnvironment().isMobileOrTablet\n ),\n ];\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n }\n }\n }\n\n public cropImage() {\n if (!this.editor) {\n return;\n }\n if (!this.editor.getEnvironment().isSafari) {\n this.editor.focus(); // Safari will keep the selection when click crop, then the focus() call should not be called\n }\n const selection = this.editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.applyFormatWithContentModel(\n this.editor,\n true /* isCropMode */,\n false /* shouldSelectImage */\n );\n }\n }\n\n private editImage(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[],\n operation: (imageEditInfo: ImageMetadataFormat) => void\n ) {\n this.startEditing(editor, image, apiOperation);\n if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {\n return;\n }\n\n operation(this.imageEditInfo);\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n\n this.applyFormatWithContentModel(\n editor,\n false /* isCrop */,\n true /* shouldSelect*/,\n true /* isApiOperation */\n );\n }\n\n /**\n * Exported for testing purpose only\n */\n public cleanInfo() {\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS, null);\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS_CARET, null);\n this.selectedImage = null;\n this.shadowSpan = null;\n this.wrapper = null;\n this.imageEditInfo = null;\n this.imageHTMLOptions = null;\n this.dndHelpers.forEach(helper => helper.dispose());\n this.dndHelpers = [];\n this.clonedImage = null;\n this.lastSrc = null;\n this.wasImageResized = false;\n this.isCropMode = false;\n this.resizers = [];\n this.rotators = [];\n this.croppers = [];\n }\n\n private removeImageWrapper() {\n let image: HTMLImageElement | null = null;\n if (this.shadowSpan && this.shadowSpan.parentElement) {\n if (\n this.shadowSpan.firstElementChild &&\n isNodeOfType(this.shadowSpan.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(this.shadowSpan.firstElementChild, 'img')\n ) {\n image = this.shadowSpan.firstElementChild;\n }\n unwrap(this.shadowSpan);\n this.shadowSpan = null;\n this.wrapper = null;\n }\n\n return image;\n }\n\n public flipImage(direction: 'horizontal' | 'vertical') {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, ['flip'], imageEditInfo => {\n const angleRad = imageEditInfo.angleRad || 0;\n const isInVerticalPostion =\n (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||\n (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);\n if (isInVerticalPostion) {\n if (direction === 'horizontal') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n } else {\n if (direction === 'vertical') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n }\n });\n }\n }\n\n public rotateImage(angleRad: number) {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, [], imageEditInfo => {\n imageEditInfo.angleRad = (imageEditInfo.angleRad || 0) + angleRad;\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ImageEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/ImageEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyChange } from './utils/applyChange';\nimport { canRegenerateImage } from './utils/canRegenerateImage';\nimport { checkIfImageWasResized, isASmallImage } from './utils/imageEditUtils';\nimport { createImageWrapper } from './utils/createImageWrapper';\nimport { Cropper } from './Cropper/cropperContext';\nimport { EDITING_MARKER, findEditingImage } from './utils/findEditingImage';\nimport { filterInnerResizerHandles } from './utils/filterInnerResizerHandles';\nimport { getDropAndDragHelpers } from './utils/getDropAndDragHelpers';\nimport { getHTMLImageOptions } from './utils/getHTMLImageOptions';\nimport { getSelectedImage } from './utils/getSelectedImage';\nimport { getSelectedImageMetadata, updateImageEditInfo } from './utils/updateImageEditInfo';\nimport { ImageEditElementClass } from './types/ImageEditElementClass';\nimport { normalizeImageSelection } from './utils/normalizeImageSelection';\nimport { Resizer } from './Resizer/resizerContext';\nimport { Rotator } from './Rotator/rotatorContext';\nimport { updateHandleCursor } from './utils/updateHandleCursor';\nimport { updateRotateHandle } from './Rotator/updateRotateHandle';\nimport { updateWrapper } from './utils/updateWrapper';\nimport {\n ChangeSource,\n getSafeIdSelector,\n getSelectedParagraphs,\n isElementOfType,\n isNodeOfType,\n mutateBlock,\n mutateSegment,\n setImageState,\n unwrap,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHelper } from '../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport type { DragAndDropContext } from './types/DragAndDropContext';\nimport type { ImageHtmlOptions } from './types/ImageHtmlOptions';\nimport type { ImageEditOptions } from './types/ImageEditOptions';\nimport type {\n ContentChangedEvent,\n ContentModelImage,\n EditorPlugin,\n IEditor,\n ImageEditOperation,\n ImageEditor,\n ImageMetadataFormat,\n KeyDownEvent,\n MouseDownEvent,\n MouseUpEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst DefaultOptions: Partial<ImageEditOptions> = {\n borderColor: '#DB626C',\n minWidth: 10,\n minHeight: 10,\n preserveRatio: true,\n disableRotate: false,\n disableSideResize: false,\n onSelectState: ['resize', 'rotate'],\n};\n\nconst MouseRightButton = 2;\nconst DRAG_ID = '_dragging';\nconst IMAGE_EDIT_CLASS = 'imageEdit';\nconst IMAGE_EDIT_CLASS_CARET = 'imageEditCaretColor';\nconst IMAGE_EDIT_FORMAT_EVENT = 'ImageEditEvent';\n\n/**\n * ImageEdit plugin handles the following image editing features:\n * - Resize image\n * - Crop image\n * - Rotate image\n * - Flip image\n */\nexport class ImageEditPlugin implements ImageEditor, EditorPlugin {\n protected editor: IEditor | null = null;\n private shadowSpan: HTMLSpanElement | null = null;\n private selectedImage: HTMLImageElement | null = null;\n protected wrapper: HTMLSpanElement | null = null;\n protected imageEditInfo: ImageMetadataFormat | null = null;\n private imageHTMLOptions: ImageHtmlOptions | null = null;\n private dndHelpers: DragAndDropHelper<DragAndDropContext, any>[] = [];\n private clonedImage: HTMLImageElement | null = null;\n private lastSrc: string | null = null;\n private wasImageResized: boolean = false;\n private isCropMode: boolean = false;\n private resizers: HTMLDivElement[] = [];\n private rotators: HTMLDivElement[] = [];\n private croppers: HTMLDivElement[] = [];\n private zoomScale: number = 1;\n private disposer: (() => void) | null = null;\n protected isEditing = false;\n protected options: ImageEditOptions;\n\n constructor(options?: ImageEditOptions) {\n this.options = { ...DefaultOptions, ...options };\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ImageEdit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = editor.attachDomEvent({\n blur: {\n beforeDispatch: () => {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n true /* shouldSelectImage */\n );\n }\n },\n },\n dragstart: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target)) {\n target.id = target.id + DRAG_ID;\n }\n }\n },\n },\n dragend: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target) && target.id.includes(DRAG_ID)) {\n target.id = target.id.replace(DRAG_ID, '').trim();\n }\n }\n },\n },\n });\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n this.isEditing = false;\n this.cleanInfo();\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n switch (event.eventType) {\n case 'mouseDown':\n this.mouseDownHandler(this.editor, event);\n break;\n case 'mouseUp':\n this.mouseUpHandler(this.editor, event);\n break;\n case 'keyDown':\n this.keyDownHandler(this.editor, event);\n break;\n case 'contentChanged':\n this.contentChangedHandler(this.editor, event);\n break;\n case 'extractContentWithDom':\n this.removeImageEditing(event.clonedRoot);\n break;\n case 'beforeLogicalRootChange':\n this.handleBeforeLogicalRootChange();\n break;\n }\n }\n\n private handleBeforeLogicalRootChange() {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n false /* shouldSelectImage */\n );\n this.removeImageWrapper();\n this.cleanInfo();\n }\n }\n\n private removeImageEditing(clonedRoot: HTMLElement) {\n const images = clonedRoot.querySelectorAll('img');\n images.forEach(image => {\n if (image.dataset.editingInfo) {\n delete image.dataset.editingInfo;\n }\n });\n }\n\n private isImageSelection(target: Node): target is HTMLElement {\n return (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n (isElementOfType(target, 'img') ||\n !!(\n isElementOfType(target, 'span') &&\n target.firstElementChild &&\n isNodeOfType(target.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(target.firstElementChild, 'img')\n ))\n );\n }\n\n private mouseUpHandler(editor: IEditor, event: MouseUpEvent) {\n const selection = editor.getDOMSelection();\n if ((selection && selection.type == 'image') || this.isEditing) {\n const shouldSelectImage =\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button === MouseRightButton;\n this.applyFormatWithContentModel(editor, this.isCropMode, shouldSelectImage);\n }\n }\n\n private mouseDownHandler(editor: IEditor, event: MouseDownEvent) {\n if (\n this.isEditing &&\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button !== MouseRightButton &&\n !this.isCropMode\n ) {\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n this.shadowSpan === event.rawEvent.target\n );\n }\n }\n\n private onDropHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n editor.formatContentModel(model => {\n const imageDragged = findEditingImage(model, selection.image.id);\n const imageDropped = findEditingImage(\n model,\n selection.image.id.replace(DRAG_ID, '').trim()\n );\n if (imageDragged && imageDropped) {\n const draggedIndex = imageDragged.paragraph.segments.indexOf(\n imageDragged.image\n );\n mutateBlock(imageDragged.paragraph).segments.splice(draggedIndex, 1);\n const segment = imageDropped.image;\n const paragraph = imageDropped.paragraph;\n mutateSegment(paragraph, segment, image => {\n image.isSelected = true;\n image.isSelectedAsImageSelection = true;\n });\n\n return true;\n }\n return false;\n });\n }\n }\n\n private keyDownHandler(editor: IEditor, event: KeyDownEvent) {\n if (this.isEditing) {\n if (\n event.rawEvent.key === 'Escape' ||\n event.rawEvent.key === 'Delete' ||\n event.rawEvent.key === 'Backspace'\n ) {\n if (event.rawEvent.key === 'Escape') {\n this.removeImageWrapper();\n }\n this.cleanInfo();\n } else {\n if (event.rawEvent.key == 'Enter' && this.isCropMode) {\n event.rawEvent.preventDefault();\n }\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n true /** should selectImage */,\n false /* isApiOperation */\n );\n }\n }\n }\n\n private setContentHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.cleanInfo();\n setImageState(selection.image, '');\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private formatEventHandler(event: ContentChangedEvent) {\n if (this.isEditing && event.formatApiName !== IMAGE_EDIT_FORMAT_EVENT) {\n this.cleanInfo();\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private contentChangedHandler(editor: IEditor, event: ContentChangedEvent) {\n switch (event.source) {\n case ChangeSource.SetContent:\n this.setContentHandler(editor);\n break;\n case ChangeSource.Format:\n this.formatEventHandler(event);\n break;\n case ChangeSource.Drop:\n this.onDropHandler(editor);\n break;\n }\n }\n\n /**\n * EXPOSED FOR TESTING PURPOSE ONLY\n */\n protected applyFormatWithContentModel(\n editor: IEditor,\n isCropMode: boolean,\n shouldSelectImage: boolean,\n isApiOperation?: boolean\n ) {\n let editingImageModel: ContentModelImage | undefined;\n const selection = editor.getDOMSelection();\n let isRTL: boolean = false;\n\n editor.formatContentModel(\n (model, context) => {\n const editingImage = getSelectedImage(model);\n const previousSelectedImage = isApiOperation\n ? editingImage\n : findEditingImage(model);\n let result = false;\n\n // Skip adding undo snapshot for now. If we detect any changes later, we will reset it\n context.skipUndoSnapshot = 'SkipAll';\n\n if (\n shouldSelectImage ||\n previousSelectedImage?.image != editingImage?.image ||\n previousSelectedImage?.image.format.imageState == EDITING_MARKER ||\n isApiOperation\n ) {\n const { lastSrc, selectedImage, imageEditInfo, clonedImage } = this;\n if (\n (this.isEditing || isApiOperation) &&\n previousSelectedImage &&\n lastSrc &&\n selectedImage &&\n imageEditInfo &&\n clonedImage\n ) {\n mutateSegment(\n previousSelectedImage.paragraph,\n previousSelectedImage.image,\n image => {\n const changeState = applyChange(\n editor,\n selectedImage,\n image,\n imageEditInfo,\n lastSrc,\n this.wasImageResized || this.isCropMode,\n clonedImage\n );\n\n if (this.wasImageResized || changeState == 'FullyChanged') {\n context.skipUndoSnapshot = false;\n }\n\n image.isSelected = shouldSelectImage;\n image.isSelectedAsImageSelection = shouldSelectImage;\n image.format.imageState = undefined;\n\n if (selection?.type == 'range' && !selection.range.collapsed) {\n const selectedParagraphs = getSelectedParagraphs(model, true);\n const isImageInRange = selectedParagraphs.some(paragraph =>\n paragraph.segments.includes(image)\n );\n if (isImageInRange) {\n image.isSelected = true;\n }\n }\n }\n );\n\n if (shouldSelectImage) {\n normalizeImageSelection(previousSelectedImage);\n }\n\n this.cleanInfo();\n result = true;\n }\n\n this.isEditing = false;\n this.isCropMode = false;\n\n if (\n editingImage &&\n selection?.type == 'image' &&\n !shouldSelectImage &&\n !isApiOperation\n ) {\n this.isEditing = true;\n this.isCropMode = isCropMode;\n mutateSegment(editingImage.paragraph, editingImage.image, image => {\n editingImageModel = image;\n isRTL = editingImage.paragraph.format.direction == 'rtl';\n this.imageEditInfo = updateImageEditInfo(image, selection.image);\n image.format.imageState = 'isEditing';\n });\n\n result = true;\n }\n }\n\n return result;\n },\n {\n onNodeCreated: (model, node) => {\n if (\n !isApiOperation &&\n editingImageModel &&\n editingImageModel == model &&\n editingImageModel.format.imageState == EDITING_MARKER &&\n isNodeOfType(node, 'ELEMENT_NODE') &&\n isElementOfType(node, 'img')\n ) {\n if (isCropMode) {\n this.startCropMode(editor, node, isRTL);\n } else {\n this.startRotateAndResize(editor, node, isRTL);\n }\n }\n },\n apiName: IMAGE_EDIT_FORMAT_EVENT,\n },\n {\n tryGetFromCache: true,\n }\n );\n }\n\n private startEditing(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n\n if (\n (this.imageEditInfo.widthPx == 0 || this.imageEditInfo.heightPx == 0) &&\n !image.complete\n ) {\n // Image dimensions are zero and loading is incomplete, wait for image to load.\n image.onload = () => {\n this.updateImageDimensionsIfZero(image);\n this.startEditingInternal(editor, image, apiOperation);\n image.onload = null;\n image.onerror = null;\n };\n image.onerror = () => {\n image.onload = null;\n image.onerror = null;\n };\n } else {\n this.updateImageDimensionsIfZero(image);\n this.startEditingInternal(editor, image, apiOperation);\n }\n }\n\n private updateImageDimensionsIfZero(image: HTMLImageElement) {\n if (this.imageEditInfo?.widthPx === 0 || this.imageEditInfo?.heightPx === 0) {\n this.imageEditInfo.widthPx = image.clientWidth;\n this.imageEditInfo.heightPx = image.clientHeight;\n }\n }\n\n private startEditingInternal(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n this.imageHTMLOptions = getHTMLImageOptions(editor, this.options, this.imageEditInfo);\n this.lastSrc = image.getAttribute('src');\n\n const {\n resizers,\n rotators,\n wrapper,\n shadowSpan,\n imageClone,\n croppers,\n } = createImageWrapper(\n editor,\n image,\n this.options,\n this.imageEditInfo,\n this.imageHTMLOptions,\n apiOperation\n );\n this.shadowSpan = shadowSpan;\n this.selectedImage = image;\n this.wrapper = wrapper;\n this.clonedImage = imageClone;\n this.wasImageResized = checkIfImageWasResized(image);\n this.resizers = resizers;\n this.rotators = rotators;\n this.croppers = croppers;\n this.zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS, `outline-style:none!important;`, [\n `span:has(>img${getSafeIdSelector(this.selectedImage.id)})`,\n ]);\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, `caret-color: transparent;`);\n }\n\n public startRotateAndResize(editor: IEditor, image: HTMLImageElement, isRTL: boolean) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['resize', 'rotate']);\n if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {\n const isMobileOrTable = !!editor.getEnvironment().isMobileOrTablet;\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.ResizeHandle,\n Resizer,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers,\n undefined /* croppers */,\n isRTL\n );\n this.wasImageResized = true;\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.RotateHandle,\n Rotator,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined /* resizers */,\n undefined /* croppers */,\n isRTL\n );\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad,\n !!this.options?.disableSideResize\n );\n this.updateResizeHandleDirection(\n this.resizers,\n this.imageEditInfo.angleRad\n );\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ];\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers,\n undefined /* croppers */,\n isRTL\n );\n\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad,\n !!this.options?.disableSideResize\n );\n }\n }\n }\n\n private updateResizeHandleDirection(resizers: HTMLDivElement[], angleRad: number | undefined) {\n const resizeHandles = filterInnerResizerHandles(resizers);\n if (angleRad !== undefined) {\n updateHandleCursor(resizeHandles, angleRad);\n }\n }\n\n private updateRotateHandleState(\n editor: IEditor,\n image: HTMLImageElement,\n wrapper: HTMLSpanElement,\n rotators: HTMLDivElement[],\n angleRad: number | undefined,\n disableSideResize: boolean\n ) {\n const viewport = editor.getVisibleViewport();\n const smallImage = isASmallImage(image.width, image.height);\n if (viewport && rotators && rotators.length > 0) {\n const rotator = rotators[0];\n const rotatorHandle = rotator.firstElementChild;\n if (\n isNodeOfType(rotatorHandle, 'ELEMENT_NODE') &&\n isElementOfType(rotatorHandle, 'div')\n ) {\n updateRotateHandle(\n viewport,\n angleRad ?? 0,\n wrapper,\n rotator,\n rotatorHandle,\n smallImage,\n disableSideResize\n );\n }\n }\n }\n\n public isOperationAllowed(operation: ImageEditOperation): boolean {\n return (\n operation === 'resize' ||\n operation === 'rotate' ||\n operation === 'flip' ||\n operation === 'crop'\n );\n }\n\n public canRegenerateImage(image: HTMLImageElement): boolean {\n return canRegenerateImage(image);\n }\n\n private startCropMode(editor: IEditor, image: HTMLImageElement, isRTL: boolean) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['crop']);\n if (this.imageEditInfo && this.selectedImage && this.wrapper && this.clonedImage) {\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.CropHandle,\n Cropper,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined /* resizers */,\n this.croppers,\n isRTL\n );\n this.isCropMode = true;\n }\n },\n this.zoomScale,\n !!editor.getEnvironment().isMobileOrTablet\n ),\n ];\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined /* resizers */,\n this.croppers,\n isRTL\n );\n }\n }\n }\n\n public cropImage() {\n if (!this.editor) {\n return;\n }\n if (!this.editor.getEnvironment().isSafari) {\n this.editor.focus(); // Safari will keep the selection when click crop, then the focus() call should not be called\n }\n const selection = this.editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.applyFormatWithContentModel(\n this.editor,\n true /* isCropMode */,\n false /* shouldSelectImage */\n );\n }\n }\n\n private editImage(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[],\n operation: (imageEditInfo: ImageMetadataFormat) => void\n ) {\n this.startEditing(editor, image, apiOperation);\n if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {\n return;\n }\n\n operation(this.imageEditInfo);\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n\n this.applyFormatWithContentModel(\n editor,\n false /* isCrop */,\n true /* shouldSelect*/,\n true /* isApiOperation */\n );\n }\n\n /**\n * Exported for testing purpose only\n */\n public cleanInfo() {\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS, null);\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS_CARET, null);\n this.selectedImage = null;\n this.shadowSpan = null;\n this.wrapper = null;\n this.imageEditInfo = null;\n this.imageHTMLOptions = null;\n this.dndHelpers.forEach(helper => helper.dispose());\n this.dndHelpers = [];\n this.clonedImage = null;\n this.lastSrc = null;\n this.wasImageResized = false;\n this.isCropMode = false;\n this.resizers = [];\n this.rotators = [];\n this.croppers = [];\n }\n\n private removeImageWrapper() {\n let image: HTMLImageElement | null = null;\n if (this.shadowSpan && this.shadowSpan.parentElement) {\n if (\n this.shadowSpan.firstElementChild &&\n isNodeOfType(this.shadowSpan.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(this.shadowSpan.firstElementChild, 'img')\n ) {\n image = this.shadowSpan.firstElementChild;\n }\n unwrap(this.shadowSpan);\n this.shadowSpan = null;\n this.wrapper = null;\n }\n\n return image;\n }\n\n public flipImage(direction: 'horizontal' | 'vertical') {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, ['flip'], imageEditInfo => {\n const angleRad = imageEditInfo.angleRad || 0;\n const isInVerticalPostion =\n (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||\n (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);\n if (isInVerticalPostion) {\n if (direction === 'horizontal') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n } else {\n if (direction === 'vertical') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n }\n });\n }\n }\n\n public rotateImage(angleRad: number) {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, [], imageEditInfo => {\n imageEditInfo.angleRad = (imageEditInfo.angleRad || 0) + angleRad;\n });\n }\n }\n}\n"]}
@@ -33,7 +33,3 @@ export declare function setSize(element: HTMLElement, left: number | undefined,
33
33
  * @returns if the user resized the image, returns true, otherwise, returns false
34
34
  */
35
35
  export declare function checkIfImageWasResized(image: HTMLImageElement): boolean;
36
- /**
37
- * @internal
38
- */
39
- export declare function isRTL(image: HTMLImageElement): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isRTL = exports.checkIfImageWasResized = exports.setSize = exports.setWrapperSizeDimensions = exports.setFlipped = exports.rotateCoordinate = exports.isASmallImage = exports.getPx = void 0;
3
+ exports.checkIfImageWasResized = exports.setSize = exports.setWrapperSizeDimensions = exports.setFlipped = exports.rotateCoordinate = exports.isASmallImage = exports.getPx = void 0;
4
4
  var constants_1 = require("../constants/constants");
5
5
  /**
6
6
  * @internal
@@ -88,13 +88,6 @@ function checkIfImageWasResized(image) {
88
88
  }
89
89
  }
90
90
  exports.checkIfImageWasResized = checkIfImageWasResized;
91
- /**
92
- * @internal
93
- */
94
- function isRTL(image) {
95
- return window.getComputedStyle(image).direction === 'rtl';
96
- }
97
- exports.isRTL = isRTL;
98
91
  function isFixedNumberValue(value) {
99
92
  var numberValue = typeof value === 'string' ? parseInt(value) : value;
100
93
  return !isNaN(numberValue);
@@ -1 +1 @@
1
- {"version":3,"file":"imageEditUtils.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/imageEditUtils.ts"],"names":[],"mappings":";;;AAAA,oDAA0D;AAE1D;;GAEG;AACH,SAAgB,KAAK,CAAC,KAAa;IAC/B,OAAO,KAAK,GAAG,IAAI,CAAC;AACxB,CAAC;AAFD,sBAEC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,OAAe,EAAE,QAAgB;IAC3D,OAAO,OAAO,IAAI,QAAQ,IAAI,CAAC,OAAO,GAAG,4BAAgB,IAAI,QAAQ,GAAG,4BAAgB,CAAC;QACrF,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK,CAAC;AAChB,CAAC;AAJD,sCAIC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,CAAS,EAAE,CAAS,EAAE,KAAa;IAChE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACjB;IACD,IAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;IACjC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,CAAC;AAPD,4CAOC;AAED;;GAEG;AACH,SAAgB,UAAU,CACtB,OAA2B,EAC3B,mBAA6B,EAC7B,iBAA2B;IAE3B,IAAI,OAAO,EAAE;QACT,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,YAAS,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAC3D,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAC3B,CAAC;KACP;AACL,CAAC;AAVD,gCAUC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CACpC,OAAoB,EACpB,KAAuB,EACvB,KAAa,EACb,MAAc;IAEd,IAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;IAC1C,IAAI,SAAS,EAAE;QACX,IAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QACnD,OAAO;KACV;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAfD,4DAeC;AAED;;GAEG;AACH,SAAgB,OAAO,CACnB,OAAoB,EACpB,IAAwB,EACxB,GAAuB,EACvB,KAAyB,EACzB,MAA0B,EAC1B,KAAyB,EACzB,MAA0B;IAE1B,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAC/E,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;IACnF,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAC/E,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;AACvF,CAAC;AAfD,0BAeC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,KAAuB;IAClD,IAAA,KAAK,GAAK,KAAK,MAAV,CAAW;IACxB,IAAM,iBAAiB,GACnB,KAAK,CAAC,QAAQ,KAAK,EAAE,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC;IACvF,IACI,iBAAiB;QACjB,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EACvE;QACE,OAAO,IAAI,CAAC;KACf;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC;AAZD,wDAYC;AAED;;GAEG;AACH,SAAgB,KAAK,CAAC,KAAuB;IACzC,OAAO,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC;AAC9D,CAAC;AAFD,sBAEC;AAED,SAAS,kBAAkB,CAAC,KAAsB;IAC9C,IAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["import { MIN_HEIGHT_WIDTH } from '../constants/constants';\n\n/**\n * @internal\n */\nexport function getPx(value: number): string {\n return value + 'px';\n}\n\n/**\n * @internal\n */\nexport function isASmallImage(widthPx: number, heightPx: number): boolean {\n return widthPx && heightPx && (widthPx < MIN_HEIGHT_WIDTH || heightPx < MIN_HEIGHT_WIDTH)\n ? true\n : false;\n}\n\n/**\n * @internal Calculate the rotated x and y distance for mouse moving\n * @param x Original x distance\n * @param y Original y distance\n * @param angle Rotated angle, in radian\n * @returns rotated x and y distances\n */\nexport function rotateCoordinate(x: number, y: number, angle: number): [number, number] {\n if (x == 0 && y == 0) {\n return [0, 0];\n }\n const hypotenuse = Math.sqrt(x * x + y * y);\n angle = Math.atan2(y, x) - angle;\n return [hypotenuse * Math.cos(angle), hypotenuse * Math.sin(angle)];\n}\n\n/**\n * @internal\n */\nexport function setFlipped(\n element: HTMLElement | null,\n flippedHorizontally?: boolean,\n flippedVertically?: boolean\n) {\n if (element) {\n element.style.transform = `scale(${flippedHorizontally ? -1 : 1}, ${\n flippedVertically ? -1 : 1\n })`;\n }\n}\n\n/**\n * @internal\n */\nexport function setWrapperSizeDimensions(\n wrapper: HTMLElement,\n image: HTMLImageElement,\n width: number,\n height: number\n) {\n const hasBorder = image.style.borderStyle;\n if (hasBorder) {\n const borderWidth = image.style.borderWidth ? 2 * parseInt(image.style.borderWidth) : 2;\n wrapper.style.width = getPx(width + borderWidth);\n wrapper.style.height = getPx(height + borderWidth);\n return;\n }\n wrapper.style.width = getPx(width);\n wrapper.style.height = getPx(height);\n}\n\n/**\n * @internal\n */\nexport function setSize(\n element: HTMLElement,\n left: number | undefined,\n top: number | undefined,\n right: number | undefined,\n bottom: number | undefined,\n width: number | undefined,\n height: number | undefined\n) {\n element.style.left = left !== undefined ? getPx(left) : element.style.left;\n element.style.top = top !== undefined ? getPx(top) : element.style.top;\n element.style.right = right !== undefined ? getPx(right) : element.style.right;\n element.style.bottom = bottom !== undefined ? getPx(bottom) : element.style.bottom;\n element.style.width = width !== undefined ? getPx(width) : element.style.width;\n element.style.height = height !== undefined ? getPx(height) : element.style.height;\n}\n\n/**\n * @internal\n * Check if the current image was resized by the user\n * @param image the current image\n * @returns if the user resized the image, returns true, otherwise, returns false\n */\nexport function checkIfImageWasResized(image: HTMLImageElement): boolean {\n const { style } = image;\n const isMaxWidthInitial =\n style.maxWidth === '' || style.maxWidth === 'initial' || style.maxWidth === 'auto';\n if (\n isMaxWidthInitial &&\n (isFixedNumberValue(style.height) || isFixedNumberValue(style.width))\n ) {\n return true;\n } else {\n return false;\n }\n}\n\n/**\n * @internal\n */\nexport function isRTL(image: HTMLImageElement): boolean {\n return window.getComputedStyle(image).direction === 'rtl';\n}\n\nfunction isFixedNumberValue(value: string | number) {\n const numberValue = typeof value === 'string' ? parseInt(value) : value;\n return !isNaN(numberValue);\n}\n"]}
1
+ {"version":3,"file":"imageEditUtils.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/imageEditUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { MIN_HEIGHT_WIDTH } from '../constants/constants';\n\n/**\n * @internal\n */\nexport function getPx(value: number): string {\n return value + 'px';\n}\n\n/**\n * @internal\n */\nexport function isASmallImage(widthPx: number, heightPx: number): boolean {\n return widthPx && heightPx && (widthPx < MIN_HEIGHT_WIDTH || heightPx < MIN_HEIGHT_WIDTH)\n ? true\n : false;\n}\n\n/**\n * @internal Calculate the rotated x and y distance for mouse moving\n * @param x Original x distance\n * @param y Original y distance\n * @param angle Rotated angle, in radian\n * @returns rotated x and y distances\n */\nexport function rotateCoordinate(x: number, y: number, angle: number): [number, number] {\n if (x == 0 && y == 0) {\n return [0, 0];\n }\n const hypotenuse = Math.sqrt(x * x + y * y);\n angle = Math.atan2(y, x) - angle;\n return [hypotenuse * Math.cos(angle), hypotenuse * Math.sin(angle)];\n}\n\n/**\n * @internal\n */\nexport function setFlipped(\n element: HTMLElement | null,\n flippedHorizontally?: boolean,\n flippedVertically?: boolean\n) {\n if (element) {\n element.style.transform = `scale(${flippedHorizontally ? -1 : 1}, ${\n flippedVertically ? -1 : 1\n })`;\n }\n}\n\n/**\n * @internal\n */\nexport function setWrapperSizeDimensions(\n wrapper: HTMLElement,\n image: HTMLImageElement,\n width: number,\n height: number\n) {\n const hasBorder = image.style.borderStyle;\n if (hasBorder) {\n const borderWidth = image.style.borderWidth ? 2 * parseInt(image.style.borderWidth) : 2;\n wrapper.style.width = getPx(width + borderWidth);\n wrapper.style.height = getPx(height + borderWidth);\n return;\n }\n wrapper.style.width = getPx(width);\n wrapper.style.height = getPx(height);\n}\n\n/**\n * @internal\n */\nexport function setSize(\n element: HTMLElement,\n left: number | undefined,\n top: number | undefined,\n right: number | undefined,\n bottom: number | undefined,\n width: number | undefined,\n height: number | undefined\n) {\n element.style.left = left !== undefined ? getPx(left) : element.style.left;\n element.style.top = top !== undefined ? getPx(top) : element.style.top;\n element.style.right = right !== undefined ? getPx(right) : element.style.right;\n element.style.bottom = bottom !== undefined ? getPx(bottom) : element.style.bottom;\n element.style.width = width !== undefined ? getPx(width) : element.style.width;\n element.style.height = height !== undefined ? getPx(height) : element.style.height;\n}\n\n/**\n * @internal\n * Check if the current image was resized by the user\n * @param image the current image\n * @returns if the user resized the image, returns true, otherwise, returns false\n */\nexport function checkIfImageWasResized(image: HTMLImageElement): boolean {\n const { style } = image;\n const isMaxWidthInitial =\n style.maxWidth === '' || style.maxWidth === 'initial' || style.maxWidth === 'auto';\n if (\n isMaxWidthInitial &&\n (isFixedNumberValue(style.height) || isFixedNumberValue(style.width))\n ) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction isFixedNumberValue(value: string | number) {\n const numberValue = typeof value === 'string' ? parseInt(value) : value;\n return !isNaN(numberValue);\n}\n"]}
@@ -3,4 +3,4 @@ import type { ImageMetadataFormat } from 'roosterjs-content-model-types';
3
3
  /**
4
4
  * @internal
5
5
  */
6
- export declare function updateWrapper(editInfo: ImageMetadataFormat, options: ImageEditOptions, image: HTMLImageElement, clonedImage: HTMLImageElement, wrapper: HTMLSpanElement, resizers?: HTMLDivElement[], croppers?: HTMLDivElement[]): void;
6
+ export declare function updateWrapper(editInfo: ImageMetadataFormat, options: ImageEditOptions, image: HTMLImageElement, clonedImage: HTMLImageElement, wrapper: HTMLSpanElement, resizers?: HTMLDivElement[], croppers?: HTMLDivElement[], isRTL?: boolean): void;
@@ -12,7 +12,7 @@ var imageEditUtils_1 = require("./imageEditUtils");
12
12
  /**
13
13
  * @internal
14
14
  */
15
- function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers, croppers) {
15
+ function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers, croppers, isRTL) {
16
16
  var angleRad = editInfo.angleRad, bottomPercent = editInfo.bottomPercent, leftPercent = editInfo.leftPercent, rightPercent = editInfo.rightPercent, topPercent = editInfo.topPercent, flippedHorizontal = editInfo.flippedHorizontal, flippedVertical = editInfo.flippedVertical;
17
17
  var generateImageSize = (0, generateImageSize_1.getGeneratedImageSize)(editInfo, croppers && (croppers === null || croppers === void 0 ? void 0 : croppers.length) > 0);
18
18
  if (!generateImageSize) {
@@ -35,7 +35,7 @@ function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers,
35
35
  wrapper.style.verticalAlign = 'text-bottom';
36
36
  // Update the text-alignment to avoid the image to overflow if the parent element have align center or right
37
37
  // or if the direction is Right To Left
38
- if ((0, imageEditUtils_1.isRTL)(clonedImage)) {
38
+ if (isRTL) {
39
39
  wrapper.style.textAlign = 'right';
40
40
  if (!croppers) {
41
41
  clonedImage.style.left = (0, imageEditUtils_1.getPx)(cropLeftPx);
@@ -1 +1 @@
1
- {"version":3,"file":"updateWrapper.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/updateWrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { doubleCheckResize } from './doubleCheckResize';\nimport { filterInnerResizerHandles } from './filterInnerResizerHandles';\nimport { getGeneratedImageSize } from './generateImageSize';\nimport { ImageEditElementClass } from '../types/ImageEditElementClass';\nimport { toArray } from 'roosterjs-content-model-dom';\nimport { updateHandleCursor } from './updateHandleCursor';\nimport { updateSideHandlesVisibility } from '../Resizer/updateSideHandlesVisibility';\nimport type { ImageEditOptions } from '../types/ImageEditOptions';\nimport type { ImageMetadataFormat } from 'roosterjs-content-model-types';\nimport {\n getPx,\n isASmallImage,\n isRTL,\n setFlipped,\n setSize,\n setWrapperSizeDimensions,\n} from './imageEditUtils';\n\n/**\n * @internal\n */\nexport function updateWrapper(\n editInfo: ImageMetadataFormat,\n options: ImageEditOptions,\n image: HTMLImageElement,\n clonedImage: HTMLImageElement,\n wrapper: HTMLSpanElement,\n resizers?: HTMLDivElement[],\n croppers?: HTMLDivElement[]\n) {\n const {\n angleRad,\n bottomPercent,\n leftPercent,\n rightPercent,\n topPercent,\n flippedHorizontal,\n flippedVertical,\n } = editInfo;\n\n const generateImageSize = getGeneratedImageSize(editInfo, croppers && croppers?.length > 0);\n if (!generateImageSize) {\n return;\n }\n const {\n targetWidth,\n targetHeight,\n originalWidth,\n originalHeight,\n visibleWidth,\n visibleHeight,\n } = generateImageSize;\n\n const marginHorizontal = (targetWidth - visibleWidth) / 2;\n const marginVertical = (targetHeight - visibleHeight) / 2;\n const cropLeftPx = originalWidth * (leftPercent || 0);\n const cropRightPx = originalWidth * (rightPercent || 0);\n const cropTopPx = originalHeight * (topPercent || 0);\n const cropBottomPx = originalHeight * (bottomPercent || 0);\n\n // Update size and margin of the wrapper\n wrapper.style.marginTop = `${marginVertical}px`;\n wrapper.style.marginBottom = `${marginVertical + 5}px `; // 5px to adjust the image on top of the handles\n wrapper.style.marginLeft = `${marginHorizontal}px`;\n wrapper.style.marginRight = `${marginHorizontal}px`;\n\n wrapper.style.transform = `rotate(${angleRad}rad)`;\n setWrapperSizeDimensions(wrapper, image, visibleWidth, visibleHeight);\n wrapper.style.verticalAlign = 'text-bottom';\n\n // Update the text-alignment to avoid the image to overflow if the parent element have align center or right\n // or if the direction is Right To Left\n if (isRTL(clonedImage)) {\n wrapper.style.textAlign = 'right';\n if (!croppers) {\n clonedImage.style.left = getPx(cropLeftPx);\n clonedImage.style.right = getPx(-cropRightPx);\n }\n } else {\n wrapper.style.textAlign = 'left';\n }\n\n // Update size of the image\n clonedImage.style.width = getPx(originalWidth);\n clonedImage.style.height = getPx(originalHeight);\n clonedImage.style.position = 'absolute';\n\n //Update flip direction\n setFlipped(clonedImage.parentElement, flippedHorizontal, flippedVertical);\n const smallImage = isASmallImage(visibleWidth, visibleWidth);\n\n if (!croppers) {\n // For rotate/resize, set the margin of the image so that cropped part won't be visible\n clonedImage.style.margin = `${-cropTopPx}px 0 0 ${-cropLeftPx}px`;\n }\n\n if (croppers && croppers.length > 0) {\n const cropContainer = croppers[0];\n const cropOverlays = croppers.filter(\n cropper => cropper.className === ImageEditElementClass.CropOverlay\n );\n const cropHandles = toArray<HTMLElement>(\n cropContainer.querySelectorAll(`.${ImageEditElementClass.CropHandle}`)\n );\n\n setSize(\n cropContainer,\n cropLeftPx,\n cropTopPx,\n cropRightPx,\n cropBottomPx,\n undefined,\n undefined\n );\n setSize(cropOverlays[0], 0, 0, cropRightPx, undefined, undefined, cropTopPx);\n setSize(cropOverlays[1], undefined, 0, 0, cropBottomPx, cropRightPx, undefined);\n setSize(cropOverlays[2], cropLeftPx, undefined, 0, 0, undefined, cropBottomPx);\n setSize(cropOverlays[3], 0, cropTopPx, undefined, 0, cropLeftPx, undefined);\n\n if (angleRad !== undefined) {\n updateHandleCursor(cropHandles, angleRad);\n }\n }\n\n if (resizers) {\n const clientWidth = wrapper.clientWidth;\n const clientHeight = wrapper.clientHeight;\n\n doubleCheckResize(editInfo, options.preserveRatio || false, clientWidth, clientHeight);\n\n const resizeHandles = filterInnerResizerHandles(resizers);\n\n if (angleRad !== undefined) {\n updateHandleCursor(resizeHandles, angleRad);\n }\n\n updateSideHandlesVisibility(resizeHandles, smallImage);\n }\n}\n"]}
1
+ {"version":3,"file":"updateWrapper.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/updateWrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { doubleCheckResize } from './doubleCheckResize';\nimport { filterInnerResizerHandles } from './filterInnerResizerHandles';\nimport { getGeneratedImageSize } from './generateImageSize';\nimport { ImageEditElementClass } from '../types/ImageEditElementClass';\nimport { toArray } from 'roosterjs-content-model-dom';\nimport { updateHandleCursor } from './updateHandleCursor';\nimport { updateSideHandlesVisibility } from '../Resizer/updateSideHandlesVisibility';\nimport type { ImageEditOptions } from '../types/ImageEditOptions';\nimport type { ImageMetadataFormat } from 'roosterjs-content-model-types';\nimport {\n getPx,\n isASmallImage,\n setFlipped,\n setSize,\n setWrapperSizeDimensions,\n} from './imageEditUtils';\n\n/**\n * @internal\n */\nexport function updateWrapper(\n editInfo: ImageMetadataFormat,\n options: ImageEditOptions,\n image: HTMLImageElement,\n clonedImage: HTMLImageElement,\n wrapper: HTMLSpanElement,\n resizers?: HTMLDivElement[],\n croppers?: HTMLDivElement[],\n isRTL?: boolean\n) {\n const {\n angleRad,\n bottomPercent,\n leftPercent,\n rightPercent,\n topPercent,\n flippedHorizontal,\n flippedVertical,\n } = editInfo;\n\n const generateImageSize = getGeneratedImageSize(editInfo, croppers && croppers?.length > 0);\n if (!generateImageSize) {\n return;\n }\n const {\n targetWidth,\n targetHeight,\n originalWidth,\n originalHeight,\n visibleWidth,\n visibleHeight,\n } = generateImageSize;\n\n const marginHorizontal = (targetWidth - visibleWidth) / 2;\n const marginVertical = (targetHeight - visibleHeight) / 2;\n const cropLeftPx = originalWidth * (leftPercent || 0);\n const cropRightPx = originalWidth * (rightPercent || 0);\n const cropTopPx = originalHeight * (topPercent || 0);\n const cropBottomPx = originalHeight * (bottomPercent || 0);\n\n // Update size and margin of the wrapper\n wrapper.style.marginTop = `${marginVertical}px`;\n wrapper.style.marginBottom = `${marginVertical + 5}px `; // 5px to adjust the image on top of the handles\n wrapper.style.marginLeft = `${marginHorizontal}px`;\n wrapper.style.marginRight = `${marginHorizontal}px`;\n\n wrapper.style.transform = `rotate(${angleRad}rad)`;\n setWrapperSizeDimensions(wrapper, image, visibleWidth, visibleHeight);\n wrapper.style.verticalAlign = 'text-bottom';\n\n // Update the text-alignment to avoid the image to overflow if the parent element have align center or right\n // or if the direction is Right To Left\n if (isRTL) {\n wrapper.style.textAlign = 'right';\n if (!croppers) {\n clonedImage.style.left = getPx(cropLeftPx);\n clonedImage.style.right = getPx(-cropRightPx);\n }\n } else {\n wrapper.style.textAlign = 'left';\n }\n\n // Update size of the image\n clonedImage.style.width = getPx(originalWidth);\n clonedImage.style.height = getPx(originalHeight);\n clonedImage.style.position = 'absolute';\n\n //Update flip direction\n setFlipped(clonedImage.parentElement, flippedHorizontal, flippedVertical);\n const smallImage = isASmallImage(visibleWidth, visibleWidth);\n\n if (!croppers) {\n // For rotate/resize, set the margin of the image so that cropped part won't be visible\n clonedImage.style.margin = `${-cropTopPx}px 0 0 ${-cropLeftPx}px`;\n }\n\n if (croppers && croppers.length > 0) {\n const cropContainer = croppers[0];\n const cropOverlays = croppers.filter(\n cropper => cropper.className === ImageEditElementClass.CropOverlay\n );\n const cropHandles = toArray<HTMLElement>(\n cropContainer.querySelectorAll(`.${ImageEditElementClass.CropHandle}`)\n );\n\n setSize(\n cropContainer,\n cropLeftPx,\n cropTopPx,\n cropRightPx,\n cropBottomPx,\n undefined,\n undefined\n );\n setSize(cropOverlays[0], 0, 0, cropRightPx, undefined, undefined, cropTopPx);\n setSize(cropOverlays[1], undefined, 0, 0, cropBottomPx, cropRightPx, undefined);\n setSize(cropOverlays[2], cropLeftPx, undefined, 0, 0, undefined, cropBottomPx);\n setSize(cropOverlays[3], 0, cropTopPx, undefined, 0, cropLeftPx, undefined);\n\n if (angleRad !== undefined) {\n updateHandleCursor(cropHandles, angleRad);\n }\n }\n\n if (resizers) {\n const clientWidth = wrapper.clientWidth;\n const clientHeight = wrapper.clientHeight;\n\n doubleCheckResize(editInfo, options.preserveRatio || false, clientWidth, clientHeight);\n\n const resizeHandles = filterInnerResizerHandles(resizers);\n\n if (angleRad !== undefined) {\n updateHandleCursor(resizeHandles, angleRad);\n }\n\n updateSideHandlesVisibility(resizeHandles, smallImage);\n }\n}\n"]}