roosterjs 8.18.0 → 8.19.2

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
@@ -3032,7 +3032,7 @@ function setAlignment(editor, alignment) {
3032
3032
  editor.addUndoSnapshot(function () {
3033
3033
  if (editor.isFeatureEnabled("TableAlignment" /* TableAlignment */) &&
3034
3034
  isATable &&
3035
- isWholeTableSelected(selection)) {
3035
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3036
3036
  alignTable(selection, alignment);
3037
3037
  }
3038
3038
  else {
@@ -3084,25 +3084,6 @@ function alignText(editor, alignment) {
3084
3084
  (0, execCommand_1.default)(editor, command);
3085
3085
  editor.queryElements('[align]', 1 /* OnSelection */, function (node) { return (node.style.textAlign = align); });
3086
3086
  }
3087
- /**
3088
- * Check if the whole table is selected
3089
- * @param selection
3090
- * @returns
3091
- */
3092
- function isWholeTableSelected(selection) {
3093
- if (!selection) {
3094
- return false;
3095
- }
3096
- var vTable = new roosterjs_editor_dom_1.VTable(selection.table);
3097
- var _a = selection.coordinates, firstCell = _a.firstCell, lastCell = _a.lastCell;
3098
- var rowsLength = vTable.cells.length - 1;
3099
- var colIndex = vTable.cells[rowsLength].length - 1;
3100
- var firstX = firstCell.x;
3101
- var firstY = firstCell.y;
3102
- var lastX = lastCell.x;
3103
- var lastY = lastCell.y;
3104
- return firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
3105
- }
3106
3087
 
3107
3088
 
3108
3089
  /***/ }),
@@ -3289,7 +3270,6 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
3289
3270
  function setIndentation(editor, indentation) {
3290
3271
  var handler = indentation == 0 /* Increase */ ? indent : outdent;
3291
3272
  (0, blockFormat_1.default)(editor, function (region, start, end) {
3292
- var _a;
3293
3273
  var blocks = (0, roosterjs_editor_dom_1.getSelectedBlockElementsInRegion)(region, true /*createBlockIfEmpty*/);
3294
3274
  var blockGroups = [[]];
3295
3275
  for (var i = 0; i < blocks.length; i++) {
@@ -3299,15 +3279,18 @@ function setIndentation(editor, indentation) {
3299
3279
  while (blocks[i + 1] && vList.contains(blocks[i + 1].getStartNode())) {
3300
3280
  i++;
3301
3281
  }
3302
- if (((_a = vList.items[0]) === null || _a === void 0 ? void 0 : _a.getNode()) == startNode &&
3303
- vList.getListItemIndex(startNode) == vList.getStart() &&
3304
- (indentation == 0 /* Increase */ ||
3305
- editor.getElementAtCursor('blockquote', startNode))) {
3282
+ var isTabKeyTextFeaturesEnabled = editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */);
3283
+ vList.rootList.style.listStylePosition = 'inside';
3284
+ if (isTabKeyTextFeaturesEnabled &&
3285
+ isFirstItem(vList, startNode) &&
3286
+ shouldHandleWithBlockquotes(indentation, editor, startNode)) {
3306
3287
  var block = editor.getBlockElementAtNode(vList.rootList);
3307
3288
  blockGroups.push([block]);
3308
3289
  }
3309
3290
  else {
3310
- vList.setIndentation(start, end, indentation);
3291
+ indentation == 1 /* Decrease */
3292
+ ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3293
+ : vList.setIndentation(start, end, indentation);
3311
3294
  vList.writeBack();
3312
3295
  blockGroups.push([]);
3313
3296
  }
@@ -3317,6 +3300,20 @@ function setIndentation(editor, indentation) {
3317
3300
  }
3318
3301
  }
3319
3302
  blockGroups.forEach(function (group) { return handler(region, group); });
3303
+ }, function () {
3304
+ var selection = editor.getSelectionRangeEx();
3305
+ if (selection.type == 1 /* TableSelection */ &&
3306
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3307
+ if (indentation == 1 /* Decrease */) {
3308
+ var quote = editor.getElementAtCursor('blockquote', selection.table);
3309
+ (0, roosterjs_editor_dom_1.unwrap)(quote);
3310
+ }
3311
+ else if (indentation == 0 /* Increase */) {
3312
+ (0, roosterjs_editor_dom_1.wrap)(selection.table, 2 /* BlockquoteWrapper */);
3313
+ }
3314
+ return false;
3315
+ }
3316
+ return true;
3320
3317
  });
3321
3318
  }
3322
3319
  exports.default = setIndentation;
@@ -3341,6 +3338,14 @@ function outdent(region, blocks) {
3341
3338
  }
3342
3339
  });
3343
3340
  }
3341
+ function isFirstItem(vList, startNode) {
3342
+ var _a;
3343
+ return (((_a = vList.items[0]) === null || _a === void 0 ? void 0 : _a.getNode()) == startNode &&
3344
+ vList.getListItemIndex(startNode) == (vList.getStart() || 1));
3345
+ }
3346
+ function shouldHandleWithBlockquotes(indentation, editor, startNode) {
3347
+ return (indentation == 0 /* Increase */ || editor.getElementAtCursor('blockquote', startNode));
3348
+ }
3344
3349
 
3345
3350
 
3346
3351
  /***/ }),
@@ -3917,12 +3922,12 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
3917
3922
  function editTable(editor, operation) {
3918
3923
  var td = editor.getElementAtCursor('TD,TH');
3919
3924
  if (td) {
3920
- editor.addUndoSnapshot(function (start, end) {
3925
+ editor.addUndoSnapshot(function () {
3921
3926
  var vtable = new roosterjs_editor_dom_1.VTable(td);
3927
+ saveTableSelection(editor, vtable);
3922
3928
  vtable.edit(operation);
3923
3929
  vtable.writeBack();
3924
- //Adding replaceNode to transform color when the theme is switched to dark.
3925
- editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
3930
+ editor.transformToDarkColor(vtable.table);
3926
3931
  editor.focus();
3927
3932
  var cellToSelect = calculateCellToSelect(operation, vtable.row, vtable.col);
3928
3933
  editor.select(vtable.getCell(cellToSelect.newRow, cellToSelect.newCol).td, 0 /* Begin */);
@@ -3954,6 +3959,12 @@ function calculateCellToSelect(operation, currentRow, currentCol) {
3954
3959
  newCol: newCol,
3955
3960
  };
3956
3961
  }
3962
+ function saveTableSelection(editor, vtable) {
3963
+ var selection = editor.getSelectionRangeEx();
3964
+ if (selection && selection.type === 1 /* TableSelection */) {
3965
+ vtable.selection = selection.coordinates;
3966
+ }
3967
+ }
3957
3968
 
3958
3969
 
3959
3970
  /***/ }),
@@ -3982,8 +3993,7 @@ function formatTable(editor, format, table) {
3982
3993
  var vtable = new roosterjs_editor_dom_1.VTable(table);
3983
3994
  vtable.applyFormat(format);
3984
3995
  vtable.writeBack();
3985
- //Adding replaceNode to transform color when the theme is switched to dark.
3986
- editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
3996
+ editor.transformToDarkColor(vtable.table);
3987
3997
  editor.focus();
3988
3998
  editor.select(start, end);
3989
3999
  }, "Format" /* Format */);
@@ -4411,6 +4421,9 @@ function toggleListType(editor, listType, startNumber, includeSiblingLists) {
4411
4421
  : (0, roosterjs_editor_dom_1.createVListFromRegion)(region, includeSiblingLists);
4412
4422
  if (vList) {
4413
4423
  vList.changeListType(start, end, listType);
4424
+ if (editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */)) {
4425
+ vList.rootList.style.listStylePosition = 'inside';
4426
+ }
4414
4427
  vList.writeBack();
4415
4428
  }
4416
4429
  });
@@ -4429,6 +4442,17 @@ exports.default = toggleListType;
4429
4442
 
4430
4443
  "use strict";
4431
4444
 
4445
+ var __assign = (this && this.__assign) || function () {
4446
+ __assign = Object.assign || function(t) {
4447
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4448
+ s = arguments[i];
4449
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
4450
+ t[p] = s[p];
4451
+ }
4452
+ return t;
4453
+ };
4454
+ return __assign.apply(this, arguments);
4455
+ };
4432
4456
  Object.defineProperty(exports, "__esModule", { value: true });
4433
4457
  exports.addUndoSnapshot = void 0;
4434
4458
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
@@ -4444,22 +4468,17 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
4444
4468
  var addUndoSnapshot = function (core, callback, changeSource, canUndoByBackspace) {
4445
4469
  var undoState = core.undo;
4446
4470
  var isNested = undoState.isNested;
4447
- var isShadowEdit = !!core.lifecycle.shadowEditFragment;
4448
4471
  var data;
4449
4472
  if (!isNested) {
4450
4473
  undoState.isNested = true;
4451
- if (!isShadowEdit) {
4452
- undoState.snapshotsService.addSnapshot(core.api.getContent(core, 2 /* RawHTMLWithSelection */), canUndoByBackspace);
4453
- undoState.hasNewContent = false;
4454
- }
4474
+ addUndoSnapshotInternal(core, canUndoByBackspace);
4455
4475
  }
4456
4476
  try {
4457
4477
  if (callback) {
4458
4478
  var range = core.api.getSelectionRange(core, true /*tryGetFromCache*/);
4459
4479
  data = callback(range && roosterjs_editor_dom_1.Position.getStart(range).normalize(), range && roosterjs_editor_dom_1.Position.getEnd(range).normalize());
4460
- if (!isNested && !isShadowEdit) {
4461
- undoState.snapshotsService.addSnapshot(core.api.getContent(core, 2 /* RawHTMLWithSelection */), false /*isAutoCompleteSnapshot*/);
4462
- undoState.hasNewContent = false;
4480
+ if (!isNested) {
4481
+ addUndoSnapshotInternal(core, false /*isAutoCompleteSnapshot*/);
4463
4482
  }
4464
4483
  }
4465
4484
  }
@@ -4485,6 +4504,19 @@ var addUndoSnapshot = function (core, callback, changeSource, canUndoByBackspace
4485
4504
  }
4486
4505
  };
4487
4506
  exports.addUndoSnapshot = addUndoSnapshot;
4507
+ function addUndoSnapshotInternal(core, canUndoByBackspace) {
4508
+ if (!core.lifecycle.shadowEditFragment) {
4509
+ var rangeEx = core.api.getSelectionRangeEx(core);
4510
+ var isDarkMode = core.lifecycle.isDarkMode;
4511
+ var metadata = (rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 1 /* TableSelection */
4512
+ ? __assign({ type: 1 /* TableSelection */, tableId: rangeEx.table.id, isDarkMode: isDarkMode }, rangeEx.coordinates) : __assign({ type: 0 /* Normal */, isDarkMode: isDarkMode, start: [], end: [] }, ((0, roosterjs_editor_dom_1.getSelectionPath)(core.contentDiv, rangeEx.ranges[0]) || {}));
4513
+ core.undo.snapshotsService.addSnapshot({
4514
+ html: core.contentDiv.innerHTML,
4515
+ metadata: metadata,
4516
+ }, canUndoByBackspace);
4517
+ core.undo.hasNewContent = false;
4518
+ }
4519
+ }
4488
4520
 
4489
4521
 
4490
4522
  /***/ }),
@@ -5424,10 +5456,10 @@ var restoreUndoSnapshot = function (core, step) {
5424
5456
  core.api.addUndoSnapshot(core, null /*callback*/, null /*changeSource*/, false /*canUndoByBackspace*/);
5425
5457
  }
5426
5458
  var snapshot = core.undo.snapshotsService.move(step);
5427
- if (snapshot != null) {
5459
+ if (snapshot && snapshot.html != null) {
5428
5460
  try {
5429
5461
  core.undo.isRestoring = true;
5430
- core.api.setContent(core, snapshot, true /*triggerContentChangedEvent*/);
5462
+ core.api.setContent(core, snapshot.html, true /*triggerContentChangedEvent*/, snapshot.metadata);
5431
5463
  }
5432
5464
  finally {
5433
5465
  core.undo.isRestoring = false;
@@ -5530,7 +5562,11 @@ var selectTable = function (core, table, coordinates) {
5530
5562
  ensureUniqueId(table, TABLE_ID);
5531
5563
  ensureUniqueId(core.contentDiv, CONTENT_DIV_ID);
5532
5564
  var ranges = select(core, table, coordinates);
5533
- core.api.selectRange(core, (0, roosterjs_editor_dom_1.createRange)(new roosterjs_editor_dom_1.Position(table.rows.item(coordinates.firstCell.y).cells.item(coordinates.firstCell.x), 0 /* Begin */)));
5565
+ if (!isMergedCell(table, coordinates)) {
5566
+ core.api.selectRange(core, (0, roosterjs_editor_dom_1.createRange)(new roosterjs_editor_dom_1.Position(table.rows
5567
+ .item(coordinates.firstCell.y)
5568
+ .cells.item(coordinates.firstCell.x), 0 /* Begin */)));
5569
+ }
5534
5570
  return {
5535
5571
  type: 1 /* TableSelection */,
5536
5572
  ranges: ranges,
@@ -5693,6 +5729,10 @@ function areValidCoordinates(input) {
5693
5729
  function isValidCoordinate(input) {
5694
5730
  return (!!input || input == 0) && input > -1;
5695
5731
  }
5732
+ function isMergedCell(table, coordinates) {
5733
+ var firstCell = coordinates.firstCell;
5734
+ return !(table.rows.item(firstCell.y) && table.rows.item(firstCell.y).cells.item(firstCell.x));
5735
+ }
5696
5736
 
5697
5737
 
5698
5738
  /***/ }),
@@ -5709,6 +5749,7 @@ function isValidCoordinate(input) {
5709
5749
  Object.defineProperty(exports, "__esModule", { value: true });
5710
5750
  exports.setContent = void 0;
5711
5751
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5752
+ var roosterjs_editor_dom_2 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5712
5753
  /**
5713
5754
  * @internal
5714
5755
  * Set HTML content to this editor. All existing content will be replaced. A ContentChanged event will be triggered
@@ -5717,20 +5758,24 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
5717
5758
  * @param content HTML content to set in
5718
5759
  * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
5719
5760
  */
5720
- var setContent = function (core, content, triggerContentChangedEvent) {
5761
+ var setContent = function (core, content, triggerContentChangedEvent, metadata) {
5721
5762
  var contentChanged = false;
5722
5763
  if (core.contentDiv.innerHTML != content) {
5723
5764
  core.api.triggerEvent(core, {
5724
5765
  eventType: 20 /* BeforeSetContent */,
5725
5766
  newContent: content,
5726
5767
  }, true /*broadcast*/);
5727
- var range = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(core.contentDiv, content, core.trustedHTMLHandler);
5728
- core.api.selectRange(core, range);
5768
+ var metadataFromContent = (0, roosterjs_editor_dom_2.setHtmlWithMetadata)(core.contentDiv, content, core.trustedHTMLHandler);
5769
+ metadata = metadata || metadataFromContent;
5770
+ selectContentMetadata(core, metadata);
5771
+ contentChanged = true;
5772
+ }
5773
+ var isDarkMode = core.lifecycle.isDarkMode;
5774
+ if ((!metadata && isDarkMode) || (metadata && !!metadata.isDarkMode != !!isDarkMode)) {
5775
+ core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, isDarkMode ? 0 /* LightToDark */ : 1 /* DarkToLight */, true /*forceTransform*/);
5729
5776
  contentChanged = true;
5730
5777
  }
5731
- // Convert content even if it hasn't changed.
5732
- core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
5733
- if (triggerContentChangedEvent && (contentChanged || core.lifecycle.isDarkMode)) {
5778
+ if (triggerContentChangedEvent && contentChanged) {
5734
5779
  core.api.triggerEvent(core, {
5735
5780
  eventType: 7 /* ContentChanged */,
5736
5781
  source: "SetContent" /* SetContent */,
@@ -5738,6 +5783,20 @@ var setContent = function (core, content, triggerContentChangedEvent) {
5738
5783
  }
5739
5784
  };
5740
5785
  exports.setContent = setContent;
5786
+ function selectContentMetadata(core, metadata) {
5787
+ switch (metadata === null || metadata === void 0 ? void 0 : metadata.type) {
5788
+ case 0 /* Normal */:
5789
+ var range = (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, metadata.start, metadata.end);
5790
+ core.api.selectRange(core, range);
5791
+ break;
5792
+ case 1 /* TableSelection */:
5793
+ var table = (0, roosterjs_editor_dom_1.queryElements)(core.contentDiv, '#' + metadata.tableId)[0];
5794
+ if (table) {
5795
+ core.api.selectTable(core, table, metadata);
5796
+ }
5797
+ break;
5798
+ }
5799
+ }
5741
5800
 
5742
5801
 
5743
5802
  /***/ }),
@@ -5848,52 +5907,70 @@ var ColorAttributeName = [
5848
5907
  * @param includeSelf True to transform the root node as well, otherwise false
5849
5908
  * @param callback The callback function to invoke before do color transformation
5850
5909
  * @param direction To specify the transform direction, light to dark, or dark to light
5910
+ * @param forceTransform By default this function will only work when editor core is in dark mode.
5911
+ * Pass true to this value to force do color transformation even editor core is in light mode
5851
5912
  */
5852
- var transformColor = function (core, rootNode, includeSelf, callback, direction) {
5853
- var elementsToTransform = core.lifecycle.isDarkMode ? getAll(rootNode, includeSelf) : [];
5854
- var transformFunction = direction == 1 /* DarkToLight */
5855
- ? transformToLightMode
5856
- : core.lifecycle.onExternalContentTransform ||
5857
- (function (element) { return transformToDarkMode(element, core.lifecycle.getDarkColor); });
5913
+ var transformColor = function (core, rootNode, includeSelf, callback, direction, forceTransform) {
5914
+ var elements = forceTransform || core.lifecycle.isDarkMode ? getAll(rootNode, includeSelf) : [];
5858
5915
  callback === null || callback === void 0 ? void 0 : callback();
5859
- elementsToTransform.forEach(function (element) { return (element === null || element === void 0 ? void 0 : element.dataset) && element.style && transformFunction(element); });
5916
+ if (direction == 1 /* DarkToLight */) {
5917
+ transformToLightMode(elements);
5918
+ }
5919
+ else if (core.lifecycle.onExternalContentTransform) {
5920
+ elements.forEach(function (element) { return core.lifecycle.onExternalContentTransform(element); });
5921
+ }
5922
+ else {
5923
+ transformToDarkMode(elements, core.lifecycle.getDarkColor);
5924
+ }
5860
5925
  };
5861
5926
  exports.transformColor = transformColor;
5862
- function transformToLightMode(element) {
5863
- ColorAttributeName.forEach(function (names) {
5864
- // Reset color styles based on the content of the ogsc/ogsb data element.
5865
- // If those data properties are empty or do not exist, set them anyway to clear the content.
5866
- element.style.setProperty(names[0 /* CssColor */], getValueOrDefault(element.dataset[names[2 /* CssDataSet */]], ''));
5867
- delete element.dataset[names[2 /* CssDataSet */]];
5868
- // Some elements might have set attribute colors. We need to reset these as well.
5869
- var value = element.dataset[names[3 /* HtmlDataSet */]];
5870
- if (getValueOrDefault(value, null)) {
5871
- element.setAttribute(names[1 /* HtmlColor */], value);
5872
- }
5873
- else {
5874
- element.removeAttribute(names[1 /* HtmlColor */]);
5875
- }
5876
- delete element.dataset[names[3 /* HtmlDataSet */]];
5927
+ function transformToLightMode(elements) {
5928
+ elements.forEach(function (element) {
5929
+ ColorAttributeName.forEach(function (names) {
5930
+ // Reset color styles based on the content of the ogsc/ogsb data element.
5931
+ // If those data properties are empty or do not exist, set them anyway to clear the content.
5932
+ element.style.setProperty(names[0 /* CssColor */], getValueOrDefault(element.dataset[names[2 /* CssDataSet */]], ''));
5933
+ delete element.dataset[names[2 /* CssDataSet */]];
5934
+ // Some elements might have set attribute colors. We need to reset these as well.
5935
+ var value = element.dataset[names[3 /* HtmlDataSet */]];
5936
+ if (getValueOrDefault(value, null)) {
5937
+ element.setAttribute(names[1 /* HtmlColor */], value);
5938
+ }
5939
+ else {
5940
+ element.removeAttribute(names[1 /* HtmlColor */]);
5941
+ }
5942
+ delete element.dataset[names[3 /* HtmlDataSet */]];
5943
+ });
5877
5944
  });
5878
5945
  }
5879
- function transformToDarkMode(element, getDarkColor) {
5880
- var computedValues = (0, roosterjs_editor_dom_1.getComputedStyles)(element, ['color', 'background-color']);
5881
- ColorAttributeName.forEach(function (names, index) {
5882
- var styleColor = element.style.getPropertyValue(names[0 /* CssColor */]);
5883
- var attrColor = element.getAttribute(names[1 /* HtmlColor */]);
5884
- if (!element.dataset[names[2 /* CssDataSet */]] &&
5885
- !element.dataset[names[3 /* HtmlDataSet */]] &&
5886
- (styleColor || attrColor) &&
5887
- styleColor != 'inherit' // For inherit style, no need to change it and let it keep inherit from parent element
5888
- ) {
5889
- var newColor = getDarkColor(computedValues[index] || styleColor || attrColor);
5946
+ function transformToDarkMode(elements, getDarkColor) {
5947
+ ColorAttributeName.forEach(function (names) {
5948
+ elements
5949
+ .map(function (element) {
5950
+ var styleColor = element.style.getPropertyValue(names[0 /* CssColor */]);
5951
+ var attrColor = element.getAttribute(names[1 /* HtmlColor */]);
5952
+ return !element.dataset[names[2 /* CssDataSet */]] &&
5953
+ !element.dataset[names[3 /* HtmlDataSet */]] &&
5954
+ (styleColor || attrColor) &&
5955
+ styleColor != 'inherit' // For inherit style, no need to change it and let it keep inherit from parent element
5956
+ ? {
5957
+ element: element,
5958
+ styleColor: styleColor,
5959
+ attrColor: attrColor,
5960
+ newColor: getDarkColor(styleColor || attrColor),
5961
+ }
5962
+ : null;
5963
+ })
5964
+ .filter(function (x) { return !!x; })
5965
+ .forEach(function (_a) {
5966
+ var element = _a.element, styleColor = _a.styleColor, attrColor = _a.attrColor, newColor = _a.newColor;
5890
5967
  element.style.setProperty(names[0 /* CssColor */], newColor, 'important');
5891
5968
  element.dataset[names[2 /* CssDataSet */]] = styleColor || '';
5892
5969
  if (attrColor) {
5893
5970
  element.setAttribute(names[1 /* HtmlColor */], newColor);
5894
5971
  element.dataset[names[3 /* HtmlDataSet */]] = attrColor;
5895
5972
  }
5896
- }
5973
+ });
5897
5974
  });
5898
5975
  }
5899
5976
  function getValueOrDefault(value, defaultValue) {
@@ -5912,7 +5989,14 @@ function getAll(rootNode, includeSelf) {
5912
5989
  var allChildren = rootNode.querySelectorAll('*');
5913
5990
  (0, roosterjs_editor_dom_1.arrayPush)(result, (0, roosterjs_editor_dom_1.toArray)(allChildren));
5914
5991
  }
5915
- return result;
5992
+ return result.filter(isHTMLElement);
5993
+ }
5994
+ // This is not a strict check, we just need to make sure this element has style so that we can set style to it
5995
+ // We don't use safeInstanceOf() here since this function will be called very frequently when extract html content
5996
+ // in dark mode, so we need to make sure this check is fast enough
5997
+ function isHTMLElement(element) {
5998
+ var htmlElement = element;
5999
+ return !!htmlElement.style && !!htmlElement.dataset;
5916
6000
  }
5917
6001
 
5918
6002
 
@@ -6043,7 +6127,6 @@ var CopyPastePlugin = /** @class */ (function () {
6043
6127
  var _this = this;
6044
6128
  var selection = this.editor.getSelectionRangeEx();
6045
6129
  if (selection && !selection.areAllCollapsed) {
6046
- var originalRange_1 = selection.ranges[0];
6047
6130
  var html = this.editor.getContent(2 /* RawHTMLWithSelection */);
6048
6131
  var tempDiv_1 = this.getTempDiv(true /*forceInLightMode*/);
6049
6132
  var newRange = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(tempDiv_1, html, this.editor.getTrustedHTMLHandler());
@@ -6057,7 +6140,7 @@ var CopyPastePlugin = /** @class */ (function () {
6057
6140
  isCut: isCut,
6058
6141
  });
6059
6142
  this.editor.runAsync(function (editor) {
6060
- _this.cleanUpAndRestoreSelection(tempDiv_1, originalRange_1, !isCut /* isCopy */);
6143
+ _this.cleanUpAndRestoreSelection(tempDiv_1, selection, !isCut /* isCopy */);
6061
6144
  if (isCut) {
6062
6145
  editor.addUndoSnapshot(function () {
6063
6146
  var position = _this.editor.deleteSelectedContent();
@@ -6086,15 +6169,35 @@ var CopyPastePlugin = /** @class */ (function () {
6086
6169
  return div;
6087
6170
  };
6088
6171
  CopyPastePlugin.prototype.cleanUpAndRestoreSelection = function (tempDiv, range, isCopy) {
6089
- if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6090
- range.collapse();
6172
+ var _a, _b;
6173
+ if (!!((_a = range) === null || _a === void 0 ? void 0 : _a.type) || range.type == 0) {
6174
+ var selection = range;
6175
+ switch (selection.type) {
6176
+ case 1 /* TableSelection */:
6177
+ this.editor.select(selection.table, selection.coordinates);
6178
+ break;
6179
+ case 0 /* Normal */:
6180
+ var range_1 = (_b = selection.ranges) === null || _b === void 0 ? void 0 : _b[0];
6181
+ this.restoreRange(range_1, isCopy);
6182
+ break;
6183
+ }
6184
+ }
6185
+ else {
6186
+ this.restoreRange(range, isCopy);
6091
6187
  }
6092
- this.editor.select(range);
6093
6188
  tempDiv.style.backgroundColor = '';
6094
6189
  tempDiv.style.color = '';
6095
6190
  tempDiv.style.display = 'none';
6096
6191
  (0, roosterjs_editor_dom_1.moveChildNodes)(tempDiv);
6097
6192
  };
6193
+ CopyPastePlugin.prototype.restoreRange = function (range, isCopy) {
6194
+ if (range) {
6195
+ if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6196
+ range.collapse();
6197
+ }
6198
+ this.editor.select(range);
6199
+ }
6200
+ };
6098
6201
  return CopyPastePlugin;
6099
6202
  }());
6100
6203
  exports.default = CopyPastePlugin;
@@ -7039,6 +7142,140 @@ var MouseUpPlugin = /** @class */ (function () {
7039
7142
  exports.default = MouseUpPlugin;
7040
7143
 
7041
7144
 
7145
+ /***/ }),
7146
+
7147
+ /***/ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts":
7148
+ /*!********************************************************************************!*\
7149
+ !*** ./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts ***!
7150
+ \********************************************************************************/
7151
+ /*! no static exports found */
7152
+ /***/ (function(module, exports, __webpack_require__) {
7153
+
7154
+ "use strict";
7155
+
7156
+ Object.defineProperty(exports, "__esModule", { value: true });
7157
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7158
+ /**
7159
+ * @internal
7160
+ * NormalizeTable plugin makes sure each table in editor has TBODY/THEAD/TFOOT tag around TR tags
7161
+ *
7162
+ * When we retrieve HTML content using innerHTML, browser will always add TBODY around TR nodes if there is not.
7163
+ * This causes some issue when we restore the HTML content with selection path since the selection path is
7164
+ * deeply coupled with DOM structure. So we need to always make sure there is already TBODY tag whenever
7165
+ * new table is inserted, to make sure the selection path we created is correct.
7166
+ */
7167
+ var NormalizeTablePlugin = /** @class */ (function () {
7168
+ function NormalizeTablePlugin() {
7169
+ }
7170
+ /**
7171
+ * Get a friendly name of this plugin
7172
+ */
7173
+ NormalizeTablePlugin.prototype.getName = function () {
7174
+ return 'NormalizeTable';
7175
+ };
7176
+ /**
7177
+ * The first method that editor will call to a plugin when editor is initializing.
7178
+ * It will pass in the editor instance, plugin should take this chance to save the
7179
+ * editor reference so that it can call to any editor method or format API later.
7180
+ * @param editor The editor object
7181
+ */
7182
+ NormalizeTablePlugin.prototype.initialize = function (editor) {
7183
+ this.editor = editor;
7184
+ };
7185
+ /**
7186
+ * The last method that editor will call to a plugin before it is disposed.
7187
+ * Plugin can take this chance to clear the reference to editor. After this method is
7188
+ * called, plugin should not call to any editor method since it will result in error.
7189
+ */
7190
+ NormalizeTablePlugin.prototype.dispose = function () {
7191
+ this.editor = null;
7192
+ };
7193
+ /**
7194
+ * Core method for a plugin. Once an event happens in editor, editor will call this
7195
+ * method of each plugin to handle the event as long as the event is not handled
7196
+ * exclusively by another plugin.
7197
+ * @param event The event to handle:
7198
+ */
7199
+ NormalizeTablePlugin.prototype.onPluginEvent = function (event) {
7200
+ switch (event.eventType) {
7201
+ case 11 /* EditorReady */:
7202
+ case 7 /* ContentChanged */:
7203
+ this.normalizeTables(this.editor.queryElements('table'));
7204
+ break;
7205
+ case 10 /* BeforePaste */:
7206
+ this.normalizeTables((0, roosterjs_editor_dom_1.toArray)(event.fragment.querySelectorAll('table')));
7207
+ break;
7208
+ case 5 /* MouseDown */:
7209
+ this.normalizeTableFromEvent(event.rawEvent);
7210
+ break;
7211
+ case 0 /* KeyDown */:
7212
+ if (event.rawEvent.shiftKey) {
7213
+ this.normalizeTableFromEvent(event.rawEvent);
7214
+ }
7215
+ break;
7216
+ }
7217
+ };
7218
+ NormalizeTablePlugin.prototype.normalizeTableFromEvent = function (event) {
7219
+ var table = this.editor.getElementAtCursor('table', event.target);
7220
+ if (table) {
7221
+ this.normalizeTables([table]);
7222
+ }
7223
+ };
7224
+ NormalizeTablePlugin.prototype.normalizeTables = function (tables) {
7225
+ if (tables.length > 0) {
7226
+ var rangeEx = this.editor.getSelectionRangeEx();
7227
+ var _a = ((rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 0 /* Normal */ && rangeEx.ranges[0]) || {}, startContainer = _a.startContainer, endContainer = _a.endContainer, startOffset = _a.startOffset, endOffset = _a.endOffset;
7228
+ var isChanged = normalizeTables(tables);
7229
+ if (isChanged) {
7230
+ if (startContainer && endContainer) {
7231
+ this.editor.select(startContainer, startOffset, endContainer, endOffset);
7232
+ }
7233
+ else if ((rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 1 /* TableSelection */) {
7234
+ this.editor.select(rangeEx.table, rangeEx.coordinates);
7235
+ }
7236
+ }
7237
+ }
7238
+ };
7239
+ return NormalizeTablePlugin;
7240
+ }());
7241
+ exports.default = NormalizeTablePlugin;
7242
+ function normalizeTables(tables) {
7243
+ var isDOMChanged = false;
7244
+ tables.forEach(function (table) {
7245
+ var tbody = null;
7246
+ for (var child = table.firstChild; child; child = child.nextSibling) {
7247
+ var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(child);
7248
+ switch (tag) {
7249
+ case 'TR':
7250
+ if (!tbody) {
7251
+ tbody = table.ownerDocument.createElement('tbody');
7252
+ table.insertBefore(tbody, child);
7253
+ }
7254
+ tbody.appendChild(child);
7255
+ child = tbody;
7256
+ isDOMChanged = true;
7257
+ break;
7258
+ case 'TBODY':
7259
+ if (tbody) {
7260
+ (0, roosterjs_editor_dom_1.moveChildNodes)(tbody, child, true /*keepExistingChildren*/);
7261
+ child.parentNode.removeChild(child);
7262
+ child = tbody;
7263
+ isDOMChanged = true;
7264
+ }
7265
+ else {
7266
+ tbody = child;
7267
+ }
7268
+ break;
7269
+ default:
7270
+ tbody = null;
7271
+ break;
7272
+ }
7273
+ }
7274
+ });
7275
+ return isDOMChanged;
7276
+ }
7277
+
7278
+
7042
7279
  /***/ }),
7043
7280
 
7044
7281
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts":
@@ -7231,7 +7468,9 @@ var UndoPlugin = /** @class */ (function () {
7231
7468
  */
7232
7469
  function UndoPlugin(options) {
7233
7470
  this.state = {
7234
- snapshotsService: options.undoSnapshotService || createUndoSnapshots(),
7471
+ snapshotsService: options.undoMetadataSnapshotService ||
7472
+ createUndoSnapshotServiceBridge(options.undoSnapshotService) ||
7473
+ createUndoSnapshots(),
7235
7474
  isRestoring: false,
7236
7475
  hasNewContent: false,
7237
7476
  isNested: false,
@@ -7301,7 +7540,9 @@ var UndoPlugin = /** @class */ (function () {
7301
7540
  this.addUndoSnapshot();
7302
7541
  break;
7303
7542
  case 7 /* ContentChanged */:
7304
- if (!this.state.isRestoring) {
7543
+ if (!(this.state.isRestoring ||
7544
+ event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
7545
+ event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
7305
7546
  this.clearRedoForInput();
7306
7547
  }
7307
7548
  break;
@@ -7387,12 +7628,26 @@ function createUndoSnapshots() {
7387
7628
  canMove: function (delta) { return (0, roosterjs_editor_dom_1.canMoveCurrentSnapshot)(snapshots, delta); },
7388
7629
  move: function (delta) { return (0, roosterjs_editor_dom_1.moveCurrentSnapshot)(snapshots, delta); },
7389
7630
  addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7390
- return (0, roosterjs_editor_dom_1.addSnapshot)(snapshots, snapshot, isAutoCompleteSnapshot);
7631
+ return (0, roosterjs_editor_dom_1.addSnapshotV2)(snapshots, snapshot, isAutoCompleteSnapshot);
7391
7632
  },
7392
- clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshots)(snapshots); },
7633
+ clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshotsV2)(snapshots); },
7393
7634
  canUndoAutoComplete: function () { return (0, roosterjs_editor_dom_1.canUndoAutoComplete)(snapshots); },
7394
7635
  };
7395
7636
  }
7637
+ function createUndoSnapshotServiceBridge(service) {
7638
+ return service
7639
+ ? {
7640
+ canMove: function (delta) { return service.canMove(delta); },
7641
+ move: function (delta) { return ({ html: service.move(delta), metadata: null }); },
7642
+ addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7643
+ return service.addSnapshot(snapshot.html +
7644
+ (snapshot.metadata ? "<!--" + JSON.stringify(snapshot.metadata) + "-->" : ''), isAutoCompleteSnapshot);
7645
+ },
7646
+ clearRedo: function () { return service.clearRedo(); },
7647
+ canUndoAutoComplete: function () { return service.canUndoAutoComplete(); },
7648
+ }
7649
+ : undefined;
7650
+ }
7396
7651
 
7397
7652
 
7398
7653
  /***/ }),
@@ -7414,6 +7669,7 @@ var EditPlugin_1 = __webpack_require__(/*! ./EditPlugin */ "./packages/roosterjs
7414
7669
  var EntityPlugin_1 = __webpack_require__(/*! ./EntityPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/EntityPlugin.ts");
7415
7670
  var LifecyclePlugin_1 = __webpack_require__(/*! ./LifecyclePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/LifecyclePlugin.ts");
7416
7671
  var MouseUpPlugin_1 = __webpack_require__(/*! ./MouseUpPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/MouseUpPlugin.ts");
7672
+ var NormalizeTablePlugin_1 = __webpack_require__(/*! ./NormalizeTablePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts");
7417
7673
  var PendingFormatStatePlugin_1 = __webpack_require__(/*! ./PendingFormatStatePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts");
7418
7674
  var TypeInContainerPlugin_1 = __webpack_require__(/*! ./TypeInContainerPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/TypeInContainerPlugin.ts");
7419
7675
  var UndoPlugin_1 = __webpack_require__(/*! ./UndoPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/UndoPlugin.ts");
@@ -7438,6 +7694,7 @@ function createCorePlugins(contentDiv, options) {
7438
7694
  mouseUp: map.mouseUp || new MouseUpPlugin_1.default(),
7439
7695
  copyPaste: map.copyPaste || new CopyPastePlugin_1.default(options),
7440
7696
  entity: map.entity || new EntityPlugin_1.default(),
7697
+ normalizeTable: map.normalizeTable || new NormalizeTablePlugin_1.default(),
7441
7698
  lifecycle: map.lifecycle || new LifecyclePlugin_1.default(options, contentDiv),
7442
7699
  };
7443
7700
  }
@@ -8094,12 +8351,13 @@ var Editor = /** @class */ (function () {
8094
8351
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
8095
8352
  */
8096
8353
  Editor.prototype.setDarkModeState = function (nextDarkMode) {
8097
- if (this.isDarkMode() == nextDarkMode) {
8354
+ if (this.isDarkMode() == !!nextDarkMode) {
8098
8355
  return;
8099
8356
  }
8100
- var currentContent = this.getContent(0 /* CleanHTML */);
8357
+ this.core.api.transformColor(this.core, this.core.contentDiv, false /*includeSelf*/, null /*callback*/, nextDarkMode
8358
+ ? 0 /* LightToDark */
8359
+ : 1 /* DarkToLight */, true /*forceTransform*/);
8101
8360
  this.triggerContentChangedEvent(nextDarkMode ? "SwitchToDarkMode" /* SwitchToDarkMode */ : "SwitchToLightMode" /* SwitchToLightMode */);
8102
- this.setContent(currentContent);
8103
8361
  };
8104
8362
  /**
8105
8363
  * Check if the editor is in dark mode
@@ -8108,6 +8366,13 @@ var Editor = /** @class */ (function () {
8108
8366
  Editor.prototype.isDarkMode = function () {
8109
8367
  return this.core.lifecycle.isDarkMode;
8110
8368
  };
8369
+ /**
8370
+ * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
8371
+ * @param node The node to transform
8372
+ */
8373
+ Editor.prototype.transformToDarkColor = function (node) {
8374
+ this.core.api.transformColor(this.core, node, true /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
8375
+ };
8111
8376
  /**
8112
8377
  * Make the editor in "Shadow Edit" mode.
8113
8378
  * In Shadow Edit mode, all format change will finally be ignored.
@@ -8272,7 +8537,8 @@ var NodeBlockElement = /** @class */ (function () {
8272
8537
  * Get the text content of this block element
8273
8538
  */
8274
8539
  NodeBlockElement.prototype.getTextContent = function () {
8275
- return this.element ? this.element.textContent : '';
8540
+ var _a;
8541
+ return ((_a = this.element) === null || _a === void 0 ? void 0 : _a.textContent) || '';
8276
8542
  };
8277
8543
  return NodeBlockElement;
8278
8544
  }());
@@ -8316,10 +8582,11 @@ var StartEndBlockElement = /** @class */ (function () {
8316
8582
  this.endNode = endNode;
8317
8583
  }
8318
8584
  StartEndBlockElement.getBlockContext = function (node) {
8319
- while (node && !(0, isBlockElement_1.default)(node)) {
8320
- node = node.parentNode;
8585
+ var currentNode = node;
8586
+ while (currentNode && !(0, isBlockElement_1.default)(currentNode)) {
8587
+ currentNode = currentNode.parentNode;
8321
8588
  }
8322
- return node;
8589
+ return currentNode;
8323
8590
  };
8324
8591
  /**
8325
8592
  * Collapse this element to a single DOM element.
@@ -8327,7 +8594,10 @@ var StartEndBlockElement = /** @class */ (function () {
8327
8594
  * If the content nodes are included in root node with other nodes, split root node
8328
8595
  */
8329
8596
  StartEndBlockElement.prototype.collapseToSingleElement = function () {
8330
- var nodes = (0, collapseNodes_1.default)(StartEndBlockElement.getBlockContext(this.startNode), this.startNode, this.endNode, true /*canSplitParent*/);
8597
+ var nodeContext = StartEndBlockElement.getBlockContext(this.startNode);
8598
+ var nodes = nodeContext
8599
+ ? (0, collapseNodes_1.default)(nodeContext, this.startNode, this.endNode, true /*canSplitParent*/)
8600
+ : [];
8331
8601
  var blockContext = StartEndBlockElement.getBlockContext(this.startNode);
8332
8602
  while (nodes[0] &&
8333
8603
  nodes[0] != blockContext &&
@@ -8435,7 +8705,10 @@ function getBlockElementAtNode(rootNode, node) {
8435
8705
  // NOTE: this container block could be just the rootNode,
8436
8706
  // which cannot be used to create block element. We will special case handle it later on
8437
8707
  var containerBlockNode = StartEndBlockElement_1.default.getBlockContext(node);
8438
- if (containerBlockNode == node) {
8708
+ if (!containerBlockNode) {
8709
+ return null;
8710
+ }
8711
+ else if (containerBlockNode == node) {
8439
8712
  return new NodeBlockElement_1.default(containerBlockNode);
8440
8713
  }
8441
8714
  // Find the head and leaf node in the block
@@ -8465,7 +8738,7 @@ function getBlockElementAtNode(rootNode, node) {
8465
8738
  }
8466
8739
  break;
8467
8740
  }
8468
- else if (parentNode != rootNode) {
8741
+ else if (parentNode && parentNode != rootNode) {
8469
8742
  // Continue collapsing to parent
8470
8743
  headNode = tailNode = parentNode;
8471
8744
  }
@@ -8495,7 +8768,7 @@ function findHeadTailLeafNode(node, containerBlockNode, isTail) {
8495
8768
  }
8496
8769
  while (result) {
8497
8770
  var sibling = node;
8498
- while (!(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8771
+ while (node.parentNode && !(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8499
8772
  node = node.parentNode;
8500
8773
  if (node == containerBlockNode) {
8501
8774
  return result;
@@ -8541,7 +8814,7 @@ function getFirstLastBlockElement(rootNode, isFirst) {
8541
8814
  do {
8542
8815
  node = node && (isFirst ? node.firstChild : node.lastChild);
8543
8816
  } while (node && node.firstChild);
8544
- return node && (0, getBlockElementAtNode_1.default)(rootNode, node);
8817
+ return (node && (0, getBlockElementAtNode_1.default)(rootNode, node)) || null;
8545
8818
  }
8546
8819
  exports.default = getFirstLastBlockElement;
8547
8820
 
@@ -8652,6 +8925,7 @@ function extractClipboardItems(items, options) {
8652
8925
  types: [],
8653
8926
  text: '',
8654
8927
  image: null,
8928
+ files: [],
8655
8929
  rawHtml: null,
8656
8930
  customValues: {},
8657
8931
  };
@@ -8676,6 +8950,16 @@ function extractClipboardItems(items, options) {
8676
8950
  }
8677
8951
  });
8678
8952
  }
8953
+ else if (item.kind == 'file') {
8954
+ return new Promise(function (resolve) {
8955
+ var file = item.getAsFile();
8956
+ if (!!file) {
8957
+ data.types.push(type);
8958
+ data.files.push(file);
8959
+ }
8960
+ resolve();
8961
+ });
8962
+ }
8679
8963
  else {
8680
8964
  var customType_1 = getAllowedCustomType(type, options === null || options === void 0 ? void 0 : options.allowedCustomPasteType);
8681
8965
  var handler_1 = contentHandlers[type] || (customType_1 ? contentHandlers[OTHER_TEXT_TYPE] : null);
@@ -8756,6 +9040,7 @@ function extractClipboardItemsForIE(dataTransfer, callback, options) {
8756
9040
  types: dataTransfer.types ? (0, toArray_1.default)(dataTransfer.types) : [],
8757
9041
  text: dataTransfer.getData('text'),
8758
9042
  image: null,
9043
+ files: [],
8759
9044
  rawHtml: null,
8760
9045
  customValues: {},
8761
9046
  };
@@ -8897,6 +9182,8 @@ var ContentTraverser = /** @class */ (function () {
8897
9182
  function ContentTraverser(scoper, skipTags) {
8898
9183
  this.scoper = scoper;
8899
9184
  this.skipTags = skipTags;
9185
+ this.currentInline = null;
9186
+ this.currentBlock = null;
8900
9187
  }
8901
9188
  /**
8902
9189
  * Create a content traverser for the whole body of given root node
@@ -9087,8 +9374,20 @@ var PositionContentSearcher = /** @class */ (function () {
9087
9374
  this.position = position;
9088
9375
  // The cached text before position that has been read so far
9089
9376
  this.text = '';
9377
+ // The cached word before position
9378
+ this.word = '';
9379
+ // The inline element before position
9380
+ this.inlineBefore = null;
9381
+ // The inline element after position
9382
+ this.inlineAfter = null;
9383
+ // The content traverser used to traverse backwards
9384
+ this.traverser = null;
9385
+ // Backward parsing has completed
9386
+ this.traversingComplete = false;
9090
9387
  // All inline elements before position that have been read so far
9091
9388
  this.inlineElements = [];
9389
+ // First non-text inline before position
9390
+ this.nearestNonTextInlineElement = null;
9092
9391
  }
9093
9392
  /**
9094
9393
  * Get the word before position. The word is determined by scanning backwards till the first white space, the portion
@@ -9100,7 +9399,7 @@ var PositionContentSearcher = /** @class */ (function () {
9100
9399
  if (!this.word) {
9101
9400
  this.traverse(function () { return _this.word; });
9102
9401
  }
9103
- return this.word;
9402
+ return this.word || '';
9104
9403
  };
9105
9404
  /**
9106
9405
  * Get the inline element before position
@@ -9147,8 +9446,8 @@ var PositionContentSearcher = /** @class */ (function () {
9147
9446
  if (!text) {
9148
9447
  return null;
9149
9448
  }
9150
- var startPosition;
9151
- var endPosition;
9449
+ var startPosition = null;
9450
+ var endPosition = null;
9152
9451
  var textIndex = text.length - 1;
9153
9452
  this.forEachTextInlineElement(function (textInline) {
9154
9453
  var nodeContent = textInline.getTextContent() || '';
@@ -9389,6 +9688,8 @@ var SelectionScoper = /** @class */ (function () {
9389
9688
  */
9390
9689
  function SelectionScoper(rootNode, range) {
9391
9690
  this.rootNode = rootNode;
9691
+ this.startBlock = null;
9692
+ this.startInline = null;
9392
9693
  this.start = Position_1.default.getStart(range).normalize();
9393
9694
  this.end = Position_1.default.getEnd(range).normalize();
9394
9695
  }
@@ -9421,7 +9722,7 @@ var SelectionScoper = /** @class */ (function () {
9421
9722
  var inScope = false;
9422
9723
  var selStartBlock = this.getStartBlockElement();
9423
9724
  if (this.start.equalTo(this.end)) {
9424
- inScope = selStartBlock && selStartBlock.equals(block);
9725
+ inScope = !!selStartBlock && selStartBlock.equals(block);
9425
9726
  }
9426
9727
  else {
9427
9728
  var selEndBlock = (0, getBlockElementAtNode_1.default)(this.rootNode, this.end.node);
@@ -9430,8 +9731,8 @@ var SelectionScoper = /** @class */ (function () {
9430
9731
  // 2) The end of selection falls on the block
9431
9732
  // 3) the block falls in-between selection start and end
9432
9733
  inScope =
9433
- selStartBlock &&
9434
- selEndBlock &&
9734
+ !!selStartBlock &&
9735
+ !!selEndBlock &&
9435
9736
  (block.equals(selStartBlock) ||
9436
9737
  block.equals(selEndBlock) ||
9437
9738
  (block.isAfter(selStartBlock) && selEndBlock.isAfter(block)));
@@ -9466,7 +9767,7 @@ var SelectionScoper = /** @class */ (function () {
9466
9767
  return start.isAfter(end) || start.equalTo(end)
9467
9768
  ? null
9468
9769
  : startPartial || endPartial
9469
- ? new PartialInlineElement_1.default(inline, startPartial && start, endPartial && end)
9770
+ ? new PartialInlineElement_1.default(inline, startPartial ? start : undefined, endPartial ? end : undefined)
9470
9771
  : inline;
9471
9772
  };
9472
9773
  return SelectionScoper;
@@ -9555,13 +9856,14 @@ function adjustInsertPositionForHyperLink(root, nodeToInsert, position, range) {
9555
9856
  * Adjust position for a node don't be nested inside tags like BR, LI, TD.
9556
9857
  */
9557
9858
  function adjustInsertPositionForStructuredNode(root, nodeToInsert, position, range) {
9859
+ var _a, _b, _c;
9558
9860
  var rootNodeToInsert = nodeToInsert;
9559
9861
  if (rootNodeToInsert.nodeType == 11 /* DocumentFragment */) {
9560
9862
  var rootNodes = (0, toArray_1.default)(rootNodeToInsert.childNodes).filter(function (n) { return (0, getTagOfNode_1.default)(n) != 'BR'; });
9561
9863
  rootNodeToInsert = rootNodes.length == 1 ? rootNodes[0] : null;
9562
9864
  }
9563
9865
  var tag = (0, getTagOfNode_1.default)(rootNodeToInsert);
9564
- var hasBrNextToRoot = tag && (0, getTagOfNode_1.default)(rootNodeToInsert.nextSibling) == 'BR';
9866
+ var hasBrNextToRoot = tag && rootNodeToInsert && (0, getTagOfNode_1.default)(rootNodeToInsert.nextSibling) == 'BR';
9565
9867
  var listItem = (0, findClosestElementAncestor_1.default)(position.node, root, 'LI');
9566
9868
  var listNode = listItem && (0, findClosestElementAncestor_1.default)(listItem, root, 'OL,UL');
9567
9869
  var tdNode = (0, findClosestElementAncestor_1.default)(position.node, root, 'TD,TH');
@@ -9570,7 +9872,9 @@ function adjustInsertPositionForStructuredNode(root, nodeToInsert, position, ran
9570
9872
  tag = listNode ? (0, getTagOfNode_1.default)(listNode) : 'UL';
9571
9873
  rootNodeToInsert = (0, wrap_1.default)(rootNodeToInsert, tag);
9572
9874
  }
9573
- if ((tag == 'OL' || tag == 'UL') && (0, getTagOfNode_1.default)(rootNodeToInsert.firstChild) == 'LI') {
9875
+ if ((tag == 'OL' || tag == 'UL') &&
9876
+ rootNodeToInsert &&
9877
+ (0, getTagOfNode_1.default)(rootNodeToInsert.firstChild) == 'LI') {
9574
9878
  var shouldInsertListAsText = !rootNodeToInsert.firstChild.nextSibling && !hasBrNextToRoot;
9575
9879
  if (hasBrNextToRoot && rootNodeToInsert.parentNode) {
9576
9880
  safeRemove(rootNodeToInsert.nextSibling);
@@ -9592,12 +9896,12 @@ function adjustInsertPositionForStructuredNode(root, nodeToInsert, position, ran
9592
9896
  var newTable = new VTable_1.default(rootNodeToInsert);
9593
9897
  var currentTable = new VTable_1.default(tdNode);
9594
9898
  if (currentTable.col == 0 &&
9595
- tdNode == currentTable.getCell(currentTable.row, 0).td &&
9596
- newTable.cells[0] &&
9597
- newTable.cells[0].length == currentTable.cells[0].length &&
9899
+ tdNode == currentTable.getCell(currentTable.row || 0, 0).td &&
9900
+ ((_a = newTable.cells) === null || _a === void 0 ? void 0 : _a[0]) &&
9901
+ newTable.cells[0].length == ((_b = currentTable.cells) === null || _b === void 0 ? void 0 : _b[0].length) &&
9598
9902
  (0, isPositionAtBeginningOf_1.default)(position, tdNode)) {
9599
9903
  if ((0, getTagOfNode_1.default)(rootNodeToInsert.firstChild) == 'TBODY' &&
9600
- !rootNodeToInsert.firstChild.nextSibling) {
9904
+ !((_c = rootNodeToInsert.firstChild) === null || _c === void 0 ? void 0 : _c.nextSibling)) {
9601
9905
  (0, unwrap_1.default)(rootNodeToInsert.firstChild);
9602
9906
  }
9603
9907
  (0, unwrap_1.default)(rootNodeToInsert);
@@ -9726,13 +10030,15 @@ function deleteSelectedContent(root, range) {
9726
10030
  nodesToDelete.forEach(function (node) { var _a; return (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node); });
9727
10031
  // 4. Merge lines for each region, so that after we don't see extra line breaks
9728
10032
  nodesPairToMerge.forEach(function (nodes) {
9729
- return (0, mergeBlocksInRegion_1.default)(nodes.region, nodes.beforeStart, nodes.afterEnd);
10033
+ if (nodes) {
10034
+ (0, mergeBlocksInRegion_1.default)(nodes.region, nodes.beforeStart, nodes.afterEnd);
10035
+ }
9730
10036
  });
9731
10037
  return nodeBefore && new Position_1.default(nodeBefore, -1 /* End */);
9732
10038
  }
9733
10039
  exports.default = deleteSelectedContent;
9734
10040
  function ensureBeforeAndAfter(node, offset, isStart) {
9735
- var _a;
10041
+ var _a, _b;
9736
10042
  if ((0, safeInstanceOf_1.default)(node, 'Text')) {
9737
10043
  var newNode = (0, splitTextNode_1.default)(node, offset, isStart);
9738
10044
  return isStart ? [newNode, node] : [node, newNode];
@@ -9759,7 +10065,7 @@ function ensureBeforeAndAfter(node, offset, isStart) {
9759
10065
  // need to add empty text node to convert to condition 3
9760
10066
  if ((nodeBefore || nodeAfter) && (!nodeBefore || !nodeAfter)) {
9761
10067
  var emptyNode = node.ownerDocument.createTextNode('');
9762
- (_a = (nodeBefore || nodeAfter).parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(emptyNode, nodeAfter);
10068
+ (_b = (_a = (nodeBefore || nodeAfter)) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(emptyNode, nodeAfter);
9763
10069
  if (nodeBefore) {
9764
10070
  nodeAfter = emptyNode;
9765
10071
  }
@@ -10579,7 +10885,6 @@ var HTML_TAG_REPLACEMENT = {
10579
10885
  table: '*',
10580
10886
  tbody: '*',
10581
10887
  td: '*',
10582
- template: '*',
10583
10888
  textarea: '*',
10584
10889
  tfoot: '*',
10585
10890
  th: '*',
@@ -10612,6 +10917,7 @@ var HTML_TAG_REPLACEMENT = {
10612
10917
  slot: null,
10613
10918
  source: null,
10614
10919
  style: null,
10920
+ template: null,
10615
10921
  title: null,
10616
10922
  track: null,
10617
10923
  video: null,
@@ -10842,7 +11148,7 @@ exports.default = getPredefinedCssForElement;
10842
11148
 
10843
11149
  Object.defineProperty(exports, "__esModule", { value: true });
10844
11150
  exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.toArray = 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.arrayPush = 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;
10845
- 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.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshot = exports.addRangeToSelection = 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.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.VTable = exports.moveChildNodes = void 0;
11151
+ 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.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.moveChildNodes = void 0;
10846
11152
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
10847
11153
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
10848
11154
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -10940,6 +11246,8 @@ var moveChildNodes_1 = __webpack_require__(/*! ./utils/moveChildNodes */ "./pack
10940
11246
  Object.defineProperty(exports, "moveChildNodes", { enumerable: true, get: function () { return moveChildNodes_1.default; } });
10941
11247
  var VTable_1 = __webpack_require__(/*! ./table/VTable */ "./packages/roosterjs-editor-dom/lib/table/VTable.ts");
10942
11248
  Object.defineProperty(exports, "VTable", { enumerable: true, get: function () { return VTable_1.default; } });
11249
+ var isWholeTableSelected_1 = __webpack_require__(/*! ./table/isWholeTableSelected */ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts");
11250
+ Object.defineProperty(exports, "isWholeTableSelected", { enumerable: true, get: function () { return isWholeTableSelected_1.default; } });
10943
11251
  var VList_1 = __webpack_require__(/*! ./list/VList */ "./packages/roosterjs-editor-dom/lib/list/VList.ts");
10944
11252
  Object.defineProperty(exports, "VList", { enumerable: true, get: function () { return VList_1.default; } });
10945
11253
  var VListItem_1 = __webpack_require__(/*! ./list/VListItem */ "./packages/roosterjs-editor-dom/lib/list/VListItem.ts");
@@ -10976,14 +11284,17 @@ var getHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/getHtmlWith
10976
11284
  Object.defineProperty(exports, "getHtmlWithSelectionPath", { enumerable: true, get: function () { return getHtmlWithSelectionPath_1.default; } });
10977
11285
  var setHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/setHtmlWithSelectionPath */ "./packages/roosterjs-editor-dom/lib/selection/setHtmlWithSelectionPath.ts");
10978
11286
  Object.defineProperty(exports, "setHtmlWithSelectionPath", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.default; } });
11287
+ Object.defineProperty(exports, "setHtmlWithMetadata", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.setHtmlWithMetadata; } });
10979
11288
  var addRangeToSelection_1 = __webpack_require__(/*! ./selection/addRangeToSelection */ "./packages/roosterjs-editor-dom/lib/selection/addRangeToSelection.ts");
10980
11289
  Object.defineProperty(exports, "addRangeToSelection", { enumerable: true, get: function () { return addRangeToSelection_1.default; } });
10981
11290
  var addSnapshot_1 = __webpack_require__(/*! ./snapshots/addSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/addSnapshot.ts");
10982
11291
  Object.defineProperty(exports, "addSnapshot", { enumerable: true, get: function () { return addSnapshot_1.default; } });
11292
+ Object.defineProperty(exports, "addSnapshotV2", { enumerable: true, get: function () { return addSnapshot_1.addSnapshotV2; } });
10983
11293
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
10984
11294
  Object.defineProperty(exports, "canMoveCurrentSnapshot", { enumerable: true, get: function () { return canMoveCurrentSnapshot_1.default; } });
10985
11295
  var clearProceedingSnapshots_1 = __webpack_require__(/*! ./snapshots/clearProceedingSnapshots */ "./packages/roosterjs-editor-dom/lib/snapshots/clearProceedingSnapshots.ts");
10986
11296
  Object.defineProperty(exports, "clearProceedingSnapshots", { enumerable: true, get: function () { return clearProceedingSnapshots_1.default; } });
11297
+ Object.defineProperty(exports, "clearProceedingSnapshotsV2", { enumerable: true, get: function () { return clearProceedingSnapshots_1.clearProceedingSnapshotsV2; } });
10987
11298
  var moveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/moveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/moveCurrentSnapshot.ts");
10988
11299
  Object.defineProperty(exports, "moveCurrentSnapshot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.default; } });
10989
11300
  Object.defineProperty(exports, "moveCurrentSnapsnot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.moveCurrentSnapsnot; } });
@@ -11220,9 +11531,9 @@ var NodeInlineElement = /** @class */ (function () {
11220
11531
  */
11221
11532
  NodeInlineElement.prototype.getTextContent = function () {
11222
11533
  // nodeValue is better way to retrieve content for a text. Others, just use textContent
11223
- return this.containerNode.nodeType == 3 /* Text */
11534
+ return ((this.containerNode.nodeType == 3 /* Text */
11224
11535
  ? this.containerNode.nodeValue
11225
- : this.containerNode.textContent;
11536
+ : this.containerNode.textContent) || '');
11226
11537
  };
11227
11538
  /**
11228
11539
  * Get the container node
@@ -11306,6 +11617,8 @@ var getLeafSibling_1 = __webpack_require__(/*! ../utils/getLeafSibling */ "./pac
11306
11617
  */
11307
11618
  var PartialInlineElement = /** @class */ (function () {
11308
11619
  function PartialInlineElement(inlineElement, start, end) {
11620
+ if (start === void 0) { start = null; }
11621
+ if (end === void 0) { end = null; }
11309
11622
  this.inlineElement = inlineElement;
11310
11623
  this.start = start;
11311
11624
  this.end = end;
@@ -11352,7 +11665,7 @@ var PartialInlineElement = /** @class */ (function () {
11352
11665
  * Get next partial inline element if it is not at the end boundary yet
11353
11666
  */
11354
11667
  get: function () {
11355
- return this.end && new PartialInlineElement(this.inlineElement, this.end, null);
11668
+ return this.end ? new PartialInlineElement(this.inlineElement, this.end) : null;
11356
11669
  },
11357
11670
  enumerable: false,
11358
11671
  configurable: true
@@ -11362,7 +11675,9 @@ var PartialInlineElement = /** @class */ (function () {
11362
11675
  * Get previous partial inline element if it is not at the begin boundary yet
11363
11676
  */
11364
11677
  get: function () {
11365
- return this.start && new PartialInlineElement(this.inlineElement, null, this.start);
11678
+ return this.start
11679
+ ? new PartialInlineElement(this.inlineElement, undefined, this.start)
11680
+ : null;
11366
11681
  },
11367
11682
  enumerable: false,
11368
11683
  configurable: true
@@ -11402,7 +11717,7 @@ var PartialInlineElement = /** @class */ (function () {
11402
11717
  var previousNode = (0, getLeafSibling_1.getPreviousLeafSibling)(container, to.node);
11403
11718
  to = previousNode ? new Position_1.default(previousNode, -1 /* End */) : null;
11404
11719
  }
11405
- (0, applyTextStyle_1.default)(container, styler, from, to);
11720
+ (0, applyTextStyle_1.default)(container, styler, from || undefined, to || undefined);
11406
11721
  };
11407
11722
  return PartialInlineElement;
11408
11723
  }());
@@ -11432,35 +11747,39 @@ var STYLET_AGS = 'SPAN,B,I,U,EM,STRONG,STRIKE,S,SMALL'.split(',');
11432
11747
  * Apply style using a styler function to the given container node in the given range
11433
11748
  * @param container The container node to apply style to
11434
11749
  * @param styler The styler function
11435
- * @param from From position
11436
- * @param to To position
11750
+ * @param fromPosition From position
11751
+ * @param toPosition To position
11437
11752
  */
11438
11753
  function applyTextStyle(container, styler, from, to) {
11439
11754
  if (from === void 0) { from = new Position_1.default(container, 0 /* Begin */).normalize(); }
11440
11755
  if (to === void 0) { to = new Position_1.default(container, -1 /* End */).normalize(); }
11441
11756
  var formatNodes = [];
11442
- while (from && to && to.isAfter(from)) {
11443
- var formatNode = from.node;
11757
+ var fromPosition = from;
11758
+ var toPosition = to;
11759
+ while (fromPosition && toPosition && toPosition.isAfter(fromPosition)) {
11760
+ var formatNode = fromPosition.node;
11444
11761
  var parentTag = (0, getTagOfNode_1.default)(formatNode.parentNode);
11445
11762
  // The code below modifies DOM. Need to get the next sibling first otherwise you won't be able to reliably get a good next sibling node
11446
11763
  var nextNode = (0, getLeafSibling_1.getNextLeafSibling)(container, formatNode);
11447
11764
  if (formatNode.nodeType == 3 /* Text */ && ['TR', 'TABLE'].indexOf(parentTag) < 0) {
11448
- if (formatNode == to.node && !to.isAtEnd) {
11449
- formatNode = (0, splitTextNode_1.default)(formatNode, to.offset, true /*returnFirstPart*/);
11765
+ if (formatNode == toPosition.node && !toPosition.isAtEnd) {
11766
+ formatNode = (0, splitTextNode_1.default)(formatNode, toPosition.offset, true /*returnFirstPart*/);
11450
11767
  }
11451
- if (from.offset > 0) {
11452
- formatNode = (0, splitTextNode_1.default)(formatNode, from.offset, false /*returnFirstPart*/);
11768
+ if (fromPosition.offset > 0) {
11769
+ formatNode = (0, splitTextNode_1.default)(formatNode, fromPosition.offset, false /*returnFirstPart*/);
11453
11770
  }
11454
11771
  formatNodes.push(formatNode);
11455
11772
  }
11456
- from = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11773
+ fromPosition = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11457
11774
  }
11458
11775
  if (formatNodes.length > 0) {
11459
11776
  if (formatNodes.every(function (node) { return node.parentNode == formatNodes[0].parentNode; })) {
11460
11777
  var newNode_1 = formatNodes.shift();
11461
11778
  formatNodes.forEach(function (node) {
11462
- newNode_1.nodeValue += node.nodeValue;
11463
- node.parentNode.removeChild(node);
11779
+ var _a;
11780
+ var newNodeValue = (newNode_1.nodeValue || '') + (node.nodeValue || '');
11781
+ newNode_1.nodeValue = newNodeValue;
11782
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
11464
11783
  });
11465
11784
  formatNodes = [newNode_1];
11466
11785
  }
@@ -11629,7 +11948,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11629
11948
  return null;
11630
11949
  }
11631
11950
  position = position.normalize();
11632
- var node = position.node, offset = position.offset, isAtEnd = position.isAtEnd;
11951
+ var offset = position.offset, isAtEnd = position.isAtEnd;
11952
+ var node = position.node;
11633
11953
  var isPartial = false;
11634
11954
  if ((!isAfter && offset == 0 && !isAtEnd) || (isAfter && isAtEnd)) {
11635
11955
  node = (0, getLeafSibling_1.getLeafSibling)(root, node, isAfter);
@@ -11644,8 +11964,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11644
11964
  var inlineElement = (0, getInlineElementAtNode_1.default)(root, node);
11645
11965
  if (inlineElement && (isPartial || inlineElement.contains(position))) {
11646
11966
  inlineElement = isAfter
11647
- ? new PartialInlineElement_1.default(inlineElement, position, null)
11648
- : new PartialInlineElement_1.default(inlineElement, null, position);
11967
+ ? new PartialInlineElement_1.default(inlineElement, position, undefined)
11968
+ : new PartialInlineElement_1.default(inlineElement, undefined, position);
11649
11969
  }
11650
11970
  return inlineElement;
11651
11971
  }
@@ -11839,9 +12159,10 @@ var VList = /** @class */ (function () {
11839
12159
  // Use a placeholder to hold the position since the root list may be moved into document fragment later
11840
12160
  this.rootList.parentNode.replaceChild(placeholder, this.rootList);
11841
12161
  this.items.forEach(function (item) {
11842
- if (item.getNewListStart() && item.getNewListStart() != start) {
12162
+ var newListStart = item.getNewListStart();
12163
+ if (newListStart && newListStart != start) {
11843
12164
  listStack.splice(1, listStack.length - 1);
11844
- start = item.getNewListStart();
12165
+ start = newListStart;
11845
12166
  }
11846
12167
  item.writeBack(listStack, _this.rootList);
11847
12168
  var topList = listStack[1];
@@ -11862,9 +12183,6 @@ var VList = /** @class */ (function () {
11862
12183
  });
11863
12184
  // Restore the content to the position of placeholder
11864
12185
  placeholder.parentNode.replaceChild(listStack[0], placeholder);
11865
- // Set rootList to null to avoid this to be called again for the same VList, because
11866
- // after change the rootList may not be available any more (e.g. outdent all items).
11867
- this.rootList = null;
11868
12186
  };
11869
12187
  /**
11870
12188
  * Sets the New List Start Property, that is going to be used to create a new List in the WriteBack function
@@ -11883,14 +12201,23 @@ var VList = /** @class */ (function () {
11883
12201
  }
11884
12202
  }
11885
12203
  };
11886
- VList.prototype.setIndentation = function (start, end, indentation, softOutdent) {
12204
+ VList.prototype.setIndentation = function (start, end, indentation, softOutdent, preventItemRemoval) {
12205
+ var _this = this;
12206
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12207
+ var shouldAddMargin = false;
11887
12208
  this.findListItems(start, end, function (item) {
11888
- return indentation == 1 /* Decrease */
12209
+ shouldAddMargin = shouldAddMargin || _this.items.indexOf(item) == 0;
12210
+ indentation == 1 /* Decrease */
11889
12211
  ? softOutdent && !item.isDummy()
11890
12212
  ? item.setIsDummy(true /*isDummy*/)
11891
- : item.outdent()
12213
+ : item.outdent(preventItemRemoval)
11892
12214
  : item.indent();
11893
12215
  });
12216
+ if (shouldAddMargin && preventItemRemoval) {
12217
+ for (var index = 0; index < this.items.length; index++) {
12218
+ this.items[index].addNegativeMargins();
12219
+ }
12220
+ }
11894
12221
  };
11895
12222
  /**
11896
12223
  * Change list type of the given range of this list.
@@ -11944,16 +12271,33 @@ var VList = /** @class */ (function () {
11944
12271
  };
11945
12272
  /**
11946
12273
  * Get the index of the List Item in the current List
12274
+ * If the root list is:
12275
+ * Ordered list, the listIndex start count is going to be the start property of the OL - 1,
12276
+ * @example For example if we want to find the index of Item 2 in the list below, the returned index is going to be 6
12277
+ * * ```html
12278
+ * <ol start="5">
12279
+ * <li>item 1</li>
12280
+ * <li>item 2</li> <!-- Node to find -->
12281
+ * <li>item 3</li>
12282
+ * </ol>
12283
+ * ```
12284
+ * Unordered list, the listIndex start count starts from 0
12285
+ * @example For example if we want to find the index of Item 2 in the list below, the returned index is going to be 2
12286
+ * ```html
12287
+ * <ul>
12288
+ * <li>item 1</li>
12289
+ * <li>item 2</li> <!-- Node to find -->
12290
+ * <li>item 3</li>
12291
+ * </ul>
12292
+ * ```
11947
12293
  * @param input List item to find in the root list
11948
12294
  */
11949
12295
  VList.prototype.getListItemIndex = function (input) {
11950
12296
  if (this.items) {
11951
- var listIndex = this.getStart() - 1;
12297
+ var listIndex = (this.getStart() || 1) - 1;
11952
12298
  for (var index = 0; index < this.items.length; index++) {
11953
12299
  var child = this.items[index];
11954
- if (child.getListType() == 1 /* Ordered */ &&
11955
- child.getLevel() == 1 &&
11956
- !child.isDummy()) {
12300
+ if (child.getLevel() == 1 && !child.isDummy()) {
11957
12301
  listIndex++;
11958
12302
  }
11959
12303
  if (child.getNode() == input) {
@@ -12000,7 +12344,7 @@ var VList = /** @class */ (function () {
12000
12344
  if ((0, getListTypeFromNode_1.isListElement)(item)) {
12001
12345
  _this.populateItems(item, newListTypes);
12002
12346
  }
12003
- else if (item.nodeType != 3 /* Text */ || item.nodeValue.trim() != '') {
12347
+ else if (item.nodeType != 3 /* Text */ || (item.nodeValue || '').trim() != '') {
12004
12348
  _this.items.push(new (VListItem_1.default.bind.apply(VListItem_1.default, __spreadArray([void 0, item], newListTypes, false)))());
12005
12349
  }
12006
12350
  });
@@ -12102,7 +12446,7 @@ var VListChain = /** @class */ (function () {
12102
12446
  var chain = chains.filter(function (c) { return c.canAppendToTail(list); })[0] ||
12103
12447
  new VListChain(region, (nameGenerator || createListChainName)());
12104
12448
  var index = chains.indexOf(chain);
12105
- var afterCurrentNode = currentNode && (0, isNodeAfter_1.default)(list, currentNode);
12449
+ var afterCurrentNode = !!currentNode && (0, isNodeAfter_1.default)(list, currentNode);
12106
12450
  if (!afterCurrentNode) {
12107
12451
  // Make sure current one is at the front if current block has not been met, so that
12108
12452
  // the first chain is always the nearest one from current node
@@ -12135,7 +12479,7 @@ var VListChain = /** @class */ (function () {
12135
12479
  * @param startNumber Start number of the new list
12136
12480
  */
12137
12481
  VListChain.prototype.createVListAtBlock = function (container, startNumber) {
12138
- if (container) {
12482
+ if (container && container.parentNode) {
12139
12483
  var list = container.ownerDocument.createElement('ol');
12140
12484
  list.start = startNumber;
12141
12485
  this.applyChainName(list);
@@ -12159,7 +12503,7 @@ var VListChain = /** @class */ (function () {
12159
12503
  var list = lists[i];
12160
12504
  list.start = lastNumber + 1;
12161
12505
  var vlist = new VList_1.default(list);
12162
- lastNumber = vlist.getLastItemNumber();
12506
+ lastNumber = vlist.getLastItemNumber() || 0;
12163
12507
  delete list.dataset[CHAIN_DATASET_NAME];
12164
12508
  delete list.dataset[AFTER_CURSOR_DATASET_NAME];
12165
12509
  vlist.writeBack();
@@ -12179,7 +12523,7 @@ var VListChain = /** @class */ (function () {
12179
12523
  */
12180
12524
  VListChain.prototype.append = function (list, isAfterCurrentNode) {
12181
12525
  this.applyChainName(list);
12182
- this.lastNumber = new VList_1.default(list).getLastItemNumber();
12526
+ this.lastNumber = new VList_1.default(list).getLastItemNumber() || 0;
12183
12527
  if (isAfterCurrentNode) {
12184
12528
  list.dataset[AFTER_CURSOR_DATASET_NAME] = 'true';
12185
12529
  }
@@ -12234,6 +12578,8 @@ var toArray_1 = __webpack_require__(/*! ../utils/toArray */ "./packages/roosterj
12234
12578
  var unwrap_1 = __webpack_require__(/*! ../utils/unwrap */ "./packages/roosterjs-editor-dom/lib/utils/unwrap.ts");
12235
12579
  var wrap_1 = __webpack_require__(/*! ../utils/wrap */ "./packages/roosterjs-editor-dom/lib/utils/wrap.ts");
12236
12580
  var orderListStyles = [null, 'lower-alpha', 'lower-roman'];
12581
+ var MARGIN_BASE = '0in 0in 0in 0.5in';
12582
+ var NEGATIVE_MARGIN = '-.25in';
12237
12583
  /**
12238
12584
  * !!! Never directly create instance of this class. It should be created within VList class !!!
12239
12585
  *
@@ -12335,6 +12681,11 @@ var VListItem = /** @class */ (function () {
12335
12681
  * If this is not an list item, it will be no op
12336
12682
  */
12337
12683
  VListItem.prototype.indent = function () {
12684
+ if (this.node.style.marginLeft == NEGATIVE_MARGIN) {
12685
+ this.node.style.margin = '';
12686
+ this.node.style.marginLeft = '';
12687
+ return;
12688
+ }
12338
12689
  var listType = this.getListType();
12339
12690
  if (listType != 0 /* None */) {
12340
12691
  this.listTypes.push(listType);
@@ -12343,12 +12694,22 @@ var VListItem = /** @class */ (function () {
12343
12694
  /**
12344
12695
  * Outdent this item
12345
12696
  * If this item is already not an list item, it will be no op
12697
+ * @param preventItemRemoval Whether prevent the list item to be removed for the listItem by default false
12346
12698
  */
12347
- VListItem.prototype.outdent = function () {
12348
- if (this.listTypes.length > 1) {
12699
+ VListItem.prototype.outdent = function (preventItemRemoval) {
12700
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12701
+ var expectedLength = preventItemRemoval ? 2 : 1;
12702
+ if (this.listTypes.length > expectedLength) {
12349
12703
  this.listTypes.pop();
12350
12704
  }
12351
12705
  };
12706
+ /**
12707
+ * Add negative margin to the List item
12708
+ */
12709
+ VListItem.prototype.addNegativeMargins = function () {
12710
+ this.node.style.margin = MARGIN_BASE;
12711
+ this.node.style.marginLeft = NEGATIVE_MARGIN;
12712
+ };
12352
12713
  /**
12353
12714
  * Change list type of this item
12354
12715
  * @param targetType The target list type to change to
@@ -12406,7 +12767,7 @@ var VListItem = /** @class */ (function () {
12406
12767
  }
12407
12768
  // 3. Add current node into deepest list element
12408
12769
  listStack[listStack.length - 1].appendChild(this.node);
12409
- this.node.style.display = this.dummy ? 'block' : null;
12770
+ this.node.style.setProperty('display', this.dummy ? 'block' : null);
12410
12771
  // 4. Inherit styles of the child element to the li, so we are able to apply the styles to the ::marker
12411
12772
  if (this.listTypes.length > 1) {
12412
12773
  if (!(this.node.style.fontSize || this.node.style.color || this.node.style.fontFamily)) {
@@ -12448,7 +12809,7 @@ function createListElement(newRoot, listType, nextLevel, originalRoot) {
12448
12809
  result = doc.createElement(listType == 1 /* Ordered */ ? 'ol' : 'ul');
12449
12810
  }
12450
12811
  if (listType == 1 /* Ordered */ && nextLevel > 1) {
12451
- result.style.listStyleType = orderListStyles[(nextLevel - 1) % orderListStyles.length];
12812
+ result.style.setProperty('list-style-type', orderListStyles[(nextLevel - 1) % orderListStyles.length]);
12452
12813
  }
12453
12814
  return result;
12454
12815
  }
@@ -12545,18 +12906,22 @@ function createVListFromRegion(region, includeSiblingLists, startNode) {
12545
12906
  }
12546
12907
  var vList = null;
12547
12908
  if (nodes.length > 0) {
12548
- var firstNode = nodes.shift();
12909
+ var firstNode = nodes.shift() || null;
12549
12910
  vList = (0, getListTypeFromNode_1.isListElement)(firstNode)
12550
12911
  ? new VList_1.default(firstNode)
12551
- : createVListFromItemNode(firstNode);
12552
- nodes.forEach(function (node) {
12553
- if ((0, getListTypeFromNode_1.isListElement)(node)) {
12554
- vList.mergeVList(new VList_1.default(node));
12555
- }
12556
- else {
12557
- vList.appendItem(node, 0 /* None */);
12558
- }
12559
- });
12912
+ : firstNode
12913
+ ? createVListFromItemNode(firstNode)
12914
+ : null;
12915
+ if (vList) {
12916
+ nodes.forEach(function (node) {
12917
+ if ((0, getListTypeFromNode_1.isListElement)(node)) {
12918
+ vList.mergeVList(new VList_1.default(node));
12919
+ }
12920
+ else {
12921
+ vList.appendItem(node, 0 /* None */);
12922
+ }
12923
+ });
12924
+ }
12560
12925
  }
12561
12926
  return vList;
12562
12927
  }
@@ -12706,11 +13071,11 @@ exports.default = setListItemStyle;
12706
13071
  function getInlineChildElementsStyle(element) {
12707
13072
  var result = [];
12708
13073
  var contentTraverser = ContentTraverser_1.default.createBodyTraverser(element);
12709
- var currentInlineElement;
13074
+ var currentInlineElement = null;
12710
13075
  while (contentTraverser.currentInlineElement != currentInlineElement) {
12711
13076
  currentInlineElement = contentTraverser.currentInlineElement;
12712
- var currentNode = currentInlineElement.getContainerNode();
12713
- currentNode = (0, findClosestElementAncestor_1.default)(currentNode);
13077
+ var currentNode = (currentInlineElement === null || currentInlineElement === void 0 ? void 0 : currentInlineElement.getContainerNode()) || null;
13078
+ currentNode = currentNode ? (0, findClosestElementAncestor_1.default)(currentNode) : null;
12714
13079
  if ((0, safeInstanceOf_1.default)(currentNode, 'HTMLElement')) {
12715
13080
  var childStyle = (0, getStyles_1.default)(currentNode);
12716
13081
  if (childStyle) {
@@ -12884,7 +13249,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12884
13249
  var children = boundary.children, innerNode = boundary.innerNode;
12885
13250
  var regions = [];
12886
13251
  if (children.length == 0) {
12887
- regions.push(creator(innerNode));
13252
+ var region = creator(innerNode);
13253
+ if (region) {
13254
+ regions.push(region);
13255
+ }
12888
13256
  }
12889
13257
  else {
12890
13258
  // Need to run one more time to add region after all children
@@ -12892,7 +13260,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12892
13260
  var _b = children[i] || {}, outerNode = _b.outerNode, boundaries = _b.boundaries;
12893
13261
  var previousOuterNode = (_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.outerNode;
12894
13262
  if (started) {
12895
- regions.push(creator(innerNode, previousOuterNode, outerNode));
13263
+ var region = creator(innerNode, previousOuterNode, outerNode);
13264
+ if (region) {
13265
+ regions.push(region);
13266
+ }
12896
13267
  }
12897
13268
  boundaries === null || boundaries === void 0 ? void 0 : boundaries.forEach(function (child) {
12898
13269
  var _a;
@@ -12985,7 +13356,10 @@ function getSelectedBlockElementsInRegion(regionBase, createBlockIfEmpty) {
12985
13356
  if (blocks.length == 0 && regionBase && !regionBase.rootNode.firstChild && createBlockIfEmpty) {
12986
13357
  var newNode = (0, createElement_1.default)(1 /* EmptyLine */, regionBase.rootNode.ownerDocument);
12987
13358
  regionBase.rootNode.appendChild(newNode);
12988
- blocks.push((0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode));
13359
+ var block = (0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode);
13360
+ if (block) {
13361
+ blocks.push(block);
13362
+ }
12989
13363
  }
12990
13364
  return blocks;
12991
13365
  }
@@ -13039,10 +13413,8 @@ function getSelectionRangeInRegion(regionBase) {
13039
13413
  var end = fullSelectionEnd.isAfter(regionEnd) ? regionEnd : fullSelectionEnd;
13040
13414
  return (0, createRange_1.default)(start, end);
13041
13415
  }
13042
- else {
13043
- return null;
13044
- }
13045
13416
  }
13417
+ return null;
13046
13418
  }
13047
13419
  exports.default = getSelectionRangeInRegion;
13048
13420
  function isRegion(regionBase) {
@@ -13119,7 +13491,7 @@ var collapseNodes_1 = __webpack_require__(/*! ../utils/collapseNodes */ "./packa
13119
13491
  * @param targetNode The node of target block element
13120
13492
  */
13121
13493
  function mergeBlocksInRegion(region, refNode, targetNode) {
13122
- var _a, _b;
13494
+ var _a, _b, _c;
13123
13495
  var block;
13124
13496
  if (!(0, isNodeInRegion_1.default)(region, refNode) ||
13125
13497
  !(0, isNodeInRegion_1.default)(region, targetNode) ||
@@ -13143,13 +13515,13 @@ function mergeBlocksInRegion(region, refNode, targetNode) {
13143
13515
  ? blockRoot.firstChild
13144
13516
  : (0, changeElementTag_1.default)(blockRoot, 'SPAN');
13145
13517
  // Remove empty node
13146
- for (var node = nodeToMerge; (0, contains_1.default)(commonContainer, node) && node.parentNode.childNodes.length == 1; node = node.parentNode) {
13518
+ for (var node = nodeToMerge; (0, contains_1.default)(commonContainer, node) && ((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.childNodes.length) == 1; node = node.parentNode) {
13147
13519
  // If the only child is the one which is about to be removed, this node should also be removed
13148
13520
  nodeToRemove = node.parentNode;
13149
13521
  }
13150
13522
  // Finally, merge blocks, and remove empty nodes
13151
- (_a = refNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(nodeToMerge, refNode.nextSibling);
13152
- (_b = nodeToRemove === null || nodeToRemove === void 0 ? void 0 : nodeToRemove.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(nodeToRemove);
13523
+ (_b = refNode.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(nodeToMerge, refNode.nextSibling);
13524
+ (_c = nodeToRemove === null || nodeToRemove === void 0 ? void 0 : nodeToRemove.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(nodeToRemove);
13153
13525
  }
13154
13526
  exports.default = mergeBlocksInRegion;
13155
13527
 
@@ -13463,8 +13835,6 @@ function getPositionFromPath(node, path) {
13463
13835
  Object.defineProperty(exports, "__esModule", { value: true });
13464
13836
  var getInnerHTML_1 = __webpack_require__(/*! ../utils/getInnerHTML */ "./packages/roosterjs-editor-dom/lib/utils/getInnerHTML.ts");
13465
13837
  var getSelectionPath_1 = __webpack_require__(/*! ./getSelectionPath */ "./packages/roosterjs-editor-dom/lib/selection/getSelectionPath.ts");
13466
- var getTagOfNode_1 = __webpack_require__(/*! ../utils/getTagOfNode */ "./packages/roosterjs-editor-dom/lib/utils/getTagOfNode.ts");
13467
- var queryElements_1 = __webpack_require__(/*! ../utils/queryElements */ "./packages/roosterjs-editor-dom/lib/utils/queryElements.ts");
13468
13838
  /**
13469
13839
  * Get inner Html of a root node with a selection path which can be used for restore selection.
13470
13840
  * The result string can be used by setHtmlWithSelectionPath() to restore the HTML and selection.
@@ -13476,32 +13846,6 @@ function getHtmlWithSelectionPath(rootNode, range) {
13476
13846
  if (!rootNode) {
13477
13847
  return '';
13478
13848
  }
13479
- var _a = range || {}, startContainer = _a.startContainer, endContainer = _a.endContainer, startOffset = _a.startOffset, endOffset = _a.endOffset;
13480
- var isDOMChanged = false;
13481
- (0, queryElements_1.default)(rootNode, 'table', function (table) {
13482
- var tbody = null;
13483
- for (var child = table.firstChild; child; child = child.nextSibling) {
13484
- if ((0, getTagOfNode_1.default)(child) == 'TR') {
13485
- if (!tbody) {
13486
- tbody = table.ownerDocument.createElement('tbody');
13487
- table.insertBefore(tbody, child);
13488
- }
13489
- tbody.appendChild(child);
13490
- child = tbody;
13491
- isDOMChanged = true;
13492
- }
13493
- else {
13494
- tbody = null;
13495
- }
13496
- }
13497
- });
13498
- if (range && isDOMChanged) {
13499
- try {
13500
- range.setStart(startContainer, startOffset);
13501
- range.setEnd(endContainer, endOffset);
13502
- }
13503
- catch (_b) { }
13504
- }
13505
13849
  var content = (0, getInnerHTML_1.default)(rootNode);
13506
13850
  var selectionPath = range && (0, getSelectionPath_1.default)(rootNode, range);
13507
13851
  return selectionPath ? content + "<!--" + JSON.stringify(selectionPath) + "-->" : content;
@@ -13719,53 +14063,88 @@ function areAllPreviousNodesEmpty(node) {
13719
14063
  "use strict";
13720
14064
 
13721
14065
  Object.defineProperty(exports, "__esModule", { value: true });
14066
+ exports.setHtmlWithMetadata = void 0;
13722
14067
  var createRange_1 = __webpack_require__(/*! ./createRange */ "./packages/roosterjs-editor-dom/lib/selection/createRange.ts");
13723
- var LastCommentRegex = /<!--([^-]+)-->$/;
14068
+ var safeInstanceOf_1 = __webpack_require__(/*! ../utils/safeInstanceOf */ "./packages/roosterjs-editor-dom/lib/utils/safeInstanceOf.ts");
13724
14069
  /**
13725
- * Restore inner Html of a root element from given html string. If the string contains selection path,
14070
+ * @deprecated Use setHtmlWithMetadata instead
14071
+ * Restore inner HTML of a root element from given html string. If the string contains selection path,
13726
14072
  * remove the selection path and return a range represented by the path
13727
14073
  * @param root The root element
13728
- * @param html The html to restore
14074
+ * @param html The HTML to restore
14075
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
13729
14076
  * @returns A selection range if the html contains a valid selection path, otherwise null
13730
14077
  */
13731
14078
  function setHtmlWithSelectionPath(rootNode, html, trustedHTMLHandler) {
14079
+ var metadata = setHtmlWithMetadata(rootNode, html, trustedHTMLHandler);
14080
+ return (metadata === null || metadata === void 0 ? void 0 : metadata.type) == 0 /* Normal */
14081
+ ? (0, createRange_1.default)(rootNode, metadata.start, metadata.end)
14082
+ : null;
14083
+ }
14084
+ exports.default = setHtmlWithSelectionPath;
14085
+ /**
14086
+ * Restore inner HTML of a root element from given html string. If the string contains metadata,
14087
+ * remove it from DOM tree and return the metadata
14088
+ * @param root The root element
14089
+ * @param html The HTML to restore
14090
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
14091
+ * @returns Content metadata if any, or undefined
14092
+ */
14093
+ function setHtmlWithMetadata(rootNode, html, trustedHTMLHandler) {
13732
14094
  if (!rootNode) {
13733
- return null;
14095
+ return undefined;
13734
14096
  }
13735
14097
  html = html || '';
13736
- var lastComment = LastCommentRegex.exec(html);
13737
14098
  rootNode.innerHTML = (trustedHTMLHandler === null || trustedHTMLHandler === void 0 ? void 0 : trustedHTMLHandler(html)) || html;
13738
- var path = getSelectionPath(rootNode, (lastComment === null || lastComment === void 0 ? void 0 : lastComment[1]) || '');
13739
- return path && (0, createRange_1.default)(rootNode, path.start, path.end);
13740
- }
13741
- exports.default = setHtmlWithSelectionPath;
13742
- function getSelectionPath(root, alternativeComment) {
13743
- var _a, _b, _c;
13744
- var pathCommentValue = '';
13745
- var pathCommentNode = null;
13746
- var path = null;
13747
- if (((_a = root.lastChild) === null || _a === void 0 ? void 0 : _a.nodeType) == 8 /* Comment */) {
13748
- pathCommentNode = root.lastChild;
13749
- pathCommentValue = pathCommentNode.nodeValue || '';
14099
+ var potentialMetadataComment = rootNode.lastChild;
14100
+ if ((0, safeInstanceOf_1.default)(potentialMetadataComment, 'Comment')) {
14101
+ try {
14102
+ var obj = JSON.parse(potentialMetadataComment.nodeValue || '');
14103
+ if (isContentMetadata(obj)) {
14104
+ rootNode.removeChild(potentialMetadataComment);
14105
+ return obj;
14106
+ }
14107
+ }
14108
+ catch (_a) { }
13750
14109
  }
13751
- else {
13752
- pathCommentValue = alternativeComment;
14110
+ return undefined;
14111
+ }
14112
+ exports.setHtmlWithMetadata = setHtmlWithMetadata;
14113
+ function isContentMetadata(obj) {
14114
+ if (!obj || typeof obj != 'object') {
14115
+ return false;
13753
14116
  }
13754
- if (pathCommentValue) {
13755
- try {
13756
- path = JSON.parse(pathCommentValue);
13757
- if (path && ((_b = path.start) === null || _b === void 0 ? void 0 : _b.length) > 0 && ((_c = path.end) === null || _c === void 0 ? void 0 : _c.length) > 0) {
13758
- if (pathCommentNode) {
13759
- root.removeChild(pathCommentNode);
13760
- }
14117
+ switch (obj.type || 0 /* Normal */) {
14118
+ case 0 /* Normal */:
14119
+ var regularMetadata = obj;
14120
+ if (isNumberArray(regularMetadata.start) && isNumberArray(regularMetadata.end)) {
14121
+ obj.type = 0 /* Normal */;
14122
+ obj.isDarkMode = !!obj.isDarkMode;
14123
+ return true;
13761
14124
  }
13762
- else {
13763
- path = null;
14125
+ break;
14126
+ case 1 /* TableSelection */:
14127
+ var tableMetadata = obj;
14128
+ if (typeof tableMetadata.tableId == 'string' &&
14129
+ !!tableMetadata.tableId &&
14130
+ isCoordinates(tableMetadata.firstCell) &&
14131
+ isCoordinates(tableMetadata.lastCell)) {
14132
+ obj.isDarkMode = !!obj.isDarkMode;
14133
+ return true;
13764
14134
  }
13765
- }
13766
- catch (_d) { }
14135
+ break;
13767
14136
  }
13768
- return path;
14137
+ return false;
14138
+ }
14139
+ function isNumberArray(obj) {
14140
+ return obj && Array.isArray(obj) && obj.every(function (o) { return typeof o == 'number'; });
14141
+ }
14142
+ function isCoordinates(obj) {
14143
+ var coordinates = obj;
14144
+ return (coordinates &&
14145
+ typeof coordinates == 'object' &&
14146
+ typeof coordinates.x == 'number' &&
14147
+ typeof coordinates.y == 'number');
13769
14148
  }
13770
14149
 
13771
14150
 
@@ -13781,23 +14160,21 @@ function getSelectionPath(root, alternativeComment) {
13781
14160
  "use strict";
13782
14161
 
13783
14162
  Object.defineProperty(exports, "__esModule", { value: true });
14163
+ exports.addSnapshotV2 = void 0;
13784
14164
  var clearProceedingSnapshots_1 = __webpack_require__(/*! ./clearProceedingSnapshots */ "./packages/roosterjs-editor-dom/lib/snapshots/clearProceedingSnapshots.ts");
13785
- /**
13786
- * Add a new snapshot to the given snapshots data structure
13787
- * @param snapshots The snapshots data structure to add new snapshot into
13788
- * @param snapshot The snapshot to add
13789
- * @param isAutoCompleteSnapshot Whether this is a snapshot before auto complete action
13790
- */
13791
- function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot) {
13792
- if (snapshots.currentIndex < 0 || snapshot != snapshots.snapshots[snapshots.currentIndex]) {
13793
- (0, clearProceedingSnapshots_1.default)(snapshots);
14165
+ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, getLength, compare) {
14166
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14167
+ compare = compare || defaultCompare;
14168
+ var currentSnapshot = snapshots.snapshots[snapshots.currentIndex];
14169
+ if (snapshots.currentIndex < 0 || !currentSnapshot || !compare(snapshot, currentSnapshot)) {
14170
+ (0, clearProceedingSnapshots_1.default)(snapshots, getLength);
13794
14171
  snapshots.snapshots.push(snapshot);
13795
14172
  snapshots.currentIndex++;
13796
- snapshots.totalSize += snapshot.length;
14173
+ snapshots.totalSize += getLength(snapshot);
13797
14174
  var removeCount = 0;
13798
14175
  while (removeCount < snapshots.snapshots.length &&
13799
14176
  snapshots.totalSize > snapshots.maxSize) {
13800
- snapshots.totalSize -= snapshots.snapshots[removeCount].length;
14177
+ snapshots.totalSize -= getLength(snapshots.snapshots[removeCount]);
13801
14178
  removeCount++;
13802
14179
  }
13803
14180
  if (removeCount > 0) {
@@ -13811,6 +14188,22 @@ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot) {
13811
14188
  }
13812
14189
  }
13813
14190
  exports.default = addSnapshot;
14191
+ /**
14192
+ * Add a new snapshot to the given snapshots data structure
14193
+ * @param snapshots The snapshots data structure to add new snapshot into
14194
+ * @param snapshot The snapshot object to add
14195
+ * @param isAutoCompleteSnapshot Whether this is a snapshot before auto complete action
14196
+ */
14197
+ function addSnapshotV2(snapshots, snapshot, isAutoCompleteSnapshot) {
14198
+ addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; }, compareSnapshots);
14199
+ }
14200
+ exports.addSnapshotV2 = addSnapshotV2;
14201
+ function compareSnapshots(s1, s2) {
14202
+ return s1.html == s2.html;
14203
+ }
14204
+ function defaultCompare(s1, s2) {
14205
+ return s1 == s2;
14206
+ }
13814
14207
 
13815
14208
 
13816
14209
  /***/ }),
@@ -13872,16 +14265,18 @@ exports.default = canUndoAutoComplete;
13872
14265
  "use strict";
13873
14266
 
13874
14267
  Object.defineProperty(exports, "__esModule", { value: true });
14268
+ exports.clearProceedingSnapshotsV2 = void 0;
13875
14269
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
13876
14270
  /**
13877
14271
  * Clear all snapshots after the current one
13878
14272
  * @param snapshots The snapshots data structure to clear
13879
14273
  */
13880
- function clearProceedingSnapshots(snapshots) {
14274
+ function clearProceedingSnapshots(snapshots, getLength) {
14275
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
13881
14276
  if ((0, canMoveCurrentSnapshot_1.default)(snapshots, 1)) {
13882
14277
  var removedSize = 0;
13883
14278
  for (var i = snapshots.currentIndex + 1; i < snapshots.snapshots.length; i++) {
13884
- removedSize += snapshots.snapshots[i].length;
14279
+ removedSize += getLength(snapshots.snapshots[i]);
13885
14280
  }
13886
14281
  snapshots.snapshots.splice(snapshots.currentIndex + 1);
13887
14282
  snapshots.totalSize -= removedSize;
@@ -13889,6 +14284,14 @@ function clearProceedingSnapshots(snapshots) {
13889
14284
  }
13890
14285
  }
13891
14286
  exports.default = clearProceedingSnapshots;
14287
+ /**
14288
+ * Clear all snapshots after the current one
14289
+ * @param snapshots The snapshots data structure to clear
14290
+ */
14291
+ function clearProceedingSnapshotsV2(snapshots) {
14292
+ clearProceedingSnapshots(snapshots, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14293
+ }
14294
+ exports.clearProceedingSnapshotsV2 = clearProceedingSnapshotsV2;
13892
14295
 
13893
14296
 
13894
14297
  /***/ }),
@@ -14084,6 +14487,18 @@ var VTable = /** @class */ (function () {
14084
14487
  */
14085
14488
  function VTable(node, normalizeSize, zoomScale) {
14086
14489
  var _this = this;
14490
+ /**
14491
+ * Virtual cells
14492
+ */
14493
+ this.cells = null;
14494
+ /**
14495
+ * Selected range of cells with the coordinates of the first and last cell selected.
14496
+ */
14497
+ this.selection = null;
14498
+ /**
14499
+ * Current format of the table
14500
+ */
14501
+ this.formatInfo = null;
14087
14502
  this.trs = [];
14088
14503
  this.table = (0, safeInstanceOf_1.default)(node, 'HTMLTableElement') ? node : getTableFromTd(node);
14089
14504
  if (this.table) {
@@ -14128,17 +14543,20 @@ var VTable = /** @class */ (function () {
14128
14543
  */
14129
14544
  VTable.prototype.writeBack = function (skipApplyFormat) {
14130
14545
  var _this = this;
14546
+ var _a;
14131
14547
  if (this.cells) {
14132
14548
  (0, moveChildNodes_1.default)(this.table);
14133
14549
  this.cells.forEach(function (row, r) {
14134
14550
  var tr = cloneNode(_this.trs[r % 2] || _this.trs[0]);
14135
- _this.table.appendChild(tr);
14136
- row.forEach(function (cell, c) {
14137
- if (cell.td) {
14138
- _this.recalculateSpans(r, c);
14139
- tr.appendChild(cell.td);
14140
- }
14141
- });
14551
+ if (tr) {
14552
+ _this.table.appendChild(tr);
14553
+ row.forEach(function (cell, c) {
14554
+ if (cell.td) {
14555
+ _this.recalculateSpans(r, c);
14556
+ tr.appendChild(cell.td);
14557
+ }
14558
+ });
14559
+ }
14142
14560
  });
14143
14561
  if (this.formatInfo && !skipApplyFormat) {
14144
14562
  (0, tableFormatInfo_1.saveTableInfo)(this.table, this.formatInfo);
@@ -14146,7 +14564,7 @@ var VTable = /** @class */ (function () {
14146
14564
  }
14147
14565
  }
14148
14566
  else if (this.table) {
14149
- this.table.parentNode.removeChild(this.table);
14567
+ (_a = this.table.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.table);
14150
14568
  }
14151
14569
  };
14152
14570
  /**
@@ -14167,7 +14585,7 @@ var VTable = /** @class */ (function () {
14167
14585
  * @param cells
14168
14586
  */
14169
14587
  VTable.prototype.deleteCellShadeDataset = function (cells) {
14170
- cells.forEach(function (row) {
14588
+ cells === null || cells === void 0 ? void 0 : cells.forEach(function (row) {
14171
14589
  row.forEach(function (cell) {
14172
14590
  if (cell.td && cell.td.dataset[CELL_SHADE]) {
14173
14591
  delete cell.td.dataset[CELL_SHADE];
@@ -14181,77 +14599,120 @@ var VTable = /** @class */ (function () {
14181
14599
  */
14182
14600
  VTable.prototype.edit = function (operation) {
14183
14601
  var _this = this;
14184
- if (!this.table) {
14602
+ if (!this.table || !this.cells || this.row === undefined || this.col == undefined) {
14185
14603
  return;
14186
14604
  }
14187
14605
  var currentRow = this.cells[this.row];
14188
14606
  var currentCell = currentRow[this.col];
14189
- var style = currentCell.td.style;
14607
+ var firstRow = this.selection ? this.selection.firstCell.y : this.row;
14608
+ var lastRow = this.selection ? this.selection.lastCell.y : this.row;
14609
+ var firstColumn = this.selection ? this.selection.firstCell.x : this.col;
14610
+ var lastColumn = this.selection ? this.selection.lastCell.x : this.col;
14190
14611
  switch (operation) {
14191
14612
  case 0 /* InsertAbove */:
14192
- this.cells.splice(this.row, 0, currentRow.map(cloneCell));
14613
+ for (var i = firstRow; i <= lastRow; i++) {
14614
+ this.cells.splice(firstRow, 0, currentRow.map(cloneCell));
14615
+ }
14193
14616
  break;
14194
14617
  case 1 /* InsertBelow */:
14195
- var newRow_1 = this.row + this.countSpanAbove(this.row, this.col);
14196
- this.cells.splice(newRow_1, 0, this.cells[newRow_1 - 1].map(function (cell, colIndex) {
14197
- var nextCell = _this.getCell(newRow_1, colIndex);
14198
- if (nextCell.spanAbove) {
14199
- return cloneCell(nextCell);
14200
- }
14201
- else if (cell.spanLeft) {
14202
- var newCell = cloneCell(cell);
14203
- newCell.spanAbove = false;
14204
- return newCell;
14205
- }
14206
- else {
14207
- return {
14208
- td: cloneNode(_this.getTd(_this.row, colIndex)),
14209
- };
14210
- }
14211
- }));
14618
+ var _loop_1 = function (i) {
14619
+ var newRow = lastRow + this_1.countSpanAbove(lastRow, this_1.col);
14620
+ this_1.cells.splice(newRow, 0, this_1.cells[newRow - 1].map(function (cell, colIndex) {
14621
+ var nextCell = _this.getCell(newRow, colIndex);
14622
+ if (nextCell.spanAbove) {
14623
+ return cloneCell(nextCell);
14624
+ }
14625
+ else if (cell.spanLeft) {
14626
+ var newCell = cloneCell(cell);
14627
+ newCell.spanAbove = false;
14628
+ return newCell;
14629
+ }
14630
+ else {
14631
+ return {
14632
+ td: cloneNode(_this.getTd(_this.row, colIndex)),
14633
+ };
14634
+ }
14635
+ }));
14636
+ };
14637
+ var this_1 = this;
14638
+ for (var i = firstRow; i <= lastRow; i++) {
14639
+ _loop_1(i);
14640
+ }
14212
14641
  break;
14213
14642
  case 2 /* InsertLeft */:
14214
- this.forEachCellOfCurrentColumn(function (cell, row) {
14215
- row.splice(_this.col, 0, cloneCell(cell));
14216
- });
14643
+ var _loop_2 = function (i) {
14644
+ this_2.forEachCellOfCurrentColumn(function (cell, row) {
14645
+ row.splice(i, 0, cloneCell(cell));
14646
+ });
14647
+ };
14648
+ var this_2 = this;
14649
+ for (var i = firstColumn; i <= lastColumn; i++) {
14650
+ _loop_2(i);
14651
+ }
14217
14652
  break;
14218
14653
  case 3 /* InsertRight */:
14219
- var newCol_1 = this.col + this.countSpanLeft(this.row, this.col);
14220
- this.forEachCellOfColumn(newCol_1 - 1, function (cell, row, i) {
14221
- var nextCell = _this.getCell(i, newCol_1);
14222
- var newCell;
14223
- if (nextCell.spanLeft) {
14224
- newCell = cloneCell(nextCell);
14225
- }
14226
- else if (cell.spanAbove) {
14227
- newCell = cloneCell(cell);
14228
- newCell.spanLeft = false;
14229
- }
14230
- else {
14231
- newCell = {
14232
- td: cloneNode(_this.getTd(i, _this.col)),
14233
- };
14234
- }
14235
- row.splice(newCol_1, 0, newCell);
14236
- });
14654
+ var _loop_3 = function (i) {
14655
+ var newCol = lastColumn + this_3.countSpanLeft(this_3.row, lastColumn);
14656
+ this_3.forEachCellOfColumn(newCol - 1, function (cell, row, i) {
14657
+ var nextCell = _this.getCell(i, newCol);
14658
+ var newCell;
14659
+ if (nextCell.spanLeft) {
14660
+ newCell = cloneCell(nextCell);
14661
+ }
14662
+ else if (cell.spanAbove) {
14663
+ newCell = cloneCell(cell);
14664
+ newCell.spanLeft = false;
14665
+ }
14666
+ else {
14667
+ newCell = {
14668
+ td: cloneNode(_this.getTd(i, _this.col)),
14669
+ };
14670
+ }
14671
+ row.splice(newCol, 0, newCell);
14672
+ });
14673
+ };
14674
+ var this_3 = this;
14675
+ for (var i = firstColumn; i <= lastColumn; i++) {
14676
+ _loop_3(i);
14677
+ }
14237
14678
  break;
14238
14679
  case 6 /* DeleteRow */:
14239
- this.forEachCellOfCurrentRow(function (cell, i) {
14240
- var nextCell = _this.getCell(_this.row + 1, i);
14241
- if (cell.td && cell.td.rowSpan > 1 && nextCell.spanAbove) {
14242
- nextCell.td = cell.td;
14243
- }
14244
- });
14245
- this.cells.splice(this.row, 1);
14680
+ var _loop_4 = function (rowIndex) {
14681
+ this_4.forEachCellOfRow(rowIndex, function (cell, i) {
14682
+ var nextCell = _this.getCell(rowIndex + 1, i);
14683
+ if (cell.td && cell.td.rowSpan > 1 && nextCell.spanAbove) {
14684
+ nextCell.td = cell.td;
14685
+ }
14686
+ });
14687
+ };
14688
+ var this_4 = this;
14689
+ for (var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++) {
14690
+ _loop_4(rowIndex);
14691
+ }
14692
+ var removedRows = this.selection
14693
+ ? this.selection.lastCell.y - this.selection.firstCell.y
14694
+ : 0;
14695
+ this.cells.splice(firstRow, removedRows + 1);
14246
14696
  break;
14247
14697
  case 5 /* DeleteColumn */:
14248
- this.forEachCellOfCurrentColumn(function (cell, row, i) {
14249
- var nextCell = _this.getCell(i, _this.col + 1);
14250
- if (cell.td && cell.td.colSpan > 1 && nextCell.spanLeft) {
14251
- nextCell.td = cell.td;
14252
- }
14253
- row.splice(_this.col, 1);
14254
- });
14698
+ var deletedColumns_1 = 0;
14699
+ var _loop_5 = function (colIndex) {
14700
+ this_5.forEachCellOfColumn(colIndex, function (cell, row, i) {
14701
+ var nextCell = _this.getCell(i, colIndex + 1);
14702
+ if (cell.td && cell.td.colSpan > 1 && nextCell.spanLeft) {
14703
+ nextCell.td = cell.td;
14704
+ }
14705
+ var removedColumns = _this.selection
14706
+ ? colIndex - deletedColumns_1
14707
+ : _this.col;
14708
+ row.splice(removedColumns, 1);
14709
+ });
14710
+ deletedColumns_1++;
14711
+ };
14712
+ var this_5 = this;
14713
+ for (var colIndex = firstColumn; colIndex <= lastColumn; colIndex++) {
14714
+ _loop_5(colIndex);
14715
+ }
14255
14716
  break;
14256
14717
  case 7 /* MergeAbove */:
14257
14718
  case 8 /* MergeBelow */:
@@ -14261,11 +14722,7 @@ var VTable = /** @class */ (function () {
14261
14722
  if (cell.td && !cell.spanAbove) {
14262
14723
  var aboveCell = rowIndex < this.row ? cell : currentCell;
14263
14724
  var belowCell = rowIndex < this.row ? currentCell : cell;
14264
- if (aboveCell.td.colSpan == belowCell.td.colSpan) {
14265
- (0, moveChildNodes_1.default)(aboveCell.td, belowCell.td, true /*keepExistingChildren*/);
14266
- belowCell.td = null;
14267
- belowCell.spanAbove = true;
14268
- }
14725
+ this.mergeCells(aboveCell, belowCell);
14269
14726
  break;
14270
14727
  }
14271
14728
  }
@@ -14278,20 +14735,30 @@ var VTable = /** @class */ (function () {
14278
14735
  if (cell.td && !cell.spanLeft) {
14279
14736
  var leftCell = colIndex < this.col ? cell : currentCell;
14280
14737
  var rightCell = colIndex < this.col ? currentCell : cell;
14281
- if (leftCell.td.rowSpan == rightCell.td.rowSpan) {
14282
- (0, moveChildNodes_1.default)(leftCell.td, rightCell.td, true /*keepExistingChildren*/);
14283
- rightCell.td = null;
14284
- rightCell.spanLeft = true;
14285
- }
14738
+ this.mergeCells(leftCell, rightCell, true /** horizontally */);
14286
14739
  break;
14287
14740
  }
14288
14741
  }
14289
14742
  break;
14743
+ case 11 /* MergeCells */:
14744
+ for (var colIndex = firstColumn; colIndex <= lastColumn; colIndex++) {
14745
+ for (var rowIndex = firstRow + 1; rowIndex <= lastRow; rowIndex++) {
14746
+ var cell = this.getCell(firstRow, colIndex);
14747
+ var nextCellBelow = this.getCell(rowIndex, colIndex);
14748
+ this.mergeCells(cell, nextCellBelow);
14749
+ }
14750
+ }
14751
+ for (var colIndex = firstColumn + 1; colIndex <= lastColumn; colIndex++) {
14752
+ var cell = this.getCell(firstRow, firstColumn);
14753
+ var nextCellRight = this.getCell(firstRow, colIndex);
14754
+ this.mergeCells(cell, nextCellRight, true /** horizontally */);
14755
+ }
14756
+ break;
14290
14757
  case 4 /* DeleteTable */:
14291
14758
  this.cells = null;
14292
14759
  break;
14293
- case 12 /* SplitVertically */:
14294
- if (currentCell.td.rowSpan > 1) {
14760
+ case 13 /* SplitVertically */:
14761
+ if (currentCell.td && currentCell.td.rowSpan > 1) {
14295
14762
  this.getCell(this.row + 1, this.col).td = cloneNode(currentCell.td);
14296
14763
  }
14297
14764
  else {
@@ -14305,8 +14772,8 @@ var VTable = /** @class */ (function () {
14305
14772
  this.cells.splice(this.row + 1, 0, splitRow);
14306
14773
  }
14307
14774
  break;
14308
- case 11 /* SplitHorizontally */:
14309
- if (currentCell.td.colSpan > 1) {
14775
+ case 12 /* SplitHorizontally */:
14776
+ if (currentCell.td && currentCell.td.colSpan > 1) {
14310
14777
  this.getCell(this.row, this.col + 1).td = cloneNode(currentCell.td);
14311
14778
  }
14312
14779
  else {
@@ -14319,38 +14786,70 @@ var VTable = /** @class */ (function () {
14319
14786
  });
14320
14787
  }
14321
14788
  break;
14322
- case 13 /* AlignCenter */:
14789
+ case 14 /* AlignCenter */:
14323
14790
  this.table.style.marginLeft = 'auto';
14324
14791
  this.table.style.marginRight = 'auto';
14325
14792
  break;
14326
- case 14 /* AlignLeft */:
14793
+ case 15 /* AlignLeft */:
14327
14794
  this.table.style.marginLeft = '';
14328
14795
  this.table.style.marginRight = 'auto';
14329
14796
  break;
14330
- case 15 /* AlignRight */:
14797
+ case 16 /* AlignRight */:
14331
14798
  this.table.style.marginLeft = 'auto';
14332
14799
  this.table.style.marginRight = '';
14333
14800
  break;
14334
- case 17 /* AlignCellCenter */:
14335
- style.textAlign = 'center';
14801
+ case 18 /* AlignCellCenter */:
14802
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'center');
14336
14803
  break;
14337
- case 16 /* AlignCellLeft */:
14338
- style.textAlign = 'left';
14804
+ case 17 /* AlignCellLeft */:
14805
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'left');
14339
14806
  break;
14340
- case 18 /* AlignCellRight */:
14341
- style.textAlign = 'right';
14807
+ case 19 /* AlignCellRight */:
14808
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'right');
14342
14809
  break;
14343
- case 19 /* AlignCellTop */:
14344
- style.verticalAlign = 'top';
14810
+ case 20 /* AlignCellTop */:
14811
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'top', true /** isVertical */);
14345
14812
  break;
14346
- case 20 /* AlignCellMiddle */:
14347
- style.verticalAlign = 'middle';
14813
+ case 21 /* AlignCellMiddle */:
14814
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'middle', true /** isVertical */);
14348
14815
  break;
14349
- case 21 /* AlignCellBottom */:
14350
- style.verticalAlign = 'bottom';
14816
+ case 22 /* AlignCellBottom */:
14817
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'bottom', true /** isVertical */);
14351
14818
  break;
14352
14819
  }
14353
14820
  };
14821
+ VTable.prototype.setAlignmentToSelectedCells = function (firstRow, lastRow, firstColumn, lastColumn, alignmentType, isVertical) {
14822
+ var _a, _b;
14823
+ for (var i = firstRow; i <= lastRow; i++) {
14824
+ for (var j = firstColumn; j <= lastColumn; j++) {
14825
+ if (this.cells) {
14826
+ var cell = this.cells[i][j].td;
14827
+ if (isVertical && cell) {
14828
+ (_a = cell.style) === null || _a === void 0 ? void 0 : _a.setProperty('vertical-align', alignmentType);
14829
+ }
14830
+ else if (cell) {
14831
+ (_b = cell.style) === null || _b === void 0 ? void 0 : _b.setProperty('text-align', alignmentType);
14832
+ }
14833
+ }
14834
+ }
14835
+ }
14836
+ };
14837
+ VTable.prototype.mergeCells = function (cell, nextCell, horizontally) {
14838
+ var _a, _b, _c, _d;
14839
+ var checkSpans = horizontally
14840
+ ? ((_a = cell.td) === null || _a === void 0 ? void 0 : _a.rowSpan) === ((_b = nextCell.td) === null || _b === void 0 ? void 0 : _b.rowSpan) && !cell.spanLeft
14841
+ : ((_c = cell.td) === null || _c === void 0 ? void 0 : _c.colSpan) === ((_d = nextCell.td) === null || _d === void 0 ? void 0 : _d.colSpan) && !cell.spanAbove;
14842
+ if (cell.td && nextCell.td && checkSpans) {
14843
+ (0, moveChildNodes_1.default)(cell.td, nextCell.td, true /*keepExistingChildren*/);
14844
+ nextCell.td = null;
14845
+ if (horizontally) {
14846
+ nextCell.spanLeft = true;
14847
+ }
14848
+ else {
14849
+ nextCell.spanAbove = true;
14850
+ }
14851
+ }
14852
+ };
14354
14853
  /**
14355
14854
  * Loop each cell of current column and invoke a callback function
14356
14855
  * @param callback The callback function to invoke
@@ -14384,7 +14883,7 @@ var VTable = /** @class */ (function () {
14384
14883
  */
14385
14884
  VTable.prototype.getCellsWithBorder = function (borderPos, getLeftCells) {
14386
14885
  var cells = [];
14387
- for (var i = 0; i < this.cells.length; i++) {
14886
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14388
14887
  for (var j = 0; j < this.cells[i].length; j++) {
14389
14888
  var cell = this.getCell(i, j);
14390
14889
  if (cell.td) {
@@ -14443,7 +14942,7 @@ var VTable = /** @class */ (function () {
14443
14942
  * @param col column of the cell
14444
14943
  */
14445
14944
  VTable.prototype.getTd = function (row, col) {
14446
- if (this.cells) {
14945
+ if (this.cells && row !== undefined && col !== undefined) {
14447
14946
  row = Math.min(this.cells.length - 1, row);
14448
14947
  col = this.cells[row] ? Math.min(this.cells[row].length - 1, col) : col;
14449
14948
  if (!isNaN(row) && !isNaN(col)) {
@@ -14467,13 +14966,17 @@ var VTable = /** @class */ (function () {
14467
14966
  return null;
14468
14967
  };
14469
14968
  VTable.prototype.forEachCellOfColumn = function (col, callback) {
14470
- for (var i = 0; i < this.cells.length; i++) {
14471
- callback(this.getCell(i, col), this.cells[i], i);
14969
+ if (col !== undefined) {
14970
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14971
+ callback(this.getCell(i, col), this.cells[i], i);
14972
+ }
14472
14973
  }
14473
14974
  };
14474
14975
  VTable.prototype.forEachCellOfRow = function (row, callback) {
14475
- for (var i = 0; i < this.cells[row].length; i++) {
14476
- callback(this.getCell(row, i), i);
14976
+ if (row !== undefined) {
14977
+ for (var i = 0; this.cells && i < this.cells[row].length; i++) {
14978
+ callback(this.getCell(row, i), i);
14979
+ }
14477
14980
  }
14478
14981
  };
14479
14982
  VTable.prototype.recalculateSpans = function (row, col) {
@@ -14491,7 +14994,7 @@ var VTable = /** @class */ (function () {
14491
14994
  };
14492
14995
  VTable.prototype.countSpanLeft = function (row, col) {
14493
14996
  var result = 1;
14494
- for (var i = col + 1; i < this.cells[row].length; i++) {
14997
+ for (var i = col + 1; this.cells && i < this.cells[row].length; i++) {
14495
14998
  var cell = this.getCell(row, i);
14496
14999
  if (cell.td || !cell.spanLeft) {
14497
15000
  break;
@@ -14502,7 +15005,7 @@ var VTable = /** @class */ (function () {
14502
15005
  };
14503
15006
  VTable.prototype.countSpanAbove = function (row, col) {
14504
15007
  var result = 1;
14505
- for (var i = row + 1; i < this.cells.length; i++) {
15008
+ for (var i = row + 1; this.cells && i < this.cells.length; i++) {
14506
15009
  var cell = this.getCell(i, col);
14507
15010
  if (cell.td || !cell.spanAbove) {
14508
15011
  break;
@@ -14527,17 +15030,19 @@ var VTable = /** @class */ (function () {
14527
15030
  // remove width/height for each row
14528
15031
  for (var i = 0, row = void 0; (row = this.table.rows[i]); i++) {
14529
15032
  row.removeAttribute('width');
14530
- row.style.width = null;
15033
+ row.style.setProperty('width', null);
14531
15034
  row.removeAttribute('height');
14532
- row.style.height = null;
15035
+ row.style.setProperty('height', null);
14533
15036
  }
14534
15037
  // set width/height for each cell
14535
- for (var i = 0; i < this.cells.length; i++) {
15038
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14536
15039
  for (var j = 0; j < this.cells[i].length; j++) {
14537
15040
  var cell = this.cells[i][j];
14538
15041
  if (cell) {
14539
15042
  var func = typeof zoomScale == 'number' ? function (n) { return n / zoomScale; } : zoomScale;
14540
- setHTMLElementSizeInPx(cell.td, (func === null || func === void 0 ? void 0 : func(cell.width)) || cell.width, (func === null || func === void 0 ? void 0 : func(cell.height)) || cell.height);
15043
+ var width = cell.width || 0;
15044
+ var height = cell.height || 0;
15045
+ setHTMLElementSizeInPx(cell.td, (func === null || func === void 0 ? void 0 : func(width)) || width, (func === null || func === void 0 ? void 0 : func(height)) || height);
14541
15046
  }
14542
15047
  }
14543
15048
  }
@@ -14881,6 +15386,40 @@ function getBorderStyle(style) {
14881
15386
  }
14882
15387
 
14883
15388
 
15389
+ /***/ }),
15390
+
15391
+ /***/ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts":
15392
+ /*!*************************************************************************!*\
15393
+ !*** ./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts ***!
15394
+ \*************************************************************************/
15395
+ /*! no static exports found */
15396
+ /***/ (function(module, exports, __webpack_require__) {
15397
+
15398
+ "use strict";
15399
+
15400
+ Object.defineProperty(exports, "__esModule", { value: true });
15401
+ /**
15402
+ * Check if the whole table is selected
15403
+ * @param vTable VTable to check whether all cells are selected
15404
+ * @param selection Table selection with first cell selected and last cell selected coordinates.
15405
+ * @returns
15406
+ */
15407
+ function isWholeTableSelected(vTable, selection) {
15408
+ if (!selection || !vTable.cells) {
15409
+ return false;
15410
+ }
15411
+ var firstCell = selection.firstCell, lastCell = selection.lastCell;
15412
+ var rowsLength = vTable.cells.length - 1;
15413
+ var colIndex = vTable.cells[rowsLength].length - 1;
15414
+ var firstX = firstCell.x;
15415
+ var firstY = firstCell.y;
15416
+ var lastX = lastCell.x;
15417
+ var lastY = lastCell.y;
15418
+ return firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
15419
+ }
15420
+ exports.default = isWholeTableSelected;
15421
+
15422
+
14884
15423
  /***/ }),
14885
15424
 
14886
15425
  /***/ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts":
@@ -18110,11 +18649,14 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
18110
18649
  */
18111
18650
  var TabInTable = {
18112
18651
  keys: [9 /* TAB */],
18113
- shouldHandleEvent: cacheGetTableCell,
18652
+ shouldHandleEvent: function (event, editor) {
18653
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18654
+ },
18114
18655
  handleEvent: function (event, editor) {
18115
18656
  var shift = event.rawEvent.shiftKey;
18116
18657
  var td = cacheGetTableCell(event, editor);
18117
- for (var vtable = new roosterjs_editor_dom_1.VTable(td), step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
18658
+ var vtable = cacheVTable(event, td);
18659
+ for (var step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
18118
18660
  if (col < 0 || col >= vtable.cells[row].length) {
18119
18661
  row += step;
18120
18662
  if (row < 0) {
@@ -18136,13 +18678,40 @@ var TabInTable = {
18136
18678
  event.rawEvent.preventDefault();
18137
18679
  },
18138
18680
  };
18681
+ /**
18682
+ * IndentTableOnTab edit feature, provides the ability to indent the table if it is all cells are selected.
18683
+ */
18684
+ var IndentTableOnTab = {
18685
+ keys: [9 /* TAB */],
18686
+ shouldHandleEvent: function (event, editor) {
18687
+ return cacheGetTableCell(event, editor) && cacheIsWholeTableSelected(event, editor);
18688
+ },
18689
+ handleEvent: function (event, editor) {
18690
+ event.rawEvent.preventDefault();
18691
+ editor.addUndoSnapshot(function () {
18692
+ var shift = event.rawEvent.shiftKey;
18693
+ var selection = editor.getSelectionRangeEx();
18694
+ var td = cacheGetTableCell(event, editor);
18695
+ var vtable = cacheVTable(event, td);
18696
+ if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
18697
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
18698
+ }
18699
+ else if (!shift) {
18700
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
18701
+ }
18702
+ editor.select(selection.table, selection.coordinates);
18703
+ });
18704
+ },
18705
+ };
18139
18706
  /**
18140
18707
  * UpDownInTable edit feature, provides the ability to jump to cell above/below when user press UP/DOWN
18141
18708
  * in table
18142
18709
  */
18143
18710
  var UpDownInTable = {
18144
18711
  keys: [38 /* UP */, 40 /* DOWN */],
18145
- shouldHandleEvent: cacheGetTableCell,
18712
+ shouldHandleEvent: function (event, editor) {
18713
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18714
+ },
18146
18715
  handleEvent: function (event, editor) {
18147
18716
  var _a;
18148
18717
  var td = cacheGetTableCell(event, editor);
@@ -18194,12 +18763,27 @@ function cacheGetTableCell(event, editor) {
18194
18763
  return (firstTd && ((0, roosterjs_editor_dom_1.getTagOfNode)(firstTd) == 'LI' ? null : firstTd));
18195
18764
  });
18196
18765
  }
18766
+ function cacheIsWholeTableSelected(event, editor) {
18767
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
18768
+ var td = cacheGetTableCell(event, editor);
18769
+ var vtable = cacheVTable(event, td);
18770
+ var selection = editor.getSelectionRangeEx();
18771
+ return (selection.type == 1 /* TableSelection */ &&
18772
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
18773
+ });
18774
+ }
18775
+ function cacheVTable(event, td) {
18776
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'VTABLE_FOR_TABLE_FEATURES', function () {
18777
+ return new roosterjs_editor_dom_1.VTable(td);
18778
+ });
18779
+ }
18197
18780
  /**
18198
18781
  * @internal
18199
18782
  */
18200
18783
  exports.TableFeatures = {
18201
18784
  tabInTable: TabInTable,
18202
18785
  upDownInTable: UpDownInTable,
18786
+ indentTableOnTab: IndentTableOnTab,
18203
18787
  };
18204
18788
 
18205
18789
 
@@ -18320,17 +18904,27 @@ function insertTab(editor, event) {
18320
18904
  var searcher = editor.getContentSearcherOfCursor(event);
18321
18905
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
18322
18906
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
18907
+ var span2;
18323
18908
  var textContent = '';
18324
18909
  for (var index = 0; index < numberOfChars; index++) {
18325
18910
  textContent += '&ensp;';
18326
18911
  }
18327
18912
  editor.insertNode(span);
18913
+ if (span.nextElementSibling && (0, roosterjs_editor_dom_1.getTagOfNode)(span.nextElementSibling) == 'A') {
18914
+ span2 = editor.getDocument().createElement('span');
18915
+ span2.textContent = ' ';
18916
+ editor.insertNode(span2);
18917
+ editor.select((0, roosterjs_editor_dom_1.createRange)(span2, -2 /* Before */));
18918
+ }
18328
18919
  editor.insertContent(textContent, {
18329
18920
  position: 5 /* Range */,
18330
18921
  range: (0, roosterjs_editor_dom_1.createRange)(span, 0 /* Begin */),
18331
18922
  updateCursor: false,
18332
18923
  });
18333
18924
  editor.select((0, roosterjs_editor_dom_1.createRange)(span, -3 /* After */));
18925
+ if (span2) {
18926
+ editor.deleteNode(span2);
18927
+ }
18334
18928
  }
18335
18929
 
18336
18930
 
@@ -22553,6 +23147,14 @@ var TableCellSelection = /** @class */ (function () {
22553
23147
  this.handleScrollEvent();
22554
23148
  }
22555
23149
  break;
23150
+ case 20 /* BeforeSetContent */:
23151
+ if (this.tableRange) {
23152
+ this.tableRange = null;
23153
+ this.firstTable = null;
23154
+ this.tableSelection = false;
23155
+ this.editor.select(null);
23156
+ }
23157
+ break;
22556
23158
  }
22557
23159
  }
22558
23160
  };
@@ -22586,10 +23188,12 @@ var TableCellSelection = /** @class */ (function () {
22586
23188
  if (selection.type == 1 /* TableSelection */) {
22587
23189
  var clonedTable = event.clonedRoot.querySelector('table#' + selection.table.id);
22588
23190
  if (clonedTable) {
23191
+ this.tableRange = selection.coordinates;
22589
23192
  var clonedVTable = new roosterjs_editor_dom_1.VTable(clonedTable);
22590
23193
  clonedVTable.selection = this.tableRange;
22591
23194
  (0, removeCellsOutsideSelection_1.removeCellsOutsideSelection)(clonedVTable);
22592
23195
  clonedVTable.writeBack();
23196
+ clonedVTable.table.id = '';
22593
23197
  event.range.selectNode(clonedTable);
22594
23198
  if (event.isCut) {
22595
23199
  (0, forEachSelectedCell_1.forEachSelectedCell)(this.vTable, function (cell) {
@@ -22608,8 +23212,9 @@ var TableCellSelection = /** @class */ (function () {
22608
23212
  */
22609
23213
  TableCellSelection.prototype.handleKeyDownEvent = function (event) {
22610
23214
  var _this = this;
22611
- var _a = event.rawEvent, shiftKey = _a.shiftKey, ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which;
22612
- if ((shiftKey && (ctrlKey || metaKey)) || which == 16 /* SHIFT */) {
23215
+ var _a = event.rawEvent, shiftKey = _a.shiftKey, ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which, defaultPrevented = _a.defaultPrevented;
23216
+ if ((shiftKey && (ctrlKey || metaKey)) || which == 16 /* SHIFT */ || defaultPrevented) {
23217
+ this.preventKeyUp = defaultPrevented;
22613
23218
  return;
22614
23219
  }
22615
23220
  if (shiftKey) {
@@ -22643,9 +23248,10 @@ var TableCellSelection = /** @class */ (function () {
22643
23248
  };
22644
23249
  TableCellSelection.prototype.handleKeyUpEvent = function (event) {
22645
23250
  var _a = event.rawEvent, shiftKey = _a.shiftKey, which = _a.which;
22646
- if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget) {
23251
+ if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget && !this.preventKeyUp) {
22647
23252
  this.clearState();
22648
23253
  }
23254
+ this.preventKeyUp = false;
22649
23255
  };
22650
23256
  TableCellSelection.prototype.handleKeySelectionInsideTable = function (event) {
22651
23257
  this.firstTarget = getCellAtCursor(this.editor, this.firstTarget);
@@ -22709,13 +23315,17 @@ var TableCellSelection = /** @class */ (function () {
22709
23315
  }
22710
23316
  }
22711
23317
  }
22712
- this.editor.getDocument().addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
22713
23318
  if (which == LEFT_CLICK && !shiftKey) {
22714
23319
  this.clearState();
22715
- this.editor
22716
- .getDocument()
22717
- .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
22718
- this.startedSelection = true;
23320
+ if (getTableAtCursor(this.editor, event.rawEvent.target)) {
23321
+ this.editor
23322
+ .getDocument()
23323
+ .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
23324
+ this.editor
23325
+ .getDocument()
23326
+ .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
23327
+ this.startedSelection = true;
23328
+ }
22719
23329
  }
22720
23330
  if (which == LEFT_CLICK && shiftKey) {
22721
23331
  this.editor.runAsync(function (editor) {
@@ -23069,10 +23679,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
23069
23679
  * and the last cell always going to be last selected in the table.
23070
23680
  */
23071
23681
  function normalizeTableSelection(vTable) {
23072
- if (!vTable || !vTable.selection) {
23682
+ var _a = (vTable === null || vTable === void 0 ? void 0 : vTable.selection) || {}, firstCell = _a.firstCell, lastCell = _a.lastCell;
23683
+ if (!vTable || !vTable.selection || !firstCell || !lastCell) {
23073
23684
  return null;
23074
23685
  }
23075
- var _a = vTable.selection, firstCell = _a.firstCell, lastCell = _a.lastCell;
23076
23686
  var rows = vTable.table.rows;
23077
23687
  var newFirst = {
23078
23688
  x: Math.min(firstCell.x, lastCell.x),
@@ -23097,8 +23707,8 @@ function normalizeTableSelection(vTable) {
23097
23707
  coord.x = rowsCells - 1;
23098
23708
  }
23099
23709
  };
23100
- fixCoordinates(firstCell);
23101
- fixCoordinates(lastCell);
23710
+ fixCoordinates(newFirst);
23711
+ fixCoordinates(newLast);
23102
23712
  return { firstCell: newFirst, lastCell: newLast };
23103
23713
  }
23104
23714
  exports.default = normalizeTableSelection;
@@ -23117,24 +23727,22 @@ exports.default = normalizeTableSelection;
23117
23727
 
23118
23728
  Object.defineProperty(exports, "__esModule", { value: true });
23119
23729
  exports.removeCellsOutsideSelection = void 0;
23730
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
23120
23731
  /**
23121
23732
  * @internal
23122
23733
  * Remove the cells outside of the selection.
23123
23734
  * @param vTable VTable to remove selection
23124
23735
  */
23125
23736
  function removeCellsOutsideSelection(vTable) {
23737
+ if ((0, roosterjs_editor_dom_1.isWholeTableSelected)(vTable, vTable.selection)) {
23738
+ return;
23739
+ }
23126
23740
  var _a = vTable.selection, firstCell = _a.firstCell, lastCell = _a.lastCell;
23127
- var rowsLength = vTable.cells.length - 1;
23128
- var colIndex = vTable.cells[rowsLength].length - 1;
23129
23741
  var resultCells = [];
23130
23742
  var firstX = firstCell.x;
23131
23743
  var firstY = firstCell.y;
23132
23744
  var lastX = lastCell.x;
23133
23745
  var lastY = lastCell.y;
23134
- var selectedAllTable = firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
23135
- if (selectedAllTable) {
23136
- return;
23137
- }
23138
23746
  vTable.cells.forEach(function (row, y) {
23139
23747
  row = row.filter(function (_, x) { return y >= firstY && y <= lastY && x >= firstX && x <= lastX; });
23140
23748
  if (row.length > 0) {
@@ -23499,7 +24107,8 @@ var TableEditor = /** @class */ (function () {
23499
24107
  _this.disposeTableResizer();
23500
24108
  _this.onStartResize();
23501
24109
  };
23502
- this.onInserted = function () {
24110
+ this.onInserted = function (table) {
24111
+ _this.editor.transformToDarkColor(table);
23503
24112
  _this.disposeTableResizer();
23504
24113
  _this.onFinishEditing();
23505
24114
  };
@@ -23736,9 +24345,7 @@ var TableInsertHandler = /** @class */ (function () {
23736
24345
  }
23737
24346
  vtable.edit(_this.isHorizontal ? 1 /* InsertBelow */ : 3 /* InsertRight */);
23738
24347
  vtable.writeBack();
23739
- //Adding replaceNode to transform color when the theme is switched to dark.
23740
- _this.editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
23741
- _this.onInsert();
24348
+ _this.onInsert(vtable.table);
23742
24349
  };
23743
24350
  this.div.addEventListener('click', this.insertTd);
23744
24351
  }