roosterjs-content-model-plugins 9.35.1 → 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
@@ -11,10 +11,11 @@ define(["require", "exports", "./deleteSteps/deleteAllSegmentBefore", "./deleteS
11
11
  * @returns True if the event is handled by content model, otherwise false
12
12
  */
13
13
  function keyboardDelete(editor, rawEvent, handleExpandedSelection) {
14
+ var _a;
14
15
  if (handleExpandedSelection === void 0) { handleExpandedSelection = true; }
15
16
  var handled = false;
16
17
  var selection = editor.getDOMSelection();
17
- if (shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection)) {
18
+ if (shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection, (_a = editor.getEnvironment().isIOS) !== null && _a !== void 0 ? _a : false)) {
18
19
  editor.formatContentModel(function (model, context) {
19
20
  var result = (0, roosterjs_content_model_dom_1.deleteSelection)(model, getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac), context).deleteResult;
20
21
  handled = (0, handleKeyboardEventCommon_1.handleKeyboardEventResult)(editor, model, rawEvent, result, context);
@@ -51,7 +52,7 @@ define(["require", "exports", "./deleteSteps/deleteAllSegmentBefore", "./deleteS
51
52
  deleteParagraphStyle_1.deleteParagraphStyle,
52
53
  ];
53
54
  }
54
- function shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection) {
55
+ function shouldDeleteWithContentModel(selection, rawEvent, handleExpandedSelection, isIOS) {
55
56
  var _a, _b;
56
57
  if (!selection) {
57
58
  return false; // Nothing to delete
@@ -77,15 +78,19 @@ define(["require", "exports", "./deleteSteps/deleteAllSegmentBefore", "./deleteS
77
78
  // When selection is collapsed and is in middle of text node, no need to use Content Model to delete
78
79
  return !((0, roosterjs_content_model_dom_1.isNodeOfType)(startContainer, 'TEXT_NODE') &&
79
80
  !(0, roosterjs_content_model_dom_1.isModifierKey)(rawEvent) &&
80
- (canDeleteBefore(rawEvent, startContainer, startOffset) ||
81
+ (canDeleteBefore(rawEvent, startContainer, startOffset, isIOS) ||
81
82
  canDeleteAfter(rawEvent, startContainer, startOffset)));
82
83
  }
83
84
  }
84
- function canDeleteBefore(rawEvent, text, offset) {
85
+ function canDeleteBefore(rawEvent, text, offset, isIOS) {
85
86
  var _a, _b;
86
- if (rawEvent.key != 'Backspace' || offset <= 1) {
87
+ if (rawEvent.key != 'Backspace') {
87
88
  return false;
88
89
  }
90
+ if (offset <= 1) {
91
+ // For iOS, allow browser to handle deletion of first character on iOS to preserve auto-capitalization
92
+ return offset === 1 && isIOS;
93
+ }
89
94
  var length = (_b = (_a = text.nodeValue) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
90
95
  if (offset == length) {
91
96
  // 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;
@@ -248,6 +248,7 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
248
248
  var _this = this;
249
249
  var editingImageModel;
250
250
  var selection = editor.getDOMSelection();
251
+ var isRTL = false;
251
252
  editor.formatContentModel(function (model, context) {
252
253
  var editingImage = (0, getSelectedImage_1.getSelectedImage)(model);
253
254
  var previousSelectedImage = isApiOperation
@@ -301,6 +302,7 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
301
302
  _this.isCropMode = isCropMode;
302
303
  (0, roosterjs_content_model_dom_1.mutateSegment)(editingImage.paragraph, editingImage.image, function (image) {
303
304
  editingImageModel = image;
305
+ isRTL = editingImage.paragraph.format.direction == 'rtl';
304
306
  _this.imageEditInfo = (0, updateImageEditInfo_1.updateImageEditInfo)(image, selection.image);
305
307
  image.format.imageState = 'isEditing';
306
308
  });
@@ -317,10 +319,10 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
317
319
  (0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') &&
318
320
  (0, roosterjs_content_model_dom_1.isElementOfType)(node, 'img')) {
319
321
  if (isCropMode) {
320
- _this.startCropMode(editor, node);
322
+ _this.startCropMode(editor, node, isRTL);
321
323
  }
322
324
  else {
323
- _this.startRotateAndResize(editor, node);
325
+ _this.startRotateAndResize(editor, node, isRTL);
324
326
  }
325
327
  }
326
328
  },
@@ -381,7 +383,7 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
381
383
  ]);
382
384
  editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, "caret-color: transparent;");
383
385
  };
384
- ImageEditPlugin.prototype.startRotateAndResize = function (editor, image) {
386
+ ImageEditPlugin.prototype.startRotateAndResize = function (editor, image, isRTL) {
385
387
  var _this = this;
386
388
  var _a, _b;
387
389
  if (this.imageEditInfo) {
@@ -393,7 +395,7 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
393
395
  _this.selectedImage &&
394
396
  _this.wrapper &&
395
397
  _this.clonedImage) {
396
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers);
398
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers, undefined /* croppers */, isRTL);
397
399
  _this.wasImageResized = true;
398
400
  }
399
401
  }, 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 () {
@@ -402,12 +404,12 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
402
404
  _this.selectedImage &&
403
405
  _this.wrapper &&
404
406
  _this.clonedImage) {
405
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper);
407
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined /* resizers */, undefined /* croppers */, isRTL);
406
408
  _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));
407
409
  _this.updateResizeHandleDirection(_this.resizers, _this.imageEditInfo.angleRad);
408
410
  }
409
411
  }, this.zoomScale, isMobileOrTable)), false);
410
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers);
412
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers, undefined /* croppers */, isRTL);
411
413
  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));
412
414
  }
413
415
  }
@@ -439,7 +441,7 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
439
441
  ImageEditPlugin.prototype.canRegenerateImage = function (image) {
440
442
  return (0, canRegenerateImage_1.canRegenerateImage)(image);
441
443
  };
442
- ImageEditPlugin.prototype.startCropMode = function (editor, image) {
444
+ ImageEditPlugin.prototype.startCropMode = function (editor, image, isRTL) {
443
445
  var _this = this;
444
446
  if (this.imageEditInfo) {
445
447
  this.startEditing(editor, image, ['crop']);
@@ -449,11 +451,11 @@ define(["require", "exports", "tslib", "./utils/applyChange", "./utils/canRegene
449
451
  _this.selectedImage &&
450
452
  _this.wrapper &&
451
453
  _this.clonedImage) {
452
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined, _this.croppers);
454
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined /* resizers */, _this.croppers, isRTL);
453
455
  _this.isCropMode = true;
454
456
  }
455
457
  }, this.zoomScale, !!editor.getEnvironment().isMobileOrTablet)), false);
456
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined, this.croppers);
458
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined /* resizers */, this.croppers, isRTL);
457
459
  }
458
460
  }
459
461
  };
@@ -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":";;;;IA+CA,IAAM,cAAc,GAA8B;QAC9C,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,iBAAiB,EAAE,KAAK;QACxB,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;KACtC,CAAC;IAEF,IAAM,gBAAgB,GAAG,CAAC,CAAC;IAC3B,IAAM,OAAO,GAAG,WAAW,CAAC;IAC5B,IAAM,gBAAgB,GAAG,WAAW,CAAC;IACrC,IAAM,sBAAsB,GAAG,qBAAqB,CAAC;IACrD,IAAM,uBAAuB,GAAG,gBAAgB,CAAC;IAEjD;;;;;;OAMG;IACH;QAoBI,yBAAY,OAA0B;YAnB5B,WAAM,GAAmB,IAAI,CAAC;YAChC,eAAU,GAA2B,IAAI,CAAC;YAC1C,kBAAa,GAA4B,IAAI,CAAC;YAC5C,YAAO,GAA2B,IAAI,CAAC;YACvC,kBAAa,GAA+B,IAAI,CAAC;YACnD,qBAAgB,GAA4B,IAAI,CAAC;YACjD,eAAU,GAAiD,EAAE,CAAC;YAC9D,gBAAW,GAA4B,IAAI,CAAC;YAC5C,YAAO,GAAkB,IAAI,CAAC;YAC9B,oBAAe,GAAY,KAAK,CAAC;YACjC,eAAU,GAAY,KAAK,CAAC;YAC5B,aAAQ,GAAqB,EAAE,CAAC;YAChC,aAAQ,GAAqB,EAAE,CAAC;YAChC,aAAQ,GAAqB,EAAE,CAAC;YAChC,cAAS,GAAW,CAAC,CAAC;YACtB,aAAQ,GAAwB,IAAI,CAAC;YACnC,cAAS,GAAG,KAAK,CAAC;YAIxB,IAAI,CAAC,OAAO,mDAAQ,cAAc,GAAK,OAAO,CAAE,CAAC;QACrD,CAAC;QAED;;WAEG;QACH,iCAAO,GAAP;YACI,OAAO,WAAW,CAAC;QACvB,CAAC;QAED;;;;;WAKG;QACH,oCAAU,GAAV,UAAW,MAAe;YAA1B,iBAmCC;YAlCG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC;gBAClC,IAAI,EAAE;oBACF,cAAc,EAAE;wBACZ,IAAI,KAAI,CAAC,SAAS,IAAI,KAAI,CAAC,MAAM,IAAI,CAAC,KAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;4BAC5D,KAAI,CAAC,2BAA2B,CAC5B,KAAI,CAAC,MAAM,EACX,KAAI,CAAC,UAAU,EACf,IAAI,CAAC,uBAAuB,CAC/B,CAAC;yBACL;oBACL,CAAC;iBACJ;gBACD,SAAS,EAAE;oBACP,cAAc,EAAE,UAAA,EAAE;wBACd,IAAI,KAAI,CAAC,MAAM,EAAE;4BACb,IAAM,MAAM,GAAG,EAAE,CAAC,MAAc,CAAC;4BACjC,IAAI,KAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;gCAC/B,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC;6BACnC;yBACJ;oBACL,CAAC;iBACJ;gBACD,OAAO,EAAE;oBACL,cAAc,EAAE,UAAA,EAAE;wBACd,IAAI,KAAI,CAAC,MAAM,EAAE;4BACb,IAAM,MAAM,GAAG,EAAE,CAAC,MAAc,CAAC;4BACjC,IAAI,KAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gCAC9D,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;6BACrD;yBACJ;oBACL,CAAC;iBACJ;aACJ,CAAC,CAAC;QACP,CAAC;QAED;;;;WAIG;QACH,iCAAO,GAAP;YACI,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACf,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;aACxB;YACD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvB,CAAC;QAED;;;;;WAKG;QACH,uCAAa,GAAb,UAAc,KAAkB;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBACd,OAAO;aACV;YACD,QAAQ,KAAK,CAAC,SAAS,EAAE;gBACrB,KAAK,WAAW;oBACZ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBAC1C,MAAM;gBACV,KAAK,SAAS;oBACV,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACxC,MAAM;gBACV,KAAK,SAAS;oBACV,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACxC,MAAM;gBACV,KAAK,gBAAgB;oBACjB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBAC/C,MAAM;gBACV,KAAK,uBAAuB;oBACxB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBAC1C,MAAM;gBACV,KAAK,yBAAyB;oBAC1B,IAAI,CAAC,6BAA6B,EAAE,CAAC;oBACrC,MAAM;aACb;QACL,CAAC;QAEO,uDAA6B,GAArC;YACI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;gBAC5D,IAAI,CAAC,2BAA2B,CAC5B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,UAAU,EACf,KAAK,CAAC,uBAAuB,CAChC,CAAC;gBACF,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;aACpB;QACL,CAAC;QAEO,4CAAkB,GAA1B,UAA2B,UAAuB;YAC9C,IAAM,MAAM,GAAG,UAAU,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,UAAA,KAAK;gBAChB,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;oBAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;iBACpC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QAEO,0CAAgB,GAAxB,UAAyB,MAAY;YACjC,OAAO,CACH,IAAA,0CAAY,EAAC,MAAM,EAAE,cAAc,CAAC;gBACpC,CAAC,IAAA,6CAAe,EAAC,MAAM,EAAE,KAAK,CAAC;oBAC3B,CAAC,CAAC,CACE,IAAA,6CAAe,EAAC,MAAM,EAAE,MAAM,CAAC;wBAC/B,MAAM,CAAC,iBAAiB;wBACxB,IAAA,0CAAY,EAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;wBACtD,IAAA,6CAAe,EAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CACnD,CAAC,CACT,CAAC;QACN,CAAC;QAEO,wCAAc,GAAtB,UAAuB,MAAe,EAAE,KAAmB;YACvD,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3C,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;gBAC5D,IAAM,iBAAiB,GACnB,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAc,CAAC;oBACpD,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,gBAAgB,CAAC;gBAC/C,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;aAChF;QACL,CAAC;QAEO,0CAAgB,GAAxB,UAAyB,MAAe,EAAE,KAAqB;YAC3D,IACI,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAc,CAAC;gBACpD,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,gBAAgB;gBAC1C,CAAC,IAAI,CAAC,UAAU,EAClB;gBACE,IAAI,CAAC,2BAA2B,CAC5B,MAAM,EACN,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,QAAQ,CAAC,MAAM,CAC5C,CAAC;aACL;QACL,CAAC;QAEO,uCAAa,GAArB,UAAsB,MAAe;YACjC,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;gBAC5B,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;oBAC3B,IAAM,YAAY,GAAG,IAAA,mCAAgB,EAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACjE,IAAM,YAAY,GAAG,IAAA,mCAAgB,EACjC,KAAK,EACL,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CACjD,CAAC;oBACF,IAAI,YAAY,IAAI,YAAY,EAAE;wBAC9B,IAAM,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CACxD,YAAY,CAAC,KAAK,CACrB,CAAC;wBACF,IAAA,yCAAW,EAAC,YAAY,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;wBACrE,IAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC;wBACnC,IAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC;wBACzC,IAAA,2CAAa,EAAC,SAAS,EAAE,OAAO,EAAE,UAAA,KAAK;4BACnC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;4BACxB,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC;wBAC5C,CAAC,CAAC,CAAC;wBAEH,OAAO,IAAI,CAAC;qBACf;oBACD,OAAO,KAAK,CAAC;gBACjB,CAAC,CAAC,CAAC;aACN;QACL,CAAC;QAEO,wCAAc,GAAtB,UAAuB,MAAe,EAAE,KAAmB;YACvD,IAAI,IAAI,CAAC,SAAS,EAAE;gBAChB,IACI,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,QAAQ;oBAC/B,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,QAAQ;oBAC/B,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,WAAW,EACpC;oBACE,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,QAAQ,EAAE;wBACjC,IAAI,CAAC,kBAAkB,EAAE,CAAC;qBAC7B;oBACD,IAAI,CAAC,SAAS,EAAE,CAAC;iBACpB;qBAAM;oBACH,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE;wBAClD,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;qBACnC;oBACD,IAAI,CAAC,2BAA2B,CAC5B,MAAM,EACN,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,yBAAyB,EAC9B,KAAK,CAAC,oBAAoB,CAC7B,CAAC;iBACL;aACJ;QACL,CAAC;QAEO,2CAAiB,GAAzB,UAA0B,MAAe;YACrC,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;gBAC5B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAA,2CAAa,EAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;aAC3B;QACL,CAAC;QAEO,4CAAkB,GAA1B,UAA2B,KAA0B;YACjD,IAAI,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa,KAAK,uBAAuB,EAAE;gBACnE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;aAC3B;QACL,CAAC;QAEO,+CAAqB,GAA7B,UAA8B,MAAe,EAAE,KAA0B;YACrE,QAAQ,KAAK,CAAC,MAAM,EAAE;gBAClB,KAAK,0CAAY,CAAC,UAAU;oBACxB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBAC/B,MAAM;gBACV,KAAK,0CAAY,CAAC,MAAM;oBACpB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;oBAC/B,MAAM;gBACV,KAAK,0CAAY,CAAC,IAAI;oBAClB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;oBAC3B,MAAM;aACb;QACL,CAAC;QAED;;WAEG;QACO,qDAA2B,GAArC,UACI,MAAe,EACf,UAAmB,EACnB,iBAA0B,EAC1B,cAAwB;YAJ5B,iBA6HC;YAvHG,IAAI,iBAAgD,CAAC;YACrD,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3C,IAAI,KAAK,GAAY,KAAK,CAAC;YAE3B,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;gBACX,IAAM,YAAY,GAAG,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAC;gBAC7C,IAAM,qBAAqB,GAAG,cAAc;oBACxC,CAAC,CAAC,YAAY;oBACd,CAAC,CAAC,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAC;gBAC9B,IAAI,MAAM,GAAG,KAAK,CAAC;gBAEnB,sFAAsF;gBACtF,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBAErC,IACI,iBAAiB;oBACjB,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,KAAK,MAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAA;oBACnD,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,KAAK,CAAC,MAAM,CAAC,UAAU,KAAI,iCAAc;oBAChE,cAAc,EAChB;oBACQ,IAAA,KAAyD,KAAI,EAA3D,SAAO,aAAA,EAAE,eAAa,mBAAA,EAAE,eAAa,mBAAA,EAAE,aAAW,iBAAS,CAAC;oBACpE,IACI,CAAC,KAAI,CAAC,SAAS,IAAI,cAAc,CAAC;wBAClC,qBAAqB;wBACrB,SAAO;wBACP,eAAa;wBACb,eAAa;wBACb,aAAW,EACb;wBACE,IAAA,2CAAa,EACT,qBAAqB,CAAC,SAAS,EAC/B,qBAAqB,CAAC,KAAK,EAC3B,UAAA,KAAK;4BACD,IAAM,WAAW,GAAG,IAAA,yBAAW,EAC3B,MAAM,EACN,eAAa,EACb,KAAK,EACL,eAAa,EACb,SAAO,EACP,KAAI,CAAC,eAAe,IAAI,KAAI,CAAC,UAAU,EACvC,aAAW,CACd,CAAC;4BAEF,IAAI,KAAI,CAAC,eAAe,IAAI,WAAW,IAAI,cAAc,EAAE;gCACvD,OAAO,CAAC,gBAAgB,GAAG,KAAK,CAAC;6BACpC;4BAED,KAAK,CAAC,UAAU,GAAG,iBAAiB,CAAC;4BACrC,KAAK,CAAC,0BAA0B,GAAG,iBAAiB,CAAC;4BACrD,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;4BAEpC,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE;gCAC1D,IAAM,kBAAkB,GAAG,IAAA,mDAAqB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gCAC9D,IAAM,cAAc,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAA,SAAS;oCACpD,OAAA,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;gCAAlC,CAAkC,CACrC,CAAC;gCACF,IAAI,cAAc,EAAE;oCAChB,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;iCAC3B;6BACJ;wBACL,CAAC,CACJ,CAAC;wBAEF,IAAI,iBAAiB,EAAE;4BACnB,IAAA,iDAAuB,EAAC,qBAAqB,CAAC,CAAC;yBAClD;wBAED,KAAI,CAAC,SAAS,EAAE,CAAC;wBACjB,MAAM,GAAG,IAAI,CAAC;qBACjB;oBAED,KAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACvB,KAAI,CAAC,UAAU,GAAG,KAAK,CAAC;oBAExB,IACI,YAAY;wBACZ,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO;wBAC1B,CAAC,iBAAiB;wBAClB,CAAC,cAAc,EACjB;wBACE,KAAI,CAAC,SAAS,GAAG,IAAI,CAAC;wBACtB,KAAI,CAAC,UAAU,GAAG,UAAU,CAAC;wBAC7B,IAAA,2CAAa,EAAC,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,KAAK,EAAE,UAAA,KAAK;4BAC3D,iBAAiB,GAAG,KAAK,CAAC;4BAC1B,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;4BACzD,KAAI,CAAC,aAAa,GAAG,IAAA,yCAAmB,EAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;4BACjE,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG,WAAW,CAAC;wBAC1C,CAAC,CAAC,CAAC;wBAEH,MAAM,GAAG,IAAI,CAAC;qBACjB;iBACJ;gBAED,OAAO,MAAM,CAAC;YAClB,CAAC,EACD;gBACI,aAAa,EAAE,UAAC,KAAK,EAAE,IAAI;oBACvB,IACI,CAAC,cAAc;wBACf,iBAAiB;wBACjB,iBAAiB,IAAI,KAAK;wBAC1B,iBAAiB,CAAC,MAAM,CAAC,UAAU,IAAI,iCAAc;wBACrD,IAAA,0CAAY,EAAC,IAAI,EAAE,cAAc,CAAC;wBAClC,IAAA,6CAAe,EAAC,IAAI,EAAE,KAAK,CAAC,EAC9B;wBACE,IAAI,UAAU,EAAE;4BACZ,KAAI,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;yBAC3C;6BAAM;4BACH,KAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;yBAClD;qBACJ;gBACL,CAAC;gBACD,OAAO,EAAE,uBAAuB;aACnC,EACD;gBACI,eAAe,EAAE,IAAI;aACxB,CACJ,CAAC;QACN,CAAC;QAEO,sCAAY,GAApB,UACI,MAAe,EACf,KAAuB,EACvB,YAAkC;YAHtC,iBA4BC;YAvBG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;gBACrB,IAAI,CAAC,aAAa,GAAG,IAAA,8CAAwB,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;aAChE;YAED,IACI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACrE,CAAC,KAAK,CAAC,QAAQ,EACjB;gBACE,+EAA+E;gBAC/E,KAAK,CAAC,MAAM,GAAG;oBACX,KAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC;oBACxC,KAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;oBACvD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;oBACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;gBACzB,CAAC,CAAC;gBACF,KAAK,CAAC,OAAO,GAAG;oBACZ,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;oBACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;gBACzB,CAAC,CAAC;aACL;iBAAM;gBACH,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC;gBACxC,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;aAC1D;QACL,CAAC;QAEO,qDAA2B,GAAnC,UAAoC,KAAuB;;YACvD,IAAI,CAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,OAAO,MAAK,CAAC,IAAI,CAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,QAAQ,MAAK,CAAC,EAAE;gBACzE,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC;gBAC/C,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;aACpD;QACL,CAAC;QAEO,8CAAoB,GAA5B,UACI,MAAe,EACf,KAAuB,EACvB,YAAkC;YAElC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;gBACrB,IAAI,CAAC,aAAa,GAAG,IAAA,8CAAwB,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;aAChE;YACD,IAAI,CAAC,gBAAgB,GAAG,IAAA,yCAAmB,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YACtF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,IAAA,KAOF,IAAA,uCAAkB,EAClB,MAAM,EACN,KAAK,EACL,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,gBAAgB,EACrB,YAAY,CACf,EAbG,QAAQ,cAAA,EACR,QAAQ,cAAA,EACR,OAAO,aAAA,EACP,UAAU,gBAAA,EACV,UAAU,gBAAA,EACV,QAAQ,cAQX,CAAC;YACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;YAC9B,IAAI,CAAC,eAAe,GAAG,IAAA,uCAAsB,EAAC,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC,kBAAkB,EAAE,CAAC;YAE5D,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,+BAA+B,EAAE;gBACrE,kBAAgB,IAAA,+CAAiB,EAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAG;aAC9D,CAAC,CAAC;YAEH,MAAM,CAAC,cAAc,CAAC,sBAAsB,EAAE,2BAA2B,CAAC,CAAC;QAC/E,CAAC;QAEM,8CAAoB,GAA3B,UAA4B,MAAe,EAAE,KAAuB,EAAE,KAAc;YAApF,iBAkGC;;YAjGG,IAAI,IAAI,CAAC,aAAa,EAAE;gBACpB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACvD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE;oBAC9E,IAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,gBAAgB,CAAC;oBACnE,IAAI,CAAC,UAAU,iFACR,IAAA,6CAAqB,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,6CAAqB,CAAC,YAAY,EAClC,wBAAO,EACP;wBACI,IACI,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,OAAO;4BACZ,KAAI,CAAC,WAAW,EAClB;4BACE,IAAA,6BAAa,EACT,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,OAAO,EACZ,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,WAAW,EAChB,KAAI,CAAC,OAAO,EACZ,KAAI,CAAC,QAAQ,EACb,SAAS,CAAC,cAAc,EACxB,KAAK,CACR,CAAC;4BACF,KAAI,CAAC,eAAe,GAAG,IAAI,CAAC;yBAC/B;oBACL,CAAC,EACD,IAAI,CAAC,SAAS,EACd,eAAe,CAClB,+BACE,IAAA,6CAAqB,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,6CAAqB,CAAC,YAAY,EAClC,wBAAO,EACP;;wBACI,IACI,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,OAAO;4BACZ,KAAI,CAAC,WAAW,EAClB;4BACE,IAAA,6BAAa,EACT,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,OAAO,EACZ,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,WAAW,EAChB,KAAI,CAAC,OAAO,EACZ,SAAS,CAAC,cAAc,EACxB,SAAS,CAAC,cAAc,EACxB,KAAK,CACR,CAAC;4BACF,KAAI,CAAC,uBAAuB,CACxB,MAAM,EACN,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,OAAO,EACZ,KAAI,CAAC,QAAQ,EACb,MAAA,KAAI,CAAC,aAAa,0CAAE,QAAQ,EAC5B,CAAC,CAAC,CAAA,MAAA,KAAI,CAAC,OAAO,0CAAE,iBAAiB,CAAA,CACpC,CAAC;4BACF,KAAI,CAAC,2BAA2B,CAC5B,KAAI,CAAC,QAAQ,EACb,KAAI,CAAC,aAAa,CAAC,QAAQ,CAC9B,CAAC;yBACL;oBACL,CAAC,EACD,IAAI,CAAC,SAAS,EACd,eAAe,CAClB,SACJ,CAAC;oBAEF,IAAA,6BAAa,EACT,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,SAAS,CAAC,cAAc,EACxB,KAAK,CACR,CAAC;oBAEF,IAAI,CAAC,uBAAuB,CACxB,MAAM,EACN,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,MAAA,IAAI,CAAC,aAAa,0CAAE,QAAQ,EAC5B,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,iBAAiB,CAAA,CACpC,CAAC;iBACL;aACJ;QACL,CAAC;QAEO,qDAA2B,GAAnC,UAAoC,QAA0B,EAAE,QAA4B;YACxF,IAAM,aAAa,GAAG,IAAA,qDAAyB,EAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,QAAQ,KAAK,SAAS,EAAE;gBACxB,IAAA,uCAAkB,EAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;aAC/C;QACL,CAAC;QAEO,iDAAuB,GAA/B,UACI,MAAe,EACf,KAAuB,EACvB,OAAwB,EACxB,QAA0B,EAC1B,QAA4B,EAC5B,iBAA0B;YAE1B,IAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC7C,IAAM,UAAU,GAAG,IAAA,8BAAa,EAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5D,IAAI,QAAQ,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC7C,IAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;gBAChD,IACI,IAAA,0CAAY,EAAC,aAAa,EAAE,cAAc,CAAC;oBAC3C,IAAA,6CAAe,EAAC,aAAa,EAAE,KAAK,CAAC,EACvC;oBACE,IAAA,uCAAkB,EACd,QAAQ,EACR,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,CAAC,EACb,OAAO,EACP,OAAO,EACP,aAAa,EACb,UAAU,EACV,iBAAiB,CACpB,CAAC;iBACL;aACJ;QACL,CAAC;QAEM,4CAAkB,GAAzB,UAA0B,SAA6B;YACnD,OAAO,CACH,SAAS,KAAK,QAAQ;gBACtB,SAAS,KAAK,QAAQ;gBACtB,SAAS,KAAK,MAAM;gBACpB,SAAS,KAAK,MAAM,CACvB,CAAC;QACN,CAAC;QAEM,4CAAkB,GAAzB,UAA0B,KAAuB;YAC7C,OAAO,IAAA,uCAAkB,EAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAEO,uCAAa,GAArB,UAAsB,MAAe,EAAE,KAAuB,EAAE,KAAc;YAA9E,iBA+CC;YA9CG,IAAI,IAAI,CAAC,aAAa,EAAE;gBACpB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC3C,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE;oBAC9E,IAAI,CAAC,UAAU,sDACR,IAAA,6CAAqB,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,6CAAqB,CAAC,UAAU,EAChC,wBAAO,EACP;wBACI,IACI,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,aAAa;4BAClB,KAAI,CAAC,OAAO;4BACZ,KAAI,CAAC,WAAW,EAClB;4BACE,IAAA,6BAAa,EACT,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,OAAO,EACZ,KAAI,CAAC,aAAa,EAClB,KAAI,CAAC,WAAW,EAChB,KAAI,CAAC,OAAO,EACZ,SAAS,CAAC,cAAc,EACxB,KAAI,CAAC,QAAQ,EACb,KAAK,CACR,CAAC;4BACF,KAAI,CAAC,UAAU,GAAG,IAAI,CAAC;yBAC1B;oBACL,CAAC,EACD,IAAI,CAAC,SAAS,EACd,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,gBAAgB,CAC7C,SACJ,CAAC;oBACF,IAAA,6BAAa,EACT,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,OAAO,EACZ,SAAS,CAAC,cAAc,EACxB,IAAI,CAAC,QAAQ,EACb,KAAK,CACR,CAAC;iBACL;aACJ;QACL,CAAC;QAEM,mCAAS,GAAhB;YACI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBACd,OAAO;aACV;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE;gBACxC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,6FAA6F;aACrH;YACD,IAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAChD,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;gBAC5B,IAAI,CAAC,2BAA2B,CAC5B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,gBAAgB,EACrB,KAAK,CAAC,uBAAuB,CAChC,CAAC;aACL;QACL,CAAC;QAEO,mCAAS,GAAjB,UACI,MAAe,EACf,KAAuB,EACvB,YAAkC,EAClC,SAAuD;YAEvD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAClF,OAAO;aACV;YAED,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE9B,IAAA,6BAAa,EACT,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,OAAO,CACf,CAAC;YAEF,IAAI,CAAC,2BAA2B,CAC5B,MAAM,EACN,KAAK,CAAC,YAAY,EAClB,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,oBAAoB,CAC5B,CAAC;QACN,CAAC;QAED;;WAEG;QACI,mCAAS,GAAhB;;YACI,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YACpD,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAC1D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAA,MAAM,IAAI,OAAA,MAAM,CAAC,OAAO,EAAE,EAAhB,CAAgB,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACvB,CAAC;QAEO,4CAAkB,GAA1B;YACI,IAAI,KAAK,GAA4B,IAAI,CAAC;YAC1C,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE;gBAClD,IACI,IAAI,CAAC,UAAU,CAAC,iBAAiB;oBACjC,IAAA,0CAAY,EAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE,cAAc,CAAC;oBAC/D,IAAA,6CAAe,EAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAC3D;oBACE,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC;iBAC7C;gBACD,IAAA,oCAAM,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;aACvB;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;QAEM,mCAAS,GAAhB,UAAiB,SAAoC;;YACjD,IAAM,SAAS,GAAG,MAAA,IAAI,CAAC,MAAM,0CAAE,eAAe,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;gBAC1D,OAAO;aACV;YACD,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,EAAE;gBACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,UAAA,aAAa;oBACtD,IAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,IAAI,CAAC,CAAC;oBAC7C,IAAM,mBAAmB,GACrB,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;wBACzD,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;oBAChE,IAAI,mBAAmB,EAAE;wBACrB,IAAI,SAAS,KAAK,YAAY,EAAE;4BAC5B,aAAa,CAAC,eAAe,GAAG,CAAC,aAAa,CAAC,eAAe,CAAC;yBAClE;6BAAM;4BACH,aAAa,CAAC,iBAAiB,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC;yBACtE;qBACJ;yBAAM;wBACH,IAAI,SAAS,KAAK,UAAU,EAAE;4BAC1B,aAAa,CAAC,eAAe,GAAG,CAAC,aAAa,CAAC,eAAe,CAAC;yBAClE;6BAAM;4BACH,aAAa,CAAC,iBAAiB,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC;yBACtE;qBACJ;gBACL,CAAC,CAAC,CAAC;aACN;QACL,CAAC;QAEM,qCAAW,GAAlB,UAAmB,QAAgB;;YAC/B,IAAM,SAAS,GAAG,MAAA,IAAI,CAAC,MAAM,0CAAE,eAAe,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;gBAC1D,OAAO;aACV;YACD,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,EAAE;gBACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,UAAA,aAAa;oBAChD,aAAa,CAAC,QAAQ,GAAG,CAAC,aAAa,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC;gBACtE,CAAC,CAAC,CAAC;aACN;QACL,CAAC;QACL,sBAAC;IAAD,CAAC,AAjyBD,IAiyBC;IAjyBY,0CAAe","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,7 +1,7 @@
1
1
  define(["require", "exports", "../constants/constants"], function (require, exports, constants_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.isRTL = exports.checkIfImageWasResized = exports.setSize = exports.setWrapperSizeDimensions = exports.setFlipped = exports.rotateCoordinate = exports.isASmallImage = exports.getPx = void 0;
4
+ exports.checkIfImageWasResized = exports.setSize = exports.setWrapperSizeDimensions = exports.setFlipped = exports.rotateCoordinate = exports.isASmallImage = exports.getPx = void 0;
5
5
  /**
6
6
  * @internal
7
7
  */
@@ -88,13 +88,6 @@ define(["require", "exports", "../constants/constants"], function (require, expo
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":"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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\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;
@@ -5,7 +5,7 @@ define(["require", "exports", "./doubleCheckResize", "./filterInnerResizerHandle
5
5
  /**
6
6
  * @internal
7
7
  */
8
- function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers, croppers) {
8
+ function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers, croppers, isRTL) {
9
9
  var angleRad = editInfo.angleRad, bottomPercent = editInfo.bottomPercent, leftPercent = editInfo.leftPercent, rightPercent = editInfo.rightPercent, topPercent = editInfo.topPercent, flippedHorizontal = editInfo.flippedHorizontal, flippedVertical = editInfo.flippedVertical;
10
10
  var generateImageSize = (0, generateImageSize_1.getGeneratedImageSize)(editInfo, croppers && (croppers === null || croppers === void 0 ? void 0 : croppers.length) > 0);
11
11
  if (!generateImageSize) {
@@ -28,7 +28,7 @@ define(["require", "exports", "./doubleCheckResize", "./filterInnerResizerHandle
28
28
  wrapper.style.verticalAlign = 'text-bottom';
29
29
  // Update the text-alignment to avoid the image to overflow if the parent element have align center or right
30
30
  // or if the direction is Right To Left
31
- if ((0, imageEditUtils_1.isRTL)(clonedImage)) {
31
+ if (isRTL) {
32
32
  wrapper.style.textAlign = 'right';
33
33
  if (!croppers) {
34
34
  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"]}