roosterjs 8.41.0 → 8.43.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.
package/dist/rooster.js CHANGED
@@ -2972,6 +2972,11 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2972
2972
  wrapper.parentNode.insertBefore(br, wrapper.nextSibling);
2973
2973
  }
2974
2974
  var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(wrapper);
2975
+ if (!isBlock &&
2976
+ isReadonly &&
2977
+ editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
2978
+ (0, roosterjs_editor_dom_1.addDelimiters)(entity.wrapper);
2979
+ }
2975
2980
  editor.triggerContentChangedEvent("InsertEntity" /* InsertEntity */, entity);
2976
2981
  return entity;
2977
2982
  }
@@ -2992,12 +2997,18 @@ exports.default = insertEntity;
2992
2997
  Object.defineProperty(exports, "__esModule", { value: true });
2993
2998
  var formatUndoSnapshot_1 = __webpack_require__(/*! ../utils/formatUndoSnapshot */ "./packages/roosterjs-editor-api/lib/utils/formatUndoSnapshot.ts");
2994
2999
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
2995
- function insertImage(editor, imageFile, attributes) {
2996
- if (typeof imageFile == 'string') {
2997
- insertImageWithSrc(editor, imageFile, attributes);
3000
+ /**
3001
+ * Insert an image to editor at current selection
3002
+ * @param editor The editor instance
3003
+ * @param imageFileOrSrc Either the image file blob or source string of the image.
3004
+ * @param attributes Optional image element attributes
3005
+ */
3006
+ function insertImage(editor, imageFileOrSrc, attributes) {
3007
+ if (typeof imageFileOrSrc == 'string') {
3008
+ insertImageWithSrc(editor, imageFileOrSrc, attributes);
2998
3009
  }
2999
3010
  else {
3000
- (0, roosterjs_editor_dom_1.readFile)(imageFile, function (dataUrl) {
3011
+ (0, roosterjs_editor_dom_1.readFile)(imageFileOrSrc, function (dataUrl) {
3001
3012
  if (dataUrl && !editor.isDisposed()) {
3002
3013
  insertImageWithSrc(editor, dataUrl, attributes);
3003
3014
  }
@@ -4786,6 +4797,7 @@ var addUndoSnapshot = function (core, callback, changeSource, canUndoByBackspace
4786
4797
  };
4787
4798
  exports.addUndoSnapshot = addUndoSnapshot;
4788
4799
  function addUndoSnapshotInternal(core, canUndoByBackspace) {
4800
+ var _a;
4789
4801
  if (!core.lifecycle.shadowEditFragment) {
4790
4802
  var rangeEx = core.api.getSelectionRangeEx(core);
4791
4803
  var isDarkMode = core.lifecycle.isDarkMode;
@@ -4793,6 +4805,7 @@ function addUndoSnapshotInternal(core, canUndoByBackspace) {
4793
4805
  core.undo.snapshotsService.addSnapshot({
4794
4806
  html: core.contentDiv.innerHTML,
4795
4807
  metadata: metadata,
4808
+ knownColors: ((_a = core.darkColorHandler) === null || _a === void 0 ? void 0 : _a.getKnownColorsCopy()) || [],
4796
4809
  }, canUndoByBackspace);
4797
4810
  core.undo.hasNewContent = false;
4798
4811
  }
@@ -5619,7 +5632,19 @@ var getStyleBasedFormatState = function (core, node) {
5619
5632
  pendableFormatSpan.style.backgroundColor,
5620
5633
  ];
5621
5634
  }
5622
- var styles = node ? (0, roosterjs_editor_dom_1.getComputedStyles)(node) : [];
5635
+ var styles = node
5636
+ ? (0, roosterjs_editor_dom_1.getComputedStyles)(node, [
5637
+ 'font-family',
5638
+ 'font-size',
5639
+ 'color',
5640
+ 'background-color',
5641
+ 'line-height',
5642
+ 'margin-top',
5643
+ 'margin-bottom',
5644
+ 'text-align',
5645
+ 'direction',
5646
+ ])
5647
+ : [];
5623
5648
  var contentDiv = core.contentDiv, darkColorHandler = core.darkColorHandler, isDarkMode = core.lifecycle.isDarkMode;
5624
5649
  if (darkColorHandler) {
5625
5650
  var styleTextColor = void 0;
@@ -5658,6 +5683,11 @@ var getStyleBasedFormatState = function (core, node) {
5658
5683
  darkModeColor: backColor.darkModeColor,
5659
5684
  }
5660
5685
  : undefined,
5686
+ lineHeight: styles[4],
5687
+ marginTop: styles[5],
5688
+ marginBottom: styles[6],
5689
+ textAlign: styles[7],
5690
+ direction: styles[8],
5661
5691
  };
5662
5692
  }
5663
5693
  else {
@@ -5690,6 +5720,9 @@ var getStyleBasedFormatState = function (core, node) {
5690
5720
  styles[3],
5691
5721
  }
5692
5722
  : undefined,
5723
+ lineHeight: styles[4],
5724
+ textAlign: styles[7],
5725
+ direction: styles[8],
5693
5726
  };
5694
5727
  }
5695
5728
  };
@@ -5931,6 +5964,13 @@ var restoreUndoSnapshot = function (core, step) {
5931
5964
  try {
5932
5965
  core.undo.isRestoring = true;
5933
5966
  core.api.setContent(core, snapshot.html, true /*triggerContentChangedEvent*/, (_a = snapshot.metadata) !== null && _a !== void 0 ? _a : undefined);
5967
+ var darkColorHandler_1 = core.darkColorHandler;
5968
+ var isDarkModel_1 = core.lifecycle.isDarkMode;
5969
+ if (darkColorHandler_1) {
5970
+ snapshot.knownColors.forEach(function (color) {
5971
+ darkColorHandler_1.registerColor(color.lightModeColor, isDarkModel_1, color.darkModeColor);
5972
+ });
5973
+ }
5934
5974
  }
5935
5975
  finally {
5936
5976
  core.undo.isRestoring = false;
@@ -6457,8 +6497,9 @@ exports.transformColor = transformColor;
6457
6497
  function transformV2(elements, darkColorHandler, toDark) {
6458
6498
  elements.forEach(function (element) {
6459
6499
  ColorAttributeName.forEach(function (names, i) {
6460
- var color = darkColorHandler.parseColorValue(element.style.getPropertyValue(names[0 /* CssColor */]) ||
6461
- element.getAttribute(names[1 /* HtmlColor */])).lightModeColor;
6500
+ var color = tryFetchAndClearFontColor(element, toDark, darkColorHandler, names) ||
6501
+ darkColorHandler.parseColorValue(element.style.getPropertyValue(names[0 /* CssColor */]) ||
6502
+ element.getAttribute(names[1 /* HtmlColor */])).lightModeColor;
6462
6503
  if (color && color != 'inherit') {
6463
6504
  (0, roosterjs_editor_dom_1.setColor)(element, color, i != 0, toDark, false /*shouldAdaptFontColor*/, darkColorHandler);
6464
6505
  }
@@ -6547,6 +6588,27 @@ function isHTMLElement(element) {
6547
6588
  var htmlElement = element;
6548
6589
  return !!htmlElement.style && !!htmlElement.dataset;
6549
6590
  }
6591
+ /**
6592
+ * There is a known issue that when input with IME in Chrome, it is possible Chrome insert a new FONT tag with colors.
6593
+ * If editor is in dark mode, this color will cause the FONT tag doesn't have light mode color info so that after convert
6594
+ * to light mode the color will be wrong.
6595
+ * To workaround it, we check if this is a known color (for light mode with VariableBasedDarkColor enabled, all used colors
6596
+ * are stored in darkColorHandler), then use the related light mode color instead.
6597
+ */
6598
+ function tryFetchAndClearFontColor(element, toDark, darkColorHandler, names) {
6599
+ var darkColor;
6600
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(element) == 'FONT' &&
6601
+ !element.style.getPropertyValue(names[0 /* CssColor */]) &&
6602
+ !toDark &&
6603
+ (darkColor = element.getAttribute(names[1 /* HtmlColor */]))) {
6604
+ var lightColor = darkColorHandler.findLightColorFromDarkColor(darkColor);
6605
+ if (lightColor) {
6606
+ element.removeAttribute(names[1 /* HtmlColor */]);
6607
+ return lightColor;
6608
+ }
6609
+ }
6610
+ return null;
6611
+ }
6550
6612
 
6551
6613
 
6552
6614
  /***/ }),
@@ -7205,6 +7267,7 @@ exports.default = EditPlugin;
7205
7267
  "use strict";
7206
7268
 
7207
7269
  Object.defineProperty(exports, "__esModule", { value: true });
7270
+ var inlineEntityOnPluginEvent_1 = __webpack_require__(/*! ./utils/InlineEntityHandlers/inlineEntityOnPluginEvent */ "./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts");
7208
7271
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7209
7272
  var ENTITY_ID_REGEX = /_(\d{1,8})$/;
7210
7273
  var ENTITY_CSS_REGEX = '^' + "_Entity" /* ENTITY_INFO_NAME */ + '$';
@@ -7291,6 +7354,7 @@ var EntityPlugin = /** @class */ (function () {
7291
7354
  * @param event PluginEvent object
7292
7355
  */
7293
7356
  EntityPlugin.prototype.onPluginEvent = function (event) {
7357
+ var _a;
7294
7358
  switch (event.eventType) {
7295
7359
  case 6 /* MouseUp */:
7296
7360
  this.handleMouseUpEvent(event);
@@ -7325,6 +7389,9 @@ var EntityPlugin = /** @class */ (function () {
7325
7389
  this.handleEntityOperationEvent(event);
7326
7390
  break;
7327
7391
  }
7392
+ if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
7393
+ (0, inlineEntityOnPluginEvent_1.inlineEntityOnPluginEvent)(event);
7394
+ }
7328
7395
  };
7329
7396
  EntityPlugin.prototype.handleContextMenuEvent = function (event) {
7330
7397
  var _a;
@@ -8219,7 +8286,7 @@ var PendingFormatStatePlugin = /** @class */ (function () {
8219
8286
  this.state.pendableFormatSpan) {
8220
8287
  this.state.pendableFormatSpan.removeAttribute('contentEditable');
8221
8288
  this.editor.insertNode(this.state.pendableFormatSpan);
8222
- this.editor.select(this.state.pendableFormatSpan, -2 /* Before */, this.state.pendableFormatSpan, -1 /* End */);
8289
+ this.editor.select(this.state.pendableFormatSpan, 0 /* Begin */, this.state.pendableFormatSpan, -1 /* End */);
8223
8290
  this.clear();
8224
8291
  }
8225
8292
  else if ((event.eventType == 0 /* KeyDown */ &&
@@ -8603,7 +8670,7 @@ function createUndoSnapshotServiceBridge(service) {
8603
8670
  ? {
8604
8671
  canMove: function (delta) { return service.canMove(delta); },
8605
8672
  move: function (delta) {
8606
- return (html = service.move(delta)) ? { html: html, metadata: null } : null;
8673
+ return (html = service.move(delta)) ? { html: html, metadata: null, knownColors: [] } : null;
8607
8674
  },
8608
8675
  addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
8609
8676
  return service.addSnapshot(snapshot.html +
@@ -8686,6 +8753,68 @@ function getPluginState(corePlugins) {
8686
8753
  exports.getPluginState = getPluginState;
8687
8754
 
8688
8755
 
8756
+ /***/ }),
8757
+
8758
+ /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts":
8759
+ /*!****************************************************************************************************************!*\
8760
+ !*** ./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts ***!
8761
+ \****************************************************************************************************************/
8762
+ /*! no static exports found */
8763
+ /***/ (function(module, exports, __webpack_require__) {
8764
+
8765
+ "use strict";
8766
+
8767
+ Object.defineProperty(exports, "__esModule", { value: true });
8768
+ exports.inlineEntityOnPluginEvent = void 0;
8769
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
8770
+ var DELIMITER_SELECTOR = '.' + "entityDelimiterAfter" /* DELIMITER_AFTER */ + ',.' + "entityDelimiterBefore" /* DELIMITER_BEFORE */;
8771
+ function inlineEntityOnPluginEvent(event) {
8772
+ switch (event.eventType) {
8773
+ case 8 /* ExtractContentWithDom */:
8774
+ case 9 /* BeforeCutCopy */:
8775
+ event.clonedRoot.querySelectorAll(DELIMITER_SELECTOR).forEach(function (node) {
8776
+ var _a;
8777
+ (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(node);
8778
+ });
8779
+ break;
8780
+ case 15 /* EntityOperation */:
8781
+ var wrapper = event.entity.wrapper;
8782
+ switch (event.operation) {
8783
+ case 4 /* RemoveFromStart */:
8784
+ case 5 /* RemoveFromEnd */:
8785
+ case 6 /* Overwrite */:
8786
+ var entity = event.entity;
8787
+ // If the entity removed is a readonly entity, try to remove delimiters around it.
8788
+ if (isReadOnly(entity)) {
8789
+ removeDelimiters(wrapper);
8790
+ }
8791
+ break;
8792
+ }
8793
+ break;
8794
+ }
8795
+ }
8796
+ exports.inlineEntityOnPluginEvent = inlineEntityOnPluginEvent;
8797
+ function getDelimiter(entityWrapper, after) {
8798
+ var el = after ? entityWrapper.nextElementSibling : entityWrapper.previousElementSibling;
8799
+ return el && (0, roosterjs_editor_dom_1.safeInstanceOf)(el, 'HTMLElement') && (0, roosterjs_editor_dom_1.getDelimiterFromElement)(el) ? el : undefined;
8800
+ }
8801
+ function removeDelimiters(entityWrapper) {
8802
+ var _a, _b;
8803
+ var el = undefined;
8804
+ if ((el = getDelimiter(entityWrapper, true))) {
8805
+ (_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(el);
8806
+ }
8807
+ if ((el = getDelimiter(entityWrapper, false))) {
8808
+ (_b = el.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(el);
8809
+ }
8810
+ }
8811
+ function isReadOnly(entity) {
8812
+ return (entity.isReadonly &&
8813
+ !(0, roosterjs_editor_dom_1.isBlockElement)(entity.wrapper) &&
8814
+ (0, roosterjs_editor_dom_1.safeInstanceOf)(entity.wrapper, 'HTMLElement'));
8815
+ }
8816
+
8817
+
8689
8818
  /***/ }),
8690
8819
 
8691
8820
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/forEachSelectedCell.ts":
@@ -8792,6 +8921,13 @@ var DarkColorHandlerImpl = /** @class */ (function () {
8792
8921
  this.getDarkColor = getDarkColor;
8793
8922
  this.knownColors = {};
8794
8923
  }
8924
+ /**
8925
+ * Get a copy of known colors
8926
+ * @returns
8927
+ */
8928
+ DarkColorHandlerImpl.prototype.getKnownColorsCopy = function () {
8929
+ return Object.values(this.knownColors);
8930
+ };
8795
8931
  /**
8796
8932
  * Given a light mode color value and an optional dark mode color value, register this color
8797
8933
  * so that editor can handle it, then return the CSS color value for current color mode.
@@ -8854,6 +8990,27 @@ var DarkColorHandlerImpl = /** @class */ (function () {
8854
8990
  }
8855
8991
  return { key: key, lightModeColor: lightModeColor, darkModeColor: darkModeColor };
8856
8992
  };
8993
+ /**
8994
+ * Find related light mode color from dark mode color.
8995
+ * @param darkColor The existing dark color
8996
+ */
8997
+ DarkColorHandlerImpl.prototype.findLightColorFromDarkColor = function (darkColor) {
8998
+ var _this = this;
8999
+ var rgbSearch = (0, roosterjs_editor_dom_1.parseColor)(darkColor);
9000
+ if (rgbSearch) {
9001
+ var key = (0, roosterjs_editor_dom_1.getObjectKeys)(this.knownColors).find(function (key) {
9002
+ var rgbCurrent = (0, roosterjs_editor_dom_1.parseColor)(_this.knownColors[key].darkModeColor);
9003
+ return (rgbCurrent &&
9004
+ rgbCurrent[0] == rgbSearch[0] &&
9005
+ rgbCurrent[1] == rgbSearch[1] &&
9006
+ rgbCurrent[2] == rgbSearch[2]);
9007
+ });
9008
+ if (key) {
9009
+ return this.knownColors[key].lightModeColor;
9010
+ }
9011
+ }
9012
+ return null;
9013
+ };
8857
9014
  return DarkColorHandlerImpl;
8858
9015
  }());
8859
9016
  exports.default = DarkColorHandlerImpl;
@@ -11110,6 +11267,76 @@ var SelectionScoper = /** @class */ (function () {
11110
11267
  exports.default = SelectionScoper;
11111
11268
 
11112
11269
 
11270
+ /***/ }),
11271
+
11272
+ /***/ "./packages/roosterjs-editor-dom/lib/delimiter/addDelimiters.ts":
11273
+ /*!**********************************************************************!*\
11274
+ !*** ./packages/roosterjs-editor-dom/lib/delimiter/addDelimiters.ts ***!
11275
+ \**********************************************************************/
11276
+ /*! no static exports found */
11277
+ /***/ (function(module, exports, __webpack_require__) {
11278
+
11279
+ "use strict";
11280
+
11281
+ Object.defineProperty(exports, "__esModule", { value: true });
11282
+ var createElement_1 = __webpack_require__(/*! ../utils/createElement */ "./packages/roosterjs-editor-dom/lib/utils/createElement.ts");
11283
+ var ZERO_WIDTH_SPACE = '\u200B';
11284
+ /**
11285
+ * Adds delimiters to the element provided.
11286
+ * @param element element to be between delimiters
11287
+ */
11288
+ function addDelimiters(element) {
11289
+ function insertDelimiter(delimiterClass) {
11290
+ var span = (0, createElement_1.default)({
11291
+ tag: 'span',
11292
+ className: delimiterClass,
11293
+ children: [ZERO_WIDTH_SPACE],
11294
+ }, element.ownerDocument);
11295
+ if (span) {
11296
+ var insertPosition = delimiterClass == "entityDelimiterAfter" /* DELIMITER_AFTER */ ? 'afterend' : 'beforebegin';
11297
+ element.insertAdjacentElement(insertPosition, span);
11298
+ }
11299
+ }
11300
+ insertDelimiter("entityDelimiterAfter" /* DELIMITER_AFTER */);
11301
+ insertDelimiter("entityDelimiterBefore" /* DELIMITER_BEFORE */);
11302
+ }
11303
+ exports.default = addDelimiters;
11304
+
11305
+
11306
+ /***/ }),
11307
+
11308
+ /***/ "./packages/roosterjs-editor-dom/lib/delimiter/getDelimiterFromElement.ts":
11309
+ /*!********************************************************************************!*\
11310
+ !*** ./packages/roosterjs-editor-dom/lib/delimiter/getDelimiterFromElement.ts ***!
11311
+ \********************************************************************************/
11312
+ /*! no static exports found */
11313
+ /***/ (function(module, exports, __webpack_require__) {
11314
+
11315
+ "use strict";
11316
+
11317
+ Object.defineProperty(exports, "__esModule", { value: true });
11318
+ var getTagOfNode_1 = __webpack_require__(/*! ../utils/getTagOfNode */ "./packages/roosterjs-editor-dom/lib/utils/getTagOfNode.ts");
11319
+ var ZERO_WIDTH_SPACE = '\u200B';
11320
+ /**
11321
+ * Retrieves Delimiter information from a provided element.
11322
+ * @param element element to try to retrieve a delimiter
11323
+ * @returns delimiter info if it is a Delimiter, else null
11324
+ */
11325
+ function getDelimiterFromElement(element) {
11326
+ if (!element) {
11327
+ return null;
11328
+ }
11329
+ if ((0, getTagOfNode_1.default)(element) == 'SPAN' &&
11330
+ (element.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */) ||
11331
+ element.classList.contains("entityDelimiterBefore" /* DELIMITER_BEFORE */)) &&
11332
+ element.textContent === ZERO_WIDTH_SPACE) {
11333
+ return element;
11334
+ }
11335
+ return null;
11336
+ }
11337
+ exports.default = getDelimiterFromElement;
11338
+
11339
+
11113
11340
  /***/ }),
11114
11341
 
11115
11342
  /***/ "./packages/roosterjs-editor-dom/lib/edit/adjustInsertPosition.ts":
@@ -12492,7 +12719,6 @@ var DEFAULT_STYLE_VALUES = {
12492
12719
  'outline-style': 'none',
12493
12720
  'outline-width': '0px',
12494
12721
  overflow: 'visible',
12495
- 'text-decoration': 'none',
12496
12722
  '-webkit-text-stroke-width': '0px',
12497
12723
  'word-wrap': 'break-word',
12498
12724
  'margin-left': '0px',
@@ -12721,9 +12947,9 @@ exports.isCssVariable = isCssVariable;
12721
12947
  "use strict";
12722
12948
 
12723
12949
  Object.defineProperty(exports, "__esModule", { value: true });
12724
- exports.getIntersectedRect = exports.moveChildNodes = exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
12725
- exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.restoreContentWithEntityPlaceholder = exports.moveContentWithEntityPlaceholders = exports.createEntityPlaceholder = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.saveTableCellMetadata = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.isNodeAfter = void 0;
12726
- exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = exports.createNumberDefinition = exports.validate = exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.removeGlobalCssStyle = exports.setGlobalCssStyles = exports.removeImportantStyleRule = exports.setStyles = void 0;
12950
+ exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.getDelimiterFromElement = exports.addDelimiters = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
12951
+ exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.restoreContentWithEntityPlaceholder = exports.moveContentWithEntityPlaceholders = exports.createEntityPlaceholder = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.saveTableCellMetadata = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.parseColor = exports.isNodeAfter = exports.getIntersectedRect = exports.moveChildNodes = void 0;
12952
+ exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = exports.createNumberDefinition = exports.validate = exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.removeGlobalCssStyle = exports.setGlobalCssStyles = exports.removeImportantStyleRule = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = void 0;
12727
12953
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
12728
12954
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
12729
12955
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -12732,6 +12958,10 @@ var ContentTraverser_1 = __webpack_require__(/*! ./contentTraverser/ContentTrave
12732
12958
  Object.defineProperty(exports, "ContentTraverser", { enumerable: true, get: function () { return ContentTraverser_1.default; } });
12733
12959
  var PositionContentSearcher_1 = __webpack_require__(/*! ./contentTraverser/PositionContentSearcher */ "./packages/roosterjs-editor-dom/lib/contentTraverser/PositionContentSearcher.ts");
12734
12960
  Object.defineProperty(exports, "PositionContentSearcher", { enumerable: true, get: function () { return PositionContentSearcher_1.default; } });
12961
+ var addDelimiters_1 = __webpack_require__(/*! ./delimiter/addDelimiters */ "./packages/roosterjs-editor-dom/lib/delimiter/addDelimiters.ts");
12962
+ Object.defineProperty(exports, "addDelimiters", { enumerable: true, get: function () { return addDelimiters_1.default; } });
12963
+ var getDelimiterFromElement_1 = __webpack_require__(/*! ./delimiter/getDelimiterFromElement */ "./packages/roosterjs-editor-dom/lib/delimiter/getDelimiterFromElement.ts");
12964
+ Object.defineProperty(exports, "getDelimiterFromElement", { enumerable: true, get: function () { return getDelimiterFromElement_1.default; } });
12735
12965
  var getInlineElementAtNode_1 = __webpack_require__(/*! ./inlineElements/getInlineElementAtNode */ "./packages/roosterjs-editor-dom/lib/inlineElements/getInlineElementAtNode.ts");
12736
12966
  Object.defineProperty(exports, "getInlineElementAtNode", { enumerable: true, get: function () { return getInlineElementAtNode_1.default; } });
12737
12967
  var ImageInlineElement_1 = __webpack_require__(/*! ./inlineElements/ImageInlineElement */ "./packages/roosterjs-editor-dom/lib/inlineElements/ImageInlineElement.ts");
@@ -12819,6 +13049,8 @@ var getIntersectedRect_1 = __webpack_require__(/*! ./utils/getIntersectedRect */
12819
13049
  Object.defineProperty(exports, "getIntersectedRect", { enumerable: true, get: function () { return getIntersectedRect_1.default; } });
12820
13050
  var isNodeAfter_1 = __webpack_require__(/*! ./utils/isNodeAfter */ "./packages/roosterjs-editor-dom/lib/utils/isNodeAfter.ts");
12821
13051
  Object.defineProperty(exports, "isNodeAfter", { enumerable: true, get: function () { return isNodeAfter_1.default; } });
13052
+ var parseColor_1 = __webpack_require__(/*! ./utils/parseColor */ "./packages/roosterjs-editor-dom/lib/utils/parseColor.ts");
13053
+ Object.defineProperty(exports, "parseColor", { enumerable: true, get: function () { return parseColor_1.default; } });
12822
13054
  var VTable_1 = __webpack_require__(/*! ./table/VTable */ "./packages/roosterjs-editor-dom/lib/table/VTable.ts");
12823
13055
  Object.defineProperty(exports, "VTable", { enumerable: true, get: function () { return VTable_1.default; } });
12824
13056
  var isWholeTableSelected_1 = __webpack_require__(/*! ./table/isWholeTableSelected */ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts");
@@ -18854,8 +19086,8 @@ function getIntersectedRect(elements, additionalRects) {
18854
19086
  if (additionalRects === void 0) { additionalRects = []; }
18855
19087
  var rects = elements
18856
19088
  .map(function (element) { return (0, normalizeRect_1.default)(element.getBoundingClientRect()); })
18857
- .filter(function (element) { return !!element; })
18858
- .concat(additionalRects);
19089
+ .concat(additionalRects)
19090
+ .filter(function (element) { return !!element; });
18859
19091
  var result = {
18860
19092
  top: Math.max.apply(Math, rects.map(function (r) { return r.top; })),
18861
19093
  bottom: Math.min.apply(Math, rects.map(function (r) { return r.bottom; })),
@@ -19397,6 +19629,51 @@ function normalizeRect(clientRect) {
19397
19629
  exports.default = normalizeRect;
19398
19630
 
19399
19631
 
19632
+ /***/ }),
19633
+
19634
+ /***/ "./packages/roosterjs-editor-dom/lib/utils/parseColor.ts":
19635
+ /*!***************************************************************!*\
19636
+ !*** ./packages/roosterjs-editor-dom/lib/utils/parseColor.ts ***!
19637
+ \***************************************************************/
19638
+ /*! no static exports found */
19639
+ /***/ (function(module, exports, __webpack_require__) {
19640
+
19641
+ "use strict";
19642
+
19643
+ Object.defineProperty(exports, "__esModule", { value: true });
19644
+ var HEX3_REGEX = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/;
19645
+ var HEX6_REGEX = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/;
19646
+ var RGB_REGEX = /^rgb\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*\)$/;
19647
+ var RGBA_REGEX = /^rgba\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*\)$/;
19648
+ /**
19649
+ * Parse color string to r/g/b value.
19650
+ * If the given color is not in a recognized format, return null
19651
+ */
19652
+ function parseColor(color) {
19653
+ color = (color || '').trim();
19654
+ var match;
19655
+ if ((match = color.match(HEX3_REGEX))) {
19656
+ return [
19657
+ parseInt(match[1] + match[1], 16),
19658
+ parseInt(match[2] + match[2], 16),
19659
+ parseInt(match[3] + match[3], 16),
19660
+ ];
19661
+ }
19662
+ else if ((match = color.match(HEX6_REGEX))) {
19663
+ return [parseInt(match[1], 16), parseInt(match[2], 16), parseInt(match[3], 16)];
19664
+ }
19665
+ else if ((match = color.match(RGB_REGEX) || color.match(RGBA_REGEX))) {
19666
+ return [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])];
19667
+ }
19668
+ else {
19669
+ // CSS color names such as red, green is not included for now.
19670
+ // If need, we can add those colors from https://www.w3.org/wiki/CSS/Properties/color/keywords
19671
+ return null;
19672
+ }
19673
+ }
19674
+ exports.default = parseColor;
19675
+
19676
+
19400
19677
  /***/ }),
19401
19678
 
19402
19679
  /***/ "./packages/roosterjs-editor-dom/lib/utils/queryElements.ts":
@@ -19566,6 +19843,7 @@ exports.default = safeInstanceOf;
19566
19843
  "use strict";
19567
19844
 
19568
19845
  Object.defineProperty(exports, "__esModule", { value: true });
19846
+ var parseColor_1 = __webpack_require__(/*! ./parseColor */ "./packages/roosterjs-editor-dom/lib/utils/parseColor.ts");
19569
19847
  var WHITE = '#ffffff';
19570
19848
  var GRAY = '#333333';
19571
19849
  var BLACK = '#000000';
@@ -19660,40 +19938,19 @@ function isADarkOrBrightColor(color) {
19660
19938
  * @returns
19661
19939
  */
19662
19940
  function calculateLightness(color) {
19663
- var _a, _b;
19664
- var r;
19665
- var g;
19666
- var b;
19667
- if (color.substring(0, 1) == '#') {
19668
- _a = getColorsFromHEX(color), r = _a[0], g = _a[1], b = _a[2];
19669
- }
19670
- else {
19671
- _b = getColorsFromRGB(color), r = _b[0], g = _b[1], b = _b[2];
19672
- }
19941
+ var colorValues = (0, parseColor_1.default)(color);
19673
19942
  // Use the values of r,g,b to calculate the lightness in the HSl representation
19674
19943
  //First calculate the fraction of the light in each color, since in css the value of r,g,b is in the interval of [0,255], we have
19675
- var red = r / 255;
19676
- var green = g / 255;
19677
- var blue = b / 255;
19678
- //Then the lightness in the HSL representation is the average between maximum fraction of r,g,b and the minimum fraction
19679
- return (Math.max(red, green, blue) + Math.min(red, green, blue)) * 50;
19680
- }
19681
- function getColorsFromHEX(color) {
19682
- if (color.length === 4) {
19683
- color = color.replace(/(.)/g, '$1$1');
19944
+ if (colorValues) {
19945
+ var red = colorValues[0] / 255;
19946
+ var green = colorValues[1] / 255;
19947
+ var blue = colorValues[2] / 255;
19948
+ //Then the lightness in the HSL representation is the average between maximum fraction of r,g,b and the minimum fraction
19949
+ return (Math.max(red, green, blue) + Math.min(red, green, blue)) * 50;
19950
+ }
19951
+ else {
19952
+ return 255;
19684
19953
  }
19685
- var colors = color.replace('#', '');
19686
- var r = parseInt(colors.substr(0, 2), 16);
19687
- var g = parseInt(colors.substr(2, 2), 16);
19688
- var b = parseInt(colors.substr(4, 2), 16);
19689
- return [r, g, b];
19690
- }
19691
- function getColorsFromRGB(color) {
19692
- var colors = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
19693
- var r = parseInt(colors[1]);
19694
- var g = parseInt(colors[2]);
19695
- var b = parseInt(colors[3]);
19696
- return [r, g, b];
19697
19954
  }
19698
19955
 
19699
19956
 
@@ -20383,6 +20640,9 @@ var DragAndDropHelper = /** @class */ (function () {
20383
20640
  this.onSubmit = onSubmit;
20384
20641
  this.handler = handler;
20385
20642
  this.zoomScale = zoomScale;
20643
+ this.initX = 0;
20644
+ this.initY = 0;
20645
+ this.initValue = undefined;
20386
20646
  this.onMouseDown = function (e) {
20387
20647
  var _a;
20388
20648
  var _b, _c;
@@ -20398,7 +20658,8 @@ var DragAndDropHelper = /** @class */ (function () {
20398
20658
  var _d = _this.dndMouse.getPageXY(e), pageX = _d[0], pageY = _d[1];
20399
20659
  var deltaX = (pageX - _this.initX) / _this.zoomScale;
20400
20660
  var deltaY = (pageY - _this.initY) / _this.zoomScale;
20401
- if ((_b = (_a = _this.handler).onDragging) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue, deltaX, deltaY)) {
20661
+ if (_this.initValue &&
20662
+ ((_b = (_a = _this.handler).onDragging) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue, deltaX, deltaY))) {
20402
20663
  (_c = _this.onSubmit) === null || _c === void 0 ? void 0 : _c.call(_this, _this.context, _this.trigger);
20403
20664
  }
20404
20665
  };
@@ -20406,7 +20667,8 @@ var DragAndDropHelper = /** @class */ (function () {
20406
20667
  var _a, _b, _c;
20407
20668
  e.preventDefault();
20408
20669
  _this.removeDocumentEvents();
20409
- if ((_b = (_a = _this.handler).onDragEnd) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue)) {
20670
+ if (_this.initValue &&
20671
+ ((_b = (_a = _this.handler).onDragEnd) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue))) {
20410
20672
  (_c = _this.onSubmit) === null || _c === void 0 ? void 0 : _c.call(_this, _this.context, _this.trigger);
20411
20673
  }
20412
20674
  };
@@ -21002,6 +21264,7 @@ var IndentWhenTab = {
21002
21264
  shouldHandleEvent: shouldHandleIndentationEvent(true),
21003
21265
  handleEvent: handleIndentationEvent(true),
21004
21266
  allowFunctionKeys: true,
21267
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
21005
21268
  };
21006
21269
  /**
21007
21270
  * OutdentWhenShiftTab edit feature, provides the ability to outdent current list when user press Shift+TAB
@@ -21011,6 +21274,7 @@ var OutdentWhenShiftTab = {
21011
21274
  shouldHandleEvent: shouldHandleIndentationEvent(false),
21012
21275
  handleEvent: handleIndentationEvent(false),
21013
21276
  allowFunctionKeys: true,
21277
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
21014
21278
  };
21015
21279
  /**
21016
21280
  * MergeInNewLine edit feature, provides the ability to merge current line into a new line when user press
@@ -21308,7 +21572,7 @@ function shouldTriggerList(event, editor, getListStyle, listType) {
21308
21572
  var textBeforeCursor = searcher.getSubStringBefore(4);
21309
21573
  var traverser = editor.getBlockTraverser();
21310
21574
  var text = traverser && traverser.currentBlockElement
21311
- ? traverser.currentBlockElement.getTextContent()
21575
+ ? traverser.currentBlockElement.getTextContent().slice(0, textBeforeCursor.length)
21312
21576
  : null;
21313
21577
  var isATheBeginning = text && text === textBeforeCursor;
21314
21578
  var listChains = getListChains(editor);
@@ -21923,6 +22187,23 @@ var UpDownInTable = {
21923
22187
  },
21924
22188
  defaultDisabled: !roosterjs_editor_dom_1.Browser.isChrome && !roosterjs_editor_dom_1.Browser.isSafari,
21925
22189
  };
22190
+ /**
22191
+ * Requires @see ExperimentalFeatures.DeleteTableWithBackspace
22192
+ * Delete a table selected with the table selector pressing Backspace key
22193
+ */
22194
+ var DeleteTableWithBackspace = {
22195
+ keys: [8 /* BACKSPACE */],
22196
+ shouldHandleEvent: function (event, editor) {
22197
+ return editor.isFeatureEnabled("DeleteTableWithBackspace" /* DeleteTableWithBackspace */) &&
22198
+ cacheIsWholeTableSelected(event, editor);
22199
+ },
22200
+ handleEvent: function (event, editor) {
22201
+ var td = cacheGetTableCell(event, editor);
22202
+ var vtable = new roosterjs_editor_dom_1.VTable(td);
22203
+ vtable.edit(4 /* DeleteTable */);
22204
+ vtable.writeBack();
22205
+ },
22206
+ };
21926
22207
  function cacheGetTableCell(event, editor) {
21927
22208
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'TABLE_CELL_FOR_TABLE_FEATURES', function () {
21928
22209
  var pos = editor.getFocusedPosition();
@@ -21951,6 +22232,7 @@ exports.TableFeatures = {
21951
22232
  tabInTable: TabInTable,
21952
22233
  upDownInTable: UpDownInTable,
21953
22234
  indentTableOnTab: IndentTableOnTab,
22235
+ deleteTableWithBackspace: DeleteTableWithBackspace,
21954
22236
  };
21955
22237
 
21956
22238
 
@@ -23066,7 +23348,7 @@ var DefaultOptions = {
23066
23348
  preserveRatio: false,
23067
23349
  minRotateDeg: 5,
23068
23350
  imageSelector: 'img',
23069
- rotateIconHTML: null,
23351
+ rotateIconHTML: '',
23070
23352
  disableCrop: false,
23071
23353
  disableRotate: false,
23072
23354
  disableSideResize: false,
@@ -23105,6 +23387,34 @@ var ImageEdit = /** @class */ (function () {
23105
23387
  function ImageEdit(options, onShowResizeHandle) {
23106
23388
  var _this = this;
23107
23389
  this.onShowResizeHandle = onShowResizeHandle;
23390
+ this.editor = null;
23391
+ this.disposer = null;
23392
+ // Current editing image
23393
+ this.image = null;
23394
+ // Image cloned from the current editing image
23395
+ this.clonedImage = null;
23396
+ // The image wrapper
23397
+ this.wrapper = null;
23398
+ // Current edit info of the image. All changes user made will be stored in this object.
23399
+ // We use this object to update the editing UI, and finally we will use this object to generate
23400
+ // the new image if necessary
23401
+ this.editInfo = null;
23402
+ // Src of the image before current editing
23403
+ this.lastSrc = null;
23404
+ // Drag and drop helper objects
23405
+ this.dndHelpers = [];
23406
+ /**
23407
+ * Identify if the image was resized by the user.
23408
+ */
23409
+ this.wasResized = false;
23410
+ /**
23411
+ * The span element that wraps the image and opens shadow dom
23412
+ */
23413
+ this.shadowSpan = null;
23414
+ /**
23415
+ * The span element that wraps the image and opens shadow dom
23416
+ */
23417
+ this.isCropping = false;
23108
23418
  /**
23109
23419
  * quit editing mode when editor lose focus
23110
23420
  */
@@ -23115,7 +23425,11 @@ var ImageEdit = /** @class */ (function () {
23115
23425
  * Remove the temp wrapper of the image
23116
23426
  */
23117
23427
  this.removeWrapper = function () {
23118
- if (_this.editor.contains(_this.image) && _this.wrapper) {
23428
+ if (_this.editor &&
23429
+ _this.image &&
23430
+ _this.image.parentNode &&
23431
+ _this.editor.contains(_this.image) &&
23432
+ _this.wrapper) {
23119
23433
  (0, roosterjs_editor_dom_1.unwrap)(_this.image.parentNode);
23120
23434
  }
23121
23435
  _this.wrapper = null;
@@ -23126,8 +23440,14 @@ var ImageEdit = /** @class */ (function () {
23126
23440
  * @param context
23127
23441
  */
23128
23442
  this.updateWrapper = function (context) {
23443
+ var _a, _b;
23129
23444
  var wrapper = _this.wrapper;
23130
- if (wrapper) {
23445
+ if (wrapper &&
23446
+ _this.editInfo &&
23447
+ _this.image &&
23448
+ _this.clonedImage &&
23449
+ _this.options &&
23450
+ ((_a = _this.shadowSpan) === null || _a === void 0 ? void 0 : _a.parentElement)) {
23131
23451
  // Prepare: get related editing elements
23132
23452
  var cropContainers = getEditElements(wrapper, "r_cropC" /* CropContainer */);
23133
23453
  var cropOverlays = getEditElements(wrapper, "r_cropO" /* CropOverlay */);
@@ -23137,9 +23457,9 @@ var ImageEdit = /** @class */ (function () {
23137
23457
  var cropHandles = getEditElements(wrapper, "r_cropH" /* CropHandle */);
23138
23458
  // Cropping and resizing will show different UI, so check if it is cropping here first
23139
23459
  _this.isCropping = cropContainers.length == 1 && cropOverlays.length == 4;
23140
- var _a = _this.editInfo, angleRad = _a.angleRad, bottomPercent = _a.bottomPercent, leftPercent = _a.leftPercent, rightPercent = _a.rightPercent, topPercent = _a.topPercent;
23460
+ var _c = _this.editInfo, angleRad = _c.angleRad, bottomPercent = _c.bottomPercent, leftPercent = _c.leftPercent, rightPercent = _c.rightPercent, topPercent = _c.topPercent;
23141
23461
  // Width/height of the image
23142
- var _b = (0, getGeneratedImageSize_1.default)(_this.editInfo, _this.isCropping), targetWidth = _b.targetWidth, targetHeight = _b.targetHeight, originalWidth = _b.originalWidth, originalHeight = _b.originalHeight, visibleWidth = _b.visibleWidth, visibleHeight = _b.visibleHeight;
23462
+ var _d = (0, getGeneratedImageSize_1.default)(_this.editInfo, _this.isCropping), targetWidth = _d.targetWidth, targetHeight = _d.targetHeight, originalWidth = _d.originalWidth, originalHeight = _d.originalHeight, visibleWidth = _d.visibleWidth, visibleHeight = _d.visibleHeight;
23143
23463
  var marginHorizontal = (targetWidth - visibleWidth) / 2;
23144
23464
  var marginVertical = (targetHeight - visibleHeight) / 2;
23145
23465
  var cropLeftPx = originalWidth * leftPercent;
@@ -23147,15 +23467,12 @@ var ImageEdit = /** @class */ (function () {
23147
23467
  var cropTopPx = originalHeight * topPercent;
23148
23468
  var cropBottomPx = originalHeight * bottomPercent;
23149
23469
  // Update size and margin of the wrapper
23150
- wrapper.style.width = getPx(visibleWidth);
23151
- wrapper.style.height = getPx(visibleHeight);
23152
23470
  wrapper.style.margin = marginVertical + "px " + marginHorizontal + "px";
23153
23471
  wrapper.style.transform = "rotate(" + angleRad + "rad)";
23154
- _this.wrapper.style.width = getPx(visibleWidth);
23155
- _this.wrapper.style.height = getPx(visibleHeight);
23472
+ setWrapperSizeDimensions(wrapper, _this.image, visibleWidth, visibleHeight);
23156
23473
  // Update the text-alignment to avoid the image to overflow if the parent element have align center or right
23157
23474
  // or if the direction is Right To Left
23158
- wrapper.style.textAlign = isRtl(wrapper.parentNode) ? 'right' : 'left';
23475
+ wrapper.style.textAlign = isRtl(_this.shadowSpan.parentElement) ? 'right' : 'left';
23159
23476
  // Update size of the image
23160
23477
  _this.clonedImage.style.width = getPx(originalWidth);
23161
23478
  _this.clonedImage.style.height = getPx(originalHeight);
@@ -23176,10 +23493,13 @@ var ImageEdit = /** @class */ (function () {
23176
23493
  var clientWidth = wrapper.clientWidth;
23177
23494
  var clientHeight = wrapper.clientHeight;
23178
23495
  _this.wasResized = true;
23179
- (0, Resizer_1.doubleCheckResize)(_this.editInfo, _this.options.preserveRatio, clientWidth, clientHeight);
23496
+ (0, Resizer_1.doubleCheckResize)(_this.editInfo, _this.options.preserveRatio || false, clientWidth, clientHeight);
23180
23497
  _this.updateWrapper();
23181
23498
  }
23182
- (0, Rotator_1.updateRotateHandlePosition)(_this.editInfo, _this.editor.getVisibleViewport(), marginVertical, rotateCenter, rotateHandle);
23499
+ var viewport = (_b = _this.editor) === null || _b === void 0 ? void 0 : _b.getVisibleViewport();
23500
+ if (rotateHandle && rotateCenter && viewport) {
23501
+ (0, Rotator_1.updateRotateHandlePosition)(_this.editInfo, viewport, marginVertical, rotateCenter, rotateHandle);
23502
+ }
23183
23503
  updateHandleCursor(resizeHandles, angleRad);
23184
23504
  }
23185
23505
  }
@@ -23205,7 +23525,7 @@ var ImageEdit = /** @class */ (function () {
23205
23525
  var _this = this;
23206
23526
  this.editor = editor;
23207
23527
  this.disposer = editor.addDomEventHandler({
23208
- blur: function () { return _this.onBlur; },
23528
+ blur: function () { return _this.onBlur(); },
23209
23529
  dragstart: function (e) {
23210
23530
  if (_this.image) {
23211
23531
  e.preventDefault();
@@ -23217,8 +23537,9 @@ var ImageEdit = /** @class */ (function () {
23217
23537
  * Dispose this plugin
23218
23538
  */
23219
23539
  ImageEdit.prototype.dispose = function () {
23540
+ var _a;
23220
23541
  this.clearDndHelpers();
23221
- this.disposer();
23542
+ (_a = this.disposer) === null || _a === void 0 ? void 0 : _a.call(this);
23222
23543
  this.disposer = null;
23223
23544
  this.editor = null;
23224
23545
  };
@@ -23227,10 +23548,13 @@ var ImageEdit = /** @class */ (function () {
23227
23548
  * @param e PluginEvent object
23228
23549
  */
23229
23550
  ImageEdit.prototype.onPluginEvent = function (e) {
23551
+ var _a;
23230
23552
  switch (e.eventType) {
23231
23553
  case 22 /* SelectionChanged */:
23232
23554
  if (e.selectionRangeEx &&
23233
- e.selectionRangeEx.type === 2 /* ImageSelection */) {
23555
+ e.selectionRangeEx.type === 2 /* ImageSelection */ &&
23556
+ this.options &&
23557
+ this.options.onSelectState !== undefined) {
23234
23558
  this.setEditingImage(e.selectionRangeEx.image, this.options.onSelectState);
23235
23559
  }
23236
23560
  break;
@@ -23253,9 +23577,11 @@ var ImageEdit = /** @class */ (function () {
23253
23577
  break;
23254
23578
  case 8 /* ExtractContentWithDom */:
23255
23579
  // When extract content, remove all image info since they may not be valid when load the content again
23256
- (0, roosterjs_editor_dom_1.toArray)(e.clonedRoot.querySelectorAll(this.options.imageSelector)).forEach(function (img) {
23257
- (0, editInfo_1.deleteEditInfo)(img);
23258
- });
23580
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.imageSelector) {
23581
+ (0, roosterjs_editor_dom_1.toArray)(e.clonedRoot.querySelectorAll(this.options.imageSelector)).forEach(function (img) {
23582
+ (0, editInfo_1.deleteEditInfo)(img);
23583
+ });
23584
+ }
23259
23585
  break;
23260
23586
  case 12 /* BeforeDispose */:
23261
23587
  this.removeWrapper();
@@ -23274,7 +23600,12 @@ var ImageEdit = /** @class */ (function () {
23274
23600
  var _this = this;
23275
23601
  var operation = typeof operationOrSelect === 'number' ? operationOrSelect : 0 /* None */;
23276
23602
  var selectImage = typeof operationOrSelect === 'number' ? false : !!operationOrSelect;
23277
- if (!image && this.image) {
23603
+ if (!image &&
23604
+ this.image &&
23605
+ this.editor &&
23606
+ this.editInfo &&
23607
+ this.lastSrc &&
23608
+ this.clonedImage) {
23278
23609
  // When there is image in editing, clean up any cached objects and elements
23279
23610
  this.clearDndHelpers();
23280
23611
  // Apply the changes, and add undo snapshot if necessary
@@ -23291,7 +23622,7 @@ var ImageEdit = /** @class */ (function () {
23291
23622
  this.clonedImage = null;
23292
23623
  this.isCropping = false;
23293
23624
  }
23294
- if (!this.image && (image === null || image === void 0 ? void 0 : image.isContentEditable)) {
23625
+ if (!this.image && (image === null || image === void 0 ? void 0 : image.isContentEditable) && this.editor) {
23295
23626
  // If there is new image to edit, enter editing mode for this image
23296
23627
  this.editor.addUndoSnapshot();
23297
23628
  this.image = image;
@@ -23315,47 +23646,55 @@ var ImageEdit = /** @class */ (function () {
23315
23646
  */
23316
23647
  ImageEdit.prototype.createWrapper = function (operation) {
23317
23648
  var _this = this;
23318
- //Clone the image and insert the clone in a entity
23319
- this.clonedImage = this.image.cloneNode(true);
23320
- this.clonedImage.removeAttribute('id');
23321
- this.wrapper = (0, roosterjs_editor_dom_1.createElement)(6 /* ImageEditWrapper */, this.image.ownerDocument);
23322
- this.wrapper.firstChild.appendChild(this.clonedImage);
23323
- this.wrapper.style.display = roosterjs_editor_dom_1.Browser.isSafari ? 'inline-block' : 'inline-flex';
23324
- // Cache current src so that we can compare it after edit see if src is changed
23325
- this.lastSrc = this.image.getAttribute('src');
23326
- // Set image src to original src to help show editing UI, also it will be used when regenerate image dataURL after editing
23327
- this.clonedImage.src = this.editInfo.src;
23328
- this.clonedImage.style.position = 'absolute';
23329
- // Get HTML for all edit elements (resize handle, rotate handle, crop handle and overlay, ...) and create HTML element
23330
- var options = {
23331
- borderColor: getColorString(this.options.borderColor, this.editor.isDarkMode()),
23332
- rotateIconHTML: this.options.rotateIconHTML,
23333
- rotateHandleBackColor: this.editor.isDarkMode()
23334
- ? DARK_MODE_BGCOLOR
23335
- : LIGHT_MODE_BGCOLOR,
23336
- isSmallImage: isASmallImage(this.editInfo),
23337
- };
23338
- var htmlData = [(0, Resizer_1.getResizeBordersHTML)(options)];
23339
- (0, roosterjs_editor_dom_1.getObjectKeys)(ImageEditHTMLMap).forEach(function (thisOperation) {
23340
- if ((operation & thisOperation) == thisOperation) {
23341
- (0, roosterjs_editor_dom_1.arrayPush)(htmlData, ImageEditHTMLMap[thisOperation](options, _this.onShowResizeHandle));
23342
- }
23343
- });
23344
- htmlData.forEach(function (data) {
23345
- var element = (0, roosterjs_editor_dom_1.createElement)(data, _this.image.ownerDocument);
23346
- if (element) {
23347
- _this.wrapper.appendChild(element);
23348
- }
23349
- });
23350
- this.insertImageWrapper(this.wrapper);
23649
+ var _a, _b;
23650
+ if (this.image && this.editor && this.options && this.editInfo) {
23651
+ //Clone the image and insert the clone in a entity
23652
+ this.clonedImage = this.image.cloneNode(true);
23653
+ this.clonedImage.removeAttribute('id');
23654
+ this.wrapper = (0, roosterjs_editor_dom_1.createElement)(6 /* ImageEditWrapper */, this.image.ownerDocument);
23655
+ (_b = (_a = this.wrapper) === null || _a === void 0 ? void 0 : _a.firstChild) === null || _b === void 0 ? void 0 : _b.appendChild(this.clonedImage);
23656
+ this.wrapper.style.display = roosterjs_editor_dom_1.Browser.isSafari ? 'inline-block' : 'inline-flex';
23657
+ // Cache current src so that we can compare it after edit see if src is changed
23658
+ this.lastSrc = this.image.getAttribute('src');
23659
+ // Set image src to original src to help show editing UI, also it will be used when regenerate image dataURL after editing
23660
+ if (this.clonedImage) {
23661
+ this.clonedImage.src = this.editInfo.src;
23662
+ this.clonedImage.style.position = 'absolute';
23663
+ }
23664
+ // Get HTML for all edit elements (resize handle, rotate handle, crop handle and overlay, ...) and create HTML element
23665
+ var options_1 = {
23666
+ borderColor: getColorString(this.options.borderColor, this.editor.isDarkMode()),
23667
+ rotateIconHTML: this.options.rotateIconHTML,
23668
+ rotateHandleBackColor: this.editor.isDarkMode()
23669
+ ? DARK_MODE_BGCOLOR
23670
+ : LIGHT_MODE_BGCOLOR,
23671
+ isSmallImage: isASmallImage(this.editInfo),
23672
+ };
23673
+ var htmlData_1 = [(0, Resizer_1.getResizeBordersHTML)(options_1)];
23674
+ (0, roosterjs_editor_dom_1.getObjectKeys)(ImageEditHTMLMap).forEach(function (thisOperation) {
23675
+ var element = ImageEditHTMLMap[thisOperation](options_1, _this.onShowResizeHandle);
23676
+ if ((operation & thisOperation) == thisOperation && element) {
23677
+ (0, roosterjs_editor_dom_1.arrayPush)(htmlData_1, element);
23678
+ }
23679
+ });
23680
+ htmlData_1.forEach(function (data) {
23681
+ var element = (0, roosterjs_editor_dom_1.createElement)(data, _this.image.ownerDocument);
23682
+ if (element && _this.wrapper) {
23683
+ _this.wrapper.appendChild(element);
23684
+ }
23685
+ });
23686
+ this.insertImageWrapper(this.wrapper);
23687
+ }
23351
23688
  };
23352
23689
  ImageEdit.prototype.insertImageWrapper = function (wrapper) {
23353
- this.shadowSpan = (0, roosterjs_editor_dom_1.wrap)(this.image, 'span');
23354
- var shadowRoot = this.shadowSpan.attachShadow({
23355
- mode: 'open',
23356
- });
23357
- this.shadowSpan.style.verticalAlign = 'bottom';
23358
- shadowRoot.appendChild(wrapper);
23690
+ if (this.image) {
23691
+ this.shadowSpan = (0, roosterjs_editor_dom_1.wrap)(this.image, 'span');
23692
+ var shadowRoot = this.shadowSpan.attachShadow({
23693
+ mode: 'open',
23694
+ });
23695
+ this.shadowSpan.style.verticalAlign = 'bottom';
23696
+ shadowRoot.appendChild(wrapper);
23697
+ }
23359
23698
  };
23360
23699
  /**
23361
23700
  * Create drag and drop helpers
@@ -23365,15 +23704,16 @@ var ImageEdit = /** @class */ (function () {
23365
23704
  */
23366
23705
  ImageEdit.prototype.createDndHelpers = function (elementClass, dragAndDrop) {
23367
23706
  var _this = this;
23368
- var commonContext = {
23369
- editInfo: this.editInfo,
23370
- options: this.options,
23371
- elementClass: elementClass,
23372
- };
23373
23707
  var wrapper = this.wrapper;
23374
- return wrapper
23708
+ return wrapper && this.editInfo
23375
23709
  ? getEditElements(wrapper, elementClass).map(function (element) {
23376
- return new DragAndDropHelper_1.default(element, __assign(__assign({}, commonContext), { x: element.dataset.x, y: element.dataset.y }), _this.updateWrapper, dragAndDrop, _this.editor.getZoomScale());
23710
+ return new DragAndDropHelper_1.default(element, {
23711
+ editInfo: _this.editInfo,
23712
+ options: _this.options,
23713
+ elementClass: elementClass,
23714
+ x: element.dataset.x,
23715
+ y: element.dataset.y,
23716
+ }, _this.updateWrapper, dragAndDrop, _this.editor ? _this.editor.getZoomScale() : 1);
23377
23717
  })
23378
23718
  : [];
23379
23719
  };
@@ -23383,21 +23723,32 @@ var ImageEdit = /** @class */ (function () {
23383
23723
  ImageEdit.prototype.clearDndHelpers = function () {
23384
23724
  var _a;
23385
23725
  (_a = this.dndHelpers) === null || _a === void 0 ? void 0 : _a.forEach(function (helper) { return helper.dispose(); });
23386
- this.dndHelpers = null;
23726
+ this.dndHelpers = [];
23387
23727
  };
23388
23728
  return ImageEdit;
23389
23729
  }());
23390
23730
  exports.default = ImageEdit;
23391
23731
  function setSize(element, left, top, right, bottom, width, height) {
23392
- element.style.left = getPx(left);
23393
- element.style.top = getPx(top);
23394
- element.style.right = getPx(right);
23395
- element.style.bottom = getPx(bottom);
23396
- element.style.width = getPx(width);
23397
- element.style.height = getPx(height);
23732
+ element.style.left = left !== undefined ? getPx(left) : element.style.left;
23733
+ element.style.top = top !== undefined ? getPx(top) : element.style.top;
23734
+ element.style.right = right !== undefined ? getPx(right) : element.style.right;
23735
+ element.style.bottom = bottom !== undefined ? getPx(bottom) : element.style.bottom;
23736
+ element.style.width = width !== undefined ? getPx(width) : element.style.width;
23737
+ element.style.height = height !== undefined ? getPx(height) : element.style.height;
23738
+ }
23739
+ function setWrapperSizeDimensions(wrapper, image, width, height) {
23740
+ var hasBorder = image.style.borderStyle;
23741
+ if (hasBorder) {
23742
+ var borderWidth = image.style.borderWidth ? 2 * parseInt(image.style.borderWidth) : 2;
23743
+ wrapper.style.width = getPx(width + borderWidth);
23744
+ wrapper.style.height = getPx(height + borderWidth);
23745
+ return;
23746
+ }
23747
+ wrapper.style.width = getPx(width);
23748
+ wrapper.style.height = getPx(height);
23398
23749
  }
23399
23750
  function getPx(value) {
23400
- return value === undefined ? null : value + 'px';
23751
+ return value + 'px';
23401
23752
  }
23402
23753
  function getEditElements(wrapper, elementClass) {
23403
23754
  return (0, roosterjs_editor_dom_1.toArray)(wrapper.querySelectorAll('.' + elementClass));
@@ -23411,12 +23762,12 @@ function handleRadIndexCalculator(angleRad) {
23411
23762
  var idx = Math.round(angleRad / DirectionRad) % DIRECTIONS;
23412
23763
  return idx < 0 ? idx + DIRECTIONS : idx;
23413
23764
  }
23414
- function rotateHandles(element, angleRad) {
23765
+ function rotateHandles(y, x, angleRad) {
23415
23766
  var radIndex = handleRadIndexCalculator(angleRad);
23416
- var originalDirection = element.dataset.y + element.dataset.x;
23767
+ var originalDirection = y + x;
23417
23768
  var originalIndex = DirectionOrder.indexOf(originalDirection);
23418
23769
  var rotatedIndex = originalIndex >= 0 && originalIndex + radIndex;
23419
- return DirectionOrder[rotatedIndex % DIRECTIONS];
23770
+ return rotatedIndex ? DirectionOrder[rotatedIndex % DIRECTIONS] : '';
23420
23771
  }
23421
23772
  /**
23422
23773
  * Rotate the resizer and cropper handles according to the image position.
@@ -23425,7 +23776,11 @@ function rotateHandles(element, angleRad) {
23425
23776
  */
23426
23777
  function updateHandleCursor(handles, angleRad) {
23427
23778
  handles.map(function (handle) {
23428
- handle.style.cursor = rotateHandles(handle, angleRad) + "-resize";
23779
+ var y = handle.dataset.y;
23780
+ var x = handle.dataset.x;
23781
+ if (y && x) {
23782
+ handle.style.cursor = rotateHandles(y, x, angleRad) + "-resize";
23783
+ }
23429
23784
  });
23430
23785
  }
23431
23786
  /**
@@ -23453,7 +23808,7 @@ function isFixedNumberValue(value) {
23453
23808
  }
23454
23809
  function isASmallImage(editInfo) {
23455
23810
  var widthPx = editInfo.widthPx, heightPx = editInfo.heightPx;
23456
- return widthPx && heightPx && widthPx * widthPx < MAX_SMALL_SIZE_IMAGE;
23811
+ return widthPx && heightPx && widthPx * widthPx < MAX_SMALL_SIZE_IMAGE ? true : false;
23457
23812
  }
23458
23813
  function getColorString(color, isDarkMode) {
23459
23814
  if (typeof color === 'string') {
@@ -23490,9 +23845,12 @@ function canRegenerateImage(img) {
23490
23845
  canvas.width = 10;
23491
23846
  canvas.height = 10;
23492
23847
  var context = canvas.getContext('2d');
23493
- context.drawImage(img, 0, 0);
23494
- context.getImageData(0, 0, 1, 1);
23495
- return true;
23848
+ if (context) {
23849
+ context.drawImage(img, 0, 0);
23850
+ context.getImageData(0, 0, 1, 1);
23851
+ return true;
23852
+ }
23853
+ return false;
23496
23854
  }
23497
23855
  catch (_a) {
23498
23856
  return false;
@@ -23522,9 +23880,12 @@ var editInfo_1 = __webpack_require__(/*! ../editInfoUtils/editInfo */ "./package
23522
23880
  */
23523
23881
  function isResizedTo(image, percentage) {
23524
23882
  var editInfo = (0, editInfo_1.getEditInfoFromImage)(image);
23525
- var _a = (0, getTargetSizeByPercentage_1.default)(editInfo, percentage), width = _a.width, height = _a.height;
23526
- return (Math.round(width) == Math.round(editInfo.widthPx) &&
23527
- Math.round(height) == Math.round(editInfo.heightPx));
23883
+ if (editInfo) {
23884
+ var _a = (0, getTargetSizeByPercentage_1.default)(editInfo, percentage), width = _a.width, height = _a.height;
23885
+ return (Math.round(width) == Math.round(editInfo.widthPx) &&
23886
+ Math.round(height) == Math.round(editInfo.heightPx));
23887
+ }
23888
+ return false;
23528
23889
  }
23529
23890
  exports.default = isResizedTo;
23530
23891
 
@@ -23589,13 +23950,13 @@ function resizeByPercentage(editor, image, percentage, minWidth, minHeight) {
23589
23950
  var editInfo = (0, editInfo_1.getEditInfoFromImage)(image);
23590
23951
  if (!(0, isResizedTo_1.default)(image, percentage)) {
23591
23952
  loadImage(image, image.src, function () {
23592
- if (!editor.isDisposed() && editor.contains(image)) {
23953
+ if (!editor.isDisposed() && editor.contains(image) && editInfo) {
23593
23954
  var lastSrc_1 = image.getAttribute('src');
23594
23955
  var _a = (0, getTargetSizeByPercentage_1.default)(editInfo, percentage), width = _a.width, height = _a.height;
23595
23956
  editInfo.widthPx = Math.max(width, minWidth);
23596
23957
  editInfo.heightPx = Math.max(height, minHeight);
23597
23958
  editor.addUndoSnapshot(function () {
23598
- (0, applyChange_1.default)(editor, image, editInfo, lastSrc_1, true /*wasResized*/);
23959
+ (0, applyChange_1.default)(editor, image, editInfo, lastSrc_1 || '', true /*wasResized*/);
23599
23960
  }, "ImageResize" /* ImageResize */);
23600
23961
  }
23601
23962
  });
@@ -23811,7 +24172,9 @@ exports.deleteEditInfo = deleteEditInfo;
23811
24172
  */
23812
24173
  function getEditInfoFromImage(image) {
23813
24174
  var obj = (0, roosterjs_editor_dom_1.getMetadata)(image);
23814
- return (0, checkEditInfoState_1.default)(obj) == 0 /* Invalid */ ? getInitialEditInfo(image) : obj;
24175
+ return !obj || (0, checkEditInfoState_1.default)(obj) == 0 /* Invalid */
24176
+ ? getInitialEditInfo(image)
24177
+ : obj;
23815
24178
  }
23816
24179
  exports.getEditInfoFromImage = getEditInfoFromImage;
23817
24180
  function getInitialEditInfo(image) {
@@ -23863,9 +24226,11 @@ function generateDataURL(image, editInfo) {
23863
24226
  canvas.width = targetWidth;
23864
24227
  canvas.height = targetHeight;
23865
24228
  var context = canvas.getContext('2d');
23866
- context.translate(targetWidth / 2, targetHeight / 2);
23867
- context.rotate(angle);
23868
- context.drawImage(image, naturalWidth * left, naturalHeight * top, imageWidth, imageHeight, -width / 2, -height / 2, width, height);
24229
+ if (context) {
24230
+ context.translate(targetWidth / 2, targetHeight / 2);
24231
+ context.rotate(angle);
24232
+ context.drawImage(image, naturalWidth * left, naturalHeight * top, imageWidth, imageHeight, -width / 2, -height / 2, width, height);
24233
+ }
23869
24234
  return canvas.toDataURL('image/png', 1.0);
23870
24235
  }
23871
24236
  exports.default = generateDataURL;
@@ -23998,7 +24363,10 @@ exports.Cropper = {
23998
24363
  var minWidth = options.minWidth, minHeight = options.minHeight;
23999
24364
  var widthPercent = 1 - leftPercent - rightPercent;
24000
24365
  var heightPercent = 1 - topPercent - bottomPercent;
24001
- if (widthPercent > 0 && heightPercent > 0) {
24366
+ if (widthPercent > 0 &&
24367
+ heightPercent > 0 &&
24368
+ minWidth !== undefined &&
24369
+ minHeight !== undefined) {
24002
24370
  var fullWidth = widthPx / widthPercent;
24003
24371
  var fullHeight = heightPx / heightPercent;
24004
24372
  var newLeft = x != 'e'
@@ -24048,7 +24416,9 @@ function getCropHTML() {
24048
24416
  className: "r_cropC" /* CropContainer */,
24049
24417
  children: [],
24050
24418
  };
24051
- Xs.forEach(function (x) { return Ys.forEach(function (y) { return containerHTML.children.push(getCropHTMLInternal(x, y)); }); });
24419
+ if (containerHTML) {
24420
+ Xs.forEach(function (x) { return Ys.forEach(function (y) { var _a; return (_a = containerHTML.children) === null || _a === void 0 ? void 0 : _a.push(getCropHTMLInternal(x, y)); }); });
24421
+ }
24052
24422
  return [containerHTML, overlayHTML, overlayHTML, overlayHTML, overlayHTML];
24053
24423
  }
24054
24424
  exports.getCropHTML = getCropHTML;
@@ -24127,36 +24497,41 @@ exports.Resizer = {
24127
24497
  var x = _a.x, y = _a.y, editInfo = _a.editInfo, options = _a.options;
24128
24498
  var ratio = base.widthPx > 0 && base.heightPx > 0 ? (base.widthPx * 1.0) / base.heightPx : 0;
24129
24499
  _b = rotateCoordinate(deltaX, deltaY, editInfo.angleRad), deltaX = _b[0], deltaY = _b[1];
24130
- var horizontalOnly = x == '';
24131
- var verticalOnly = y == '';
24132
- var shouldPreserveRatio = !(horizontalOnly || verticalOnly) && (options.preserveRatio || e.shiftKey);
24133
- var newWidth = horizontalOnly
24134
- ? base.widthPx
24135
- : Math.max(base.widthPx + deltaX * (x == 'w' ? -1 : 1), options.minWidth);
24136
- var newHeight = verticalOnly
24137
- ? base.heightPx
24138
- : Math.max(base.heightPx + deltaY * (y == 'n' ? -1 : 1), options.minHeight);
24139
- if (shouldPreserveRatio && ratio > 0) {
24140
- if (ratio > 1) {
24141
- // first sure newHeight is right,calculate newWidth
24142
- newWidth = newHeight * ratio;
24143
- if (newWidth < options.minWidth) {
24144
- newWidth = options.minWidth;
24145
- newHeight = newWidth / ratio;
24146
- }
24147
- }
24148
- else {
24149
- // first sure newWidth is right,calculate newHeight
24150
- newHeight = newWidth / ratio;
24151
- if (newHeight < options.minHeight) {
24152
- newHeight = options.minHeight;
24500
+ if (options.minWidth !== undefined && options.minHeight !== undefined) {
24501
+ var horizontalOnly = x == '';
24502
+ var verticalOnly = y == '';
24503
+ var shouldPreserveRatio = !(horizontalOnly || verticalOnly) && (options.preserveRatio || e.shiftKey);
24504
+ var newWidth = horizontalOnly
24505
+ ? base.widthPx
24506
+ : Math.max(base.widthPx + deltaX * (x == 'w' ? -1 : 1), options.minWidth);
24507
+ var newHeight = verticalOnly
24508
+ ? base.heightPx
24509
+ : Math.max(base.heightPx + deltaY * (y == 'n' ? -1 : 1), options.minHeight);
24510
+ if (shouldPreserveRatio && ratio > 0) {
24511
+ if (ratio > 1) {
24512
+ // first sure newHeight is right,calculate newWidth
24153
24513
  newWidth = newHeight * ratio;
24514
+ if (newWidth < options.minWidth) {
24515
+ newWidth = options.minWidth;
24516
+ newHeight = newWidth / ratio;
24517
+ }
24518
+ }
24519
+ else {
24520
+ // first sure newWidth is right,calculate newHeight
24521
+ newHeight = newWidth / ratio;
24522
+ if (newHeight < options.minHeight) {
24523
+ newHeight = options.minHeight;
24524
+ newWidth = newHeight * ratio;
24525
+ }
24154
24526
  }
24155
24527
  }
24528
+ editInfo.widthPx = newWidth;
24529
+ editInfo.heightPx = newHeight;
24530
+ return true;
24531
+ }
24532
+ else {
24533
+ return false;
24156
24534
  }
24157
- editInfo.widthPx = newWidth;
24158
- editInfo.heightPx = newHeight;
24159
- return true;
24160
24535
  },
24161
24536
  };
24162
24537
  /**
@@ -24216,10 +24591,12 @@ function getCornerResizeHTML(_a, onShowResizeHandle) {
24216
24591
  var elementData = (x == '') == (y == '')
24217
24592
  ? getResizeHandleHTML(x, y, resizeBorderColor, 1 /* CircularHandlesCorner */)
24218
24593
  : null;
24219
- if (onShowResizeHandle) {
24594
+ if (onShowResizeHandle && elementData) {
24220
24595
  onShowResizeHandle(elementData, x, y);
24221
24596
  }
24222
- result.push(elementData);
24597
+ if (elementData) {
24598
+ result.push(elementData);
24599
+ }
24223
24600
  });
24224
24601
  });
24225
24602
  return result;
@@ -24240,10 +24617,12 @@ function getSideResizeHTML(_a, onShowResizeHandle) {
24240
24617
  var elementData = (x == '') != (y == '')
24241
24618
  ? getResizeHandleHTML(x, y, resizeBorderColor, 1 /* CircularHandlesCorner */)
24242
24619
  : null;
24243
- if (onShowResizeHandle) {
24620
+ if (onShowResizeHandle && elementData) {
24244
24621
  onShowResizeHandle(elementData, x, y);
24245
24622
  }
24246
- result.push(elementData);
24623
+ if (elementData) {
24624
+ result.push(elementData);
24625
+ }
24247
24626
  });
24248
24627
  });
24249
24628
  return result;
@@ -24336,7 +24715,7 @@ exports.Rotator = {
24336
24715
  var newX = distance * Math.sin(base.angleRad) + deltaX;
24337
24716
  var newY = distance * Math.cos(base.angleRad) - deltaY;
24338
24717
  var angleInRad = Math.atan2(newX, newY);
24339
- if (!e.altKey) {
24718
+ if (!e.altKey && options && options.minRotateDeg !== undefined) {
24340
24719
  var angleInDeg = angleInRad * DEG_PER_RAD;
24341
24720
  var adjustedAngleInDeg = Math.round(angleInDeg / options.minRotateDeg) * options.minRotateDeg;
24342
24721
  angleInRad = adjustedAngleInDeg / DEG_PER_RAD;
@@ -24356,18 +24735,20 @@ exports.Rotator = {
24356
24735
  * Fix it by reduce the distance from image to rotate handle
24357
24736
  */
24358
24737
  function updateRotateHandlePosition(editInfo, editorRect, marginVertical, rotateCenter, rotateHandle) {
24359
- var _a;
24360
- var top = ((_a = rotateHandle.getBoundingClientRect()) === null || _a === void 0 ? void 0 : _a.top) - (editorRect === null || editorRect === void 0 ? void 0 : editorRect.top);
24361
- var angleRad = editInfo.angleRad, heightPx = editInfo.heightPx;
24362
- var cosAngle = Math.cos(angleRad);
24363
- var adjustedDistance = cosAngle <= 0
24364
- ? Number.MAX_SAFE_INTEGER
24365
- : (top + heightPx / 2 + marginVertical) / cosAngle - heightPx / 2;
24366
- var rotateGap = Math.max(Math.min(ROTATE_GAP, adjustedDistance), 0);
24367
- var rotateTop = Math.max(Math.min(ROTATE_SIZE, adjustedDistance - rotateGap), 0);
24368
- rotateCenter.style.top = -rotateGap + 'px';
24369
- rotateCenter.style.height = rotateGap + 'px';
24370
- rotateHandle.style.top = -rotateTop + 'px';
24738
+ var rotateHandleRect = rotateHandle.getBoundingClientRect();
24739
+ if (rotateHandleRect) {
24740
+ var top_1 = rotateHandleRect.top - editorRect.top;
24741
+ var angleRad = editInfo.angleRad, heightPx = editInfo.heightPx;
24742
+ var cosAngle = Math.cos(angleRad);
24743
+ var adjustedDistance = cosAngle <= 0
24744
+ ? Number.MAX_SAFE_INTEGER
24745
+ : (top_1 + heightPx / 2 + marginVertical) / cosAngle - heightPx / 2;
24746
+ var rotateGap = Math.max(Math.min(ROTATE_GAP, adjustedDistance), 0);
24747
+ var rotateTop = Math.max(Math.min(ROTATE_SIZE, adjustedDistance - rotateGap), 0);
24748
+ rotateCenter.style.top = -rotateGap + 'px';
24749
+ rotateCenter.style.height = rotateGap + 'px';
24750
+ rotateHandle.style.top = -rotateTop + 'px';
24751
+ }
24371
24752
  }
24372
24753
  exports.updateRotateHandlePosition = updateRotateHandlePosition;
24373
24754
  /**
@@ -29192,6 +29573,35 @@ var CompatibleDefinitionType;
29192
29573
  })(CompatibleDefinitionType = exports.CompatibleDefinitionType || (exports.CompatibleDefinitionType = {}));
29193
29574
 
29194
29575
 
29576
+ /***/ }),
29577
+
29578
+ /***/ "./packages/roosterjs-editor-types/lib/compatibleEnum/DelimiterClasses.ts":
29579
+ /*!********************************************************************************!*\
29580
+ !*** ./packages/roosterjs-editor-types/lib/compatibleEnum/DelimiterClasses.ts ***!
29581
+ \********************************************************************************/
29582
+ /*! no static exports found */
29583
+ /***/ (function(module, exports, __webpack_require__) {
29584
+
29585
+ "use strict";
29586
+
29587
+ Object.defineProperty(exports, "__esModule", { value: true });
29588
+ exports.CompatibleDelimiterClasses = void 0;
29589
+ /**
29590
+ * Class names for Delimiter
29591
+ */
29592
+ var CompatibleDelimiterClasses;
29593
+ (function (CompatibleDelimiterClasses) {
29594
+ /**
29595
+ * Class name to specify this delimiter is before an entity
29596
+ */
29597
+ CompatibleDelimiterClasses["DELIMITER_BEFORE"] = "entityDelimiterBefore";
29598
+ /**
29599
+ * Class name to specify this delimiter is after an entity
29600
+ */
29601
+ CompatibleDelimiterClasses["DELIMITER_AFTER"] = "entityDelimiterAfter";
29602
+ })(CompatibleDelimiterClasses = exports.CompatibleDelimiterClasses || (exports.CompatibleDelimiterClasses = {}));
29603
+
29604
+
29195
29605
  /***/ }),
29196
29606
 
29197
29607
  /***/ "./packages/roosterjs-editor-types/lib/compatibleEnum/Direction.ts":
@@ -29740,6 +30150,14 @@ var CompatibleExperimentalFeatures;
29740
30150
  * if you need them work for dark mode
29741
30151
  */
29742
30152
  CompatibleExperimentalFeatures["VariableBasedDarkColor"] = "VariableBasedDarkColor";
30153
+ /**
30154
+ * Delete table with Backspace key with the whole was selected with table selector
30155
+ */
30156
+ CompatibleExperimentalFeatures["DeleteTableWithBackspace"] = "DeleteTableWithBackspace";
30157
+ /**
30158
+ * Add entities around a Read Only Inline entity to prevent cursor to be hidden when cursor is next of it.
30159
+ */
30160
+ CompatibleExperimentalFeatures["InlineEntityReadOnlyDelimiters"] = "InlineEntityReadOnlyDelimiters";
29743
30161
  })(CompatibleExperimentalFeatures = exports.CompatibleExperimentalFeatures || (exports.CompatibleExperimentalFeatures = {}));
29744
30162
 
29745
30163
 
@@ -30705,7 +31123,7 @@ var CompatibleTableOperation;
30705
31123
  "use strict";
30706
31124
 
30707
31125
  Object.defineProperty(exports, "__esModule", { value: true });
30708
- exports.CompatibleTableOperation = exports.CompatibleTableBorderFormat = exports.CompatibleSelectionRangeTypes = exports.CompatibleRegionType = exports.CompatibleQueryScope = exports.CompatiblePositionType = exports.CompatiblePluginEventType = exports.CompatibleNumberingListType = exports.CompatibleNodeType = exports.CompatibleListType = exports.CompatibleKnownCreateElementDataIndex = exports.CompatibleKeys = exports.CompatibleIndentation = exports.CompatibleImageEditOperation = exports.CompatibleGetContentMode = exports.CompatibleFontSizeChange = exports.CompatibleExperimentalFeatures = exports.CompatibleEntityOperation = exports.CompatibleEntityClasses = exports.CompatibleDocumentPosition = exports.CompatibleDocumentCommand = exports.CompatibleDirection = exports.CompatibleDefinitionType = exports.CompatibleDarkModeDatasetNames = exports.CompatibleContentType = exports.CompatibleContentTypePrefix = exports.CompatibleContentPosition = exports.CompatibleColorTransformDirection = exports.CompatibleClearFormatMode = exports.CompatibleChangeSource = exports.CompatibleCapitalization = exports.CompatibleBulletListType = exports.CompatibleAlignment = void 0;
31126
+ exports.CompatibleTableOperation = exports.CompatibleTableBorderFormat = exports.CompatibleSelectionRangeTypes = exports.CompatibleRegionType = exports.CompatibleQueryScope = exports.CompatiblePositionType = exports.CompatiblePluginEventType = exports.CompatibleNumberingListType = exports.CompatibleNodeType = exports.CompatibleListType = exports.CompatibleKnownCreateElementDataIndex = exports.CompatibleKeys = exports.CompatibleIndentation = exports.CompatibleImageEditOperation = exports.CompatibleGetContentMode = exports.CompatibleFontSizeChange = exports.CompatibleExperimentalFeatures = exports.CompatibleEntityOperation = exports.CompatibleEntityClasses = exports.CompatibleDocumentPosition = exports.CompatibleDocumentCommand = exports.CompatibleDirection = exports.CompatibleDelimiterClasses = exports.CompatibleDefinitionType = exports.CompatibleDarkModeDatasetNames = exports.CompatibleContentType = exports.CompatibleContentTypePrefix = exports.CompatibleContentPosition = exports.CompatibleColorTransformDirection = exports.CompatibleClearFormatMode = exports.CompatibleChangeSource = exports.CompatibleCapitalization = exports.CompatibleBulletListType = exports.CompatibleAlignment = void 0;
30709
31127
  var Alignment_1 = __webpack_require__(/*! ./Alignment */ "./packages/roosterjs-editor-types/lib/compatibleEnum/Alignment.ts");
30710
31128
  Object.defineProperty(exports, "CompatibleAlignment", { enumerable: true, get: function () { return Alignment_1.CompatibleAlignment; } });
30711
31129
  var BulletListType_1 = __webpack_require__(/*! ./BulletListType */ "./packages/roosterjs-editor-types/lib/compatibleEnum/BulletListType.ts");
@@ -30727,6 +31145,8 @@ var DarkModeDatasetNames_1 = __webpack_require__(/*! ./DarkModeDatasetNames */ "
30727
31145
  Object.defineProperty(exports, "CompatibleDarkModeDatasetNames", { enumerable: true, get: function () { return DarkModeDatasetNames_1.CompatibleDarkModeDatasetNames; } });
30728
31146
  var DefinitionType_1 = __webpack_require__(/*! ./DefinitionType */ "./packages/roosterjs-editor-types/lib/compatibleEnum/DefinitionType.ts");
30729
31147
  Object.defineProperty(exports, "CompatibleDefinitionType", { enumerable: true, get: function () { return DefinitionType_1.CompatibleDefinitionType; } });
31148
+ var DelimiterClasses_1 = __webpack_require__(/*! ./DelimiterClasses */ "./packages/roosterjs-editor-types/lib/compatibleEnum/DelimiterClasses.ts");
31149
+ Object.defineProperty(exports, "CompatibleDelimiterClasses", { enumerable: true, get: function () { return DelimiterClasses_1.CompatibleDelimiterClasses; } });
30730
31150
  var Direction_1 = __webpack_require__(/*! ./Direction */ "./packages/roosterjs-editor-types/lib/compatibleEnum/Direction.ts");
30731
31151
  Object.defineProperty(exports, "CompatibleDirection", { enumerable: true, get: function () { return Direction_1.CompatibleDirection; } });
30732
31152
  var DocumentCommand_1 = __webpack_require__(/*! ./DocumentCommand */ "./packages/roosterjs-editor-types/lib/compatibleEnum/DocumentCommand.ts");