roosterjs 8.31.0 → 8.32.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.
@@ -3061,6 +3061,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3061
3061
  var blockFormat_1 = __webpack_require__(/*! ../utils/blockFormat */ "./packages/roosterjs-editor-api/lib/utils/blockFormat.ts");
3062
3062
  var execCommand_1 = __webpack_require__(/*! ../utils/execCommand */ "./packages/roosterjs-editor-api/lib/utils/execCommand.ts");
3063
3063
  var formatUndoSnapshot_1 = __webpack_require__(/*! ../utils/formatUndoSnapshot */ "./packages/roosterjs-editor-api/lib/utils/formatUndoSnapshot.ts");
3064
+ var normalizeBlockquote_1 = __webpack_require__(/*! ../utils/normalizeBlockquote */ "./packages/roosterjs-editor-api/lib/utils/normalizeBlockquote.ts");
3064
3065
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
3065
3066
  /**
3066
3067
  * Set content alignment
@@ -3129,7 +3130,14 @@ function alignText(editor, alignment) {
3129
3130
  align = 'right';
3130
3131
  }
3131
3132
  (0, execCommand_1.default)(editor, command);
3132
- editor.queryElements('[align]', 1 /* OnSelection */, function (node) { return (node.style.textAlign = align); });
3133
+ var elements = editor.queryElements('[align]', 1 /* OnSelection */, function (node) {
3134
+ node.style.textAlign = align;
3135
+ (0, normalizeBlockquote_1.default)(node);
3136
+ });
3137
+ if (elements.length == 0) {
3138
+ var node = editor.getElementAtCursor();
3139
+ (0, normalizeBlockquote_1.default)(node);
3140
+ }
3133
3141
  }
3134
3142
  function isList(element) {
3135
3143
  return (0, roosterjs_editor_dom_1.findClosestElementAncestor)(element, undefined /** root */, 'LI');
@@ -3318,6 +3326,7 @@ exports.default = setImageAltText;
3318
3326
 
3319
3327
  Object.defineProperty(exports, "__esModule", { value: true });
3320
3328
  var blockFormat_1 = __webpack_require__(/*! ../utils/blockFormat */ "./packages/roosterjs-editor-api/lib/utils/blockFormat.ts");
3329
+ var normalizeBlockquote_1 = __webpack_require__(/*! ../utils/normalizeBlockquote */ "./packages/roosterjs-editor-api/lib/utils/normalizeBlockquote.ts");
3321
3330
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
3322
3331
  /**
3323
3332
  * Set indentation at selection
@@ -3350,7 +3359,7 @@ function setIndentation(editor, indentation) {
3350
3359
  indentation == 1 /* Decrease */
3351
3360
  ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3352
3361
  : vList.setIndentation(start, end, indentation);
3353
- vList.writeBack();
3362
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
3354
3363
  blockGroups.push([]);
3355
3364
  }
3356
3365
  }
@@ -3374,12 +3383,14 @@ function setIndentation(editor, indentation) {
3374
3383
  }
3375
3384
  return true;
3376
3385
  }, 'setIndentation');
3386
+ function indent(region, blocks) {
3387
+ var nodes = (0, roosterjs_editor_dom_1.collapseNodesInRegion)(region, blocks);
3388
+ (0, roosterjs_editor_dom_1.wrap)(nodes, 2 /* BlockquoteWrapper */);
3389
+ var quotesHandled = [];
3390
+ nodes.forEach(function (node) { return (0, normalizeBlockquote_1.default)(node, quotesHandled); });
3391
+ }
3377
3392
  }
3378
3393
  exports.default = setIndentation;
3379
- function indent(region, blocks) {
3380
- var nodes = (0, roosterjs_editor_dom_1.collapseNodesInRegion)(region, blocks);
3381
- (0, roosterjs_editor_dom_1.wrap)(nodes, 2 /* BlockquoteWrapper */);
3382
- }
3383
3394
  function outdent(region, blocks) {
3384
3395
  blocks.forEach(function (blockElement) {
3385
3396
  var node = blockElement.collapseToSingleElement();
@@ -3436,7 +3447,7 @@ function setOrderedListNumbering(editor, separator, startNumber) {
3436
3447
  var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(regions[0], false /*includeSiblingLists*/, separator);
3437
3448
  if (vList) {
3438
3449
  vList.split(separator, startNumber);
3439
- vList.writeBack();
3450
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
3440
3451
  }
3441
3452
  }
3442
3453
  }, 'setOrderedListNumbering');
@@ -3944,8 +3955,6 @@ Object.defineProperty(exports, "experimentCommitListChains", { enumerable: true,
3944
3955
  Object.defineProperty(exports, "__esModule", { value: true });
3945
3956
  var formatUndoSnapshot_1 = __webpack_require__(/*! ../utils/formatUndoSnapshot */ "./packages/roosterjs-editor-api/lib/utils/formatUndoSnapshot.ts");
3946
3957
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
3947
- var TEMP_BACKGROUND_COLOR = 'originalBackgroundColor';
3948
- var CELL_SHADE = 'cellShade';
3949
3958
  /**
3950
3959
  * Set background color of cells.
3951
3960
  * @param editor The editor instance
@@ -3958,9 +3967,7 @@ function applyCellShading(editor, color) {
3958
3967
  regions.forEach(function (region) {
3959
3968
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(region.rootNode, 'HTMLTableCellElement')) {
3960
3969
  (0, roosterjs_editor_dom_1.setColor)(region.rootNode, color, true /* isBackgroundColor */, editor.isDarkMode(), true /** shouldAdaptFontColor */);
3961
- region.rootNode.dataset[CELL_SHADE] = 'true';
3962
- region.rootNode.dataset[TEMP_BACKGROUND_COLOR] =
3963
- region.rootNode.style.backgroundColor;
3970
+ (0, roosterjs_editor_dom_1.saveTableCellMetadata)(region.rootNode, { bgColorOverride: true });
3964
3971
  }
3965
3972
  });
3966
3973
  }, 'applyCellShading');
@@ -4433,7 +4440,8 @@ function commitListChains(editor, chains) {
4433
4440
  var range = editor.getSelectionRange();
4434
4441
  var start = range && roosterjs_editor_dom_1.Position.getStart(range);
4435
4442
  var end = range && roosterjs_editor_dom_1.Position.getEnd(range);
4436
- chains.forEach(function (chain) { return chain.commit(); });
4443
+ var shouldReuseAllAncestorListElements_1 = editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */);
4444
+ chains.forEach(function (chain) { return chain.commit(shouldReuseAllAncestorListElements_1); });
4437
4445
  editor.select(start, end);
4438
4446
  }
4439
4447
  }
@@ -4532,6 +4540,61 @@ function formatUndoSnapshot(editor, callback, apiName) {
4532
4540
  exports.default = formatUndoSnapshot;
4533
4541
 
4534
4542
 
4543
+ /***/ }),
4544
+
4545
+ /***/ "./packages/roosterjs-editor-api/lib/utils/normalizeBlockquote.ts":
4546
+ /*!************************************************************************!*\
4547
+ !*** ./packages/roosterjs-editor-api/lib/utils/normalizeBlockquote.ts ***!
4548
+ \************************************************************************/
4549
+ /*! no static exports found */
4550
+ /***/ (function(module, exports, __webpack_require__) {
4551
+
4552
+ "use strict";
4553
+
4554
+ Object.defineProperty(exports, "__esModule", { value: true });
4555
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
4556
+ /**
4557
+ * @internal
4558
+ * @param node start node to normalize
4559
+ * @param quotesHandled Optional parameter to prevent already modified quotes to be rechecked.
4560
+ * @returns
4561
+ */
4562
+ function normalizeBlockquote(node, quotesHandled) {
4563
+ if ((0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLElement')) {
4564
+ var alignment = node.style.textAlign;
4565
+ var quote = (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, undefined /* root */, 'blockquote');
4566
+ var isNodeRTL = isRTL(node);
4567
+ if (quotesHandled) {
4568
+ if (quotesHandled.indexOf(quote) > -1) {
4569
+ return;
4570
+ }
4571
+ quotesHandled.push(quote);
4572
+ }
4573
+ while (quote) {
4574
+ if (alignment == 'center') {
4575
+ if (isNodeRTL) {
4576
+ delete quote.style.marginInlineEnd;
4577
+ quote.style.marginInlineStart = 'auto';
4578
+ }
4579
+ else {
4580
+ delete quote.style.marginInlineStart;
4581
+ quote.style.marginInlineEnd = 'auto';
4582
+ }
4583
+ }
4584
+ else {
4585
+ delete quote.style.marginInlineStart;
4586
+ delete quote.style.marginInlineEnd;
4587
+ }
4588
+ quote = (0, roosterjs_editor_dom_1.findClosestElementAncestor)(quote.parentElement, undefined /* root */, 'blockquote');
4589
+ }
4590
+ }
4591
+ }
4592
+ exports.default = normalizeBlockquote;
4593
+ function isRTL(el) {
4594
+ return (0, roosterjs_editor_dom_1.getComputedStyle)(el, 'direction') == 'rtl' || el.getAttribute('dir') == 'rtl';
4595
+ }
4596
+
4597
+
4535
4598
  /***/ }),
4536
4599
 
4537
4600
  /***/ "./packages/roosterjs-editor-api/lib/utils/toggleListType.ts":
@@ -4579,7 +4642,7 @@ function toggleListType(editor, listType, startNumber, includeSiblingLists, orde
4579
4642
  if (editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
4580
4643
  vList.setListStyleType(orderedStyle, unorderedStyle);
4581
4644
  }
4582
- vList.writeBack();
4645
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
4583
4646
  }
4584
4647
  }, undefined /* beforeRunCallback */, apiNameOverride || 'toggleListType');
4585
4648
  }
@@ -4765,6 +4828,7 @@ var getStyleBasedFormatState_1 = __webpack_require__(/*! ./getStyleBasedFormatSt
4765
4828
  var hasFocus_1 = __webpack_require__(/*! ./hasFocus */ "./packages/roosterjs-editor-core/lib/coreApi/hasFocus.ts");
4766
4829
  var insertNode_1 = __webpack_require__(/*! ./insertNode */ "./packages/roosterjs-editor-core/lib/coreApi/insertNode.ts");
4767
4830
  var restoreUndoSnapshot_1 = __webpack_require__(/*! ./restoreUndoSnapshot */ "./packages/roosterjs-editor-core/lib/coreApi/restoreUndoSnapshot.ts");
4831
+ var selectImage_1 = __webpack_require__(/*! ./selectImage */ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts");
4768
4832
  var selectRange_1 = __webpack_require__(/*! ./selectRange */ "./packages/roosterjs-editor-core/lib/coreApi/selectRange.ts");
4769
4833
  var selectTable_1 = __webpack_require__(/*! ./selectTable */ "./packages/roosterjs-editor-core/lib/coreApi/selectTable.ts");
4770
4834
  var setContent_1 = __webpack_require__(/*! ./setContent */ "./packages/roosterjs-editor-core/lib/coreApi/setContent.ts");
@@ -4794,6 +4858,7 @@ exports.coreApiMap = {
4794
4858
  transformColor: transformColor_1.transformColor,
4795
4859
  triggerEvent: triggerEvent_1.triggerEvent,
4796
4860
  selectTable: selectTable_1.selectTable,
4861
+ selectImage: selectImage_1.selectImage,
4797
4862
  };
4798
4863
 
4799
4864
 
@@ -4975,11 +5040,14 @@ function getCurrentFormat(core, node) {
4975
5040
  };
4976
5041
  }
4977
5042
  function createBeforePasteEvent(core, clipboardData) {
5043
+ var options = (0, roosterjs_editor_dom_1.createDefaultHtmlSanitizerOptions)();
5044
+ // Remove "caret-color" style generated by Safari to make sure caret shows in right color after paste
5045
+ options.cssStyleCallbacks['caret-color'] = function () { return false; };
4978
5046
  return {
4979
5047
  eventType: 10 /* BeforePaste */,
4980
5048
  clipboardData: clipboardData,
4981
5049
  fragment: core.contentDiv.ownerDocument.createDocumentFragment(),
4982
- sanitizingOption: (0, roosterjs_editor_dom_1.createDefaultHtmlSanitizerOptions)(),
5050
+ sanitizingOption: options,
4983
5051
  htmlBefore: '',
4984
5052
  htmlAfter: '',
4985
5053
  htmlAttributes: {},
@@ -5363,10 +5431,10 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
5363
5431
  * @returns A Range object of the selection range
5364
5432
  */
5365
5433
  var getSelectionRangeEx = function (core) {
5366
- var _a, _b;
5434
+ var _a, _b, _c;
5367
5435
  var result = null;
5368
5436
  if (core.lifecycle.shadowEditFragment) {
5369
- var _c = core.lifecycle, shadowEditTableSelectionPath = _c.shadowEditTableSelectionPath, shadowEditSelectionPath = _c.shadowEditSelectionPath;
5437
+ var _d = core.lifecycle, shadowEditTableSelectionPath = _d.shadowEditTableSelectionPath, shadowEditSelectionPath = _d.shadowEditSelectionPath, shadowEditImageSelectionPath = _d.shadowEditImageSelectionPath;
5370
5438
  if (((shadowEditTableSelectionPath === null || shadowEditTableSelectionPath === void 0 ? void 0 : shadowEditTableSelectionPath.length) || 0) > 0) {
5371
5439
  var ranges = core.lifecycle.shadowEditTableSelectionPath.map(function (path) {
5372
5440
  return (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, path.start, path.end);
@@ -5379,6 +5447,18 @@ var getSelectionRangeEx = function (core) {
5379
5447
  coordinates: undefined,
5380
5448
  };
5381
5449
  }
5450
+ else if (((shadowEditImageSelectionPath === null || shadowEditImageSelectionPath === void 0 ? void 0 : shadowEditImageSelectionPath.length) || 0) > 0) {
5451
+ var ranges = core.lifecycle.shadowEditImageSelectionPath.map(function (path) {
5452
+ return (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, path.start, path.end);
5453
+ });
5454
+ return {
5455
+ type: 2 /* ImageSelection */,
5456
+ ranges: ranges,
5457
+ areAllCollapsed: checkAllCollapsed(ranges),
5458
+ image: (0, roosterjs_editor_dom_1.findClosestElementAncestor)(ranges[0].startContainer, core.contentDiv, 'img'),
5459
+ imageId: undefined,
5460
+ };
5461
+ }
5382
5462
  else {
5383
5463
  var shadowRange = shadowEditSelectionPath &&
5384
5464
  (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, shadowEditSelectionPath.start, shadowEditSelectionPath.end);
@@ -5390,6 +5470,9 @@ var getSelectionRangeEx = function (core) {
5390
5470
  if (core.domEvent.tableSelectionRange) {
5391
5471
  return core.domEvent.tableSelectionRange;
5392
5472
  }
5473
+ if (core.domEvent.imageSelectionRange) {
5474
+ return core.domEvent.imageSelectionRange;
5475
+ }
5393
5476
  var selection = (_a = core.contentDiv.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
5394
5477
  if (!result && selection && selection.rangeCount > 0) {
5395
5478
  var range = selection.getRangeAt(0);
@@ -5398,7 +5481,7 @@ var getSelectionRangeEx = function (core) {
5398
5481
  }
5399
5482
  }
5400
5483
  }
5401
- return ((_b = core.domEvent.tableSelectionRange) !== null && _b !== void 0 ? _b : createNormalSelectionEx(core.domEvent.selectionRange ? [core.domEvent.selectionRange] : []));
5484
+ return ((_c = (_b = core.domEvent.tableSelectionRange) !== null && _b !== void 0 ? _b : core.domEvent.imageSelectionRange) !== null && _c !== void 0 ? _c : createNormalSelectionEx(core.domEvent.selectionRange ? [core.domEvent.selectionRange] : []));
5402
5485
  }
5403
5486
  };
5404
5487
  exports.getSelectionRangeEx = getSelectionRangeEx;
@@ -5708,6 +5791,71 @@ var restoreUndoSnapshot = function (core, step) {
5708
5791
  exports.restoreUndoSnapshot = restoreUndoSnapshot;
5709
5792
 
5710
5793
 
5794
+ /***/ }),
5795
+
5796
+ /***/ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts":
5797
+ /*!*******************************************************************!*\
5798
+ !*** ./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts ***!
5799
+ \*******************************************************************/
5800
+ /*! no static exports found */
5801
+ /***/ (function(module, exports, __webpack_require__) {
5802
+
5803
+ "use strict";
5804
+
5805
+ Object.defineProperty(exports, "__esModule", { value: true });
5806
+ exports.selectImage = void 0;
5807
+ var addSelectionStyle_1 = __webpack_require__(/*! ./utils/addSelectionStyle */ "./packages/roosterjs-editor-core/lib/coreApi/utils/addSelectionStyle.ts");
5808
+ var addUniqueId_1 = __webpack_require__(/*! ./utils/addUniqueId */ "./packages/roosterjs-editor-core/lib/coreApi/utils/addUniqueId.ts");
5809
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5810
+ var IMAGE_ID = 'imageSelected';
5811
+ var CONTENT_DIV_ID = 'contentDiv_';
5812
+ var STYLE_ID = 'imageStyle';
5813
+ /**
5814
+ * @internal
5815
+ * Select a image and save data of the selected range
5816
+ * @param image Image to select
5817
+ * @returns Selected image information
5818
+ */
5819
+ var selectImage = function (core, image) {
5820
+ unselect(core);
5821
+ if (image) {
5822
+ var range = (0, roosterjs_editor_dom_1.createRange)(image);
5823
+ (0, addUniqueId_1.default)(image, IMAGE_ID);
5824
+ (0, addUniqueId_1.default)(core.contentDiv, CONTENT_DIV_ID);
5825
+ select(core, image);
5826
+ return {
5827
+ type: 2 /* ImageSelection */,
5828
+ ranges: [range],
5829
+ image: image,
5830
+ areAllCollapsed: range.collapsed,
5831
+ };
5832
+ }
5833
+ return null;
5834
+ };
5835
+ exports.selectImage = selectImage;
5836
+ var select = function (core, image) {
5837
+ var borderCSS = buildBorderCSS(core, image.id);
5838
+ (0, addSelectionStyle_1.default)(core, borderCSS, STYLE_ID);
5839
+ };
5840
+ var buildBorderCSS = function (core, imageId) {
5841
+ var borderColor = core.imageSelectionBorderColor || '#DB626C';
5842
+ return ('#' +
5843
+ core.contentDiv.id +
5844
+ ' #' +
5845
+ imageId +
5846
+ ' { margin: -2px; border: 2px solid' +
5847
+ borderColor +
5848
+ ' !important; }');
5849
+ };
5850
+ var unselect = function (core) {
5851
+ var doc = core.contentDiv.ownerDocument;
5852
+ var styleTag = doc.getElementById(STYLE_ID + core.contentDiv.id);
5853
+ if (styleTag) {
5854
+ doc.head.removeChild(styleTag);
5855
+ }
5856
+ };
5857
+
5858
+
5711
5859
  /***/ }),
5712
5860
 
5713
5861
  /***/ "./packages/roosterjs-editor-core/lib/coreApi/selectRange.ts":
@@ -5785,6 +5933,8 @@ function restorePendingFormatState(core) {
5785
5933
 
5786
5934
  Object.defineProperty(exports, "__esModule", { value: true });
5787
5935
  exports.selectTable = void 0;
5936
+ var addSelectionStyle_1 = __webpack_require__(/*! ./utils/addSelectionStyle */ "./packages/roosterjs-editor-core/lib/coreApi/utils/addSelectionStyle.ts");
5937
+ var addUniqueId_1 = __webpack_require__(/*! ./utils/addUniqueId */ "./packages/roosterjs-editor-core/lib/coreApi/utils/addUniqueId.ts");
5788
5938
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5789
5939
  var TABLE_ID = 'tableSelected';
5790
5940
  var CONTENT_DIV_ID = 'contentDiv_';
@@ -5802,8 +5952,8 @@ var selectTable = function (core, table, coordinates) {
5802
5952
  var _a;
5803
5953
  unselect(core);
5804
5954
  if (areValidCoordinates(coordinates) && table) {
5805
- ensureUniqueId(table, TABLE_ID);
5806
- ensureUniqueId(core.contentDiv, CONTENT_DIV_ID);
5955
+ (0, addUniqueId_1.default)(table, TABLE_ID);
5956
+ (0, addUniqueId_1.default)(core.contentDiv, CONTENT_DIV_ID);
5807
5957
  var ranges = select(core, table, coordinates);
5808
5958
  if (!isMergedCell(table, coordinates)) {
5809
5959
  var cellToSelect = (_a = table.rows
@@ -5889,17 +6039,9 @@ function buildCss(table, coordinates, contentDivSelector) {
5889
6039
  return { css: css, ranges: ranges };
5890
6040
  }
5891
6041
  function select(core, table, coordinates) {
5892
- var _a;
5893
- var doc = core.contentDiv.ownerDocument;
5894
6042
  var contentDivSelector = '#' + core.contentDiv.id;
5895
- var _b = buildCss(table, coordinates, contentDivSelector), css = _b.css, ranges = _b.ranges;
5896
- var styleElement = doc.getElementById(STYLE_ID + core.contentDiv.id);
5897
- if (!styleElement) {
5898
- styleElement = doc.createElement('style');
5899
- doc.head.appendChild(styleElement);
5900
- styleElement.id = STYLE_ID + core.contentDiv.id;
5901
- }
5902
- (_a = styleElement.sheet) === null || _a === void 0 ? void 0 : _a.insertRule(css);
6043
+ var _a = buildCss(table, coordinates, contentDivSelector), css = _a.css, ranges = _a.ranges;
6044
+ (0, addSelectionStyle_1.default)(core, css, STYLE_ID);
5903
6045
  return ranges;
5904
6046
  }
5905
6047
  function unselect(core) {
@@ -5912,27 +6054,6 @@ function unselect(core) {
5912
6054
  }
5913
6055
  }
5914
6056
  }
5915
- function ensureUniqueId(el, idPrefix) {
5916
- var doc = el.ownerDocument;
5917
- if (!el.id) {
5918
- var cont_1 = 0;
5919
- var getElement = function () { return doc.getElementById(idPrefix + cont_1); };
5920
- //Ensure that there are no elements with the same ID
5921
- var element = getElement();
5922
- while (element) {
5923
- cont_1++;
5924
- element = getElement();
5925
- }
5926
- el.id = idPrefix + cont_1;
5927
- }
5928
- else {
5929
- var elements = doc.querySelectorAll("#" + el.id);
5930
- if (elements.length > 1) {
5931
- el.removeAttribute('id');
5932
- ensureUniqueId(el, idPrefix);
5933
- }
5934
- }
5935
- }
5936
6057
  function generateCssFromCell(contentDivSelector, tableId, middleElSelector, rowIndex, cellTag, index) {
5937
6058
  return (contentDivSelector +
5938
6059
  ' #' +
@@ -6068,20 +6189,23 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
6068
6189
  */
6069
6190
  var switchShadowEdit = function (core, isOn) {
6070
6191
  var lifecycle = core.lifecycle, contentDiv = core.contentDiv;
6071
- var shadowEditFragment = lifecycle.shadowEditFragment, shadowEditSelectionPath = lifecycle.shadowEditSelectionPath, shadowEditTableSelectionPath = lifecycle.shadowEditTableSelectionPath;
6192
+ var shadowEditFragment = lifecycle.shadowEditFragment, shadowEditSelectionPath = lifecycle.shadowEditSelectionPath, shadowEditTableSelectionPath = lifecycle.shadowEditTableSelectionPath, shadowEditImageSelectionPath = lifecycle.shadowEditImageSelectionPath;
6072
6193
  var wasInShadowEdit = !!shadowEditFragment;
6194
+ var getShadowEditSelectionPath = function (selectionType, shadowEditSelection) {
6195
+ return (((shadowEditSelection === null || shadowEditSelection === void 0 ? void 0 : shadowEditSelection.type) == selectionType &&
6196
+ shadowEditSelection.ranges
6197
+ .map(function (range) { return (0, roosterjs_editor_dom_1.getSelectionPath)(contentDiv, range); })
6198
+ .map(function (w) { return w; })) ||
6199
+ null);
6200
+ };
6073
6201
  if (isOn) {
6074
6202
  if (!wasInShadowEdit) {
6075
6203
  var selection = core.api.getSelectionRangeEx(core);
6076
6204
  var range = core.api.getSelectionRange(core, true /*tryGetFromCache*/);
6077
6205
  shadowEditSelectionPath = range && (0, roosterjs_editor_dom_1.getSelectionPath)(contentDiv, range);
6078
- shadowEditTableSelectionPath =
6079
- ((selection === null || selection === void 0 ? void 0 : selection.type) == 1 /* TableSelection */ &&
6080
- selection.ranges
6081
- .map(function (range) { return (0, roosterjs_editor_dom_1.getSelectionPath)(contentDiv, range); })
6082
- .map(function (w) { return w; })) ||
6083
- null;
6206
+ shadowEditTableSelectionPath = getShadowEditSelectionPath(1 /* TableSelection */, selection);
6084
6207
  shadowEditFragment = core.contentDiv.ownerDocument.createDocumentFragment();
6208
+ shadowEditImageSelectionPath = getShadowEditSelectionPath(2 /* ImageSelection */, selection);
6085
6209
  (0, roosterjs_editor_dom_1.moveChildNodes)(shadowEditFragment, contentDiv);
6086
6210
  shadowEditFragment.normalize();
6087
6211
  core.api.triggerEvent(core, {
@@ -6092,6 +6216,7 @@ var switchShadowEdit = function (core, isOn) {
6092
6216
  lifecycle.shadowEditFragment = shadowEditFragment;
6093
6217
  lifecycle.shadowEditSelectionPath = shadowEditSelectionPath;
6094
6218
  lifecycle.shadowEditTableSelectionPath = shadowEditTableSelectionPath;
6219
+ lifecycle.shadowEditImageSelectionPath = shadowEditImageSelectionPath;
6095
6220
  }
6096
6221
  (0, roosterjs_editor_dom_1.moveChildNodes)(contentDiv);
6097
6222
  if (lifecycle.shadowEditFragment) {
@@ -6113,6 +6238,13 @@ var switchShadowEdit = function (core, isOn) {
6113
6238
  if (shadowEditSelectionPath) {
6114
6239
  core.api.selectRange(core, (0, roosterjs_editor_dom_1.createRange)(contentDiv, shadowEditSelectionPath.start, shadowEditSelectionPath.end));
6115
6240
  }
6241
+ if (core.domEvent.imageSelectionRange) {
6242
+ var image = core.domEvent.imageSelectionRange.image;
6243
+ var imageElement = core.contentDiv.querySelector('#' + image.id);
6244
+ if (imageElement) {
6245
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, image);
6246
+ }
6247
+ }
6116
6248
  if (core.domEvent.tableSelectionRange) {
6117
6249
  var _a = core.domEvent.tableSelectionRange, table = _a.table, coordinates = _a.coordinates;
6118
6250
  var tableId = table.id;
@@ -6313,6 +6445,83 @@ function handledExclusively(event, plugin) {
6313
6445
  }
6314
6446
 
6315
6447
 
6448
+ /***/ }),
6449
+
6450
+ /***/ "./packages/roosterjs-editor-core/lib/coreApi/utils/addSelectionStyle.ts":
6451
+ /*!*******************************************************************************!*\
6452
+ !*** ./packages/roosterjs-editor-core/lib/coreApi/utils/addSelectionStyle.ts ***!
6453
+ \*******************************************************************************/
6454
+ /*! no static exports found */
6455
+ /***/ (function(module, exports, __webpack_require__) {
6456
+
6457
+ "use strict";
6458
+
6459
+ Object.defineProperty(exports, "__esModule", { value: true });
6460
+ /**
6461
+ * Add style to selected elements
6462
+ * @param core The Editor core object
6463
+ * @param cssRule The css rule that must added to the selection
6464
+ * @param styleId the ID of the style tag
6465
+ */
6466
+ function addSelectionStyle(core, cssRule, styleId) {
6467
+ var _a;
6468
+ var styleTagId = styleId + core.contentDiv.id;
6469
+ var doc = core.contentDiv.ownerDocument;
6470
+ var styleTag = doc.getElementById(styleTagId);
6471
+ if (!styleTag) {
6472
+ styleTag = doc.createElement('style');
6473
+ styleTag.id = styleTagId;
6474
+ doc.head.appendChild(styleTag);
6475
+ }
6476
+ (_a = styleTag.sheet) === null || _a === void 0 ? void 0 : _a.insertRule(cssRule);
6477
+ }
6478
+ exports.default = addSelectionStyle;
6479
+
6480
+
6481
+ /***/ }),
6482
+
6483
+ /***/ "./packages/roosterjs-editor-core/lib/coreApi/utils/addUniqueId.ts":
6484
+ /*!*************************************************************************!*\
6485
+ !*** ./packages/roosterjs-editor-core/lib/coreApi/utils/addUniqueId.ts ***!
6486
+ \*************************************************************************/
6487
+ /*! no static exports found */
6488
+ /***/ (function(module, exports, __webpack_require__) {
6489
+
6490
+ "use strict";
6491
+
6492
+ Object.defineProperty(exports, "__esModule", { value: true });
6493
+ /**
6494
+ * Add an unique id to element and ensure that is unique
6495
+ * @param el The HTMLElement that will receive the id
6496
+ * @param idPrefix The prefix that will antecede the id (Ex: tableSelected01)
6497
+ */
6498
+ function addUniqueId(el, idPrefix) {
6499
+ var doc = el.ownerDocument;
6500
+ if (!el.id) {
6501
+ applyId(el, idPrefix, doc);
6502
+ }
6503
+ else {
6504
+ var elements = doc.querySelectorAll("#" + el.id);
6505
+ if (elements.length > 1) {
6506
+ el.removeAttribute('id');
6507
+ applyId(el, idPrefix, doc);
6508
+ }
6509
+ }
6510
+ }
6511
+ exports.default = addUniqueId;
6512
+ function applyId(el, idPrefix, doc) {
6513
+ var cont = 0;
6514
+ var getElement = function () { return doc.getElementById(idPrefix + cont); };
6515
+ //Ensure that there are no elements with the same ID
6516
+ var element = getElement();
6517
+ while (element) {
6518
+ cont++;
6519
+ element = getElement();
6520
+ }
6521
+ el.id = idPrefix + cont;
6522
+ }
6523
+
6524
+
6316
6525
  /***/ }),
6317
6526
 
6318
6527
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/CopyPastePlugin.ts":
@@ -6566,9 +6775,13 @@ var DOMEventPlugin = /** @class */ (function () {
6566
6775
  };
6567
6776
  this.onFocus = function () {
6568
6777
  var _a = _this.state.tableSelectionRange || {}, table = _a.table, coordinates = _a.coordinates;
6778
+ var image = (_this.state.imageSelectionRange || {}).image;
6569
6779
  if (table && coordinates) {
6570
6780
  _this.editor.select(table, coordinates);
6571
6781
  }
6782
+ else if (image) {
6783
+ _this.editor.select(image);
6784
+ }
6572
6785
  else {
6573
6786
  _this.editor.select(_this.state.selectionRange);
6574
6787
  }
@@ -6632,6 +6845,7 @@ var DOMEventPlugin = /** @class */ (function () {
6632
6845
  stopPrintableKeyboardEventPropagation: !options.allowKeyboardEventPropagation,
6633
6846
  contextMenuProviders: ((_a = options.plugins) === null || _a === void 0 ? void 0 : _a.filter(isContextMenuProvider)) || [],
6634
6847
  tableSelectionRange: null,
6848
+ imageSelectionRange: null,
6635
6849
  };
6636
6850
  }
6637
6851
  /**
@@ -7268,6 +7482,7 @@ var LifecyclePlugin = /** @class */ (function () {
7268
7482
  shadowEditFragment: null,
7269
7483
  shadowEditSelectionPath: null,
7270
7484
  shadowEditTableSelectionPath: null,
7485
+ shadowEditImageSelectionPath: null,
7271
7486
  };
7272
7487
  }
7273
7488
  /**
@@ -7525,7 +7740,6 @@ var NormalizeTablePlugin = /** @class */ (function () {
7525
7740
  case 11 /* EditorReady */:
7526
7741
  case 7 /* ContentChanged */:
7527
7742
  this.normalizeTables(this.editor.queryElements('table'));
7528
- this.normalizeBlockquotes(this.editor.queryElements('blockquote'));
7529
7743
  break;
7530
7744
  case 10 /* BeforePaste */:
7531
7745
  this.normalizeTables((0, roosterjs_editor_dom_1.toArray)(event.fragment.querySelectorAll('table')));
@@ -7566,31 +7780,9 @@ var NormalizeTablePlugin = /** @class */ (function () {
7566
7780
  }
7567
7781
  }
7568
7782
  };
7569
- NormalizeTablePlugin.prototype.normalizeBlockquotes = function (elements) {
7570
- elements.forEach(function (quote) {
7571
- var centeredElement = quote.querySelector('[style^="text-align: center"]');
7572
- if (centeredElement) {
7573
- if (isRTL(centeredElement)) {
7574
- delete quote.style.marginInlineEnd;
7575
- quote.style.marginInlineStart = 'auto';
7576
- }
7577
- else {
7578
- delete quote.style.marginInlineStart;
7579
- quote.style.marginInlineEnd = 'auto';
7580
- }
7581
- }
7582
- else {
7583
- delete quote.style.marginInlineStart;
7584
- delete quote.style.marginInlineEnd;
7585
- }
7586
- });
7587
- };
7588
7783
  return NormalizeTablePlugin;
7589
7784
  }());
7590
7785
  exports.default = NormalizeTablePlugin;
7591
- function isRTL(el) {
7592
- return (0, roosterjs_editor_dom_1.getComputedStyle)(el, 'direction') == 'rtl' || el.getAttribute('dir') == 'rtl';
7593
- }
7594
7786
  function normalizeTables(tables) {
7595
7787
  var isDOMChanged = false;
7596
7788
  tables.forEach(function (table) {
@@ -8287,7 +8479,13 @@ var Editor = /** @class */ (function () {
8287
8479
  }
8288
8480
  });
8289
8481
  var zoomScale = ((_a = options.zoomScale) !== null && _a !== void 0 ? _a : -1) > 0 ? options.zoomScale : 1;
8290
- this.core = __assign(__assign({ contentDiv: contentDiv, api: __assign(__assign({}, coreApiMap_1.coreApiMap), (options.coreApiOverride || {})), originalApi: coreApiMap_1.coreApiMap, plugins: plugins.filter(function (x) { return !!x; }) }, (0, createCorePlugins_1.getPluginState)(corePlugins)), { trustedHTMLHandler: options.trustedHTMLHandler || (function (html) { return html; }), zoomScale: zoomScale, sizeTransformer: options.sizeTransformer || (function (size) { return size / zoomScale; }) });
8482
+ this.core = __assign(__assign({ contentDiv: contentDiv, api: __assign(__assign({}, coreApiMap_1.coreApiMap), (options.coreApiOverride || {})), originalApi: coreApiMap_1.coreApiMap, plugins: plugins.filter(function (x) { return !!x; }) }, (0, createCorePlugins_1.getPluginState)(corePlugins)), { trustedHTMLHandler: options.trustedHTMLHandler || (function (html) { return html; }), zoomScale: zoomScale, sizeTransformer: options.sizeTransformer || (function (size) { return size / zoomScale; }), getVisibleViewport: options.getVisibleViewport ||
8483
+ (function () {
8484
+ var scrollContainer = _this.getScrollContainer();
8485
+ return (0, roosterjs_editor_dom_1.getIntersectedRect)(scrollContainer == contentDiv
8486
+ ? [scrollContainer]
8487
+ : [scrollContainer, contentDiv]);
8488
+ }), imageSelectionBorderColor: options.imageSelectionBorderColor });
8291
8489
  // 3. Initialize plugins
8292
8490
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
8293
8491
  // 4. Ensure user will type in a container node, not the editor content DIV
@@ -8555,6 +8753,17 @@ var Editor = /** @class */ (function () {
8555
8753
  core.api.selectTable(core, null);
8556
8754
  core.domEvent.tableSelectionRange = null;
8557
8755
  }
8756
+ if (this.isFeatureEnabled("ImageSelection" /* ImageSelection */) &&
8757
+ (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLImageElement') &&
8758
+ !arg2) {
8759
+ var selection = core.api.selectImage(core, arg1);
8760
+ core.domEvent.imageSelectionRange = selection;
8761
+ return !!selection;
8762
+ }
8763
+ else {
8764
+ core.api.selectImage(core, null);
8765
+ core.domEvent.imageSelectionRange = null;
8766
+ }
8558
8767
  var range = !arg1
8559
8768
  ? null
8560
8769
  : (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Range')
@@ -8832,6 +9041,8 @@ var Editor = /** @class */ (function () {
8832
9041
  return this.getCore().contentDiv.getAttribute(name);
8833
9042
  };
8834
9043
  /**
9044
+ * @deprecated Use getVisibleViewport() instead.
9045
+ *
8835
9046
  * Get current relative distance from top-left corner of the given element to top-left corner of editor content DIV.
8836
9047
  * @param element The element to calculate from. If the given element is not in editor, return value will be null
8837
9048
  * @param addScroll When pass true, The return value will also add scrollLeft and scrollTop if any. So the value
@@ -9004,6 +9215,12 @@ var Editor = /** @class */ (function () {
9004
9215
  }
9005
9216
  }
9006
9217
  };
9218
+ /**
9219
+ * Retrieves the rect of the visible viewport of the editor.
9220
+ */
9221
+ Editor.prototype.getVisibleViewport = function () {
9222
+ return this.getCore().getVisibleViewport();
9223
+ };
9007
9224
  /**
9008
9225
  * @returns the current EditorCore object
9009
9226
  * @throws a standard Error if there's no core object
@@ -11780,9 +11997,9 @@ exports.default = getPredefinedCssForElement;
11780
11997
  "use strict";
11781
11998
 
11782
11999
  Object.defineProperty(exports, "__esModule", { value: true });
11783
- exports.VTable = exports.moveChildNodes = exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
11784
- exports.createNumberDefinition = exports.validate = exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = void 0;
11785
- exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = void 0;
12000
+ exports.getIntersectedRect = exports.moveChildNodes = exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
12001
+ exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.saveTableCellMetadata = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = void 0;
12002
+ exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = exports.createNumberDefinition = exports.validate = void 0;
11786
12003
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
11787
12004
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
11788
12005
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -11874,6 +12091,8 @@ Object.defineProperty(exports, "createElement", { enumerable: true, get: functio
11874
12091
  Object.defineProperty(exports, "KnownCreateElementData", { enumerable: true, get: function () { return createElement_1.KnownCreateElementData; } });
11875
12092
  var moveChildNodes_1 = __webpack_require__(/*! ./utils/moveChildNodes */ "./packages/roosterjs-editor-dom/lib/utils/moveChildNodes.ts");
11876
12093
  Object.defineProperty(exports, "moveChildNodes", { enumerable: true, get: function () { return moveChildNodes_1.default; } });
12094
+ var getIntersectedRect_1 = __webpack_require__(/*! ./utils/getIntersectedRect */ "./packages/roosterjs-editor-dom/lib/utils/getIntersectedRect.ts");
12095
+ Object.defineProperty(exports, "getIntersectedRect", { enumerable: true, get: function () { return getIntersectedRect_1.default; } });
11877
12096
  var VTable_1 = __webpack_require__(/*! ./table/VTable */ "./packages/roosterjs-editor-dom/lib/table/VTable.ts");
11878
12097
  Object.defineProperty(exports, "VTable", { enumerable: true, get: function () { return VTable_1.default; } });
11879
12098
  var isWholeTableSelected_1 = __webpack_require__(/*! ./table/isWholeTableSelected */ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts");
@@ -11890,6 +12109,8 @@ var setListItemStyle_1 = __webpack_require__(/*! ./list/setListItemStyle */ "./p
11890
12109
  Object.defineProperty(exports, "setListItemStyle", { enumerable: true, get: function () { return setListItemStyle_1.default; } });
11891
12110
  var tableFormatInfo_1 = __webpack_require__(/*! ./table/tableFormatInfo */ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts");
11892
12111
  Object.defineProperty(exports, "getTableFormatInfo", { enumerable: true, get: function () { return tableFormatInfo_1.getTableFormatInfo; } });
12112
+ var tableCellInfo_1 = __webpack_require__(/*! ./table/tableCellInfo */ "./packages/roosterjs-editor-dom/lib/table/tableCellInfo.ts");
12113
+ Object.defineProperty(exports, "saveTableCellMetadata", { enumerable: true, get: function () { return tableCellInfo_1.saveTableCellMetadata; } });
11893
12114
  var getRegionsFromRange_1 = __webpack_require__(/*! ./region/getRegionsFromRange */ "./packages/roosterjs-editor-dom/lib/region/getRegionsFromRange.ts");
11894
12115
  Object.defineProperty(exports, "getRegionsFromRange", { enumerable: true, get: function () { return getRegionsFromRange_1.default; } });
11895
12116
  var getSelectedBlockElementsInRegion_1 = __webpack_require__(/*! ./region/getSelectedBlockElementsInRegion */ "./packages/roosterjs-editor-dom/lib/region/getSelectedBlockElementsInRegion.ts");
@@ -12860,8 +13081,10 @@ var VList = /** @class */ (function () {
12860
13081
  /**
12861
13082
  * Write the result back into DOM tree
12862
13083
  * After that, this VList becomes unavailable because we set this.rootList to null
13084
+ *
13085
+ * @param shouldReuseAllAncestorListElements Optional - defaults to false.
12863
13086
  */
12864
- VList.prototype.writeBack = function () {
13087
+ VList.prototype.writeBack = function (shouldReuseAllAncestorListElements) {
12865
13088
  var _this = this;
12866
13089
  if (!this.rootList) {
12867
13090
  throw new Error('rootList must not be null');
@@ -12879,7 +13102,7 @@ var VList = /** @class */ (function () {
12879
13102
  listStack.splice(1, listStack.length - 1);
12880
13103
  start = newListStart;
12881
13104
  }
12882
- item.writeBack(listStack, _this.rootList);
13105
+ item.writeBack(listStack, _this.rootList, shouldReuseAllAncestorListElements);
12883
13106
  var topList = listStack[1];
12884
13107
  if ((0, safeInstanceOf_1.default)(topList, 'HTMLOListElement')) {
12885
13108
  if (lastList != topList) {
@@ -13259,7 +13482,7 @@ var VListChain = /** @class */ (function () {
13259
13482
  * After change the lists, commit the change to all lists in this chain to update the list number,
13260
13483
  * and clear the temporary dataset values added to list node
13261
13484
  */
13262
- VListChain.prototype.commit = function () {
13485
+ VListChain.prototype.commit = function (shouldReuseAllAncestorListElements) {
13263
13486
  var lists = this.getLists();
13264
13487
  var lastNumber = 0;
13265
13488
  for (var i = 0; i < lists.length; i++) {
@@ -13269,7 +13492,7 @@ var VListChain = /** @class */ (function () {
13269
13492
  lastNumber = vlist.getLastItemNumber() || 0;
13270
13493
  delete list.dataset[CHAIN_DATASET_NAME];
13271
13494
  delete list.dataset[AFTER_CURSOR_DATASET_NAME];
13272
- vlist.writeBack();
13495
+ vlist.writeBack(shouldReuseAllAncestorListElements);
13273
13496
  }
13274
13497
  };
13275
13498
  /**
@@ -13355,7 +13578,7 @@ var NEGATIVE_MARGIN = '-.25in';
13355
13578
  */
13356
13579
  exports.ListStyleDefinitionMetadata = (0, definitionCreators_1.createObjectDefinition)({
13357
13580
  orderedStyleType: (0, definitionCreators_1.createNumberDefinition)(true /** isOptional */, undefined /** value **/, 1 /* Min */, 20 /* Max */),
13358
- unorderedStyleType: (0, definitionCreators_1.createNumberDefinition)(true /** isOptional */, undefined /** value **/, 1 /* Min */, 8 /* Max */),
13581
+ unorderedStyleType: (0, definitionCreators_1.createNumberDefinition)(true /** isOptional */, undefined /** value **/, 1 /* Min */, 9 /* Max */),
13359
13582
  }, true /** isOptional */, true /** allowNull */);
13360
13583
  /**
13361
13584
  * !!! Never directly create instance of this class. It should be created within VList class !!!
@@ -13543,19 +13766,41 @@ var VListItem = /** @class */ (function () {
13543
13766
  * Write the change result back into DOM
13544
13767
  * @param listStack current stack of list elements
13545
13768
  * @param originalRoot Original list root element. It will be reused when write back if possible
13769
+ * @param shouldReuseAllAncestorListElements Optional - defaults to false. If true, only make
13770
+ * sure the direct parent of this list matches the list types when writing back.
13546
13771
  */
13547
- VListItem.prototype.writeBack = function (listStack, originalRoot) {
13772
+ VListItem.prototype.writeBack = function (listStack, originalRoot, shouldReuseAllAncestorListElements) {
13548
13773
  var _a;
13774
+ if (shouldReuseAllAncestorListElements === void 0) { shouldReuseAllAncestorListElements = false; }
13549
13775
  var nextLevel = 1;
13550
- // 1. Determine list elements that we can reuse
13551
- // e.g.:
13552
- // passed in listStack: Fragment > OL > UL > OL
13553
- // local listTypes: null > OL > UL > UL > OL
13554
- // then Fragment > OL > UL can be reused
13555
- for (; nextLevel < listStack.length; nextLevel++) {
13556
- if ((0, getListTypeFromNode_1.default)(listStack[nextLevel]) !== this.listTypes[nextLevel]) {
13557
- listStack.splice(nextLevel);
13558
- break;
13776
+ if (shouldReuseAllAncestorListElements) {
13777
+ // Remove any un-needed lists from the stack.
13778
+ if (listStack.length > this.listTypes.length) {
13779
+ listStack.splice(this.listTypes.length);
13780
+ }
13781
+ // 1. If the listStack is the same length as the listTypes for this item, check
13782
+ // if the last item needs to change, and remove it if needed. We can always re-use
13783
+ // the other lists even if the type doesn't match - since the display is the same
13784
+ // as long as the list immediately surrounding the item is correct.
13785
+ var listStackEndIndex = listStack.length - 1;
13786
+ if (listStackEndIndex === this.listTypes.length - 1 && // they are the same length
13787
+ (0, getListTypeFromNode_1.default)(listStack[listStackEndIndex]) !==
13788
+ this.listTypes[listStackEndIndex]) {
13789
+ listStack.splice(listStackEndIndex);
13790
+ }
13791
+ nextLevel = listStack.length;
13792
+ }
13793
+ else {
13794
+ // 1. Determine list elements that we can reuse
13795
+ // e.g.:
13796
+ // passed in listStack: Fragment > OL > UL > OL
13797
+ // local listTypes: null > OL > UL > UL > OL
13798
+ // then Fragment > OL > UL can be reused
13799
+ for (; nextLevel < listStack.length; nextLevel++) {
13800
+ if ((0, getListTypeFromNode_1.default)(listStack[nextLevel]) !== this.listTypes[nextLevel]) {
13801
+ listStack.splice(nextLevel);
13802
+ break;
13803
+ }
13559
13804
  }
13560
13805
  }
13561
13806
  // 2. Add new list elements
@@ -13572,7 +13817,8 @@ var VListItem = /** @class */ (function () {
13572
13817
  //apply the styles of the current parent list to the new list
13573
13818
  if (this.getDeepChildIndex(originalRoot) == stackLength) {
13574
13819
  var listStyleType = (_a = this.node.parentElement) === null || _a === void 0 ? void 0 : _a.style.listStyleType;
13575
- if (listStyleType) {
13820
+ if (listStyleType &&
13821
+ (0, getTagOfNode_1.default)(this.node.parentElement) === (0, getTagOfNode_1.default)(newList)) {
13576
13822
  newList.style.listStyleType = listStyleType;
13577
13823
  }
13578
13824
  }
@@ -14438,6 +14684,10 @@ function validate(input, def) {
14438
14684
  if ((def.isOptional && typeof input === 'undefined') || (def.allowNull && input === null)) {
14439
14685
  result = true;
14440
14686
  }
14687
+ else if ((!def.isOptional && typeof input === 'undefined') ||
14688
+ (!def.allowNull && input === null)) {
14689
+ return false;
14690
+ }
14441
14691
  else {
14442
14692
  switch (def.type) {
14443
14693
  case 2 /* String */:
@@ -15850,7 +16100,7 @@ var normalizeRect_1 = __webpack_require__(/*! ../utils/normalizeRect */ "./packa
15850
16100
  var safeInstanceOf_1 = __webpack_require__(/*! ../utils/safeInstanceOf */ "./packages/roosterjs-editor-dom/lib/utils/safeInstanceOf.ts");
15851
16101
  var toArray_1 = __webpack_require__(/*! ../jsUtils/toArray */ "./packages/roosterjs-editor-dom/lib/jsUtils/toArray.ts");
15852
16102
  var tableFormatInfo_1 = __webpack_require__(/*! ./tableFormatInfo */ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts");
15853
- var CELL_SHADE = 'cellShade';
16103
+ var metadata_1 = __webpack_require__(/*! ../metadata/metadata */ "./packages/roosterjs-editor-dom/lib/metadata/metadata.ts");
15854
16104
  var DEFAULT_FORMAT = {
15855
16105
  topBorderColor: '#ABABAB',
15856
16106
  bottomBorderColor: '#ABABAB',
@@ -16004,8 +16254,8 @@ var VTable = /** @class */ (function () {
16004
16254
  VTable.prototype.deleteCellShadeDataset = function (cells) {
16005
16255
  cells === null || cells === void 0 ? void 0 : cells.forEach(function (row) {
16006
16256
  row.forEach(function (cell) {
16007
- if (cell.td && cell.td.dataset[CELL_SHADE]) {
16008
- delete cell.td.dataset[CELL_SHADE];
16257
+ if (cell.td) {
16258
+ (0, metadata_1.removeMetadata)(cell.td);
16009
16259
  }
16010
16260
  });
16011
16261
  });
@@ -16549,10 +16799,10 @@ function cloneNode(node) {
16549
16799
  Object.defineProperty(exports, "__esModule", { value: true });
16550
16800
  var changeElementTag_1 = __webpack_require__(/*! ../utils/changeElementTag */ "./packages/roosterjs-editor-dom/lib/utils/changeElementTag.ts");
16551
16801
  var setColor_1 = __webpack_require__(/*! ../utils/setColor */ "./packages/roosterjs-editor-dom/lib/utils/setColor.ts");
16802
+ var tableCellInfo_1 = __webpack_require__(/*! ./tableCellInfo */ "./packages/roosterjs-editor-dom/lib/table/tableCellInfo.ts");
16552
16803
  var TRANSPARENT = 'transparent';
16553
16804
  var TABLE_CELL_TAG_NAME = 'TD';
16554
16805
  var TABLE_HEADER_TAG_NAME = 'TH';
16555
- var CELL_SHADE = 'cellShade';
16556
16806
  /**
16557
16807
  * @internal
16558
16808
  * Apply the given table format to this virtual table
@@ -16575,11 +16825,11 @@ exports.default = applyTableFormat;
16575
16825
  * @returns
16576
16826
  */
16577
16827
  function hasCellShade(cell) {
16828
+ var _a;
16578
16829
  if (!cell.td) {
16579
16830
  return false;
16580
16831
  }
16581
- var colorShade = cell.td.dataset[CELL_SHADE];
16582
- return colorShade ? true : false;
16832
+ return !!((_a = (0, tableCellInfo_1.getTableCellMetadata)(cell.td)) === null || _a === void 0 ? void 0 : _a.bgColorOverride);
16583
16833
  }
16584
16834
  /**
16585
16835
  * Set color to the table
@@ -16857,6 +17107,47 @@ function isWholeTableSelected(vTable, selection) {
16857
17107
  exports.default = isWholeTableSelected;
16858
17108
 
16859
17109
 
17110
+ /***/ }),
17111
+
17112
+ /***/ "./packages/roosterjs-editor-dom/lib/table/tableCellInfo.ts":
17113
+ /*!******************************************************************!*\
17114
+ !*** ./packages/roosterjs-editor-dom/lib/table/tableCellInfo.ts ***!
17115
+ \******************************************************************/
17116
+ /*! no static exports found */
17117
+ /***/ (function(module, exports, __webpack_require__) {
17118
+
17119
+ "use strict";
17120
+
17121
+ Object.defineProperty(exports, "__esModule", { value: true });
17122
+ exports.saveTableCellMetadata = exports.getTableCellMetadata = void 0;
17123
+ var definitionCreators_1 = __webpack_require__(/*! ../metadata/definitionCreators */ "./packages/roosterjs-editor-dom/lib/metadata/definitionCreators.ts");
17124
+ var metadata_1 = __webpack_require__(/*! ../metadata/metadata */ "./packages/roosterjs-editor-dom/lib/metadata/metadata.ts");
17125
+ var BooleanDefinition = (0, definitionCreators_1.createBooleanDefinition)(false /** isOptional */, undefined /** value */, true /** allowNull */);
17126
+ var TableCellFormatMetadata = (0, definitionCreators_1.createObjectDefinition)({
17127
+ bgColorOverride: BooleanDefinition,
17128
+ }, false /* isOptional */, true /** allowNull */);
17129
+ /**
17130
+ * @internal
17131
+ * Get the format info of a table cell
17132
+ * @param cell The table cell to use
17133
+ */
17134
+ function getTableCellMetadata(cell) {
17135
+ return (0, metadata_1.getMetadata)(cell, TableCellFormatMetadata);
17136
+ }
17137
+ exports.getTableCellMetadata = getTableCellMetadata;
17138
+ /**
17139
+ * Add metadata to a cell
17140
+ * @param cell The table cell to add the metadata
17141
+ * @param format The format of the table
17142
+ */
17143
+ function saveTableCellMetadata(cell, format) {
17144
+ if (cell && format) {
17145
+ (0, metadata_1.setMetadata)(cell, format, TableCellFormatMetadata);
17146
+ }
17147
+ }
17148
+ exports.saveTableCellMetadata = saveTableCellMetadata;
17149
+
17150
+
16860
17151
  /***/ }),
16861
17152
 
16862
17153
  /***/ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts":
@@ -17508,6 +17799,61 @@ function getInnerHTML(node) {
17508
17799
  exports.default = getInnerHTML;
17509
17800
 
17510
17801
 
17802
+ /***/ }),
17803
+
17804
+ /***/ "./packages/roosterjs-editor-dom/lib/utils/getIntersectedRect.ts":
17805
+ /*!***********************************************************************!*\
17806
+ !*** ./packages/roosterjs-editor-dom/lib/utils/getIntersectedRect.ts ***!
17807
+ \***********************************************************************/
17808
+ /*! no static exports found */
17809
+ /***/ (function(module, exports, __webpack_require__) {
17810
+
17811
+ "use strict";
17812
+
17813
+ Object.defineProperty(exports, "__esModule", { value: true });
17814
+ var normalizeRect_1 = __webpack_require__(/*! ./normalizeRect */ "./packages/roosterjs-editor-dom/lib/utils/normalizeRect.ts");
17815
+ /**
17816
+ * Get the intersected Rect of elements provided
17817
+ *
17818
+ * @example
17819
+ * The result of the following Elements Rects would be:
17820
+ {
17821
+ top: Element2.top,
17822
+ bottom: Element1.bottom,
17823
+ left: Element2.left,
17824
+ right: Element2.right
17825
+ }
17826
+ +-------------------------+
17827
+ | Element 1 |
17828
+ | +-----------------+ |
17829
+ | | Element2 | |
17830
+ | | | |
17831
+ | | | |
17832
+ +-------------------------+
17833
+ | |
17834
+ +-----------------+
17835
+
17836
+ * @param elements Elements to use.
17837
+ * @param additionalRects additional rects to use
17838
+ * @returns If the Rect is valid return the rect, if not, return null.
17839
+ */
17840
+ function getIntersectedRect(elements, additionalRects) {
17841
+ if (additionalRects === void 0) { additionalRects = []; }
17842
+ var rects = elements
17843
+ .map(function (element) { return (0, normalizeRect_1.default)(element.getBoundingClientRect()); })
17844
+ .filter(function (element) { return !!element; })
17845
+ .concat(additionalRects);
17846
+ var result = {
17847
+ top: Math.max.apply(Math, rects.map(function (r) { return r.top; })),
17848
+ bottom: Math.min.apply(Math, rects.map(function (r) { return r.bottom; })),
17849
+ left: Math.max.apply(Math, rects.map(function (r) { return r.left; })),
17850
+ right: Math.min.apply(Math, rects.map(function (r) { return r.right; })),
17851
+ };
17852
+ return result.top < result.bottom && result.left < result.right ? result : null;
17853
+ }
17854
+ exports.default = getIntersectedRect;
17855
+
17856
+
17511
17857
  /***/ }),
17512
17858
 
17513
17859
  /***/ "./packages/roosterjs-editor-dom/lib/utils/getLeafNode.ts":
@@ -18794,6 +19140,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
18794
19140
  __exportStar(__webpack_require__(/*! ./plugins/ImageResize/index */ "./packages/roosterjs-editor-plugins/lib/plugins/ImageResize/index.ts"), exports);
18795
19141
 
18796
19142
 
19143
+ /***/ }),
19144
+
19145
+ /***/ "./packages/roosterjs-editor-plugins/lib/ImageSelection.ts":
19146
+ /*!*****************************************************************!*\
19147
+ !*** ./packages/roosterjs-editor-plugins/lib/ImageSelection.ts ***!
19148
+ \*****************************************************************/
19149
+ /*! no static exports found */
19150
+ /***/ (function(module, exports, __webpack_require__) {
19151
+
19152
+ "use strict";
19153
+
19154
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19155
+ if (k2 === undefined) k2 = k;
19156
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
19157
+ }) : (function(o, m, k, k2) {
19158
+ if (k2 === undefined) k2 = k;
19159
+ o[k2] = m[k];
19160
+ }));
19161
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19162
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19163
+ };
19164
+ Object.defineProperty(exports, "__esModule", { value: true });
19165
+ __exportStar(__webpack_require__(/*! ./plugins/ImageSelection/index */ "./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/index.ts"), exports);
19166
+
19167
+
18797
19168
  /***/ }),
18798
19169
 
18799
19170
  /***/ "./packages/roosterjs-editor-plugins/lib/Paste.ts":
@@ -18954,6 +19325,7 @@ __exportStar(__webpack_require__(/*! ./TableResize */ "./packages/roosterjs-edit
18954
19325
  __exportStar(__webpack_require__(/*! ./Watermark */ "./packages/roosterjs-editor-plugins/lib/Watermark.ts"), exports);
18955
19326
  __exportStar(__webpack_require__(/*! ./TableCellSelection */ "./packages/roosterjs-editor-plugins/lib/TableCellSelection.ts"), exports);
18956
19327
  __exportStar(__webpack_require__(/*! ./AutoFormat */ "./packages/roosterjs-editor-plugins/lib/AutoFormat.ts"), exports);
19328
+ __exportStar(__webpack_require__(/*! ./ImageSelection */ "./packages/roosterjs-editor-plugins/lib/ImageSelection.ts"), exports);
18957
19329
 
18958
19330
 
18959
19331
  /***/ }),
@@ -19637,7 +20009,7 @@ var MergeInNewLine = {
19637
20009
  (0, roosterjs_editor_api_1.blockFormat)(editor, function (region, start, end) {
19638
20010
  var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li);
19639
20011
  vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
19640
- vList.writeBack();
20012
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
19641
20013
  event.rawEvent.preventDefault();
19642
20014
  });
19643
20015
  }
@@ -19713,7 +20085,8 @@ function isAListPattern(textBeforeCursor) {
19713
20085
  var AutoBullet = {
19714
20086
  keys: [32 /* SPACE */],
19715
20087
  shouldHandleEvent: function (event, editor) {
19716
- if (!cacheGetListElement(event, editor)) {
20088
+ if (!cacheGetListElement(event, editor) &&
20089
+ !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
19717
20090
  var searcher = editor.getContentSearcherOfCursor(event);
19718
20091
  var textBeforeCursor = searcher.getSubStringBefore(4);
19719
20092
  // Auto list is triggered if:
@@ -19801,23 +20174,13 @@ var AutoNumberingList = {
19801
20174
  event.rawEvent.preventDefault();
19802
20175
  editor.addUndoSnapshot(function () {
19803
20176
  var _a;
19804
- var regions;
19805
20177
  var searcher = editor.getContentSearcherOfCursor();
19806
20178
  var textBeforeCursor = searcher.getSubStringBefore(5);
19807
20179
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
19808
- if (!textRange) {
19809
- // no op if the range can't be found
19810
- }
19811
- else if ((regions = editor.getSelectedRegions()) && regions.length == 1) {
19812
- var num = parseInt(textBeforeCursor);
19813
- var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor, num);
19814
- prepareAutoBullet(editor, textRange);
19815
- (0, roosterjs_editor_api_1.toggleNumbering)(editor, num, listStyle, 'autoToggleList' /** apiNameOverride */);
19816
- }
19817
- else {
20180
+ if (textRange) {
19818
20181
  var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
19819
20182
  prepareAutoBullet(editor, textRange);
19820
- (0, roosterjs_editor_api_1.toggleNumbering)(editor, undefined /* startNumber*/, listStyle, 'autoToggleList' /** apiNameOverride */);
20183
+ (0, roosterjs_editor_api_1.toggleNumbering)(editor, undefined /** startNumber */, listStyle, 'autoToggleList' /** apiNameOverride */);
19821
20184
  }
19822
20185
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
19823
20186
  }, null /*changeSource*/, true /*canUndoByBackspace*/);
@@ -19889,7 +20252,14 @@ function shouldTriggerList(event, editor, getListStyle) {
19889
20252
  var searcher = editor.getContentSearcherOfCursor(event);
19890
20253
  var textBeforeCursor = searcher.getSubStringBefore(4);
19891
20254
  var itHasSpace = /\s/g.test(textBeforeCursor);
19892
- return (!itHasSpace && !searcher.getNearestNonTextInlineElement() && getListStyle(textBeforeCursor));
20255
+ var element = editor.getElementAtCursor();
20256
+ var previousNode = editor.getBodyTraverser(element).getPreviousBlockElement();
20257
+ var isLi = previousNode
20258
+ ? (0, roosterjs_editor_dom_1.getTagOfNode)(previousNode === null || previousNode === void 0 ? void 0 : previousNode.collapseToSingleElement()) === 'LI'
20259
+ : false;
20260
+ return (!itHasSpace &&
20261
+ !searcher.getNearestNonTextInlineElement() &&
20262
+ getListStyle(textBeforeCursor, !isLi));
19893
20263
  }
19894
20264
  /**
19895
20265
  * @internal
@@ -19943,7 +20313,7 @@ function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
19943
20313
  var searcher = editor.getContentSearcherOfCursor(event);
19944
20314
  var startPosition;
19945
20315
  var endPosition;
19946
- searcher.forEachTextInlineElement(function (textInlineElement) {
20316
+ searcher === null || searcher === void 0 ? void 0 : searcher.forEachTextInlineElement(function (textInlineElement) {
19947
20317
  if (endPosition && startPosition) {
19948
20318
  return true;
19949
20319
  }
@@ -19987,7 +20357,8 @@ function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
19987
20357
  var textContentRange = range.cloneRange();
19988
20358
  textContentRange.setStart(textContentRange.startContainer, textContentRange.startOffset + 1);
19989
20359
  // set the removal range to include the typed last character.
19990
- range.setEnd(range.endContainer, range.endOffset + 1);
20360
+ var lastIndex = range.endContainer.length;
20361
+ range.setEnd(range.endContainer, lastIndex);
19991
20362
  // extract content and put it into a new element.
19992
20363
  var elementToWrap = editor.getDocument().createElement(elementTag);
19993
20364
  elementToWrap.appendChild(textContentRange.extractContents());
@@ -20005,19 +20376,19 @@ function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
20005
20376
  /**
20006
20377
  * Markdown bold feature. Make bold text with markdown shortcuts.
20007
20378
  */
20008
- var MarkdownBold = generateBasicMarkdownFeature(56 /* EIGHT_ASTERISK */, '*', 'b', true);
20379
+ var MarkdownBold = generateBasicMarkdownFeature(56 /* EIGHT_ASTERISK */, '*', 'b', true /* useShiftKey */);
20009
20380
  /**
20010
20381
  * Markdown italics feature. Make italic text with markdown shortcuts.
20011
20382
  */
20012
- var MarkdownItalic = generateBasicMarkdownFeature(189 /* DASH_UNDERSCORE */, '_', 'i', true);
20383
+ var MarkdownItalic = generateBasicMarkdownFeature(189 /* DASH_UNDERSCORE */, '_', 'i', true /* useShiftKey */);
20013
20384
  /**
20014
20385
  * Markdown strikethrough feature. MAke strikethrough text with markdown shortcuts.
20015
20386
  */
20016
- var MarkdownStrikethrough = generateBasicMarkdownFeature(192 /* GRAVE_TILDE */, '~', 's', true);
20387
+ var MarkdownStrikethrough = generateBasicMarkdownFeature(192 /* GRAVE_TILDE */, '~', 's', true /* useShiftKey */);
20017
20388
  /**
20018
20389
  * Markdown inline code feature. Marks specific text as inline code with markdown shortcuts.
20019
20390
  */
20020
- var MarkdownInlineCode = generateBasicMarkdownFeature(192 /* GRAVE_TILDE */, '`', 'code', false);
20391
+ var MarkdownInlineCode = generateBasicMarkdownFeature(192 /* GRAVE_TILDE */, '`', 'code', false /* useShiftKey */);
20021
20392
  /**
20022
20393
  * @internal
20023
20394
  */
@@ -20737,13 +21108,7 @@ var characters = {
20737
21108
  '-': 2 /* Dash */,
20738
21109
  ')': 3 /* Parenthesis */,
20739
21110
  };
20740
- var numberingTriggers = {
20741
- '1': 1 /* Decimal */,
20742
- i: 4 /* LowerRoman */,
20743
- I: 5 /* UpperRoman */,
20744
- a: 2 /* LowerAlpha */,
20745
- A: 3 /* UpperAlpha */,
20746
- };
21111
+ var numberingTriggers = ['1', 'a', 'A', 'I', 'i'];
20747
21112
  var identifyNumberingType = function (text) {
20748
21113
  if (!isNaN(parseInt(text))) {
20749
21114
  return 1 /* Decimal */;
@@ -20802,16 +21167,14 @@ var DecimalsTypes = (_f = {},
20802
21167
  _f[3 /* Parenthesis */] = 3 /* DecimalParenthesis */,
20803
21168
  _f[4 /* DoubleParenthesis */] = 4 /* DecimalDoubleParenthesis */,
20804
21169
  _f);
20805
- var identifyNumberingListType = function (numbering, isDoubleParenthesis, startNumber) {
21170
+ var identifyNumberingListType = function (numbering, isDoubleParenthesis) {
20806
21171
  var separatorCharacter = isDoubleParenthesis
20807
21172
  ? 4 /* DoubleParenthesis */
20808
21173
  : characters[numbering[1]];
20809
21174
  // if separator is not valid, no need to check if the number is valid.
20810
21175
  if (separatorCharacter) {
20811
- var number = numbering.length === 3 ? numbering[1] : numbering[0];
20812
- var numberingType = startNumber
20813
- ? identifyNumberingType(number)
20814
- : numberingTriggers[number];
21176
+ var number = numbering[numbering.length - 2];
21177
+ var numberingType = identifyNumberingType(number);
20815
21178
  return numberingType ? numberingListTypes[numberingType](separatorCharacter) : null;
20816
21179
  }
20817
21180
  return null;
@@ -20819,16 +21182,22 @@ var identifyNumberingListType = function (numbering, isDoubleParenthesis, startN
20819
21182
  /**
20820
21183
  * @internal
20821
21184
  * @param textBeforeCursor The trigger character
20822
- * @param startNumber (Optional) Start number of the list
21185
+ * @param isTheFirstItem (Optional) Is the start number of a list.
20823
21186
  * @returns The style of a numbering list triggered by a string
20824
21187
  */
20825
- function getAutoNumberingListStyle(textBeforeCursor, startNumber) {
21188
+ function getAutoNumberingListStyle(textBeforeCursor, isTheFirstItem) {
20826
21189
  var trigger = textBeforeCursor.trim();
21190
+ //Only the staring items ['1', 'a', 'A', 'I', 'i'] must trigger a new list. All the other triggers is used to keep the list chain.
21191
+ //The index is always the character before the last character
21192
+ var listIndex = trigger[trigger.length - 2];
21193
+ if (isTheFirstItem && numberingTriggers.indexOf(listIndex) < 0) {
21194
+ return null;
21195
+ }
20827
21196
  // the marker must be a combination of 2 or 3 characters, so if the length is less than 2, no need to check
20828
21197
  // If the marker length is 3, the marker style is double parenthesis such as (1), (A).
20829
21198
  var isDoubleParenthesis = trigger.length === 3 && trigger[0] === '(' && trigger[2] === ')';
20830
21199
  var numberingType = trigger.length === 2 || isDoubleParenthesis
20831
- ? identifyNumberingListType(trigger, isDoubleParenthesis, startNumber)
21200
+ ? identifyNumberingListType(trigger, isDoubleParenthesis)
20832
21201
  : null;
20833
21202
  return numberingType;
20834
21203
  }
@@ -22996,6 +23365,99 @@ var ImageResize_1 = __webpack_require__(/*! ./ImageResize */ "./packages/rooster
22996
23365
  Object.defineProperty(exports, "ImageResize", { enumerable: true, get: function () { return ImageResize_1.default; } });
22997
23366
 
22998
23367
 
23368
+ /***/ }),
23369
+
23370
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/ImageSelection.ts":
23371
+ /*!****************************************************************************************!*\
23372
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/ImageSelection.ts ***!
23373
+ \****************************************************************************************/
23374
+ /*! no static exports found */
23375
+ /***/ (function(module, exports, __webpack_require__) {
23376
+
23377
+ "use strict";
23378
+
23379
+ Object.defineProperty(exports, "__esModule", { value: true });
23380
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
23381
+ /**
23382
+ * Detect image selection and help highlight the image
23383
+ */
23384
+ var ImageSelection = /** @class */ (function () {
23385
+ function ImageSelection() {
23386
+ this.editor = null;
23387
+ this.imageId = null;
23388
+ }
23389
+ /**
23390
+ * Get a friendly name of this plugin
23391
+ */
23392
+ ImageSelection.prototype.getName = function () {
23393
+ return 'ImageSelection';
23394
+ };
23395
+ /**
23396
+ * Initialize this plugin. This should only be called from Editor
23397
+ * @param editor Editor instance
23398
+ */
23399
+ ImageSelection.prototype.initialize = function (editor) {
23400
+ this.editor = editor;
23401
+ };
23402
+ /**
23403
+ * Dispose this plugin
23404
+ */
23405
+ ImageSelection.prototype.dispose = function () {
23406
+ this.editor.select(null);
23407
+ this.editor = null;
23408
+ this.imageId = null;
23409
+ };
23410
+ ImageSelection.prototype.onPluginEvent = function (event) {
23411
+ if (this.editor) {
23412
+ switch (event.eventType) {
23413
+ case 17 /* EnteredShadowEdit */:
23414
+ var selection = this.editor.getSelectionRangeEx();
23415
+ if (selection.type == 2 /* ImageSelection */) {
23416
+ this.editor.select(selection.image);
23417
+ }
23418
+ break;
23419
+ case 18 /* LeavingShadowEdit */:
23420
+ if (this.imageId) {
23421
+ var images = this.editor.queryElements('#' + this.imageId);
23422
+ if (images.length == 1) {
23423
+ var image = images[0];
23424
+ this.editor.select(image);
23425
+ }
23426
+ this.imageId = null;
23427
+ }
23428
+ break;
23429
+ case 5 /* MouseDown */:
23430
+ var target = event.rawEvent.target;
23431
+ if ((0, roosterjs_editor_dom_1.safeInstanceOf)(target, 'HTMLImageElement')) {
23432
+ this.editor.select(target);
23433
+ this.imageId = target.id;
23434
+ }
23435
+ break;
23436
+ }
23437
+ }
23438
+ };
23439
+ return ImageSelection;
23440
+ }());
23441
+ exports.default = ImageSelection;
23442
+
23443
+
23444
+ /***/ }),
23445
+
23446
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/index.ts":
23447
+ /*!*******************************************************************************!*\
23448
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/index.ts ***!
23449
+ \*******************************************************************************/
23450
+ /*! no static exports found */
23451
+ /***/ (function(module, exports, __webpack_require__) {
23452
+
23453
+ "use strict";
23454
+
23455
+ Object.defineProperty(exports, "__esModule", { value: true });
23456
+ exports.ImageSelection = void 0;
23457
+ var ImageSelection_1 = __webpack_require__(/*! ./ImageSelection */ "./packages/roosterjs-editor-plugins/lib/plugins/ImageSelection/ImageSelection.ts");
23458
+ Object.defineProperty(exports, "ImageSelection", { enumerable: true, get: function () { return ImageSelection_1.default; } });
23459
+
23460
+
22999
23461
  /***/ }),
23000
23462
 
23001
23463
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/Paste.ts":
@@ -26425,12 +26887,18 @@ var INSERTER_HOVER_OFFSET = 5;
26425
26887
  * When set a different current table or change current TD, we need to update these areas
26426
26888
  */
26427
26889
  var TableEditor = /** @class */ (function () {
26428
- function TableEditor(editor, table, onChanged, onShowHelperElement, eventTarget) {
26890
+ function TableEditor(editor, table, onChanged, onShowHelperElement, contentDiv) {
26429
26891
  var _this = this;
26430
26892
  this.editor = editor;
26431
26893
  this.table = table;
26432
26894
  this.onChanged = onChanged;
26433
26895
  this.onShowHelperElement = onShowHelperElement;
26896
+ // 1, 2 - Insert a column or a row
26897
+ this.horizontalInserter = null;
26898
+ this.verticalInserter = null;
26899
+ // 3, 4 - Resize a column or a row from a cell
26900
+ this.horizontalResizer = null;
26901
+ this.verticalResizer = null;
26434
26902
  this.onFinishEditing = function () {
26435
26903
  _this.editor.focus();
26436
26904
  _this.editor.select(_this.start, _this.end);
@@ -26484,8 +26952,9 @@ var TableEditor = /** @class */ (function () {
26484
26952
  }
26485
26953
  };
26486
26954
  this.isRTL = (0, roosterjs_editor_dom_1.getComputedStyle)(table, 'direction') == 'rtl';
26487
- this.tableResizer = (0, TableResizer_1.default)(table, editor.getZoomScale(), this.isRTL, this.onStartTableResize, this.onFinishEditing, this.onShowHelperElement);
26488
- this.tableSelector = (0, TableSelector_1.default)(table, editor.getZoomScale(), this.onSelect, this.onShowHelperElement, this.getShouldShowTableSelectorHandler(this.editor.getScrollContainer(), eventTarget));
26955
+ var zoomScale = editor.getZoomScale();
26956
+ this.tableResizer = (0, TableResizer_1.default)(table, zoomScale, this.isRTL, this.onStartTableResize, this.onFinishEditing, this.onShowHelperElement);
26957
+ this.tableSelector = (0, TableSelector_1.default)(table, zoomScale, editor, this.onSelect, this.onShowHelperElement, contentDiv);
26489
26958
  this.isCurrentlyEditing = false;
26490
26959
  }
26491
26960
  TableEditor.prototype.dispose = function () {
@@ -26570,7 +27039,7 @@ var TableEditor = /** @class */ (function () {
26570
27039
  this.disposeTableInserter();
26571
27040
  }
26572
27041
  if (!this.horizontalInserter && !this.verticalInserter && td) {
26573
- var newInserter = (0, TableInserter_1.default)(this.editor, td, this.isRTL, isHorizontal, this.onInserted, this.onShowHelperElement);
27042
+ var newInserter = (0, TableInserter_1.default)(this.editor, td, this.isRTL, !!isHorizontal, this.onInserted, this.onShowHelperElement);
26574
27043
  if (isHorizontal) {
26575
27044
  this.horizontalInserter = newInserter;
26576
27045
  }
@@ -26620,21 +27089,6 @@ var TableEditor = /** @class */ (function () {
26620
27089
  }
26621
27090
  this.editor.addUndoSnapshot();
26622
27091
  };
26623
- TableEditor.prototype.getShouldShowTableSelectorHandler = function (scrollContainer, eventTarget) {
26624
- if (eventTarget && (0, roosterjs_editor_dom_1.safeInstanceOf)(eventTarget, 'HTMLElement') && scrollContainer) {
26625
- var scrollContainerRect_1 = (0, roosterjs_editor_dom_1.normalizeRect)(scrollContainer.getBoundingClientRect());
26626
- var containerRect_1 = (0, roosterjs_editor_dom_1.normalizeRect)(eventTarget.getBoundingClientRect());
26627
- if (scrollContainerRect_1 && containerRect_1) {
26628
- var scrollContainerVisibleTop_1 = scrollContainer.scrollTop - scrollContainerRect_1.top;
26629
- return function (rect) {
26630
- return containerRect_1.top <= rect.top &&
26631
- scrollContainerVisibleTop_1 <= rect.top &&
26632
- scrollContainerRect_1.top <= rect.top;
26633
- };
26634
- }
26635
- }
26636
- return function () { return true; };
26637
- };
26638
27092
  return TableEditor;
26639
27093
  }());
26640
27094
  exports.default = TableEditor;
@@ -26658,10 +27112,12 @@ exports.disposeTableEditFeature = void 0;
26658
27112
  */
26659
27113
  function disposeTableEditFeature(resizer) {
26660
27114
  var _a, _b, _c;
26661
- (_b = (_a = resizer.div) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(resizer.div);
26662
- resizer.div = null;
26663
- (_c = resizer.featureHandler) === null || _c === void 0 ? void 0 : _c.dispose();
26664
- resizer.featureHandler = null;
27115
+ if (resizer) {
27116
+ (_b = (_a = resizer.div) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(resizer.div);
27117
+ resizer.div = null;
27118
+ (_c = resizer.featureHandler) === null || _c === void 0 ? void 0 : _c.dispose();
27119
+ resizer.featureHandler = null;
27120
+ }
26665
27121
  }
26666
27122
  exports.disposeTableEditFeature = disposeTableEditFeature;
26667
27123
 
@@ -26712,6 +27168,7 @@ function createTableInserter(editor, td, isRTL, isHorizontal, onInsert, onShowHe
26712
27168
  var handler = new TableInsertHandler(div, td, isHorizontal, editor, onInsert);
26713
27169
  return { div: div, featureHandler: handler, node: td };
26714
27170
  }
27171
+ return null;
26715
27172
  }
26716
27173
  exports.default = createTableInserter;
26717
27174
  var TableInsertHandler = /** @class */ (function () {
@@ -26894,10 +27351,10 @@ var TABLE_SELECTOR_ID = '_Table_Selector';
26894
27351
  /**
26895
27352
  * @internal
26896
27353
  */
26897
- function createTableSelector(table, zoomScale, onFinishDragging, onShowHelperElement, shouldShow) {
27354
+ function createTableSelector(table, zoomScale, editor, onFinishDragging, onShowHelperElement, contentDiv) {
26898
27355
  var rect = (0, roosterjs_editor_dom_1.normalizeRect)(table.getBoundingClientRect());
26899
- if (rect && shouldShow && !shouldShow(rect)) {
26900
- return { div: null, featureHandler: null, node: table };
27356
+ if (!isTableTopVisible(editor, rect, contentDiv)) {
27357
+ return null;
26901
27358
  }
26902
27359
  var document = table.ownerDocument;
26903
27360
  var createElementData = {
@@ -26935,6 +27392,14 @@ function setSelectorDivPosition(context, trigger) {
26935
27392
  trigger.style.left = rect.left - TABLE_SELECTOR_LENGTH - 2 + "px";
26936
27393
  }
26937
27394
  }
27395
+ function isTableTopVisible(editor, rect, contentDiv) {
27396
+ var visibleViewport = editor.getVisibleViewport();
27397
+ if (contentDiv && (0, roosterjs_editor_dom_1.safeInstanceOf)(contentDiv, 'HTMLElement') && visibleViewport && rect) {
27398
+ var containerRect = (0, roosterjs_editor_dom_1.normalizeRect)(contentDiv.getBoundingClientRect());
27399
+ return containerRect.top <= rect.top && visibleViewport.top <= rect.top;
27400
+ }
27401
+ return true;
27402
+ }
26938
27403
 
26939
27404
 
26940
27405
  /***/ }),
@@ -27211,10 +27676,14 @@ var CompatibleBulletListType;
27211
27676
  * Bullet triggered by -->
27212
27677
  */
27213
27678
  CompatibleBulletListType[CompatibleBulletListType["DoubleLongArrow"] = 8] = "DoubleLongArrow";
27679
+ /**
27680
+ * Bullet type circle
27681
+ */
27682
+ CompatibleBulletListType[CompatibleBulletListType["Circle"] = 9] = "Circle";
27214
27683
  /**
27215
27684
  * Maximum value of the enum
27216
27685
  */
27217
- CompatibleBulletListType[CompatibleBulletListType["Max"] = 8] = "Max";
27686
+ CompatibleBulletListType[CompatibleBulletListType["Max"] = 9] = "Max";
27218
27687
  })(CompatibleBulletListType = exports.CompatibleBulletListType || (exports.CompatibleBulletListType = {}));
27219
27688
 
27220
27689
 
@@ -28081,6 +28550,17 @@ var CompatibleExperimentalFeatures;
28081
28550
  * e.g. We will move list items with "display: block" into previous list item and change tag to be DIV
28082
28551
  */
28083
28552
  CompatibleExperimentalFeatures["NormalizeList"] = "NormalizeList";
28553
+ /**
28554
+ * When a html image is selected, the selected image data will be stored by editor core.
28555
+ */
28556
+ CompatibleExperimentalFeatures["ImageSelection"] = "ImageSelection";
28557
+ /**
28558
+ * With this feature enabled, when writing back a list item we will re-use all
28559
+ * ancestor list elements, even if they don't match the types currently in the
28560
+ * listTypes array for that item. The only list that we will ensure is correct
28561
+ * is the one closest to the item.
28562
+ */
28563
+ CompatibleExperimentalFeatures["ReuseAllAncestorListElements"] = "ReuseAllAncestorListElements";
28084
28564
  })(CompatibleExperimentalFeatures = exports.CompatibleExperimentalFeatures || (exports.CompatibleExperimentalFeatures = {}));
28085
28565
 
28086
28566
 
@@ -28814,6 +29294,10 @@ var CompatibleSelectionRangeTypes;
28814
29294
  * Selection made inside of a single table.
28815
29295
  */
28816
29296
  CompatibleSelectionRangeTypes[CompatibleSelectionRangeTypes["TableSelection"] = 1] = "TableSelection";
29297
+ /**
29298
+ * Selection made in a image.
29299
+ */
29300
+ CompatibleSelectionRangeTypes[CompatibleSelectionRangeTypes["ImageSelection"] = 2] = "ImageSelection";
28817
29301
  })(CompatibleSelectionRangeTypes = exports.CompatibleSelectionRangeTypes || (exports.CompatibleSelectionRangeTypes = {}));
28818
29302
 
28819
29303