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