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