roosterjs 9.6.0 → 9.8.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.
@@ -2093,8 +2093,8 @@ exports["default"] = getDarkColor;
2093
2093
  "use strict";
2094
2094
 
2095
2095
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2096
- exports.formatTextSegmentBeforeSelectionMarker = exports.formatSegmentWithContentModel = exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2097
- exports.getListAnnounceData = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = void 0;
2096
+ exports.formatSegmentWithContentModel = exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.splitTextSegment = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2097
+ exports.getListAnnounceData = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = void 0;
2098
2098
  var insertTable_1 = __webpack_require__(/*! ./publicApi/table/insertTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts");
2099
2099
  Object.defineProperty(exports, "insertTable", ({ enumerable: true, get: function () { return insertTable_1.insertTable; } }));
2100
2100
  var formatTable_1 = __webpack_require__(/*! ./publicApi/table/formatTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/formatTable.ts");
@@ -2135,6 +2135,8 @@ var applySegmentFormat_1 = __webpack_require__(/*! ./publicApi/segment/applySegm
2135
2135
  Object.defineProperty(exports, "applySegmentFormat", ({ enumerable: true, get: function () { return applySegmentFormat_1.applySegmentFormat; } }));
2136
2136
  var changeCapitalization_1 = __webpack_require__(/*! ./publicApi/segment/changeCapitalization */ "./packages/roosterjs-content-model-api/lib/publicApi/segment/changeCapitalization.ts");
2137
2137
  Object.defineProperty(exports, "changeCapitalization", ({ enumerable: true, get: function () { return changeCapitalization_1.changeCapitalization; } }));
2138
+ var splitTextSegment_1 = __webpack_require__(/*! ./publicApi/segment/splitTextSegment */ "./packages/roosterjs-content-model-api/lib/publicApi/segment/splitTextSegment.ts");
2139
+ Object.defineProperty(exports, "splitTextSegment", ({ enumerable: true, get: function () { return splitTextSegment_1.splitTextSegment; } }));
2138
2140
  var insertImage_1 = __webpack_require__(/*! ./publicApi/image/insertImage */ "./packages/roosterjs-content-model-api/lib/publicApi/image/insertImage.ts");
2139
2141
  Object.defineProperty(exports, "insertImage", ({ enumerable: true, get: function () { return insertImage_1.insertImage; } }));
2140
2142
  var setListStyle_1 = __webpack_require__(/*! ./publicApi/list/setListStyle */ "./packages/roosterjs-content-model-api/lib/publicApi/list/setListStyle.ts");
@@ -3459,6 +3461,15 @@ function setListType(model, listType, removeMargins) {
3459
3461
  }
3460
3462
  (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(index, 1, newListItem);
3461
3463
  existingListItems.push(newListItem);
3464
+ var levelIndex = newListItem.levels.length - 1;
3465
+ var level = (0, roosterjs_content_model_dom_1.mutateBlock)(newListItem).levels[levelIndex];
3466
+ if (level) {
3467
+ (0, roosterjs_content_model_dom_1.updateListMetadata)(level, function (metadata) {
3468
+ return Object.assign({}, metadata, {
3469
+ applyListStyleFromLevel: true,
3470
+ });
3471
+ });
3472
+ }
3462
3473
  }
3463
3474
  else {
3464
3475
  existingListItems.forEach(function (x) { return ((0, roosterjs_content_model_dom_1.mutateBlock)(x).levels[0].format.marginBottom = '0px'); });
@@ -5877,6 +5888,47 @@ function setTextColor(editor, textColor) {
5877
5888
  exports.setTextColor = setTextColor;
5878
5889
 
5879
5890
 
5891
+ /***/ }),
5892
+
5893
+ /***/ "./packages/roosterjs-content-model-api/lib/publicApi/segment/splitTextSegment.ts":
5894
+ /*!****************************************************************************************!*\
5895
+ !*** ./packages/roosterjs-content-model-api/lib/publicApi/segment/splitTextSegment.ts ***!
5896
+ \****************************************************************************************/
5897
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
5898
+
5899
+ "use strict";
5900
+
5901
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5902
+ exports.splitTextSegment = void 0;
5903
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
5904
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
5905
+ /**
5906
+ * Split given text segments from the given range
5907
+ * @param textSegment segment to split
5908
+ * @param parent parent paragraph the text segment exist in
5909
+ * @param start starting point of the split
5910
+ * @param end ending point of the split
5911
+ * @returns text segment from the indicated split.
5912
+ */
5913
+ function splitTextSegment(textSegment, parent, start, end) {
5914
+ var _a;
5915
+ var text = textSegment.text;
5916
+ var index = parent.segments.indexOf(textSegment);
5917
+ var middleSegment = (0, roosterjs_content_model_dom_1.createText)(text.substring(start, end), textSegment.format, textSegment.link, textSegment.code);
5918
+ var newSegments = [middleSegment];
5919
+ if (start > 0) {
5920
+ newSegments.unshift((0, roosterjs_content_model_dom_1.createText)(text.substring(0, start), textSegment.format, textSegment.link, textSegment.code));
5921
+ }
5922
+ if (end < text.length) {
5923
+ newSegments.push((0, roosterjs_content_model_dom_1.createText)(text.substring(end), textSegment.format, textSegment.link, textSegment.code));
5924
+ }
5925
+ newSegments.forEach(function (segment) { return (segment.isSelected = textSegment.isSelected); });
5926
+ (_a = parent.segments).splice.apply(_a, (0, tslib_1.__spreadArray)([index, 1], (0, tslib_1.__read)(newSegments), false));
5927
+ return middleSegment;
5928
+ }
5929
+ exports.splitTextSegment = splitTextSegment;
5930
+
5931
+
5880
5932
  /***/ }),
5881
5933
 
5882
5934
  /***/ "./packages/roosterjs-content-model-api/lib/publicApi/segment/toggleBold.ts":
@@ -8259,12 +8311,14 @@ exports.getPath = getPath;
8259
8311
  /*!********************************************************************************!*\
8260
8312
  !*** ./packages/roosterjs-content-model-core/lib/coreApi/announce/announce.ts ***!
8261
8313
  \********************************************************************************/
8262
- /***/ ((__unused_webpack_module, exports) => {
8314
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8263
8315
 
8264
8316
  "use strict";
8265
8317
 
8266
8318
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8267
8319
  exports.announce = void 0;
8320
+ var createAriaLiveElement_1 = __webpack_require__(/*! ../../utils/createAriaLiveElement */ "./packages/roosterjs-content-model-core/lib/utils/createAriaLiveElement.ts");
8321
+ var DOT_STRING = '.';
8268
8322
  /**
8269
8323
  * @internal
8270
8324
  * Announce the given data
@@ -8272,17 +8326,17 @@ exports.announce = void 0;
8272
8326
  * @param announceData Data to announce
8273
8327
  */
8274
8328
  var announce = function (core, announceData) {
8275
- var _a;
8276
- var text = announceData.text, defaultStrings = announceData.defaultStrings, _b = announceData.formatStrings, formatStrings = _b === void 0 ? [] : _b;
8329
+ var text = announceData.text, defaultStrings = announceData.defaultStrings, _a = announceData.formatStrings, formatStrings = _a === void 0 ? [] : _a;
8277
8330
  var announcerStringGetter = core.lifecycle.announcerStringGetter;
8278
8331
  var template = defaultStrings && (announcerStringGetter === null || announcerStringGetter === void 0 ? void 0 : announcerStringGetter(defaultStrings));
8279
8332
  var textToAnnounce = formatString(template || text, formatStrings);
8280
- if (textToAnnounce) {
8333
+ if (!core.lifecycle.announceContainer) {
8334
+ core.lifecycle.announceContainer = (0, createAriaLiveElement_1.createAriaLiveElement)(core.physicalRoot.ownerDocument);
8335
+ }
8336
+ if (textToAnnounce && core.lifecycle.announceContainer) {
8281
8337
  var announceContainer = core.lifecycle.announceContainer;
8282
- if (!announceContainer || textToAnnounce == announceContainer.textContent) {
8283
- (_a = announceContainer === null || announceContainer === void 0 ? void 0 : announceContainer.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(announceContainer);
8284
- announceContainer = createAriaLiveElement(core.physicalRoot.ownerDocument);
8285
- core.lifecycle.announceContainer = announceContainer;
8338
+ if (textToAnnounce == announceContainer.textContent) {
8339
+ textToAnnounce += DOT_STRING;
8286
8340
  }
8287
8341
  if (announceContainer) {
8288
8342
  announceContainer.textContent = textToAnnounce;
@@ -8301,19 +8355,6 @@ function formatString(text, formatStrings) {
8301
8355
  });
8302
8356
  return text;
8303
8357
  }
8304
- function createAriaLiveElement(document) {
8305
- var div = document.createElement('div');
8306
- div.style.clip = 'rect(0px, 0px, 0px, 0px)';
8307
- div.style.clipPath = 'inset(100%)';
8308
- div.style.height = '1px';
8309
- div.style.overflow = 'hidden';
8310
- div.style.position = 'absolute';
8311
- div.style.whiteSpace = 'nowrap';
8312
- div.style.width = '1px';
8313
- div.ariaLive = 'assertive';
8314
- document.body.appendChild(div);
8315
- return div;
8316
- }
8317
8358
 
8318
8359
 
8319
8360
  /***/ }),
@@ -8426,7 +8467,7 @@ exports.coreApiMap = {
8426
8467
 
8427
8468
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8428
8469
  exports.createContentModel = void 0;
8429
- var updateCachedSelection_1 = __webpack_require__(/*! ../../corePlugin/cache/updateCachedSelection */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCachedSelection.ts");
8470
+ var updateCache_1 = __webpack_require__(/*! ../../corePlugin/cache/updateCache */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCache.ts");
8430
8471
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
8431
8472
  /**
8432
8473
  * @internal
@@ -8462,8 +8503,7 @@ var createContentModel = function (core, option, selectionOverride) {
8462
8503
  }
8463
8504
  var model = (0, roosterjs_content_model_dom_1.domToContentModel)(core.logicalRoot, domToModelContext);
8464
8505
  if (saveIndex) {
8465
- core.cache.cachedModel = model;
8466
- (0, updateCachedSelection_1.updateCachedSelection)(core.cache, selection);
8506
+ (0, updateCache_1.updateCache)(core.cache, model, selection);
8467
8507
  }
8468
8508
  return model;
8469
8509
  };
@@ -9165,7 +9205,7 @@ exports.restoreUndoSnapshot = restoreUndoSnapshot;
9165
9205
 
9166
9206
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9167
9207
  exports.setContentModel = void 0;
9168
- var updateCachedSelection_1 = __webpack_require__(/*! ../../corePlugin/cache/updateCachedSelection */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCachedSelection.ts");
9208
+ var updateCache_1 = __webpack_require__(/*! ../../corePlugin/cache/updateCache */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCache.ts");
9169
9209
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
9170
9210
  /**
9171
9211
  * @internal
@@ -9183,15 +9223,15 @@ var setContentModel = function (core, model, option, onNodeCreated) {
9183
9223
  modelToDomContext.onNodeCreated = onNodeCreated;
9184
9224
  var selection = (0, roosterjs_content_model_dom_1.contentModelToDom)(core.logicalRoot.ownerDocument, core.logicalRoot, model, modelToDomContext);
9185
9225
  if (!core.lifecycle.shadowEditFragment) {
9186
- (0, updateCachedSelection_1.updateCachedSelection)(core.cache, selection || undefined);
9226
+ // Clear pending mutations since we will use our latest model object to replace existing cache
9227
+ (_a = core.cache.textMutationObserver) === null || _a === void 0 ? void 0 : _a.flushMutations(true /*ignoreMutations*/);
9228
+ (0, updateCache_1.updateCache)(core.cache, model, selection);
9187
9229
  if (!(option === null || option === void 0 ? void 0 : option.ignoreSelection) && selection) {
9188
9230
  core.api.setDOMSelection(core, selection);
9189
9231
  }
9190
9232
  else {
9191
9233
  core.selection.selection = selection;
9192
9234
  }
9193
- // Clear pending mutations since we will use our latest model object to replace existing cache
9194
- (_a = core.cache.textMutationObserver) === null || _a === void 0 ? void 0 : _a.flushMutations(model);
9195
9235
  }
9196
9236
  return selection;
9197
9237
  };
@@ -9204,12 +9244,13 @@ exports.setContentModel = setContentModel;
9204
9244
  /*!**************************************************************************************************!*\
9205
9245
  !*** ./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts ***!
9206
9246
  \**************************************************************************************************/
9207
- /***/ ((__unused_webpack_module, exports) => {
9247
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
9208
9248
 
9209
9249
  "use strict";
9210
9250
 
9211
9251
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9212
9252
  exports.addRangeToSelection = void 0;
9253
+ var areSameSelections_1 = __webpack_require__(/*! ../../corePlugin/cache/areSameSelections */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts");
9213
9254
  /**
9214
9255
  * @internal
9215
9256
  */
@@ -9219,11 +9260,7 @@ function addRangeToSelection(doc, range, isReverted) {
9219
9260
  var selection = (_a = doc.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
9220
9261
  if (selection) {
9221
9262
  var currentRange = selection.rangeCount > 0 && selection.getRangeAt(0);
9222
- if (currentRange &&
9223
- currentRange.startContainer == range.startContainer &&
9224
- currentRange.endContainer == range.endContainer &&
9225
- currentRange.startOffset == range.startOffset &&
9226
- currentRange.endOffset == range.endOffset) {
9263
+ if (currentRange && (0, areSameSelections_1.areSameRanges)(currentRange, range)) {
9227
9264
  return;
9228
9265
  }
9229
9266
  selection.removeAllRanges();
@@ -9238,40 +9275,6 @@ function addRangeToSelection(doc, range, isReverted) {
9238
9275
  exports.addRangeToSelection = addRangeToSelection;
9239
9276
 
9240
9277
 
9241
- /***/ }),
9242
-
9243
- /***/ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/ensureImageHasSpanParent.ts":
9244
- /*!*******************************************************************************************************!*\
9245
- !*** ./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/ensureImageHasSpanParent.ts ***!
9246
- \*******************************************************************************************************/
9247
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
9248
-
9249
- "use strict";
9250
-
9251
- Object.defineProperty(exports, "__esModule", ({ value: true }));
9252
- exports.ensureImageHasSpanParent = void 0;
9253
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
9254
- /**
9255
- * @internal
9256
- * Ensure image is wrapped by a span element
9257
- * @param image
9258
- * @returns the image
9259
- */
9260
- function ensureImageHasSpanParent(image) {
9261
- var parent = image.parentElement;
9262
- if (parent &&
9263
- (0, roosterjs_content_model_dom_1.isNodeOfType)(parent, 'ELEMENT_NODE') &&
9264
- (0, roosterjs_content_model_dom_1.isElementOfType)(parent, 'span') &&
9265
- parent.firstChild == image &&
9266
- parent.lastChild == image) {
9267
- return image;
9268
- }
9269
- (0, roosterjs_content_model_dom_1.wrap)(image.ownerDocument, image, 'span');
9270
- return image;
9271
- }
9272
- exports.ensureImageHasSpanParent = ensureImageHasSpanParent;
9273
-
9274
-
9275
9278
  /***/ }),
9276
9279
 
9277
9280
  /***/ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/findLastedCoInMergedCell.ts":
@@ -9374,7 +9377,7 @@ exports.findTableCellElement = findTableCellElement;
9374
9377
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9375
9378
  exports.setDOMSelection = void 0;
9376
9379
  var addRangeToSelection_1 = __webpack_require__(/*! ./addRangeToSelection */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts");
9377
- var ensureImageHasSpanParent_1 = __webpack_require__(/*! ./ensureImageHasSpanParent */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/ensureImageHasSpanParent.ts");
9380
+ var areSameSelections_1 = __webpack_require__(/*! ../../corePlugin/cache/areSameSelections */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts");
9378
9381
  var ensureUniqueId_1 = __webpack_require__(/*! ../setEditorStyle/ensureUniqueId */ "./packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/ensureUniqueId.ts");
9379
9382
  var findLastedCoInMergedCell_1 = __webpack_require__(/*! ./findLastedCoInMergedCell */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/findLastedCoInMergedCell.ts");
9380
9383
  var findTableCellElement_1 = __webpack_require__(/*! ./findTableCellElement */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/findTableCellElement.ts");
@@ -9387,11 +9390,16 @@ var TABLE_ID = 'table';
9387
9390
  var CARET_CSS_RULE = 'caret-color: transparent';
9388
9391
  var TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';
9389
9392
  var SELECTION_SELECTOR = '*::selection';
9393
+ var DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';
9390
9394
  /**
9391
9395
  * @internal
9392
9396
  */
9393
9397
  var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
9394
9398
  var _a, _b, _c;
9399
+ var existingSelection = core.api.getDOMSelection(core);
9400
+ if (existingSelection && selection && (0, areSameSelections_1.areSameSelections)(existingSelection, selection)) {
9401
+ return;
9402
+ }
9395
9403
  // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.
9396
9404
  // Set skipReselectOnFocus to skip this behavior
9397
9405
  var skipReselectOnFocus = core.selection.skipReselectOnFocus;
@@ -9404,15 +9412,12 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
9404
9412
  try {
9405
9413
  switch (selection === null || selection === void 0 ? void 0 : selection.type) {
9406
9414
  case 'image':
9407
- var image = (0, ensureImageHasSpanParent_1.ensureImageHasSpanParent)(selection.image);
9408
- core.selection.selection = {
9409
- type: 'image',
9410
- image: image,
9411
- };
9415
+ var image = selection.image;
9416
+ core.selection.selection = selection;
9412
9417
  var imageSelectionColor = isDarkMode
9413
9418
  ? core.selection.imageSelectionBorderColorDark
9414
9419
  : core.selection.imageSelectionBorderColor;
9415
- core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:solid!important; outline-color:" + imageSelectionColor + "!important;display: " + (core.environment.isSafari ? '-webkit-inline-flex' : 'inline-flex') + ";", ["span:has(>img#" + (0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID) + ")"]);
9420
+ core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:solid!important; outline-color:" + (imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR) + "!important;", ["#" + (0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID)]);
9416
9421
  core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, TRANSPARENT_SELECTION_CSS_RULE, [SELECTION_SELECTOR]);
9417
9422
  setRangeSelection(doc, image, false /* collapse */);
9418
9423
  break;
@@ -9567,7 +9572,7 @@ function ensureUniqueId(element, idPrefix) {
9567
9572
  idPrefix = element.id || idPrefix;
9568
9573
  var doc = element.ownerDocument;
9569
9574
  var i = 0;
9570
- while (!element.id || doc.querySelectorAll('#' + element.id).length > 1) {
9575
+ while (!element.id || doc.querySelectorAll("[id=\"" + element.id + "\"]").length > 1) {
9571
9576
  element.id = idPrefix + '_' + i++;
9572
9577
  }
9573
9578
  return element.id;
@@ -9807,10 +9812,10 @@ function handledExclusively(event, plugin) {
9807
9812
 
9808
9813
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9809
9814
  exports.createCachePlugin = void 0;
9810
- var areSameSelection_1 = __webpack_require__(/*! ./areSameSelection */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelection.ts");
9815
+ var areSameSelections_1 = __webpack_require__(/*! ./areSameSelections */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts");
9811
9816
  var textMutationObserver_1 = __webpack_require__(/*! ./textMutationObserver */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/textMutationObserver.ts");
9812
9817
  var domIndexerImpl_1 = __webpack_require__(/*! ./domIndexerImpl */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts");
9813
- var updateCachedSelection_1 = __webpack_require__(/*! ./updateCachedSelection */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCachedSelection.ts");
9818
+ var updateCache_1 = __webpack_require__(/*! ./updateCache */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCache.ts");
9814
9819
  /**
9815
9820
  * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary
9816
9821
  */
@@ -9823,40 +9828,37 @@ var CachePlugin = /** @class */ (function () {
9823
9828
  function CachePlugin(option, contentDiv) {
9824
9829
  var _this = this;
9825
9830
  this.editor = null;
9826
- this.onMutation = function (isTextChangeOnly) {
9831
+ this.onMutation = function (mutation) {
9832
+ var _a;
9827
9833
  if (_this.editor) {
9828
- if (isTextChangeOnly) {
9829
- _this.updateCachedModel(_this.editor, true /*forceUpdate*/);
9830
- }
9831
- else {
9832
- _this.invalidateCache();
9834
+ switch (mutation.type) {
9835
+ case 'childList':
9836
+ if (!((_a = _this.state.domIndexer) === null || _a === void 0 ? void 0 : _a.reconcileChildList(mutation.addedNodes, mutation.removedNodes))) {
9837
+ _this.invalidateCache();
9838
+ }
9839
+ break;
9840
+ case 'text':
9841
+ _this.updateCachedModel(_this.editor, true /*forceUpdate*/);
9842
+ break;
9843
+ case 'unknown':
9844
+ _this.invalidateCache();
9845
+ break;
9833
9846
  }
9834
9847
  }
9835
9848
  };
9836
- this.onSkipMutation = function (newModel) {
9837
- var _a;
9838
- if (!((_a = _this.editor) === null || _a === void 0 ? void 0 : _a.isInShadowEdit())) {
9839
- _this.state.cachedModel = newModel;
9840
- _this.state.cachedSelection = undefined;
9841
- }
9842
- };
9843
9849
  this.onNativeSelectionChange = function () {
9844
9850
  var _a;
9845
9851
  if ((_a = _this.editor) === null || _a === void 0 ? void 0 : _a.hasFocus()) {
9846
9852
  _this.updateCachedModel(_this.editor);
9847
9853
  }
9848
9854
  };
9849
- if (option.disableCache) {
9850
- this.state = {};
9851
- }
9852
- else {
9853
- var domIndexer = new domIndexerImpl_1.DomIndexerImpl(option.experimentalFeatures &&
9854
- option.experimentalFeatures.indexOf('PersistCache') >= 0);
9855
- this.state = {
9856
- domIndexer: domIndexer,
9857
- textMutationObserver: (0, textMutationObserver_1.createTextMutationObserver)(contentDiv, domIndexer, this.onMutation, this.onSkipMutation),
9855
+ this.state = option.disableCache
9856
+ ? {}
9857
+ : {
9858
+ domIndexer: new domIndexerImpl_1.DomIndexerImpl(option.experimentalFeatures &&
9859
+ option.experimentalFeatures.indexOf('PersistCache') >= 0),
9860
+ textMutationObserver: (0, textMutationObserver_1.createTextMutationObserver)(contentDiv, this.onMutation),
9858
9861
  };
9859
- }
9860
9862
  }
9861
9863
  /**
9862
9864
  * Get name of this plugin
@@ -9921,8 +9923,7 @@ var CachePlugin = /** @class */ (function () {
9921
9923
  case 'contentChanged':
9922
9924
  var contentModel = event.contentModel, selection = event.selection;
9923
9925
  if (contentModel && this.state.domIndexer) {
9924
- this.state.cachedModel = contentModel;
9925
- (0, updateCachedSelection_1.updateCachedSelection)(this.state, selection);
9926
+ (0, updateCache_1.updateCache)(this.state, contentModel, selection);
9926
9927
  }
9927
9928
  else {
9928
9929
  this.invalidateCache();
@@ -9939,6 +9940,9 @@ var CachePlugin = /** @class */ (function () {
9939
9940
  };
9940
9941
  CachePlugin.prototype.updateCachedModel = function (editor, forceUpdate) {
9941
9942
  var _a;
9943
+ if (editor.isInShadowEdit()) {
9944
+ return;
9945
+ }
9942
9946
  var cachedSelection = this.state.cachedSelection;
9943
9947
  this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range
9944
9948
  var newRangeEx = editor.getDOMSelection() || undefined;
@@ -9946,7 +9950,7 @@ var CachePlugin = /** @class */ (function () {
9946
9950
  var isSelectionChanged = forceUpdate ||
9947
9951
  !cachedSelection ||
9948
9952
  !newRangeEx ||
9949
- !(0, areSameSelection_1.areSameSelection)(newRangeEx, cachedSelection);
9953
+ !(0, areSameSelections_1.areSameSelections)(newRangeEx, cachedSelection);
9950
9954
  if (isSelectionChanged) {
9951
9955
  if (!model ||
9952
9956
  !newRangeEx ||
@@ -9954,7 +9958,7 @@ var CachePlugin = /** @class */ (function () {
9954
9958
  this.invalidateCache();
9955
9959
  }
9956
9960
  else {
9957
- (0, updateCachedSelection_1.updateCachedSelection)(this.state, newRangeEx);
9961
+ (0, updateCache_1.updateCache)(this.state, model, newRangeEx);
9958
9962
  }
9959
9963
  }
9960
9964
  else {
@@ -9977,21 +9981,21 @@ exports.createCachePlugin = createCachePlugin;
9977
9981
 
9978
9982
  /***/ }),
9979
9983
 
9980
- /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelection.ts":
9981
- /*!****************************************************************************************!*\
9982
- !*** ./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelection.ts ***!
9983
- \****************************************************************************************/
9984
+ /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts":
9985
+ /*!*****************************************************************************************!*\
9986
+ !*** ./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts ***!
9987
+ \*****************************************************************************************/
9984
9988
  /***/ ((__unused_webpack_module, exports) => {
9985
9989
 
9986
9990
  "use strict";
9987
9991
 
9988
9992
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9989
- exports.areSameSelection = void 0;
9993
+ exports.areSameRanges = exports.areSameTableSelections = exports.areSameSelections = void 0;
9990
9994
  /**
9991
9995
  * @internal
9992
9996
  * Check if the given selections are the same
9993
9997
  */
9994
- function areSameSelection(sel1, sel2) {
9998
+ function areSameSelections(sel1, sel2) {
9995
9999
  if (sel1 == sel2) {
9996
10000
  return true;
9997
10001
  }
@@ -9999,22 +10003,56 @@ function areSameSelection(sel1, sel2) {
9999
10003
  case 'image':
10000
10004
  return sel2.type == 'image' && sel2.image == sel1.image;
10001
10005
  case 'table':
10002
- return (sel2.type == 'table' &&
10003
- sel2.table == sel1.table &&
10004
- sel2.firstColumn == sel1.firstColumn &&
10005
- sel2.lastColumn == sel1.lastColumn &&
10006
- sel2.firstRow == sel1.firstRow &&
10007
- sel2.lastRow == sel1.lastRow);
10006
+ return sel2.type == 'table' && areSameTableSelections(sel1, sel2);
10008
10007
  case 'range':
10009
10008
  default:
10010
- return (sel2.type == 'range' &&
10011
- sel1.range.startContainer == sel2.start.node &&
10012
- sel1.range.endContainer == sel2.end.node &&
10013
- sel1.range.startOffset == sel2.start.offset &&
10014
- sel1.range.endOffset == sel2.end.offset);
10009
+ if (sel2.type == 'range') {
10010
+ var range1 = sel1.range;
10011
+ if (isCacheSelection(sel2)) {
10012
+ var start = sel2.start, end = sel2.end;
10013
+ return (range1.startContainer == start.node &&
10014
+ range1.endContainer == end.node &&
10015
+ range1.startOffset == start.offset &&
10016
+ range1.endOffset == end.offset);
10017
+ }
10018
+ else {
10019
+ return areSameRanges(range1, sel2.range);
10020
+ }
10021
+ }
10022
+ else {
10023
+ return false;
10024
+ }
10015
10025
  }
10016
10026
  }
10017
- exports.areSameSelection = areSameSelection;
10027
+ exports.areSameSelections = areSameSelections;
10028
+ function areSame(o1, o2, keys) {
10029
+ return keys.every(function (k) { return o1[k] == o2[k]; });
10030
+ }
10031
+ var TableSelectionKeys = [
10032
+ 'table',
10033
+ 'firstColumn',
10034
+ 'lastColumn',
10035
+ 'firstRow',
10036
+ 'lastRow',
10037
+ ];
10038
+ var RangeKeys = ['startContainer', 'endContainer', 'startOffset', 'endOffset'];
10039
+ /**
10040
+ * @internal
10041
+ */
10042
+ function areSameTableSelections(t1, t2) {
10043
+ return areSame(t1, t2, TableSelectionKeys);
10044
+ }
10045
+ exports.areSameTableSelections = areSameTableSelections;
10046
+ /**
10047
+ * @internal
10048
+ */
10049
+ function areSameRanges(r1, r2) {
10050
+ return areSame(r1, r2, RangeKeys);
10051
+ }
10052
+ exports.areSameRanges = areSameRanges;
10053
+ function isCacheSelection(sel) {
10054
+ return !!sel.start;
10055
+ }
10018
10056
 
10019
10057
 
10020
10058
  /***/ }),
@@ -10353,12 +10391,10 @@ exports.DomIndexerImpl = DomIndexerImpl;
10353
10391
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10354
10392
  exports.createTextMutationObserver = void 0;
10355
10393
  var TextMutationObserverImpl = /** @class */ (function () {
10356
- function TextMutationObserverImpl(contentDiv, domIndexer, onMutation, onSkipMutation) {
10394
+ function TextMutationObserverImpl(contentDiv, onMutation) {
10357
10395
  var _this = this;
10358
10396
  this.contentDiv = contentDiv;
10359
- this.domIndexer = domIndexer;
10360
10397
  this.onMutation = onMutation;
10361
- this.onSkipMutation = onSkipMutation;
10362
10398
  this.onMutationInternal = function (mutations) {
10363
10399
  var canHandle = true;
10364
10400
  var firstTarget = null;
@@ -10399,14 +10435,20 @@ var TextMutationObserverImpl = /** @class */ (function () {
10399
10435
  break;
10400
10436
  }
10401
10437
  }
10402
- if (canHandle && (addedNodes.length > 0 || removedNodes.length > 0)) {
10403
- canHandle = _this.domIndexer.reconcileChildList(addedNodes, removedNodes);
10404
- }
10405
- if (canHandle && reconcileText) {
10406
- _this.onMutation(true /*textOnly*/);
10438
+ if (canHandle) {
10439
+ if (addedNodes.length > 0 || removedNodes.length > 0) {
10440
+ _this.onMutation({
10441
+ type: 'childList',
10442
+ addedNodes: addedNodes,
10443
+ removedNodes: removedNodes,
10444
+ });
10445
+ }
10446
+ if (reconcileText) {
10447
+ _this.onMutation({ type: 'text' });
10448
+ }
10407
10449
  }
10408
- else if (!canHandle) {
10409
- _this.onMutation(false /*textOnly*/);
10450
+ else {
10451
+ _this.onMutation({ type: 'unknown' });
10410
10452
  }
10411
10453
  };
10412
10454
  this.observer = new MutationObserver(this.onMutationInternal);
@@ -10422,12 +10464,9 @@ var TextMutationObserverImpl = /** @class */ (function () {
10422
10464
  TextMutationObserverImpl.prototype.stopObserving = function () {
10423
10465
  this.observer.disconnect();
10424
10466
  };
10425
- TextMutationObserverImpl.prototype.flushMutations = function (model) {
10467
+ TextMutationObserverImpl.prototype.flushMutations = function (ignoreMutations) {
10426
10468
  var mutations = this.observer.takeRecords();
10427
- if (model) {
10428
- this.onSkipMutation(model);
10429
- }
10430
- else {
10469
+ if (!ignoreMutations) {
10431
10470
  this.onMutationInternal(mutations);
10432
10471
  }
10433
10472
  };
@@ -10436,28 +10475,29 @@ var TextMutationObserverImpl = /** @class */ (function () {
10436
10475
  /**
10437
10476
  * @internal
10438
10477
  */
10439
- function createTextMutationObserver(contentDiv, domIndexer, onMutation, onSkipMutation) {
10440
- return new TextMutationObserverImpl(contentDiv, domIndexer, onMutation, onSkipMutation);
10478
+ function createTextMutationObserver(contentDiv, onMutation) {
10479
+ return new TextMutationObserverImpl(contentDiv, onMutation);
10441
10480
  }
10442
10481
  exports.createTextMutationObserver = createTextMutationObserver;
10443
10482
 
10444
10483
 
10445
10484
  /***/ }),
10446
10485
 
10447
- /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCachedSelection.ts":
10448
- /*!*********************************************************************************************!*\
10449
- !*** ./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCachedSelection.ts ***!
10450
- \*********************************************************************************************/
10486
+ /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCache.ts":
10487
+ /*!***********************************************************************************!*\
10488
+ !*** ./packages/roosterjs-content-model-core/lib/corePlugin/cache/updateCache.ts ***!
10489
+ \***********************************************************************************/
10451
10490
  /***/ ((__unused_webpack_module, exports) => {
10452
10491
 
10453
10492
  "use strict";
10454
10493
 
10455
10494
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10456
- exports.updateCachedSelection = void 0;
10495
+ exports.updateCache = void 0;
10457
10496
  /**
10458
10497
  * @internal
10459
10498
  */
10460
- function updateCachedSelection(state, selection) {
10499
+ function updateCache(state, model, selection) {
10500
+ state.cachedModel = model;
10461
10501
  if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'range') {
10462
10502
  var _a = selection.range, startContainer = _a.startContainer, startOffset = _a.startOffset, endContainer = _a.endContainer, endOffset = _a.endOffset, isReverted = selection.isReverted;
10463
10503
  state.cachedSelection = {
@@ -10474,10 +10514,10 @@ function updateCachedSelection(state, selection) {
10474
10514
  };
10475
10515
  }
10476
10516
  else {
10477
- state.cachedSelection = selection;
10517
+ state.cachedSelection = selection !== null && selection !== void 0 ? selection : undefined;
10478
10518
  }
10479
10519
  }
10480
- exports.updateCachedSelection = updateCachedSelection;
10520
+ exports.updateCache = updateCache;
10481
10521
 
10482
10522
 
10483
10523
  /***/ }),
@@ -12235,6 +12275,7 @@ exports.applyPendingFormat = applyPendingFormat;
12235
12275
  Object.defineProperty(exports, "__esModule", ({ value: true }));
12236
12276
  exports.createLifecyclePlugin = void 0;
12237
12277
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
12278
+ var createAriaLiveElement_1 = __webpack_require__(/*! ../../utils/createAriaLiveElement */ "./packages/roosterjs-content-model-core/lib/utils/createAriaLiveElement.ts");
12238
12279
  var ContentEditableAttributeName = 'contenteditable';
12239
12280
  var DefaultTextColor = '#000000';
12240
12281
  var DefaultBackColor = '#ffffff';
@@ -12294,6 +12335,8 @@ var LifecyclePlugin = /** @class */ (function () {
12294
12335
  this.adjustColor();
12295
12336
  // Let other plugins know that we are ready
12296
12337
  this.editor.triggerEvent('editorReady', {}, true /*broadcast*/);
12338
+ // Initialize the Announce container.
12339
+ this.state.announceContainer = (0, createAriaLiveElement_1.createAriaLiveElement)(editor.getDocument());
12297
12340
  };
12298
12341
  /**
12299
12342
  * Dispose this plugin
@@ -12377,7 +12420,6 @@ var isSingleImageInSelection_1 = __webpack_require__(/*! ./isSingleImageInSelect
12377
12420
  var normalizePos_1 = __webpack_require__(/*! ./normalizePos */ "./packages/roosterjs-content-model-core/lib/corePlugin/selection/normalizePos.ts");
12378
12421
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
12379
12422
  var MouseLeftButton = 0;
12380
- var MouseMiddleButton = 1;
12381
12423
  var MouseRightButton = 2;
12382
12424
  var Up = 'ArrowUp';
12383
12425
  var Down = 'ArrowDown';
@@ -12492,16 +12534,17 @@ var SelectionPlugin = /** @class */ (function () {
12492
12534
  var newSelection = _this.editor.getDOMSelection();
12493
12535
  //If am image selection changed to a wider range due a keyboard event, we should update the selection
12494
12536
  var selection = _this.editor.getDocument().getSelection();
12495
- if ((newSelection === null || newSelection === void 0 ? void 0 : newSelection.type) == 'image' && selection) {
12496
- if (selection && !(0, isSingleImageInSelection_1.isSingleImageInSelection)(selection)) {
12497
- var range = selection.getRangeAt(0);
12498
- _this.editor.setDOMSelection({
12499
- type: 'range',
12500
- range: range,
12501
- isReverted: selection.focusNode != range.endContainer ||
12502
- selection.focusOffset != range.endOffset,
12503
- });
12504
- }
12537
+ if ((newSelection === null || newSelection === void 0 ? void 0 : newSelection.type) == 'image' &&
12538
+ selection &&
12539
+ selection.focusNode &&
12540
+ !(0, isSingleImageInSelection_1.isSingleImageInSelection)(selection)) {
12541
+ var range = selection.getRangeAt(0);
12542
+ _this.editor.setDOMSelection({
12543
+ type: 'range',
12544
+ range: range,
12545
+ isReverted: selection.focusNode != range.endContainer ||
12546
+ selection.focusOffset != range.endOffset,
12547
+ });
12505
12548
  }
12506
12549
  // Safari has problem to handle onBlur event. When blur, we cannot get the original selection from editor.
12507
12550
  // So we always save a selection whenever editor has focus. Then after blur, we can still use this cached selection.
@@ -12583,7 +12626,7 @@ var SelectionPlugin = /** @class */ (function () {
12583
12626
  this.onMouseDown(this.editor, event.rawEvent);
12584
12627
  break;
12585
12628
  case 'mouseUp':
12586
- this.onMouseUp(event);
12629
+ this.onMouseUp();
12587
12630
  break;
12588
12631
  case 'keyDown':
12589
12632
  this.onKeyDown(this.editor, event.rawEvent);
@@ -12603,15 +12646,20 @@ var SelectionPlugin = /** @class */ (function () {
12603
12646
  var selection = editor.getDOMSelection();
12604
12647
  var image;
12605
12648
  // Image selection
12606
- if (rawEvent.button === MouseRightButton &&
12607
- (image =
12608
- (_a = this.getClickingImage(rawEvent)) !== null && _a !== void 0 ? _a : this.getContainedTargetImage(rawEvent, selection)) &&
12609
- image.isContentEditable) {
12610
- this.selectImageWithRange(image, rawEvent);
12611
- return;
12649
+ if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image' &&
12650
+ (rawEvent.button == MouseLeftButton ||
12651
+ (rawEvent.button == MouseRightButton &&
12652
+ !this.getClickingImage(rawEvent) &&
12653
+ !this.getContainedTargetImage(rawEvent, selection)))) {
12654
+ this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);
12612
12655
  }
12613
- else if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image' && selection.image !== rawEvent.target) {
12614
- this.selectBeforeOrAfterElement(editor, selection.image);
12656
+ if ((image =
12657
+ (_a = this.getClickingImage(rawEvent)) !== null && _a !== void 0 ? _a : this.getContainedTargetImage(rawEvent, selection)) &&
12658
+ image.isContentEditable) {
12659
+ this.setDOMSelection({
12660
+ type: 'image',
12661
+ image: image,
12662
+ }, null);
12615
12663
  return;
12616
12664
  }
12617
12665
  // Table selection
@@ -12640,32 +12688,7 @@ var SelectionPlugin = /** @class */ (function () {
12640
12688
  });
12641
12689
  }
12642
12690
  };
12643
- SelectionPlugin.prototype.selectImageWithRange = function (image, event) {
12644
- var _a;
12645
- var range = image.ownerDocument.createRange();
12646
- range.selectNode(image);
12647
- var domSelection = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getDOMSelection();
12648
- if ((domSelection === null || domSelection === void 0 ? void 0 : domSelection.type) == 'image' && image == domSelection.image) {
12649
- event.preventDefault();
12650
- }
12651
- else {
12652
- this.setDOMSelection({
12653
- type: 'range',
12654
- isReverted: false,
12655
- range: range,
12656
- }, null);
12657
- }
12658
- };
12659
- SelectionPlugin.prototype.onMouseUp = function (event) {
12660
- var image;
12661
- if ((image = this.getClickingImage(event.rawEvent)) &&
12662
- image.isContentEditable &&
12663
- event.rawEvent.button != MouseMiddleButton &&
12664
- (event.rawEvent.button ==
12665
- MouseRightButton /* it's not possible to drag using right click */ ||
12666
- event.isClicking)) {
12667
- this.selectImageWithRange(image, event.rawEvent);
12668
- }
12691
+ SelectionPlugin.prototype.onMouseUp = function () {
12669
12692
  this.detachMouseEvent();
12670
12693
  };
12671
12694
  SelectionPlugin.prototype.onKeyDown = function (editor, rawEvent) {
@@ -12743,6 +12766,7 @@ var SelectionPlugin = /** @class */ (function () {
12743
12766
  return;
12744
12767
  }
12745
12768
  var lastCo = (0, findCoordinate_1.findCoordinate)(tableSel === null || tableSel === void 0 ? void 0 : tableSel.parsedTable, end, domHelper);
12769
+ var tabMove = false;
12746
12770
  var _h = this.state.tableSelection, parsedTable = _h.parsedTable, oldCo = _h.firstCo, table = _h.table;
12747
12771
  if (lastCo && tableSel.table == table) {
12748
12772
  if (lastCo.col != oldCo.col && (key == Up || key == Down)) {
@@ -12780,7 +12804,8 @@ var SelectionPlugin = /** @class */ (function () {
12780
12804
  }
12781
12805
  var cell = parsedTable[row][col];
12782
12806
  if (typeof cell != 'string') {
12783
- this.setRangeSelectionInTable(cell, 0, this.editor);
12807
+ tabMove = true;
12808
+ this.setRangeSelectionInTable(cell, 0, this.editor, true /* selectAll */);
12784
12809
  lastCo.row = row;
12785
12810
  lastCo.col = col;
12786
12811
  break;
@@ -12798,18 +12823,23 @@ var SelectionPlugin = /** @class */ (function () {
12798
12823
  (_f = this.editor) === null || _f === void 0 ? void 0 : _f.announce({ defaultStrings: 'announceOnFocusLastCell' });
12799
12824
  }
12800
12825
  }
12801
- if (!collapsed && lastCo) {
12826
+ if (!collapsed && lastCo && !tabMove) {
12802
12827
  this.state.tableSelection = tableSel;
12803
12828
  this.updateTableSelection(lastCo);
12804
12829
  }
12805
12830
  }
12806
12831
  };
12807
- SelectionPlugin.prototype.setRangeSelectionInTable = function (cell, nodeOffset, editor) {
12808
- // Get deepest editable position in the cell
12809
- var _a = (0, normalizePos_1.normalizePos)(cell, nodeOffset), node = _a.node, offset = _a.offset;
12832
+ SelectionPlugin.prototype.setRangeSelectionInTable = function (cell, nodeOffset, editor, selectAll) {
12810
12833
  var range = editor.getDocument().createRange();
12811
- range.setStart(node, offset);
12812
- range.collapse(true /*toStart*/);
12834
+ if (selectAll) {
12835
+ range.selectNodeContents(cell);
12836
+ }
12837
+ else {
12838
+ // Get deepest editable position in the cell
12839
+ var _a = (0, normalizePos_1.normalizePos)(cell, nodeOffset), node = _a.node, offset = _a.offset;
12840
+ range.setStart(node, offset);
12841
+ range.collapse(true /* toStart */);
12842
+ }
12813
12843
  this.setDOMSelection({
12814
12844
  type: 'range',
12815
12845
  range: range,
@@ -14442,6 +14472,37 @@ function shouldUseTableProcessor(element, context) {
14442
14472
  }
14443
14473
 
14444
14474
 
14475
+ /***/ }),
14476
+
14477
+ /***/ "./packages/roosterjs-content-model-core/lib/utils/createAriaLiveElement.ts":
14478
+ /*!**********************************************************************************!*\
14479
+ !*** ./packages/roosterjs-content-model-core/lib/utils/createAriaLiveElement.ts ***!
14480
+ \**********************************************************************************/
14481
+ /***/ ((__unused_webpack_module, exports) => {
14482
+
14483
+ "use strict";
14484
+
14485
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
14486
+ exports.createAriaLiveElement = void 0;
14487
+ /**
14488
+ * @internal
14489
+ */
14490
+ function createAriaLiveElement(document) {
14491
+ var div = document.createElement('div');
14492
+ div.style.clip = 'rect(0px, 0px, 0px, 0px)';
14493
+ div.style.clipPath = 'inset(100%)';
14494
+ div.style.height = '1px';
14495
+ div.style.overflow = 'hidden';
14496
+ div.style.position = 'absolute';
14497
+ div.style.whiteSpace = 'nowrap';
14498
+ div.style.width = '1px';
14499
+ div.ariaLive = 'assertive';
14500
+ document.body.appendChild(div);
14501
+ return div;
14502
+ }
14503
+ exports.createAriaLiveElement = createAriaLiveElement;
14504
+
14505
+
14445
14506
  /***/ }),
14446
14507
 
14447
14508
  /***/ "./packages/roosterjs-content-model-dom/lib/config/defaultContentModelFormatMap.ts":
@@ -17541,16 +17602,14 @@ var normalizeRect_1 = __webpack_require__(/*! ../normalizeRect */ "./packages/ro
17541
17602
  * @param pos The input DOM insert point
17542
17603
  */
17543
17604
  function getDOMInsertPointRect(doc, pos) {
17544
- var _a;
17545
- var node = pos.node, offset = pos.offset;
17605
+ var _a, _b;
17546
17606
  var range = doc.createRange();
17547
- range.setStart(node, offset);
17548
- // 1) try to get rect using range.getBoundingClientRect()
17549
- var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
17550
- if (rect) {
17551
- return rect;
17552
- }
17553
- // 2) try to get rect using range.getClientRects
17607
+ return ((_b = (_a = tryGetRectFromPos(pos, range)) !== null && _a !== void 0 ? _a : tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range)) !== null && _b !== void 0 ? _b : tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect
17608
+ );
17609
+ }
17610
+ exports.getDOMInsertPointRect = getDOMInsertPointRect;
17611
+ function normalizeInsertPoint(pos) {
17612
+ var node = pos.node, offset = pos.offset;
17554
17613
  while (node.lastChild) {
17555
17614
  if (offset == node.childNodes.length) {
17556
17615
  node = node.lastChild;
@@ -17561,32 +17620,26 @@ function getDOMInsertPointRect(doc, pos) {
17561
17620
  offset = 0;
17562
17621
  }
17563
17622
  }
17564
- var rects = range.getClientRects && range.getClientRects();
17565
- rect = rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
17623
+ return { node: node, offset: offset };
17624
+ }
17625
+ function tryGetRectFromPos(pos, range) {
17626
+ var node = pos.node, offset = pos.offset;
17627
+ range.setStart(node, offset);
17628
+ range.setEnd(node, offset);
17629
+ var rect = (0, normalizeRect_1.normalizeRect)(range.getBoundingClientRect());
17566
17630
  if (rect) {
17567
17631
  return rect;
17568
17632
  }
17569
- // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
17570
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'TEXT_NODE')) {
17571
- var span = node.ownerDocument.createElement('span');
17572
- span.textContent = '\u200b';
17573
- range.insertNode(span);
17574
- rect = (0, normalizeRect_1.normalizeRect)(span.getBoundingClientRect());
17575
- (_a = span.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(span);
17576
- if (rect) {
17577
- return rect;
17578
- }
17579
- }
17580
- // 4) try getBoundingClientRect on element
17581
- if ((0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {
17582
- rect = (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect());
17583
- if (rect) {
17584
- return rect;
17585
- }
17633
+ else {
17634
+ var rects = range.getClientRects && range.getClientRects();
17635
+ return rects && rects.length == 1 ? (0, normalizeRect_1.normalizeRect)(rects[0]) : null;
17586
17636
  }
17587
- return null;
17588
17637
  }
17589
- exports.getDOMInsertPointRect = getDOMInsertPointRect;
17638
+ function tryGetRectFromNode(node) {
17639
+ return (0, isNodeOfType_1.isNodeOfType)(node, 'ELEMENT_NODE') && node.getBoundingClientRect
17640
+ ? (0, normalizeRect_1.normalizeRect)(node.getBoundingClientRect())
17641
+ : null;
17642
+ }
17590
17643
 
17591
17644
 
17592
17645
  /***/ }),
@@ -25880,8 +25933,7 @@ function removeUnnecessarySpan(root) {
25880
25933
  for (var child = root.firstChild; child;) {
25881
25934
  if ((0, isNodeOfType_1.isNodeOfType)(child, 'ELEMENT_NODE') &&
25882
25935
  child.tagName == 'SPAN' &&
25883
- child.attributes.length == 0 &&
25884
- !isImageSpan(child)) {
25936
+ child.attributes.length == 0) {
25885
25937
  var node = child;
25886
25938
  var refNode = child.nextSibling;
25887
25939
  child = child.nextSibling;
@@ -25898,11 +25950,6 @@ function removeUnnecessarySpan(root) {
25898
25950
  }
25899
25951
  }
25900
25952
  exports.removeUnnecessarySpan = removeUnnecessarySpan;
25901
- var isImageSpan = function (child) {
25902
- return ((0, isNodeOfType_1.isNodeOfType)(child.firstChild, 'ELEMENT_NODE') &&
25903
- child.firstChild.tagName == 'IMG' &&
25904
- child.firstChild == child.lastChild);
25905
- };
25906
25953
 
25907
25954
 
25908
25955
  /***/ }),
@@ -26312,7 +26359,7 @@ var getChangeSource = function (shouldList, shouldHyphen, shouldLink) {
26312
26359
 
26313
26360
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26314
26361
  exports.transformHyphen = void 0;
26315
- var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
26362
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26316
26363
  /**
26317
26364
  * @internal
26318
26365
  */
@@ -26321,7 +26368,7 @@ function transformHyphen(previousSegment, paragraph, context) {
26321
26368
  var dashes = segments[segments.length - 2];
26322
26369
  if (dashes === '--') {
26323
26370
  var textIndex = previousSegment.text.lastIndexOf('--');
26324
- var textSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, textIndex, textIndex + 2);
26371
+ var textSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, textIndex, textIndex + 2);
26325
26372
  textSegment.text = textSegment.text.replace('--', '—');
26326
26373
  context.canUndoByBackspace = true;
26327
26374
  return true;
@@ -26331,7 +26378,7 @@ function transformHyphen(previousSegment, paragraph, context) {
26331
26378
  var hasDashes = text && (text === null || text === void 0 ? void 0 : text.indexOf('--')) > -1;
26332
26379
  if (hasDashes && text.trim() !== '--') {
26333
26380
  var textIndex = previousSegment.text.indexOf(text);
26334
- var textSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, textIndex, textIndex + text.length - 1);
26381
+ var textSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, textIndex, textIndex + text.length - 1);
26335
26382
  var textLength = textSegment.text.length;
26336
26383
  if (textSegment.text[0] !== '-' && textSegment.text[textLength - 1] !== '-') {
26337
26384
  textSegment.text = textSegment.text.replace('--', '—');
@@ -26364,8 +26411,10 @@ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-mo
26364
26411
  */
26365
26412
  function createLink(editor) {
26366
26413
  var anchorNode = null;
26414
+ var links = [];
26367
26415
  (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, linkSegment, _paragraph) {
26368
26416
  if (linkSegment.link) {
26417
+ links.push(linkSegment.link);
26369
26418
  return true;
26370
26419
  }
26371
26420
  var linkData = null;
@@ -26377,13 +26426,16 @@ function createLink(editor) {
26377
26426
  },
26378
26427
  dataset: {},
26379
26428
  });
26429
+ if (linkSegment.link) {
26430
+ links.push(linkSegment.link);
26431
+ }
26380
26432
  return true;
26381
26433
  }
26382
26434
  return false;
26383
26435
  }, {
26384
26436
  changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoLink,
26385
- onNodeCreated: function (_modelElement, node) {
26386
- if (!anchorNode) {
26437
+ onNodeCreated: function (modelElement, node) {
26438
+ if (!anchorNode && links.indexOf(modelElement) >= 0) {
26387
26439
  anchorNode = node;
26388
26440
  }
26389
26441
  },
@@ -26406,7 +26458,6 @@ exports.createLink = createLink;
26406
26458
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26407
26459
  exports.createLinkAfterSpace = void 0;
26408
26460
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26409
- var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
26410
26461
  /**
26411
26462
  * @internal
26412
26463
  */
@@ -26415,7 +26466,7 @@ function createLinkAfterSpace(previousSegment, paragraph, context) {
26415
26466
  var url = link === null || link === void 0 ? void 0 : link.trim();
26416
26467
  var linkData = null;
26417
26468
  if (url && link && (linkData = (0, roosterjs_content_model_api_1.matchLink)(url))) {
26418
- var linkSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
26469
+ var linkSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
26419
26470
  linkSegment.link = {
26420
26471
  format: {
26421
26472
  href: linkData.normalizedUrl,
@@ -26794,7 +26845,9 @@ function canAppendList(index, previousListIndex) {
26794
26845
 
26795
26846
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26796
26847
  exports.keyboardListTrigger = void 0;
26848
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
26797
26849
  var getListTypeStyle_1 = __webpack_require__(/*! ./getListTypeStyle */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/list/getListTypeStyle.ts");
26850
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
26798
26851
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26799
26852
  /**
26800
26853
  * @internal
@@ -26808,6 +26861,7 @@ function keyboardListTrigger(model, paragraph, context, shouldSearchForBullet, s
26808
26861
  var listType = listStyleType.listType, styleType = listStyleType.styleType, index = listStyleType.index;
26809
26862
  triggerList(model, listType, styleType, index);
26810
26863
  context.canUndoByBackspace = true;
26864
+ setAnnounceData(model, context);
26811
26865
  return true;
26812
26866
  }
26813
26867
  return false;
@@ -26822,11 +26876,21 @@ var triggerList = function (model, listType, styleType, index) {
26822
26876
  (0, roosterjs_content_model_api_1.setModelListStyle)(model, isOrderedList
26823
26877
  ? {
26824
26878
  orderedStyleType: styleType,
26879
+ applyListStyleFromLevel: false,
26825
26880
  }
26826
26881
  : {
26827
26882
  unorderedStyleType: styleType,
26883
+ applyListStyleFromLevel: false,
26828
26884
  });
26829
26885
  };
26886
+ function setAnnounceData(model, context) {
26887
+ var _a = (0, tslib_1.__read)((0, roosterjs_content_model_dom_1.getOperationalBlocks)(model, ['ListItem'], [] // Set stop types to be empty so we can find list items even cross the boundary of table, then we can always operation on the list item if any
26888
+ ), 1), paragraphOrListItems = _a[0];
26889
+ if (paragraphOrListItems && (0, roosterjs_content_model_dom_1.isBlockGroupOfType)(paragraphOrListItems.block, 'ListItem')) {
26890
+ var path = paragraphOrListItems.path, block = paragraphOrListItems.block;
26891
+ context.announceData = (0, roosterjs_content_model_api_1.getListAnnounceData)((0, tslib_1.__spreadArray)([block], (0, tslib_1.__read)(path), false));
26892
+ }
26893
+ }
26830
26894
 
26831
26895
 
26832
26896
  /***/ }),
@@ -26841,7 +26905,7 @@ var triggerList = function (model, listType, styleType, index) {
26841
26905
 
26842
26906
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26843
26907
  exports.transformFraction = void 0;
26844
- var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
26908
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26845
26909
  var FRACTIONS = new Map([
26846
26910
  ['1/2', '½'],
26847
26911
  ['1/4', '¼'],
@@ -26857,7 +26921,7 @@ function transformFraction(previousSegment, paragraph, context) {
26857
26921
  if (fraction && text) {
26858
26922
  var textLength = previousSegment.text.length - 1;
26859
26923
  var textIndex = textLength - fraction.length;
26860
- var textSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, textIndex, textLength);
26924
+ var textSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, textIndex, textLength);
26861
26925
  textSegment.text = text;
26862
26926
  context.canUndoByBackspace = true;
26863
26927
  return true;
@@ -26879,7 +26943,7 @@ exports.transformFraction = transformFraction;
26879
26943
 
26880
26944
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26881
26945
  exports.transformOrdinals = void 0;
26882
- var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
26946
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26883
26947
  var getOrdinal = function (value) {
26884
26948
  var ORDINALS = {
26885
26949
  1: 'st',
@@ -26898,7 +26962,7 @@ function transformOrdinals(previousSegment, paragraph, context) {
26898
26962
  var ordinal = value.substring(value.length - 2);
26899
26963
  var ordinalValue = parseInt(value);
26900
26964
  if (ordinalValue && getOrdinal(ordinalValue) === ordinal) {
26901
- var ordinalSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - 3, previousSegment.text.length - 1);
26965
+ var ordinalSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - 3, previousSegment.text.length - 1);
26902
26966
  ordinalSegment.format.superOrSubScriptSequence = 'super';
26903
26967
  context.canUndoByBackspace = true;
26904
26968
  return true;
@@ -27119,6 +27183,9 @@ var keyboardTab_1 = __webpack_require__(/*! ./keyboardTab */ "./packages/rooster
27119
27183
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
27120
27184
  var BACKSPACE_KEY = 8;
27121
27185
  var DELETE_KEY = 46;
27186
+ var DefaultOptions = {
27187
+ handleTabKey: true,
27188
+ };
27122
27189
  /**
27123
27190
  * Edit plugins helps editor to do editing operation on top of content model.
27124
27191
  * This includes:
@@ -27127,7 +27194,13 @@ var DELETE_KEY = 46;
27127
27194
  * 3. Tab Key
27128
27195
  */
27129
27196
  var EditPlugin = /** @class */ (function () {
27130
- function EditPlugin() {
27197
+ /**
27198
+ * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:
27199
+ * handleTabKey: A boolean that enables or disables Tab key handling. Defaults to true.
27200
+ */
27201
+ function EditPlugin(options) {
27202
+ if (options === void 0) { options = DefaultOptions; }
27203
+ this.options = options;
27131
27204
  this.editor = null;
27132
27205
  this.disposer = null;
27133
27206
  this.shouldHandleNextInputEvent = false;
@@ -27200,6 +27273,7 @@ var EditPlugin = /** @class */ (function () {
27200
27273
  */
27201
27274
  EditPlugin.prototype.willHandleEventExclusively = function (event) {
27202
27275
  if (this.editor &&
27276
+ this.options.handleTabKey &&
27203
27277
  event.eventType == 'keyDown' &&
27204
27278
  event.rawEvent.key == 'Tab' &&
27205
27279
  !event.rawEvent.shiftKey) {
@@ -27241,7 +27315,9 @@ var EditPlugin = /** @class */ (function () {
27241
27315
  }
27242
27316
  break;
27243
27317
  case 'Tab':
27244
- (0, keyboardTab_1.keyboardTab)(editor, rawEvent);
27318
+ if (this.options.handleTabKey) {
27319
+ (0, keyboardTab_1.keyboardTab)(editor, rawEvent);
27320
+ }
27245
27321
  break;
27246
27322
  case 'Unidentified':
27247
27323
  if (editor.getEnvironment().isAndroid) {
@@ -28900,10 +28976,13 @@ var canRegenerateImage_1 = __webpack_require__(/*! ./utils/canRegenerateImage */
28900
28976
  var imageEditUtils_1 = __webpack_require__(/*! ./utils/imageEditUtils */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/imageEditUtils.ts");
28901
28977
  var createImageWrapper_1 = __webpack_require__(/*! ./utils/createImageWrapper */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/createImageWrapper.ts");
28902
28978
  var cropperContext_1 = __webpack_require__(/*! ./Cropper/cropperContext */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Cropper/cropperContext.ts");
28979
+ var findEditingImage_1 = __webpack_require__(/*! ./utils/findEditingImage */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/findEditingImage.ts");
28903
28980
  var getDropAndDragHelpers_1 = __webpack_require__(/*! ./utils/getDropAndDragHelpers */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getDropAndDragHelpers.ts");
28904
28981
  var getHTMLImageOptions_1 = __webpack_require__(/*! ./utils/getHTMLImageOptions */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getHTMLImageOptions.ts");
28982
+ var getSelectedImage_1 = __webpack_require__(/*! ./utils/getSelectedImage */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedImage.ts");
28905
28983
  var updateImageEditInfo_1 = __webpack_require__(/*! ./utils/updateImageEditInfo */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/updateImageEditInfo.ts");
28906
28984
  var ImageEditElementClass_1 = __webpack_require__(/*! ./types/ImageEditElementClass */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/types/ImageEditElementClass.ts");
28985
+ var normalizeImageSelection_1 = __webpack_require__(/*! ./utils/normalizeImageSelection */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/normalizeImageSelection.ts");
28907
28986
  var resizerContext_1 = __webpack_require__(/*! ./Resizer/resizerContext */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Resizer/resizerContext.ts");
28908
28987
  var rotatorContext_1 = __webpack_require__(/*! ./Rotator/rotatorContext */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Rotator/rotatorContext.ts");
28909
28988
  var updateRotateHandle_1 = __webpack_require__(/*! ./Rotator/updateRotateHandle */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Rotator/updateRotateHandle.ts");
@@ -28916,9 +28995,9 @@ var DefaultOptions = {
28916
28995
  preserveRatio: true,
28917
28996
  disableRotate: false,
28918
28997
  disableSideResize: false,
28919
- onSelectState: 'resize',
28998
+ onSelectState: ['resize', 'rotate'],
28920
28999
  };
28921
- var IMAGE_EDIT_CHANGE_SOURCE = 'ImageEdit';
29000
+ var MouseRightButton = 2;
28922
29001
  /**
28923
29002
  * ImageEdit plugin handles the following image editing features:
28924
29003
  * - Resize image
@@ -28946,6 +29025,8 @@ var ImageEditPlugin = /** @class */ (function () {
28946
29025
  this.croppers = [];
28947
29026
  this.zoomScale = 1;
28948
29027
  this.disposer = null;
29028
+ //EXPOSED FOR TEST ONLY
29029
+ this.isEditing = false;
28949
29030
  }
28950
29031
  /**
28951
29032
  * Get name of this plugin
@@ -28965,7 +29046,9 @@ var ImageEditPlugin = /** @class */ (function () {
28965
29046
  this.disposer = editor.attachDomEvent({
28966
29047
  blur: {
28967
29048
  beforeDispatch: function () {
28968
- _this.formatImageWithContentModel(editor, true /* shouldSelectImage */, true /* shouldSelectAsImageSelection*/);
29049
+ if (_this.editor) {
29050
+ _this.applyFormatWithContentModel(_this.editor, _this.isCropMode, true /* shouldSelectImage */);
29051
+ }
28969
29052
  },
28970
29053
  },
28971
29054
  });
@@ -28977,6 +29060,7 @@ var ImageEditPlugin = /** @class */ (function () {
28977
29060
  */
28978
29061
  ImageEditPlugin.prototype.dispose = function () {
28979
29062
  this.editor = null;
29063
+ this.isEditing = false;
28980
29064
  this.cleanInfo();
28981
29065
  if (this.disposer) {
28982
29066
  this.disposer();
@@ -28989,16 +29073,148 @@ var ImageEditPlugin = /** @class */ (function () {
28989
29073
  * exclusively by another plugin.
28990
29074
  * @param event The event to handle:
28991
29075
  */
28992
- ImageEditPlugin.prototype.onPluginEvent = function (_event) { };
28993
- ImageEditPlugin.prototype.startEditing = function (editor, image, apiOperation) {
28994
- var imageSpan = image.parentElement;
28995
- if (!imageSpan || (imageSpan && !(0, roosterjs_content_model_dom_1.isElementOfType)(imageSpan, 'span'))) {
29076
+ ImageEditPlugin.prototype.onPluginEvent = function (event) {
29077
+ if (!this.editor) {
28996
29078
  return;
28997
29079
  }
28998
- this.imageEditInfo = (0, updateImageEditInfo_1.getSelectedImageMetadata)(editor, image);
29080
+ switch (event.eventType) {
29081
+ case 'mouseUp':
29082
+ this.mouseUpHandler(this.editor, event);
29083
+ break;
29084
+ case 'keyDown':
29085
+ this.keyDownHandler(this.editor, event);
29086
+ break;
29087
+ }
29088
+ };
29089
+ ImageEditPlugin.prototype.isImageSelection = function (target) {
29090
+ return ((0, roosterjs_content_model_dom_1.isNodeOfType)(target, 'ELEMENT_NODE') &&
29091
+ ((0, roosterjs_content_model_dom_1.isElementOfType)(target, 'img') ||
29092
+ !!((0, roosterjs_content_model_dom_1.isElementOfType)(target, 'span') &&
29093
+ target.firstElementChild &&
29094
+ (0, roosterjs_content_model_dom_1.isNodeOfType)(target.firstElementChild, 'ELEMENT_NODE') &&
29095
+ (0, roosterjs_content_model_dom_1.isElementOfType)(target.firstElementChild, 'img'))));
29096
+ };
29097
+ ImageEditPlugin.prototype.mouseUpHandler = function (editor, event) {
29098
+ var selection = editor.getDOMSelection();
29099
+ if ((selection && selection.type == 'image') || this.isEditing) {
29100
+ var shouldSelectImage = this.isImageSelection(event.rawEvent.target) &&
29101
+ event.rawEvent.button === MouseRightButton;
29102
+ this.applyFormatWithContentModel(editor, this.isCropMode, shouldSelectImage);
29103
+ }
29104
+ };
29105
+ //Sometimes the cursor can be inside the editing image and inside shadow dom, then the cursor need to moved out of shadow dom
29106
+ ImageEditPlugin.prototype.selectBeforeEditingImage = function (editor, element) {
29107
+ var parent = element.parentNode;
29108
+ if (parent && (0, roosterjs_content_model_dom_1.isNodeOfType)(parent, 'ELEMENT_NODE') && parent.shadowRoot) {
29109
+ element = parent;
29110
+ parent = parent.parentNode;
29111
+ }
29112
+ var index = parent && (0, roosterjs_content_model_dom_1.toArray)(parent.childNodes).indexOf(element);
29113
+ if (index !== null && index >= 0 && parent) {
29114
+ var doc = editor.getDocument();
29115
+ var range = doc.createRange();
29116
+ range.setStart(parent, index);
29117
+ range.collapse();
29118
+ editor.setDOMSelection({
29119
+ type: 'range',
29120
+ range: range,
29121
+ isReverted: false,
29122
+ });
29123
+ }
29124
+ };
29125
+ ImageEditPlugin.prototype.keyDownHandler = function (editor, event) {
29126
+ if (this.isEditing) {
29127
+ if (event.rawEvent.key === 'Escape') {
29128
+ this.removeImageWrapper();
29129
+ }
29130
+ else {
29131
+ var selection = editor.getDOMSelection();
29132
+ var isImageSelection = (selection === null || selection === void 0 ? void 0 : selection.type) == 'image';
29133
+ if (isImageSelection) {
29134
+ this.selectBeforeEditingImage(editor, selection.image);
29135
+ }
29136
+ this.applyFormatWithContentModel(editor, this.isCropMode, ((0, roosterjs_content_model_dom_1.isModifierKey)(event.rawEvent) || event.rawEvent.shiftKey) && isImageSelection //if it's a modifier key over a image, the image should select the image
29137
+ );
29138
+ }
29139
+ }
29140
+ };
29141
+ ImageEditPlugin.prototype.applyFormatWithContentModel = function (editor, isCropMode, shouldSelectImage, isApiOperation) {
29142
+ var _this = this;
29143
+ var editingImageModel;
29144
+ var selection = editor.getDOMSelection();
29145
+ editor.formatContentModel(function (model) {
29146
+ var editingImage = (0, getSelectedImage_1.getSelectedImage)(model);
29147
+ var previousSelectedImage = isApiOperation
29148
+ ? editingImage
29149
+ : (0, findEditingImage_1.findEditingImage)(model);
29150
+ var result = false;
29151
+ if (shouldSelectImage ||
29152
+ (previousSelectedImage === null || previousSelectedImage === void 0 ? void 0 : previousSelectedImage.image) != (editingImage === null || editingImage === void 0 ? void 0 : editingImage.image) ||
29153
+ (previousSelectedImage === null || previousSelectedImage === void 0 ? void 0 : previousSelectedImage.image.dataset.isEditing) ||
29154
+ isApiOperation) {
29155
+ var _a = _this, lastSrc_1 = _a.lastSrc, selectedImage_1 = _a.selectedImage, imageEditInfo_1 = _a.imageEditInfo, clonedImage_1 = _a.clonedImage;
29156
+ if ((_this.isEditing || isApiOperation) &&
29157
+ previousSelectedImage &&
29158
+ lastSrc_1 &&
29159
+ selectedImage_1 &&
29160
+ imageEditInfo_1 &&
29161
+ clonedImage_1) {
29162
+ (0, roosterjs_content_model_dom_1.mutateSegment)(previousSelectedImage.paragraph, previousSelectedImage.image, function (image) {
29163
+ (0, applyChange_1.applyChange)(editor, selectedImage_1, image, imageEditInfo_1, lastSrc_1, _this.wasImageResized || _this.isCropMode, clonedImage_1);
29164
+ delete image.dataset.isEditing;
29165
+ image.isSelected = shouldSelectImage;
29166
+ image.isSelectedAsImageSelection = shouldSelectImage;
29167
+ });
29168
+ if (shouldSelectImage) {
29169
+ (0, normalizeImageSelection_1.normalizeImageSelection)(previousSelectedImage);
29170
+ }
29171
+ _this.cleanInfo();
29172
+ result = true;
29173
+ }
29174
+ _this.isEditing = false;
29175
+ _this.isCropMode = false;
29176
+ if (editingImage &&
29177
+ (selection === null || selection === void 0 ? void 0 : selection.type) == 'image' &&
29178
+ !shouldSelectImage &&
29179
+ !isApiOperation) {
29180
+ _this.isEditing = true;
29181
+ _this.isCropMode = isCropMode;
29182
+ (0, roosterjs_content_model_dom_1.mutateSegment)(editingImage.paragraph, editingImage.image, function (image) {
29183
+ editingImageModel = image;
29184
+ _this.imageEditInfo = (0, updateImageEditInfo_1.updateImageEditInfo)(image, selection.image);
29185
+ image.dataset.isEditing = 'true';
29186
+ });
29187
+ result = true;
29188
+ }
29189
+ }
29190
+ return result;
29191
+ }, {
29192
+ onNodeCreated: function (model, node) {
29193
+ if (!isApiOperation &&
29194
+ editingImageModel &&
29195
+ editingImageModel == model &&
29196
+ editingImageModel.dataset.isEditing &&
29197
+ (0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') &&
29198
+ (0, roosterjs_content_model_dom_1.isElementOfType)(node, 'img')) {
29199
+ if (isCropMode) {
29200
+ _this.startCropMode(editor, node);
29201
+ }
29202
+ else {
29203
+ _this.startRotateAndResize(editor, node);
29204
+ }
29205
+ }
29206
+ },
29207
+ }, {
29208
+ tryGetFromCache: true,
29209
+ });
29210
+ };
29211
+ ImageEditPlugin.prototype.startEditing = function (editor, image, apiOperation) {
29212
+ if (!this.imageEditInfo) {
29213
+ this.imageEditInfo = (0, updateImageEditInfo_1.getSelectedImageMetadata)(editor, image);
29214
+ }
28999
29215
  this.lastSrc = image.getAttribute('src');
29000
29216
  this.imageHTMLOptions = (0, getHTMLImageOptions_1.getHTMLImageOptions)(editor, this.options, this.imageEditInfo);
29001
- var _a = (0, createImageWrapper_1.createImageWrapper)(editor, image, imageSpan, this.options, this.imageEditInfo, this.imageHTMLOptions, apiOperation || this.options.onSelectState), resizers = _a.resizers, rotators = _a.rotators, wrapper = _a.wrapper, shadowSpan = _a.shadowSpan, imageClone = _a.imageClone, croppers = _a.croppers;
29217
+ var _a = (0, createImageWrapper_1.createImageWrapper)(editor, image, this.options, this.imageEditInfo, this.imageHTMLOptions, apiOperation), resizers = _a.resizers, rotators = _a.rotators, wrapper = _a.wrapper, shadowSpan = _a.shadowSpan, imageClone = _a.imageClone, croppers = _a.croppers;
29002
29218
  this.shadowSpan = shadowSpan;
29003
29219
  this.selectedImage = image;
29004
29220
  this.wrapper = wrapper;
@@ -29012,34 +29228,33 @@ var ImageEditPlugin = /** @class */ (function () {
29012
29228
  "span:has(>img#" + this.selectedImage.id + ")",
29013
29229
  ]);
29014
29230
  };
29015
- ImageEditPlugin.prototype.startRotateAndResize = function (editor, image, apiOperation) {
29231
+ ImageEditPlugin.prototype.startRotateAndResize = function (editor, image) {
29016
29232
  var _this = this;
29017
29233
  var _a;
29018
- if (this.wrapper && this.selectedImage && this.shadowSpan) {
29019
- this.removeImageWrapper();
29020
- }
29021
- this.startEditing(editor, image, apiOperation);
29022
- if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {
29023
- this.dndHelpers = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.ResizeHandle, resizerContext_1.Resizer, function () {
29024
- if (_this.imageEditInfo &&
29025
- _this.selectedImage &&
29026
- _this.wrapper &&
29027
- _this.clonedImage) {
29028
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers);
29029
- _this.wasImageResized = true;
29030
- }
29031
- }, this.zoomScale)), false), (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.RotateHandle, rotatorContext_1.Rotator, function () {
29032
- var _a;
29033
- if (_this.imageEditInfo &&
29034
- _this.selectedImage &&
29035
- _this.wrapper &&
29036
- _this.clonedImage) {
29037
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.rotators);
29038
- _this.updateRotateHandleState(editor, _this.selectedImage, _this.wrapper, _this.rotators, (_a = _this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29039
- }
29040
- }, this.zoomScale)), false);
29041
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers);
29042
- this.updateRotateHandleState(editor, this.selectedImage, this.wrapper, this.rotators, (_a = this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29234
+ if (this.imageEditInfo) {
29235
+ this.startEditing(editor, image, ['resize', 'rotate']);
29236
+ if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {
29237
+ this.dndHelpers = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.ResizeHandle, resizerContext_1.Resizer, function () {
29238
+ if (_this.imageEditInfo &&
29239
+ _this.selectedImage &&
29240
+ _this.wrapper &&
29241
+ _this.clonedImage) {
29242
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers);
29243
+ _this.wasImageResized = true;
29244
+ }
29245
+ }, this.zoomScale)), false), (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.RotateHandle, rotatorContext_1.Rotator, function () {
29246
+ var _a;
29247
+ if (_this.imageEditInfo &&
29248
+ _this.selectedImage &&
29249
+ _this.wrapper &&
29250
+ _this.clonedImage) {
29251
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper);
29252
+ _this.updateRotateHandleState(editor, _this.selectedImage, _this.wrapper, _this.rotators, (_a = _this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29253
+ }
29254
+ }, this.zoomScale)), false);
29255
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers);
29256
+ this.updateRotateHandleState(editor, this.selectedImage, this.wrapper, this.rotators, (_a = this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29257
+ }
29043
29258
  }
29044
29259
  };
29045
29260
  ImageEditPlugin.prototype.updateRotateHandleState = function (editor, image, wrapper, rotators, angleRad) {
@@ -29055,49 +29270,52 @@ var ImageEditPlugin = /** @class */ (function () {
29055
29270
  }
29056
29271
  };
29057
29272
  ImageEditPlugin.prototype.isOperationAllowed = function (operation) {
29058
- return operation === 'resize' || operation === 'rotate' || operation === 'flip';
29273
+ return (operation === 'resize' ||
29274
+ operation === 'rotate' ||
29275
+ operation === 'flip' ||
29276
+ operation === 'crop');
29059
29277
  };
29060
29278
  ImageEditPlugin.prototype.canRegenerateImage = function (image) {
29061
29279
  return (0, canRegenerateImage_1.canRegenerateImage)(image);
29062
29280
  };
29063
- ImageEditPlugin.prototype.cropImage = function () {
29281
+ ImageEditPlugin.prototype.startCropMode = function (editor, image) {
29064
29282
  var _this = this;
29065
- var _a, _b;
29066
- var selection = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getDOMSelection();
29067
- if (!this.editor || !selection || selection.type !== 'image') {
29283
+ if (this.imageEditInfo) {
29284
+ this.startEditing(editor, image, ['crop']);
29285
+ if (this.imageEditInfo && this.selectedImage && this.wrapper && this.clonedImage) {
29286
+ this.dndHelpers = (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.CropHandle, cropperContext_1.Cropper, function () {
29287
+ if (_this.imageEditInfo &&
29288
+ _this.selectedImage &&
29289
+ _this.wrapper &&
29290
+ _this.clonedImage) {
29291
+ (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined, _this.croppers);
29292
+ _this.isCropMode = true;
29293
+ }
29294
+ }, this.zoomScale)), false);
29295
+ (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined, this.croppers);
29296
+ }
29297
+ }
29298
+ };
29299
+ ImageEditPlugin.prototype.cropImage = function () {
29300
+ if (!this.editor) {
29068
29301
  return;
29069
29302
  }
29070
- var image = selection.image;
29071
- if (this.wrapper && this.selectedImage && this.shadowSpan) {
29072
- image = (_b = this.removeImageWrapper()) !== null && _b !== void 0 ? _b : image;
29303
+ if (!this.editor.getEnvironment().isSafari) {
29304
+ this.editor.focus(); // Safari will keep the selection when click crop, then the focus() call should not be called
29073
29305
  }
29074
- this.startEditing(this.editor, image, 'crop');
29075
- if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {
29076
- return;
29306
+ var selection = this.editor.getDOMSelection();
29307
+ if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
29308
+ this.applyFormatWithContentModel(this.editor, true /* isCropMode */, false /* shouldSelectImage */);
29077
29309
  }
29078
- this.dndHelpers = (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.CropHandle, cropperContext_1.Cropper, function () {
29079
- if (_this.imageEditInfo &&
29080
- _this.selectedImage &&
29081
- _this.wrapper &&
29082
- _this.clonedImage) {
29083
- (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined, _this.croppers);
29084
- _this.isCropMode = true;
29085
- }
29086
- }, this.zoomScale)), false);
29087
- (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined, this.croppers);
29088
29310
  };
29089
29311
  ImageEditPlugin.prototype.editImage = function (editor, image, apiOperation, operation) {
29090
- var _a;
29091
- if (this.wrapper && this.selectedImage && this.shadowSpan) {
29092
- image = (_a = this.removeImageWrapper()) !== null && _a !== void 0 ? _a : image;
29093
- }
29094
29312
  this.startEditing(editor, image, apiOperation);
29095
29313
  if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {
29096
29314
  return;
29097
29315
  }
29098
29316
  operation(this.imageEditInfo);
29099
29317
  (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper);
29100
- this.formatImageWithContentModel(editor, true /* shouldSelect*/, true /* shouldSelectAsImageSelection*/);
29318
+ this.applyFormatWithContentModel(editor, false /* isCrop */, true /* shouldSelect*/, true /* isApiOperation */);
29101
29319
  };
29102
29320
  ImageEditPlugin.prototype.cleanInfo = function () {
29103
29321
  var _a;
@@ -29117,42 +29335,6 @@ var ImageEditPlugin = /** @class */ (function () {
29117
29335
  this.rotators = [];
29118
29336
  this.croppers = [];
29119
29337
  };
29120
- ImageEditPlugin.prototype.formatImageWithContentModel = function (editor, shouldSelectImage, shouldSelectAsImageSelection) {
29121
- var _this = this;
29122
- if (this.lastSrc &&
29123
- this.selectedImage &&
29124
- this.imageEditInfo &&
29125
- this.clonedImage &&
29126
- this.shadowSpan) {
29127
- editor.formatContentModel(function (model) {
29128
- var selectedSegmentsAndParagraphs = (0, roosterjs_content_model_dom_1.getSelectedSegmentsAndParagraphs)(model, false);
29129
- if (!selectedSegmentsAndParagraphs[0]) {
29130
- return false;
29131
- }
29132
- var segment = selectedSegmentsAndParagraphs[0][0];
29133
- var paragraph = selectedSegmentsAndParagraphs[0][1];
29134
- if (paragraph && segment.segmentType == 'Image') {
29135
- (0, roosterjs_content_model_dom_1.mutateSegment)(paragraph, segment, function (image) {
29136
- if (_this.lastSrc &&
29137
- _this.selectedImage &&
29138
- _this.imageEditInfo &&
29139
- _this.clonedImage) {
29140
- (0, applyChange_1.applyChange)(editor, _this.selectedImage, image, _this.imageEditInfo, _this.lastSrc, _this.wasImageResized || _this.isCropMode, _this.clonedImage);
29141
- image.isSelected = shouldSelectImage;
29142
- image.isSelectedAsImageSelection = shouldSelectAsImageSelection;
29143
- }
29144
- });
29145
- return true;
29146
- }
29147
- return false;
29148
- }, {
29149
- changeSource: IMAGE_EDIT_CHANGE_SOURCE,
29150
- onNodeCreated: function () {
29151
- _this.cleanInfo();
29152
- },
29153
- });
29154
- }
29155
- };
29156
29338
  ImageEditPlugin.prototype.removeImageWrapper = function () {
29157
29339
  var image = null;
29158
29340
  if (this.shadowSpan && this.shadowSpan.parentElement) {
@@ -29175,7 +29357,7 @@ var ImageEditPlugin = /** @class */ (function () {
29175
29357
  }
29176
29358
  var image = selection.image;
29177
29359
  if (this.editor) {
29178
- this.editImage(this.editor, image, 'flip', function (imageEditInfo) {
29360
+ this.editImage(this.editor, image, ['flip'], function (imageEditInfo) {
29179
29361
  var angleRad = imageEditInfo.angleRad || 0;
29180
29362
  var isInVerticalPostion = (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||
29181
29363
  (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);
@@ -29206,15 +29388,19 @@ var ImageEditPlugin = /** @class */ (function () {
29206
29388
  }
29207
29389
  var image = selection.image;
29208
29390
  if (this.editor) {
29209
- this.editImage(this.editor, image, 'rotate', function (imageEditInfo) {
29391
+ this.editImage(this.editor, image, [], function (imageEditInfo) {
29210
29392
  imageEditInfo.angleRad = (imageEditInfo.angleRad || 0) + angleRad;
29211
29393
  });
29212
29394
  }
29213
29395
  };
29214
- //EXPOSED FOR TEST ONLY
29215
- ImageEditPlugin.prototype.getWrapper = function () {
29216
- return this.wrapper;
29217
- };
29396
+ Object.defineProperty(ImageEditPlugin.prototype, "isEditingImage", {
29397
+ //EXPOSED FOR TEST ONLY
29398
+ get: function () {
29399
+ return this.isEditing;
29400
+ },
29401
+ enumerable: false,
29402
+ configurable: true
29403
+ });
29218
29404
  return ImageEditPlugin;
29219
29405
  }());
29220
29406
  exports.ImageEditPlugin = ImageEditPlugin;
@@ -29779,7 +29965,8 @@ var updateImageEditInfo_1 = __webpack_require__(/*! ./updateImageEditInfo */ "./
29779
29965
  function applyChange(editor, image, contentModelImage, editInfo, previousSrc, wasResizedOrCropped, editingImage) {
29780
29966
  var _a;
29781
29967
  var newSrc = '';
29782
- var initEditInfo = (_a = (0, updateImageEditInfo_1.getSelectedImageMetadata)(editor, editingImage !== null && editingImage !== void 0 ? editingImage : image)) !== null && _a !== void 0 ? _a : undefined;
29968
+ var imageEditing = editingImage !== null && editingImage !== void 0 ? editingImage : image;
29969
+ var initEditInfo = (_a = (0, updateImageEditInfo_1.updateImageEditInfo)(contentModelImage, imageEditing)) !== null && _a !== void 0 ? _a : undefined;
29783
29970
  var state = (0, checkEditInfoState_1.checkEditInfoState)(editInfo, initEditInfo);
29784
29971
  switch (state) {
29785
29972
  case 'ResizeOnly':
@@ -29811,12 +29998,12 @@ function applyChange(editor, image, contentModelImage, editInfo, previousSrc, wa
29811
29998
  if (newSrc == editInfo.src) {
29812
29999
  // If newSrc is the same with original one, it means there is only size change, but no rotation, no cropping,
29813
30000
  // so we don't need to keep edit info, we can delete it
29814
- (0, updateImageEditInfo_1.updateImageEditInfo)(contentModelImage, null);
30001
+ (0, updateImageEditInfo_1.updateImageEditInfo)(contentModelImage, imageEditing, null);
29815
30002
  }
29816
30003
  else {
29817
30004
  // Otherwise, save the new edit info to the image so that next time when we edit the same image, we know
29818
30005
  // the edit info
29819
- (0, updateImageEditInfo_1.updateImageEditInfo)(contentModelImage, editInfo);
30006
+ (0, updateImageEditInfo_1.updateImageEditInfo)(contentModelImage, imageEditing, editInfo);
29820
30007
  }
29821
30008
  // Write back the change to image, and set its new size
29822
30009
  var generatedImageSize = (0, generateImageSize_1.getGeneratedImageSize)(editInfo);
@@ -29827,11 +30014,6 @@ function applyChange(editor, image, contentModelImage, editInfo, previousSrc, wa
29827
30014
  if (wasResizedOrCropped || state == 'FullyChanged') {
29828
30015
  contentModelImage.format.width = generatedImageSize.targetWidth + 'px';
29829
30016
  contentModelImage.format.height = generatedImageSize.targetHeight + 'px';
29830
- // Remove width/height style so that it won't affect the image size, since style width/height has higher priority
29831
- image.style.removeProperty('width');
29832
- image.style.removeProperty('height');
29833
- image.style.removeProperty('max-width');
29834
- image.style.removeProperty('max-height');
29835
30017
  }
29836
30018
  }
29837
30019
  exports.applyChange = applyChange;
@@ -29958,25 +30140,27 @@ exports.createImageWrapper = void 0;
29958
30140
  var createImageCropper_1 = __webpack_require__(/*! ../Cropper/createImageCropper */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Cropper/createImageCropper.ts");
29959
30141
  var createImageResizer_1 = __webpack_require__(/*! ../Resizer/createImageResizer */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Resizer/createImageResizer.ts");
29960
30142
  var createImageRotator_1 = __webpack_require__(/*! ../Rotator/createImageRotator */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/Rotator/createImageRotator.ts");
30143
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
29961
30144
  /**
29962
30145
  * @internal
29963
30146
  */
29964
- function createImageWrapper(editor, image, imageSpan, options, editInfo, htmlOptions, operation) {
30147
+ function createImageWrapper(editor, image, options, editInfo, htmlOptions, operation) {
29965
30148
  var imageClone = cloneImage(image, editInfo);
29966
30149
  var doc = editor.getDocument();
29967
30150
  var rotators = [];
29968
- if (!options.disableRotate && operation === 'rotate') {
30151
+ if (!options.disableRotate && operation.indexOf('rotate') > -1) {
29969
30152
  rotators = (0, createImageRotator_1.createImageRotator)(doc, htmlOptions);
29970
30153
  }
29971
30154
  var resizers = [];
29972
- if (operation === 'resize') {
30155
+ if (operation.indexOf('resize') > -1) {
29973
30156
  resizers = (0, createImageResizer_1.createImageResizer)(doc);
29974
30157
  }
29975
30158
  var croppers = [];
29976
- if (operation === 'crop') {
30159
+ if (operation.indexOf('crop') > -1) {
29977
30160
  croppers = (0, createImageCropper_1.createImageCropper)(doc);
29978
30161
  }
29979
30162
  var wrapper = createWrapper(editor, imageClone, options, editInfo, resizers, rotators, croppers);
30163
+ var imageSpan = (0, roosterjs_content_model_dom_1.wrap)(doc, image, 'span');
29980
30164
  var shadowSpan = createShadowSpan(wrapper, imageSpan);
29981
30165
  return { wrapper: wrapper, shadowSpan: shadowSpan, imageClone: imageClone, resizers: resizers, rotators: rotators, croppers: croppers };
29982
30166
  }
@@ -29996,8 +30180,10 @@ var createWrapper = function (editor, image, options, editInfo, resizers, rotato
29996
30180
  var imageBox = doc.createElement('div');
29997
30181
  imageBox.setAttribute("style", "position:relative;width:100%;height:100%;overflow:hidden;transform:scale(1);");
29998
30182
  imageBox.appendChild(image);
29999
- wrapper.setAttribute('style', "max-width: 100%; position: relative; display: inline-flex; font-size: 24px; margin: 0px; transform: rotate(" + ((_a = editInfo.angleRad) !== null && _a !== void 0 ? _a : 0) + "rad); text-align: left;");
30000
- wrapper.style.display = editor.getEnvironment().isSafari ? 'inline-block' : 'inline-flex';
30183
+ wrapper.setAttribute('style', "font-size: 24px; margin: 0px; transform: rotate(" + ((_a = editInfo.angleRad) !== null && _a !== void 0 ? _a : 0) + "rad);");
30184
+ wrapper.style.display = editor.getEnvironment().isSafari
30185
+ ? '-webkit-inline-flex'
30186
+ : 'inline-flex';
30001
30187
  var border = createBorder(editor, options.borderColor);
30002
30188
  wrapper.appendChild(imageBox);
30003
30189
  wrapper.appendChild(border);
@@ -30086,6 +30272,59 @@ function doubleCheckResize(editInfo, preserveRatio, actualWidth, actualHeight) {
30086
30272
  exports.doubleCheckResize = doubleCheckResize;
30087
30273
 
30088
30274
 
30275
+ /***/ }),
30276
+
30277
+ /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/findEditingImage.ts":
30278
+ /*!******************************************************************************************!*\
30279
+ !*** ./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/findEditingImage.ts ***!
30280
+ \******************************************************************************************/
30281
+ /***/ ((__unused_webpack_module, exports) => {
30282
+
30283
+ "use strict";
30284
+
30285
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
30286
+ exports.findEditingImage = void 0;
30287
+ /**
30288
+ * @internal
30289
+ */
30290
+ function findEditingImage(group) {
30291
+ for (var i = 0; i < group.blocks.length; i++) {
30292
+ var block = group.blocks[i];
30293
+ switch (block.blockType) {
30294
+ case 'BlockGroup':
30295
+ var result = findEditingImage(block);
30296
+ if (result) {
30297
+ return result;
30298
+ }
30299
+ break;
30300
+ case 'Paragraph':
30301
+ for (var j = 0; j < block.segments.length; j++) {
30302
+ var segment = block.segments[j];
30303
+ switch (segment.segmentType) {
30304
+ case 'Image':
30305
+ if (segment.dataset.isEditing) {
30306
+ return {
30307
+ paragraph: block,
30308
+ image: segment,
30309
+ };
30310
+ }
30311
+ break;
30312
+ case 'General':
30313
+ var result_1 = findEditingImage(segment);
30314
+ if (result_1) {
30315
+ return result_1;
30316
+ }
30317
+ break;
30318
+ }
30319
+ }
30320
+ break;
30321
+ }
30322
+ }
30323
+ return null;
30324
+ }
30325
+ exports.findEditingImage = findEditingImage;
30326
+
30327
+
30089
30328
  /***/ }),
30090
30329
 
30091
30330
  /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/generateDataURL.ts":
@@ -30270,28 +30509,33 @@ exports.getHTMLImageOptions = getHTMLImageOptions;
30270
30509
 
30271
30510
  /***/ }),
30272
30511
 
30273
- /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedContentModelImage.ts":
30274
- /*!******************************************************************************************************!*\
30275
- !*** ./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedContentModelImage.ts ***!
30276
- \******************************************************************************************************/
30512
+ /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedImage.ts":
30513
+ /*!******************************************************************************************!*\
30514
+ !*** ./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedImage.ts ***!
30515
+ \******************************************************************************************/
30277
30516
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
30278
30517
 
30279
30518
  "use strict";
30280
30519
 
30281
30520
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30282
- exports.getSelectedContentModelImage = void 0;
30521
+ exports.getSelectedImage = void 0;
30283
30522
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
30284
30523
  /**
30285
30524
  * @internal
30286
30525
  */
30287
- function getSelectedContentModelImage(model) {
30288
- var selectedSegments = (0, roosterjs_content_model_dom_1.getSelectedSegments)(model, false /*includeFormatHolder*/);
30289
- if (selectedSegments.length == 1 && selectedSegments[0].segmentType == 'Image') {
30290
- return selectedSegments[0];
30526
+ function getSelectedImage(model) {
30527
+ var selections = (0, roosterjs_content_model_dom_1.getSelectedSegmentsAndParagraphs)(model, false);
30528
+ if (selections.length == 1 && selections[0][0].segmentType == 'Image' && selections[0][1]) {
30529
+ return {
30530
+ image: selections[0][0],
30531
+ paragraph: selections[0][1],
30532
+ };
30533
+ }
30534
+ else {
30535
+ return null;
30291
30536
  }
30292
- return null;
30293
30537
  }
30294
- exports.getSelectedContentModelImage = getSelectedContentModelImage;
30538
+ exports.getSelectedImage = getSelectedImage;
30295
30539
 
30296
30540
 
30297
30541
  /***/ }),
@@ -30406,6 +30650,48 @@ function isFixedNumberValue(value) {
30406
30650
  }
30407
30651
 
30408
30652
 
30653
+ /***/ }),
30654
+
30655
+ /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/normalizeImageSelection.ts":
30656
+ /*!*************************************************************************************************!*\
30657
+ !*** ./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/normalizeImageSelection.ts ***!
30658
+ \*************************************************************************************************/
30659
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
30660
+
30661
+ "use strict";
30662
+
30663
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
30664
+ exports.normalizeImageSelection = void 0;
30665
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
30666
+ /**
30667
+ * Selecting directly on the image will only capture the image segment.
30668
+ * However, if the selection is made while the image is within a wrapper, it will capture the span that encloses the image.
30669
+ * In the last case, the selection will be marked as <---SelectionMarker---><---Image---><---SelectionMarker--->.
30670
+ * To fix this behavior the extra selection markers are removed.
30671
+ * @internal
30672
+ */
30673
+ function normalizeImageSelection(imageAndParagraph) {
30674
+ var paragraph = imageAndParagraph.paragraph;
30675
+ var index = paragraph.segments.indexOf(imageAndParagraph.image);
30676
+ if (index > 0) {
30677
+ var markerBefore = paragraph.segments[index - 1];
30678
+ var markerAfter = paragraph.segments[index + 1];
30679
+ if (markerBefore &&
30680
+ markerAfter &&
30681
+ markerAfter.segmentType == 'SelectionMarker' &&
30682
+ markerBefore.segmentType == 'SelectionMarker' &&
30683
+ markerAfter.isSelected &&
30684
+ markerBefore.isSelected) {
30685
+ var mutatedParagraph = (0, roosterjs_content_model_dom_1.mutateBlock)(paragraph);
30686
+ mutatedParagraph.segments.splice(index - 1, 1);
30687
+ mutatedParagraph.segments.splice(index, 1);
30688
+ }
30689
+ return imageAndParagraph;
30690
+ }
30691
+ }
30692
+ exports.normalizeImageSelection = normalizeImageSelection;
30693
+
30694
+
30409
30695
  /***/ }),
30410
30696
 
30411
30697
  /***/ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/updateHandleCursor.ts":
@@ -30463,18 +30749,19 @@ exports.updateHandleCursor = updateHandleCursor;
30463
30749
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30464
30750
  exports.getSelectedImageMetadata = exports.updateImageEditInfo = void 0;
30465
30751
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
30466
- var getSelectedContentModelImage_1 = __webpack_require__(/*! ./getSelectedContentModelImage */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedContentModelImage.ts");
30752
+ var getSelectedImage_1 = __webpack_require__(/*! ./getSelectedImage */ "./packages/roosterjs-content-model-plugins/lib/imageEdit/utils/getSelectedImage.ts");
30467
30753
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
30468
30754
  /**
30469
30755
  * @internal
30470
30756
  */
30471
- function updateImageEditInfo(contentModelImage, newImageMetadata) {
30472
- (0, roosterjs_content_model_dom_1.updateImageMetadata)(contentModelImage, newImageMetadata !== undefined
30757
+ function updateImageEditInfo(contentModelImage, image, newImageMetadata) {
30758
+ var contentModelMetadata = (0, roosterjs_content_model_dom_1.updateImageMetadata)(contentModelImage, newImageMetadata !== undefined
30473
30759
  ? function (format) {
30474
30760
  format = newImageMetadata;
30475
30761
  return format;
30476
30762
  }
30477
30763
  : undefined);
30764
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getInitialEditInfo(image)), contentModelMetadata);
30478
30765
  }
30479
30766
  exports.updateImageEditInfo = updateImageEditInfo;
30480
30767
  function getInitialEditInfo(image) {
@@ -30498,9 +30785,12 @@ function getInitialEditInfo(image) {
30498
30785
  function getSelectedImageMetadata(editor, image) {
30499
30786
  var imageMetadata = getInitialEditInfo(image);
30500
30787
  editor.formatContentModel(function (model) {
30501
- var selectedImage = (0, getSelectedContentModelImage_1.getSelectedContentModelImage)(model);
30502
- if (selectedImage) {
30503
- imageMetadata = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, imageMetadata), selectedImage.dataset);
30788
+ var selectedImage = (0, getSelectedImage_1.getSelectedImage)(model);
30789
+ if (selectedImage === null || selectedImage === void 0 ? void 0 : selectedImage.image) {
30790
+ (0, roosterjs_content_model_dom_1.mutateSegment)(selectedImage.paragraph, selectedImage === null || selectedImage === void 0 ? void 0 : selectedImage.image, function (modelImage) {
30791
+ imageMetadata = updateImageEditInfo(modelImage, image);
30792
+ });
30793
+ return true;
30504
30794
  }
30505
30795
  return false;
30506
30796
  });
@@ -30580,7 +30870,7 @@ function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers,
30580
30870
  (0, imageEditUtils_1.setSize)(cropOverlays[1], undefined, 0, 0, cropBottomPx, cropRightPx, undefined);
30581
30871
  (0, imageEditUtils_1.setSize)(cropOverlays[2], cropLeftPx, undefined, 0, 0, undefined, cropBottomPx);
30582
30872
  (0, imageEditUtils_1.setSize)(cropOverlays[3], 0, cropTopPx, undefined, 0, cropLeftPx, undefined);
30583
- if (angleRad) {
30873
+ if (angleRad !== undefined) {
30584
30874
  (0, updateHandleCursor_1.updateHandleCursor)(croppers, angleRad);
30585
30875
  }
30586
30876
  }
@@ -30597,7 +30887,7 @@ function updateWrapper(editInfo, options, image, clonedImage, wrapper, resizers,
30597
30887
  }
30598
30888
  })
30599
30889
  .filter(function (handle) { return !!handle; });
30600
- if (angleRad) {
30890
+ if (angleRad !== undefined) {
30601
30891
  (0, updateHandleCursor_1.updateHandleCursor)(resizeHandles, angleRad);
30602
30892
  }
30603
30893
  (0, updateSideHandlesVisibility_1.updateSideHandlesVisibility)(resizeHandles, smallImage);
@@ -30617,11 +30907,13 @@ exports.updateWrapper = updateWrapper;
30617
30907
  "use strict";
30618
30908
 
30619
30909
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30620
- exports.ImageEditPlugin = exports.CustomReplacePlugin = exports.PickerPlugin = exports.HyperlinkPlugin = exports.MarkdownPlugin = exports.WatermarkPlugin = exports.ContextMenuPluginBase = exports.ShortcutPlugin = exports.ShortcutOutdentList = exports.ShortcutIndentList = exports.ShortcutDecreaseFont = exports.ShortcutIncreaseFont = exports.ShortcutNumbering = exports.ShortcutBullet = exports.ShortcutRedoMacOS = exports.ShortcutRedoAlt = exports.ShortcutRedo = exports.ShortcutUndo2 = exports.ShortcutUndo = exports.ShortcutClearFormat = exports.ShortcutUnderline = exports.ShortcutItalic = exports.ShortcutBold = exports.AutoFormatPlugin = exports.EditPlugin = exports.PastePlugin = exports.TableEditPlugin = void 0;
30910
+ exports.ImageEditPlugin = exports.CustomReplacePlugin = exports.PickerPlugin = exports.HyperlinkPlugin = exports.MarkdownPlugin = exports.WatermarkPlugin = exports.ContextMenuPluginBase = exports.ShortcutPlugin = exports.ShortcutOutdentList = exports.ShortcutIndentList = exports.ShortcutDecreaseFont = exports.ShortcutIncreaseFont = exports.ShortcutNumbering = exports.ShortcutBullet = exports.ShortcutRedoMacOS = exports.ShortcutRedoAlt = exports.ShortcutRedo = exports.ShortcutUndo2 = exports.ShortcutUndo = exports.ShortcutClearFormat = exports.ShortcutUnderline = exports.ShortcutItalic = exports.ShortcutBold = exports.AutoFormatPlugin = exports.EditPlugin = exports.DefaultSanitizers = exports.PastePlugin = exports.TableEditPlugin = void 0;
30621
30911
  var TableEditPlugin_1 = __webpack_require__(/*! ./tableEdit/TableEditPlugin */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/TableEditPlugin.ts");
30622
30912
  Object.defineProperty(exports, "TableEditPlugin", ({ enumerable: true, get: function () { return TableEditPlugin_1.TableEditPlugin; } }));
30623
30913
  var PastePlugin_1 = __webpack_require__(/*! ./paste/PastePlugin */ "./packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts");
30624
30914
  Object.defineProperty(exports, "PastePlugin", ({ enumerable: true, get: function () { return PastePlugin_1.PastePlugin; } }));
30915
+ var DefaultSanitizers_1 = __webpack_require__(/*! ./paste/DefaultSanitizers */ "./packages/roosterjs-content-model-plugins/lib/paste/DefaultSanitizers.ts");
30916
+ Object.defineProperty(exports, "DefaultSanitizers", ({ enumerable: true, get: function () { return DefaultSanitizers_1.DefaultSanitizers; } }));
30625
30917
  var EditPlugin_1 = __webpack_require__(/*! ./edit/EditPlugin */ "./packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts");
30626
30918
  Object.defineProperty(exports, "EditPlugin", ({ enumerable: true, get: function () { return EditPlugin_1.EditPlugin; } }));
30627
30919
  var AutoFormatPlugin_1 = __webpack_require__(/*! ./autoFormat/AutoFormatPlugin */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts");
@@ -30880,7 +31172,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
30880
31172
  exports.setFormat = void 0;
30881
31173
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
30882
31174
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
30883
- var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
30884
31175
  /**
30885
31176
  * @internal
30886
31177
  */
@@ -30895,7 +31186,7 @@ function setFormat(editor, character, format, codeFormat) {
30895
31186
  .substring(0, lastCharIndex - 1)
30896
31187
  .lastIndexOf(character);
30897
31188
  if (lastCharIndex - firstCharIndex > 2) {
30898
- var formattedText = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, firstCharIndex, lastCharIndex);
31189
+ var formattedText = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, firstCharIndex, lastCharIndex);
30899
31190
  formattedText.text = formattedText.text.replace(character, '').slice(0, -1);
30900
31191
  formattedText.format = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, formattedText.format), format);
30901
31192
  if (codeFormat) {
@@ -30927,7 +31218,7 @@ exports.setFormat = setFormat;
30927
31218
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30928
31219
  exports.divParagraphSanitizer = exports.DefaultSanitizers = void 0;
30929
31220
  /**
30930
- * @internal
31221
+ * Default style sanitizers for PastePlugin.
30931
31222
  */
30932
31223
  exports.DefaultSanitizers = {
30933
31224
  width: divParagraphSanitizer,
@@ -32704,7 +32995,7 @@ exports.PickerPlugin = PickerPlugin;
32704
32995
 
32705
32996
  Object.defineProperty(exports, "__esModule", ({ value: true }));
32706
32997
  exports.getQueryString = void 0;
32707
- var splitTextSegment_1 = __webpack_require__(/*! ../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
32998
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
32708
32999
  /**
32709
33000
  * @internal
32710
33001
  */
@@ -32721,7 +33012,7 @@ function getQueryString(triggerCharacter, paragraph, previousSegment, splittedSe
32721
33012
  if (index >= 0) {
32722
33013
  result = segment.text.substring(index) + result;
32723
33014
  splittedSegmentResult === null || splittedSegmentResult === void 0 ? void 0 : splittedSegmentResult.unshift(index > 0
32724
- ? (0, splitTextSegment_1.splitTextSegment)(segment, paragraph, index, segment.text.length)
33015
+ ? (0, roosterjs_content_model_api_1.splitTextSegment)(segment, paragraph, index, segment.text.length)
32725
33016
  : segment);
32726
33017
  break;
32727
33018
  }
@@ -32987,42 +33278,6 @@ function getIntersectedRect(elements, additionalRects) {
32987
33278
  exports.getIntersectedRect = getIntersectedRect;
32988
33279
 
32989
33280
 
32990
- /***/ }),
32991
-
32992
- /***/ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts":
32993
- /*!**************************************************************************************!*\
32994
- !*** ./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts ***!
32995
- \**************************************************************************************/
32996
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
32997
-
32998
- "use strict";
32999
-
33000
- Object.defineProperty(exports, "__esModule", ({ value: true }));
33001
- exports.splitTextSegment = void 0;
33002
- var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
33003
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
33004
- /**
33005
- * @internal
33006
- */
33007
- function splitTextSegment(textSegment, parent, start, end) {
33008
- var _a;
33009
- var text = textSegment.text;
33010
- var index = parent.segments.indexOf(textSegment);
33011
- var middleSegment = (0, roosterjs_content_model_dom_1.createText)(text.substring(start, end), textSegment.format, textSegment.link, textSegment.code);
33012
- var newSegments = [middleSegment];
33013
- if (start > 0) {
33014
- newSegments.unshift((0, roosterjs_content_model_dom_1.createText)(text.substring(0, start), textSegment.format, textSegment.link, textSegment.code));
33015
- }
33016
- if (end < text.length) {
33017
- newSegments.push((0, roosterjs_content_model_dom_1.createText)(text.substring(end), textSegment.format, textSegment.link, textSegment.code));
33018
- }
33019
- newSegments.forEach(function (segment) { return (segment.isSelected = textSegment.isSelected); });
33020
- (_a = parent.segments).splice.apply(_a, (0, tslib_1.__spreadArray)([index, 1], (0, tslib_1.__read)(newSegments), false));
33021
- return middleSegment;
33022
- }
33023
- exports.splitTextSegment = splitTextSegment;
33024
-
33025
-
33026
33281
  /***/ }),
33027
33282
 
33028
33283
  /***/ "./packages/roosterjs-content-model-plugins/lib/shortcut/ShortcutPlugin.ts":
@@ -33710,8 +33965,10 @@ var TableEditor = /** @class */ (function () {
33710
33965
  _this.disposeTableInserter();
33711
33966
  _this.disposeCellResizers();
33712
33967
  };
33713
- this.onEndTableMove = function () {
33714
- _this.disposeTableMover();
33968
+ this.onEndTableMove = function (disposeHandler) {
33969
+ if (disposeHandler) {
33970
+ _this.disposeTableMover();
33971
+ }
33715
33972
  return _this.onFinishEditing();
33716
33973
  };
33717
33974
  this.onInserted = function () {
@@ -34485,9 +34742,9 @@ function onDragEnd(context, event, initValue) {
34485
34742
  // Reset cursor
34486
34743
  setTableMoverCursor(editor, false);
34487
34744
  if (element == context.div) {
34488
- // Table mover was only clicked, select whole table
34745
+ // Table mover was only clicked, select whole table and do not dismiss the handler element.
34489
34746
  selectWholeTable(table);
34490
- context.onEnd();
34747
+ context.onEnd(false /* disposeHandler */);
34491
34748
  return true;
34492
34749
  }
34493
34750
  else {
@@ -34496,7 +34753,7 @@ function onDragEnd(context, event, initValue) {
34496
34753
  !editor.getDOMHelper().isNodeInEditor(element) ||
34497
34754
  disableMovement) {
34498
34755
  editor.setDOMSelection((_a = initValue === null || initValue === void 0 ? void 0 : initValue.initialSelection) !== null && _a !== void 0 ? _a : null);
34499
- context.onEnd();
34756
+ context.onEnd(true /* disposeHandler */);
34500
34757
  return false;
34501
34758
  }
34502
34759
  var insertionSuccess_1 = false;
@@ -34554,7 +34811,7 @@ function onDragEnd(context, event, initValue) {
34554
34811
  // No movement, restore initial selection
34555
34812
  editor.setDOMSelection((_b = initValue === null || initValue === void 0 ? void 0 : initValue.initialSelection) !== null && _b !== void 0 ? _b : null);
34556
34813
  }
34557
- context.onEnd();
34814
+ context.onEnd(true /* disposeHandler */);
34558
34815
  return insertionSuccess_1;
34559
34816
  }
34560
34817
  }
@@ -34812,6 +35069,7 @@ exports.getCMTableFromTable = getCMTableFromTable;
34812
35069
 
34813
35070
  Object.defineProperty(exports, "__esModule", ({ value: true }));
34814
35071
  exports.WatermarkPlugin = void 0;
35072
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
34815
35073
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
34816
35074
  var isModelEmptyFast_1 = __webpack_require__(/*! ./isModelEmptyFast */ "./packages/roosterjs-content-model-plugins/lib/watermark/isModelEmptyFast.ts");
34817
35075
  var WATERMARK_CONTENT_KEY = '_WatermarkContent';
@@ -34832,6 +35090,7 @@ var WatermarkPlugin = /** @class */ (function () {
34832
35090
  this.watermark = watermark;
34833
35091
  this.editor = null;
34834
35092
  this.isShowing = false;
35093
+ this.darkTextColor = null;
34835
35094
  this.format = format || {
34836
35095
  fontSize: '14px',
34837
35096
  textColor: '#AAAAAA',
@@ -34871,6 +35130,21 @@ var WatermarkPlugin = /** @class */ (function () {
34871
35130
  // When input text, editor must not be empty, so we can do hide watermark now without checking content model
34872
35131
  this.showHide(editor, false /*isEmpty*/);
34873
35132
  }
35133
+ else if (event.eventType == 'contentChanged' &&
35134
+ (event.source == roosterjs_content_model_dom_1.ChangeSource.SwitchToDarkMode ||
35135
+ event.source == roosterjs_content_model_dom_1.ChangeSource.SwitchToLightMode) &&
35136
+ this.isShowing) {
35137
+ // When the placeholder is shown and user switches the mode, we need to update watermark style
35138
+ if (event.source == roosterjs_content_model_dom_1.ChangeSource.SwitchToDarkMode &&
35139
+ !this.darkTextColor &&
35140
+ this.format.textColor) {
35141
+ // Get the dark color only once when dark mode is enabled for the first time
35142
+ this.darkTextColor = editor
35143
+ .getColorManager()
35144
+ .getDarkColor(this.format.textColor, undefined, 'text');
35145
+ }
35146
+ this.applyWatermarkStyle(editor);
35147
+ }
34874
35148
  else if (event.eventType == 'editorReady' ||
34875
35149
  event.eventType == 'contentChanged' ||
34876
35150
  event.eventType == 'input' ||
@@ -34891,15 +35165,18 @@ var WatermarkPlugin = /** @class */ (function () {
34891
35165
  }
34892
35166
  };
34893
35167
  WatermarkPlugin.prototype.show = function (editor) {
34894
- var _this = this;
35168
+ this.applyWatermarkStyle(editor);
35169
+ this.isShowing = true;
35170
+ };
35171
+ WatermarkPlugin.prototype.applyWatermarkStyle = function (editor) {
34895
35172
  var rule = "position: absolute; pointer-events: none; content: \"" + this.watermark + "\";";
35173
+ var format = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, this.format), { textColor: editor.isDarkMode() ? this.darkTextColor : this.format.textColor });
34896
35174
  (0, roosterjs_content_model_dom_1.getObjectKeys)(styleMap).forEach(function (x) {
34897
- if (_this.format[x]) {
34898
- rule += styleMap[x] + ": " + _this.format[x] + "!important;";
35175
+ if (format[x]) {
35176
+ rule += styleMap[x] + ": " + format[x] + "!important;";
34899
35177
  }
34900
35178
  });
34901
35179
  editor.setEditorStyle(WATERMARK_CONTENT_KEY, rule, 'before');
34902
- this.isShowing = true;
34903
35180
  };
34904
35181
  WatermarkPlugin.prototype.hide = function (editor) {
34905
35182
  editor.setEditorStyle(WATERMARK_CONTENT_KEY, null);