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