roosterjs 8.18.0 → 8.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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;
@@ -5708,6 +5740,7 @@ function isValidCoordinate(input) {
5708
5740
  Object.defineProperty(exports, "__esModule", { value: true });
5709
5741
  exports.setContent = void 0;
5710
5742
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5743
+ var roosterjs_editor_dom_2 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5711
5744
  /**
5712
5745
  * @internal
5713
5746
  * Set HTML content to this editor. All existing content will be replaced. A ContentChanged event will be triggered
@@ -5716,20 +5749,24 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
5716
5749
  * @param content HTML content to set in
5717
5750
  * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
5718
5751
  */
5719
- var setContent = function (core, content, triggerContentChangedEvent) {
5752
+ var setContent = function (core, content, triggerContentChangedEvent, metadata) {
5720
5753
  var contentChanged = false;
5721
5754
  if (core.contentDiv.innerHTML != content) {
5722
5755
  core.api.triggerEvent(core, {
5723
5756
  eventType: 20 /* BeforeSetContent */,
5724
5757
  newContent: content,
5725
5758
  }, true /*broadcast*/);
5726
- var range = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(core.contentDiv, content, core.trustedHTMLHandler);
5727
- core.api.selectRange(core, range);
5759
+ var metadataFromContent = (0, roosterjs_editor_dom_2.setHtmlWithMetadata)(core.contentDiv, content, core.trustedHTMLHandler);
5760
+ metadata = metadata || metadataFromContent;
5761
+ selectContentMetadata(core, metadata);
5762
+ contentChanged = true;
5763
+ }
5764
+ var isDarkMode = core.lifecycle.isDarkMode;
5765
+ if ((!metadata && isDarkMode) || (metadata && !!metadata.isDarkMode != !!isDarkMode)) {
5766
+ core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, isDarkMode ? 0 /* LightToDark */ : 1 /* DarkToLight */, true /*forceTransform*/);
5728
5767
  contentChanged = true;
5729
5768
  }
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)) {
5769
+ if (triggerContentChangedEvent && contentChanged) {
5733
5770
  core.api.triggerEvent(core, {
5734
5771
  eventType: 7 /* ContentChanged */,
5735
5772
  source: "SetContent" /* SetContent */,
@@ -5737,6 +5774,20 @@ var setContent = function (core, content, triggerContentChangedEvent) {
5737
5774
  }
5738
5775
  };
5739
5776
  exports.setContent = setContent;
5777
+ function selectContentMetadata(core, metadata) {
5778
+ switch (metadata === null || metadata === void 0 ? void 0 : metadata.type) {
5779
+ case 0 /* Normal */:
5780
+ var range = (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, metadata.start, metadata.end);
5781
+ core.api.selectRange(core, range);
5782
+ break;
5783
+ case 1 /* TableSelection */:
5784
+ var table = (0, roosterjs_editor_dom_1.queryElements)(core.contentDiv, '#' + metadata.tableId)[0];
5785
+ if (table) {
5786
+ core.api.selectTable(core, table, metadata);
5787
+ }
5788
+ break;
5789
+ }
5790
+ }
5740
5791
 
5741
5792
 
5742
5793
  /***/ }),
@@ -5847,52 +5898,70 @@ var ColorAttributeName = [
5847
5898
  * @param includeSelf True to transform the root node as well, otherwise false
5848
5899
  * @param callback The callback function to invoke before do color transformation
5849
5900
  * @param direction To specify the transform direction, light to dark, or dark to light
5901
+ * @param forceTransform By default this function will only work when editor core is in dark mode.
5902
+ * Pass true to this value to force do color transformation even editor core is in light mode
5850
5903
  */
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); });
5904
+ var transformColor = function (core, rootNode, includeSelf, callback, direction, forceTransform) {
5905
+ var elements = forceTransform || core.lifecycle.isDarkMode ? getAll(rootNode, includeSelf) : [];
5857
5906
  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); });
5907
+ if (direction == 1 /* DarkToLight */) {
5908
+ transformToLightMode(elements);
5909
+ }
5910
+ else if (core.lifecycle.onExternalContentTransform) {
5911
+ elements.forEach(function (element) { return core.lifecycle.onExternalContentTransform(element); });
5912
+ }
5913
+ else {
5914
+ transformToDarkMode(elements, core.lifecycle.getDarkColor);
5915
+ }
5859
5916
  };
5860
5917
  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 */]];
5918
+ function transformToLightMode(elements) {
5919
+ elements.forEach(function (element) {
5920
+ ColorAttributeName.forEach(function (names) {
5921
+ // Reset color styles based on the content of the ogsc/ogsb data element.
5922
+ // If those data properties are empty or do not exist, set them anyway to clear the content.
5923
+ element.style.setProperty(names[0 /* CssColor */], getValueOrDefault(element.dataset[names[2 /* CssDataSet */]], ''));
5924
+ delete element.dataset[names[2 /* CssDataSet */]];
5925
+ // Some elements might have set attribute colors. We need to reset these as well.
5926
+ var value = element.dataset[names[3 /* HtmlDataSet */]];
5927
+ if (getValueOrDefault(value, null)) {
5928
+ element.setAttribute(names[1 /* HtmlColor */], value);
5929
+ }
5930
+ else {
5931
+ element.removeAttribute(names[1 /* HtmlColor */]);
5932
+ }
5933
+ delete element.dataset[names[3 /* HtmlDataSet */]];
5934
+ });
5876
5935
  });
5877
5936
  }
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);
5937
+ function transformToDarkMode(elements, getDarkColor) {
5938
+ ColorAttributeName.forEach(function (names) {
5939
+ elements
5940
+ .map(function (element) {
5941
+ var styleColor = element.style.getPropertyValue(names[0 /* CssColor */]);
5942
+ var attrColor = element.getAttribute(names[1 /* HtmlColor */]);
5943
+ return !element.dataset[names[2 /* CssDataSet */]] &&
5944
+ !element.dataset[names[3 /* HtmlDataSet */]] &&
5945
+ (styleColor || attrColor) &&
5946
+ styleColor != 'inherit' // For inherit style, no need to change it and let it keep inherit from parent element
5947
+ ? {
5948
+ element: element,
5949
+ styleColor: styleColor,
5950
+ attrColor: attrColor,
5951
+ newColor: getDarkColor(styleColor || attrColor),
5952
+ }
5953
+ : null;
5954
+ })
5955
+ .filter(function (x) { return !!x; })
5956
+ .forEach(function (_a) {
5957
+ var element = _a.element, styleColor = _a.styleColor, attrColor = _a.attrColor, newColor = _a.newColor;
5889
5958
  element.style.setProperty(names[0 /* CssColor */], newColor, 'important');
5890
5959
  element.dataset[names[2 /* CssDataSet */]] = styleColor || '';
5891
5960
  if (attrColor) {
5892
5961
  element.setAttribute(names[1 /* HtmlColor */], newColor);
5893
5962
  element.dataset[names[3 /* HtmlDataSet */]] = attrColor;
5894
5963
  }
5895
- }
5964
+ });
5896
5965
  });
5897
5966
  }
5898
5967
  function getValueOrDefault(value, defaultValue) {
@@ -5911,7 +5980,14 @@ function getAll(rootNode, includeSelf) {
5911
5980
  var allChildren = rootNode.querySelectorAll('*');
5912
5981
  (0, roosterjs_editor_dom_1.arrayPush)(result, (0, roosterjs_editor_dom_1.toArray)(allChildren));
5913
5982
  }
5914
- return result;
5983
+ return result.filter(isHTMLElement);
5984
+ }
5985
+ // This is not a strict check, we just need to make sure this element has style so that we can set style to it
5986
+ // We don't use safeInstanceOf() here since this function will be called very frequently when extract html content
5987
+ // in dark mode, so we need to make sure this check is fast enough
5988
+ function isHTMLElement(element) {
5989
+ var htmlElement = element;
5990
+ return !!htmlElement.style && !!htmlElement.dataset;
5915
5991
  }
5916
5992
 
5917
5993
 
@@ -6042,7 +6118,6 @@ var CopyPastePlugin = /** @class */ (function () {
6042
6118
  var _this = this;
6043
6119
  var selection = this.editor.getSelectionRangeEx();
6044
6120
  if (selection && !selection.areAllCollapsed) {
6045
- var originalRange_1 = selection.ranges[0];
6046
6121
  var html = this.editor.getContent(2 /* RawHTMLWithSelection */);
6047
6122
  var tempDiv_1 = this.getTempDiv(true /*forceInLightMode*/);
6048
6123
  var newRange = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(tempDiv_1, html, this.editor.getTrustedHTMLHandler());
@@ -6056,7 +6131,7 @@ var CopyPastePlugin = /** @class */ (function () {
6056
6131
  isCut: isCut,
6057
6132
  });
6058
6133
  this.editor.runAsync(function (editor) {
6059
- _this.cleanUpAndRestoreSelection(tempDiv_1, originalRange_1, !isCut /* isCopy */);
6134
+ _this.cleanUpAndRestoreSelection(tempDiv_1, selection, !isCut /* isCopy */);
6060
6135
  if (isCut) {
6061
6136
  editor.addUndoSnapshot(function () {
6062
6137
  var position = _this.editor.deleteSelectedContent();
@@ -6085,15 +6160,35 @@ var CopyPastePlugin = /** @class */ (function () {
6085
6160
  return div;
6086
6161
  };
6087
6162
  CopyPastePlugin.prototype.cleanUpAndRestoreSelection = function (tempDiv, range, isCopy) {
6088
- if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6089
- range.collapse();
6163
+ var _a, _b;
6164
+ if (!!((_a = range) === null || _a === void 0 ? void 0 : _a.type)) {
6165
+ var selection = range;
6166
+ switch (selection.type) {
6167
+ case 1 /* TableSelection */:
6168
+ this.editor.select(selection.table, selection.coordinates);
6169
+ break;
6170
+ case 0 /* Normal */:
6171
+ var range_1 = (_b = selection.ranges) === null || _b === void 0 ? void 0 : _b[0];
6172
+ this.restoreRange(range_1, isCopy);
6173
+ break;
6174
+ }
6175
+ }
6176
+ else {
6177
+ this.restoreRange(range, isCopy);
6090
6178
  }
6091
- this.editor.select(range);
6092
6179
  tempDiv.style.backgroundColor = '';
6093
6180
  tempDiv.style.color = '';
6094
6181
  tempDiv.style.display = 'none';
6095
6182
  (0, roosterjs_editor_dom_1.moveChildNodes)(tempDiv);
6096
6183
  };
6184
+ CopyPastePlugin.prototype.restoreRange = function (range, isCopy) {
6185
+ if (range) {
6186
+ if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6187
+ range.collapse();
6188
+ }
6189
+ this.editor.select(range);
6190
+ }
6191
+ };
6097
6192
  return CopyPastePlugin;
6098
6193
  }());
6099
6194
  exports.default = CopyPastePlugin;
@@ -7038,6 +7133,140 @@ var MouseUpPlugin = /** @class */ (function () {
7038
7133
  exports.default = MouseUpPlugin;
7039
7134
 
7040
7135
 
7136
+ /***/ }),
7137
+
7138
+ /***/ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts":
7139
+ /*!********************************************************************************!*\
7140
+ !*** ./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts ***!
7141
+ \********************************************************************************/
7142
+ /*! no static exports found */
7143
+ /***/ (function(module, exports, __webpack_require__) {
7144
+
7145
+ "use strict";
7146
+
7147
+ Object.defineProperty(exports, "__esModule", { value: true });
7148
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7149
+ /**
7150
+ * @internal
7151
+ * NormalizeTable plugin makes sure each table in editor has TBODY/THEAD/TFOOT tag around TR tags
7152
+ *
7153
+ * When we retrieve HTML content using innerHTML, browser will always add TBODY around TR nodes if there is not.
7154
+ * This causes some issue when we restore the HTML content with selection path since the selection path is
7155
+ * deeply coupled with DOM structure. So we need to always make sure there is already TBODY tag whenever
7156
+ * new table is inserted, to make sure the selection path we created is correct.
7157
+ */
7158
+ var NormalizeTablePlugin = /** @class */ (function () {
7159
+ function NormalizeTablePlugin() {
7160
+ }
7161
+ /**
7162
+ * Get a friendly name of this plugin
7163
+ */
7164
+ NormalizeTablePlugin.prototype.getName = function () {
7165
+ return 'NormalizeTable';
7166
+ };
7167
+ /**
7168
+ * The first method that editor will call to a plugin when editor is initializing.
7169
+ * It will pass in the editor instance, plugin should take this chance to save the
7170
+ * editor reference so that it can call to any editor method or format API later.
7171
+ * @param editor The editor object
7172
+ */
7173
+ NormalizeTablePlugin.prototype.initialize = function (editor) {
7174
+ this.editor = editor;
7175
+ };
7176
+ /**
7177
+ * The last method that editor will call to a plugin before it is disposed.
7178
+ * Plugin can take this chance to clear the reference to editor. After this method is
7179
+ * called, plugin should not call to any editor method since it will result in error.
7180
+ */
7181
+ NormalizeTablePlugin.prototype.dispose = function () {
7182
+ this.editor = null;
7183
+ };
7184
+ /**
7185
+ * Core method for a plugin. Once an event happens in editor, editor will call this
7186
+ * method of each plugin to handle the event as long as the event is not handled
7187
+ * exclusively by another plugin.
7188
+ * @param event The event to handle:
7189
+ */
7190
+ NormalizeTablePlugin.prototype.onPluginEvent = function (event) {
7191
+ switch (event.eventType) {
7192
+ case 11 /* EditorReady */:
7193
+ case 7 /* ContentChanged */:
7194
+ this.normalizeTables(this.editor.queryElements('table'));
7195
+ break;
7196
+ case 10 /* BeforePaste */:
7197
+ this.normalizeTables((0, roosterjs_editor_dom_1.toArray)(event.fragment.querySelectorAll('table')));
7198
+ break;
7199
+ case 5 /* MouseDown */:
7200
+ this.normalizeTableFromEvent(event.rawEvent);
7201
+ break;
7202
+ case 0 /* KeyDown */:
7203
+ if (event.rawEvent.shiftKey) {
7204
+ this.normalizeTableFromEvent(event.rawEvent);
7205
+ }
7206
+ break;
7207
+ }
7208
+ };
7209
+ NormalizeTablePlugin.prototype.normalizeTableFromEvent = function (event) {
7210
+ var table = this.editor.getElementAtCursor('table', event.target);
7211
+ if (table) {
7212
+ this.normalizeTables([table]);
7213
+ }
7214
+ };
7215
+ NormalizeTablePlugin.prototype.normalizeTables = function (tables) {
7216
+ if (tables.length > 0) {
7217
+ var rangeEx = this.editor.getSelectionRangeEx();
7218
+ 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;
7219
+ var isChanged = normalizeTables(tables);
7220
+ if (isChanged) {
7221
+ if (startContainer && endContainer) {
7222
+ this.editor.select(startContainer, startOffset, endContainer, endOffset);
7223
+ }
7224
+ else if ((rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 1 /* TableSelection */) {
7225
+ this.editor.select(rangeEx.table, rangeEx.coordinates);
7226
+ }
7227
+ }
7228
+ }
7229
+ };
7230
+ return NormalizeTablePlugin;
7231
+ }());
7232
+ exports.default = NormalizeTablePlugin;
7233
+ function normalizeTables(tables) {
7234
+ var isDOMChanged = false;
7235
+ tables.forEach(function (table) {
7236
+ var tbody = null;
7237
+ for (var child = table.firstChild; child; child = child.nextSibling) {
7238
+ var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(child);
7239
+ switch (tag) {
7240
+ case 'TR':
7241
+ if (!tbody) {
7242
+ tbody = table.ownerDocument.createElement('tbody');
7243
+ table.insertBefore(tbody, child);
7244
+ }
7245
+ tbody.appendChild(child);
7246
+ child = tbody;
7247
+ isDOMChanged = true;
7248
+ break;
7249
+ case 'TBODY':
7250
+ if (tbody) {
7251
+ (0, roosterjs_editor_dom_1.moveChildNodes)(tbody, child, true /*keepExistingChildren*/);
7252
+ child.parentNode.removeChild(child);
7253
+ child = tbody;
7254
+ isDOMChanged = true;
7255
+ }
7256
+ else {
7257
+ tbody = child;
7258
+ }
7259
+ break;
7260
+ default:
7261
+ tbody = null;
7262
+ break;
7263
+ }
7264
+ }
7265
+ });
7266
+ return isDOMChanged;
7267
+ }
7268
+
7269
+
7041
7270
  /***/ }),
7042
7271
 
7043
7272
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts":
@@ -7230,7 +7459,9 @@ var UndoPlugin = /** @class */ (function () {
7230
7459
  */
7231
7460
  function UndoPlugin(options) {
7232
7461
  this.state = {
7233
- snapshotsService: options.undoSnapshotService || createUndoSnapshots(),
7462
+ snapshotsService: options.undoMetadataSnapshotService ||
7463
+ createUndoSnapshotServiceBridge(options.undoSnapshotService) ||
7464
+ createUndoSnapshots(),
7234
7465
  isRestoring: false,
7235
7466
  hasNewContent: false,
7236
7467
  isNested: false,
@@ -7300,7 +7531,9 @@ var UndoPlugin = /** @class */ (function () {
7300
7531
  this.addUndoSnapshot();
7301
7532
  break;
7302
7533
  case 7 /* ContentChanged */:
7303
- if (!this.state.isRestoring) {
7534
+ if (!(this.state.isRestoring ||
7535
+ event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
7536
+ event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
7304
7537
  this.clearRedoForInput();
7305
7538
  }
7306
7539
  break;
@@ -7386,12 +7619,26 @@ function createUndoSnapshots() {
7386
7619
  canMove: function (delta) { return (0, roosterjs_editor_dom_1.canMoveCurrentSnapshot)(snapshots, delta); },
7387
7620
  move: function (delta) { return (0, roosterjs_editor_dom_1.moveCurrentSnapshot)(snapshots, delta); },
7388
7621
  addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7389
- return (0, roosterjs_editor_dom_1.addSnapshot)(snapshots, snapshot, isAutoCompleteSnapshot);
7622
+ return (0, roosterjs_editor_dom_1.addSnapshotV2)(snapshots, snapshot, isAutoCompleteSnapshot);
7390
7623
  },
7391
- clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshots)(snapshots); },
7624
+ clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshotsV2)(snapshots); },
7392
7625
  canUndoAutoComplete: function () { return (0, roosterjs_editor_dom_1.canUndoAutoComplete)(snapshots); },
7393
7626
  };
7394
7627
  }
7628
+ function createUndoSnapshotServiceBridge(service) {
7629
+ return service
7630
+ ? {
7631
+ canMove: function (delta) { return service.canMove(delta); },
7632
+ move: function (delta) { return ({ html: service.move(delta), metadata: null }); },
7633
+ addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7634
+ return service.addSnapshot(snapshot.html +
7635
+ (snapshot.metadata ? "<!--" + JSON.stringify(snapshot.metadata) + "-->" : ''), isAutoCompleteSnapshot);
7636
+ },
7637
+ clearRedo: function () { return service.clearRedo(); },
7638
+ canUndoAutoComplete: function () { return service.canUndoAutoComplete(); },
7639
+ }
7640
+ : undefined;
7641
+ }
7395
7642
 
7396
7643
 
7397
7644
  /***/ }),
@@ -7413,6 +7660,7 @@ var EditPlugin_1 = __webpack_require__(/*! ./EditPlugin */ "./packages/roosterjs
7413
7660
  var EntityPlugin_1 = __webpack_require__(/*! ./EntityPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/EntityPlugin.ts");
7414
7661
  var LifecyclePlugin_1 = __webpack_require__(/*! ./LifecyclePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/LifecyclePlugin.ts");
7415
7662
  var MouseUpPlugin_1 = __webpack_require__(/*! ./MouseUpPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/MouseUpPlugin.ts");
7663
+ var NormalizeTablePlugin_1 = __webpack_require__(/*! ./NormalizeTablePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts");
7416
7664
  var PendingFormatStatePlugin_1 = __webpack_require__(/*! ./PendingFormatStatePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts");
7417
7665
  var TypeInContainerPlugin_1 = __webpack_require__(/*! ./TypeInContainerPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/TypeInContainerPlugin.ts");
7418
7666
  var UndoPlugin_1 = __webpack_require__(/*! ./UndoPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/UndoPlugin.ts");
@@ -7437,6 +7685,7 @@ function createCorePlugins(contentDiv, options) {
7437
7685
  mouseUp: map.mouseUp || new MouseUpPlugin_1.default(),
7438
7686
  copyPaste: map.copyPaste || new CopyPastePlugin_1.default(options),
7439
7687
  entity: map.entity || new EntityPlugin_1.default(),
7688
+ normalizeTable: map.normalizeTable || new NormalizeTablePlugin_1.default(),
7440
7689
  lifecycle: map.lifecycle || new LifecyclePlugin_1.default(options, contentDiv),
7441
7690
  };
7442
7691
  }
@@ -8093,12 +8342,13 @@ var Editor = /** @class */ (function () {
8093
8342
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
8094
8343
  */
8095
8344
  Editor.prototype.setDarkModeState = function (nextDarkMode) {
8096
- if (this.isDarkMode() == nextDarkMode) {
8345
+ if (this.isDarkMode() == !!nextDarkMode) {
8097
8346
  return;
8098
8347
  }
8099
- var currentContent = this.getContent(0 /* CleanHTML */);
8348
+ this.core.api.transformColor(this.core, this.core.contentDiv, false /*includeSelf*/, null /*callback*/, nextDarkMode
8349
+ ? 0 /* LightToDark */
8350
+ : 1 /* DarkToLight */, true /*forceTransform*/);
8100
8351
  this.triggerContentChangedEvent(nextDarkMode ? "SwitchToDarkMode" /* SwitchToDarkMode */ : "SwitchToLightMode" /* SwitchToLightMode */);
8101
- this.setContent(currentContent);
8102
8352
  };
8103
8353
  /**
8104
8354
  * Check if the editor is in dark mode
@@ -8107,6 +8357,13 @@ var Editor = /** @class */ (function () {
8107
8357
  Editor.prototype.isDarkMode = function () {
8108
8358
  return this.core.lifecycle.isDarkMode;
8109
8359
  };
8360
+ /**
8361
+ * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
8362
+ * @param node The node to transform
8363
+ */
8364
+ Editor.prototype.transformToDarkColor = function (node) {
8365
+ this.core.api.transformColor(this.core, node, true /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
8366
+ };
8110
8367
  /**
8111
8368
  * Make the editor in "Shadow Edit" mode.
8112
8369
  * In Shadow Edit mode, all format change will finally be ignored.
@@ -8271,7 +8528,8 @@ var NodeBlockElement = /** @class */ (function () {
8271
8528
  * Get the text content of this block element
8272
8529
  */
8273
8530
  NodeBlockElement.prototype.getTextContent = function () {
8274
- return this.element ? this.element.textContent : '';
8531
+ var _a;
8532
+ return ((_a = this.element) === null || _a === void 0 ? void 0 : _a.textContent) || '';
8275
8533
  };
8276
8534
  return NodeBlockElement;
8277
8535
  }());
@@ -8315,10 +8573,11 @@ var StartEndBlockElement = /** @class */ (function () {
8315
8573
  this.endNode = endNode;
8316
8574
  }
8317
8575
  StartEndBlockElement.getBlockContext = function (node) {
8318
- while (node && !(0, isBlockElement_1.default)(node)) {
8319
- node = node.parentNode;
8576
+ var currentNode = node;
8577
+ while (currentNode && !(0, isBlockElement_1.default)(currentNode)) {
8578
+ currentNode = currentNode.parentNode;
8320
8579
  }
8321
- return node;
8580
+ return currentNode;
8322
8581
  };
8323
8582
  /**
8324
8583
  * Collapse this element to a single DOM element.
@@ -8326,7 +8585,10 @@ var StartEndBlockElement = /** @class */ (function () {
8326
8585
  * If the content nodes are included in root node with other nodes, split root node
8327
8586
  */
8328
8587
  StartEndBlockElement.prototype.collapseToSingleElement = function () {
8329
- var nodes = (0, collapseNodes_1.default)(StartEndBlockElement.getBlockContext(this.startNode), this.startNode, this.endNode, true /*canSplitParent*/);
8588
+ var nodeContext = StartEndBlockElement.getBlockContext(this.startNode);
8589
+ var nodes = nodeContext
8590
+ ? (0, collapseNodes_1.default)(nodeContext, this.startNode, this.endNode, true /*canSplitParent*/)
8591
+ : [];
8330
8592
  var blockContext = StartEndBlockElement.getBlockContext(this.startNode);
8331
8593
  while (nodes[0] &&
8332
8594
  nodes[0] != blockContext &&
@@ -8434,7 +8696,10 @@ function getBlockElementAtNode(rootNode, node) {
8434
8696
  // NOTE: this container block could be just the rootNode,
8435
8697
  // which cannot be used to create block element. We will special case handle it later on
8436
8698
  var containerBlockNode = StartEndBlockElement_1.default.getBlockContext(node);
8437
- if (containerBlockNode == node) {
8699
+ if (!containerBlockNode) {
8700
+ return null;
8701
+ }
8702
+ else if (containerBlockNode == node) {
8438
8703
  return new NodeBlockElement_1.default(containerBlockNode);
8439
8704
  }
8440
8705
  // Find the head and leaf node in the block
@@ -8464,7 +8729,7 @@ function getBlockElementAtNode(rootNode, node) {
8464
8729
  }
8465
8730
  break;
8466
8731
  }
8467
- else if (parentNode != rootNode) {
8732
+ else if (parentNode && parentNode != rootNode) {
8468
8733
  // Continue collapsing to parent
8469
8734
  headNode = tailNode = parentNode;
8470
8735
  }
@@ -8494,7 +8759,7 @@ function findHeadTailLeafNode(node, containerBlockNode, isTail) {
8494
8759
  }
8495
8760
  while (result) {
8496
8761
  var sibling = node;
8497
- while (!(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8762
+ while (node.parentNode && !(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8498
8763
  node = node.parentNode;
8499
8764
  if (node == containerBlockNode) {
8500
8765
  return result;
@@ -8540,7 +8805,7 @@ function getFirstLastBlockElement(rootNode, isFirst) {
8540
8805
  do {
8541
8806
  node = node && (isFirst ? node.firstChild : node.lastChild);
8542
8807
  } while (node && node.firstChild);
8543
- return node && (0, getBlockElementAtNode_1.default)(rootNode, node);
8808
+ return (node && (0, getBlockElementAtNode_1.default)(rootNode, node)) || null;
8544
8809
  }
8545
8810
  exports.default = getFirstLastBlockElement;
8546
8811
 
@@ -8651,6 +8916,7 @@ function extractClipboardItems(items, options) {
8651
8916
  types: [],
8652
8917
  text: '',
8653
8918
  image: null,
8919
+ files: [],
8654
8920
  rawHtml: null,
8655
8921
  customValues: {},
8656
8922
  };
@@ -8675,6 +8941,16 @@ function extractClipboardItems(items, options) {
8675
8941
  }
8676
8942
  });
8677
8943
  }
8944
+ else if (item.kind == 'file') {
8945
+ return new Promise(function (resolve) {
8946
+ var file = item.getAsFile();
8947
+ if (!!file) {
8948
+ data.types.push(type);
8949
+ data.files.push(file);
8950
+ }
8951
+ resolve();
8952
+ });
8953
+ }
8678
8954
  else {
8679
8955
  var customType_1 = getAllowedCustomType(type, options === null || options === void 0 ? void 0 : options.allowedCustomPasteType);
8680
8956
  var handler_1 = contentHandlers[type] || (customType_1 ? contentHandlers[OTHER_TEXT_TYPE] : null);
@@ -8755,6 +9031,7 @@ function extractClipboardItemsForIE(dataTransfer, callback, options) {
8755
9031
  types: dataTransfer.types ? (0, toArray_1.default)(dataTransfer.types) : [],
8756
9032
  text: dataTransfer.getData('text'),
8757
9033
  image: null,
9034
+ files: [],
8758
9035
  rawHtml: null,
8759
9036
  customValues: {},
8760
9037
  };
@@ -8896,6 +9173,8 @@ var ContentTraverser = /** @class */ (function () {
8896
9173
  function ContentTraverser(scoper, skipTags) {
8897
9174
  this.scoper = scoper;
8898
9175
  this.skipTags = skipTags;
9176
+ this.currentInline = null;
9177
+ this.currentBlock = null;
8899
9178
  }
8900
9179
  /**
8901
9180
  * Create a content traverser for the whole body of given root node
@@ -9086,8 +9365,20 @@ var PositionContentSearcher = /** @class */ (function () {
9086
9365
  this.position = position;
9087
9366
  // The cached text before position that has been read so far
9088
9367
  this.text = '';
9368
+ // The cached word before position
9369
+ this.word = '';
9370
+ // The inline element before position
9371
+ this.inlineBefore = null;
9372
+ // The inline element after position
9373
+ this.inlineAfter = null;
9374
+ // The content traverser used to traverse backwards
9375
+ this.traverser = null;
9376
+ // Backward parsing has completed
9377
+ this.traversingComplete = false;
9089
9378
  // All inline elements before position that have been read so far
9090
9379
  this.inlineElements = [];
9380
+ // First non-text inline before position
9381
+ this.nearestNonTextInlineElement = null;
9091
9382
  }
9092
9383
  /**
9093
9384
  * Get the word before position. The word is determined by scanning backwards till the first white space, the portion
@@ -9099,7 +9390,7 @@ var PositionContentSearcher = /** @class */ (function () {
9099
9390
  if (!this.word) {
9100
9391
  this.traverse(function () { return _this.word; });
9101
9392
  }
9102
- return this.word;
9393
+ return this.word || '';
9103
9394
  };
9104
9395
  /**
9105
9396
  * Get the inline element before position
@@ -9146,8 +9437,8 @@ var PositionContentSearcher = /** @class */ (function () {
9146
9437
  if (!text) {
9147
9438
  return null;
9148
9439
  }
9149
- var startPosition;
9150
- var endPosition;
9440
+ var startPosition = null;
9441
+ var endPosition = null;
9151
9442
  var textIndex = text.length - 1;
9152
9443
  this.forEachTextInlineElement(function (textInline) {
9153
9444
  var nodeContent = textInline.getTextContent() || '';
@@ -9388,6 +9679,8 @@ var SelectionScoper = /** @class */ (function () {
9388
9679
  */
9389
9680
  function SelectionScoper(rootNode, range) {
9390
9681
  this.rootNode = rootNode;
9682
+ this.startBlock = null;
9683
+ this.startInline = null;
9391
9684
  this.start = Position_1.default.getStart(range).normalize();
9392
9685
  this.end = Position_1.default.getEnd(range).normalize();
9393
9686
  }
@@ -9420,7 +9713,7 @@ var SelectionScoper = /** @class */ (function () {
9420
9713
  var inScope = false;
9421
9714
  var selStartBlock = this.getStartBlockElement();
9422
9715
  if (this.start.equalTo(this.end)) {
9423
- inScope = selStartBlock && selStartBlock.equals(block);
9716
+ inScope = !!selStartBlock && selStartBlock.equals(block);
9424
9717
  }
9425
9718
  else {
9426
9719
  var selEndBlock = (0, getBlockElementAtNode_1.default)(this.rootNode, this.end.node);
@@ -9429,8 +9722,8 @@ var SelectionScoper = /** @class */ (function () {
9429
9722
  // 2) The end of selection falls on the block
9430
9723
  // 3) the block falls in-between selection start and end
9431
9724
  inScope =
9432
- selStartBlock &&
9433
- selEndBlock &&
9725
+ !!selStartBlock &&
9726
+ !!selEndBlock &&
9434
9727
  (block.equals(selStartBlock) ||
9435
9728
  block.equals(selEndBlock) ||
9436
9729
  (block.isAfter(selStartBlock) && selEndBlock.isAfter(block)));
@@ -9465,7 +9758,7 @@ var SelectionScoper = /** @class */ (function () {
9465
9758
  return start.isAfter(end) || start.equalTo(end)
9466
9759
  ? null
9467
9760
  : startPartial || endPartial
9468
- ? new PartialInlineElement_1.default(inline, startPartial && start, endPartial && end)
9761
+ ? new PartialInlineElement_1.default(inline, startPartial ? start : undefined, endPartial ? end : undefined)
9469
9762
  : inline;
9470
9763
  };
9471
9764
  return SelectionScoper;
@@ -10578,7 +10871,6 @@ var HTML_TAG_REPLACEMENT = {
10578
10871
  table: '*',
10579
10872
  tbody: '*',
10580
10873
  td: '*',
10581
- template: '*',
10582
10874
  textarea: '*',
10583
10875
  tfoot: '*',
10584
10876
  th: '*',
@@ -10611,6 +10903,7 @@ var HTML_TAG_REPLACEMENT = {
10611
10903
  slot: null,
10612
10904
  source: null,
10613
10905
  style: null,
10906
+ template: null,
10614
10907
  title: null,
10615
10908
  track: null,
10616
10909
  video: null,
@@ -10841,7 +11134,7 @@ exports.default = getPredefinedCssForElement;
10841
11134
 
10842
11135
  Object.defineProperty(exports, "__esModule", { value: true });
10843
11136
  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;
11137
+ 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
11138
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
10846
11139
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
10847
11140
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -10939,6 +11232,8 @@ var moveChildNodes_1 = __webpack_require__(/*! ./utils/moveChildNodes */ "./pack
10939
11232
  Object.defineProperty(exports, "moveChildNodes", { enumerable: true, get: function () { return moveChildNodes_1.default; } });
10940
11233
  var VTable_1 = __webpack_require__(/*! ./table/VTable */ "./packages/roosterjs-editor-dom/lib/table/VTable.ts");
10941
11234
  Object.defineProperty(exports, "VTable", { enumerable: true, get: function () { return VTable_1.default; } });
11235
+ var isWholeTableSelected_1 = __webpack_require__(/*! ./table/isWholeTableSelected */ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts");
11236
+ Object.defineProperty(exports, "isWholeTableSelected", { enumerable: true, get: function () { return isWholeTableSelected_1.default; } });
10942
11237
  var VList_1 = __webpack_require__(/*! ./list/VList */ "./packages/roosterjs-editor-dom/lib/list/VList.ts");
10943
11238
  Object.defineProperty(exports, "VList", { enumerable: true, get: function () { return VList_1.default; } });
10944
11239
  var VListItem_1 = __webpack_require__(/*! ./list/VListItem */ "./packages/roosterjs-editor-dom/lib/list/VListItem.ts");
@@ -10975,14 +11270,17 @@ var getHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/getHtmlWith
10975
11270
  Object.defineProperty(exports, "getHtmlWithSelectionPath", { enumerable: true, get: function () { return getHtmlWithSelectionPath_1.default; } });
10976
11271
  var setHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/setHtmlWithSelectionPath */ "./packages/roosterjs-editor-dom/lib/selection/setHtmlWithSelectionPath.ts");
10977
11272
  Object.defineProperty(exports, "setHtmlWithSelectionPath", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.default; } });
11273
+ Object.defineProperty(exports, "setHtmlWithMetadata", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.setHtmlWithMetadata; } });
10978
11274
  var addRangeToSelection_1 = __webpack_require__(/*! ./selection/addRangeToSelection */ "./packages/roosterjs-editor-dom/lib/selection/addRangeToSelection.ts");
10979
11275
  Object.defineProperty(exports, "addRangeToSelection", { enumerable: true, get: function () { return addRangeToSelection_1.default; } });
10980
11276
  var addSnapshot_1 = __webpack_require__(/*! ./snapshots/addSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/addSnapshot.ts");
10981
11277
  Object.defineProperty(exports, "addSnapshot", { enumerable: true, get: function () { return addSnapshot_1.default; } });
11278
+ Object.defineProperty(exports, "addSnapshotV2", { enumerable: true, get: function () { return addSnapshot_1.addSnapshotV2; } });
10982
11279
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
10983
11280
  Object.defineProperty(exports, "canMoveCurrentSnapshot", { enumerable: true, get: function () { return canMoveCurrentSnapshot_1.default; } });
10984
11281
  var clearProceedingSnapshots_1 = __webpack_require__(/*! ./snapshots/clearProceedingSnapshots */ "./packages/roosterjs-editor-dom/lib/snapshots/clearProceedingSnapshots.ts");
10985
11282
  Object.defineProperty(exports, "clearProceedingSnapshots", { enumerable: true, get: function () { return clearProceedingSnapshots_1.default; } });
11283
+ Object.defineProperty(exports, "clearProceedingSnapshotsV2", { enumerable: true, get: function () { return clearProceedingSnapshots_1.clearProceedingSnapshotsV2; } });
10986
11284
  var moveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/moveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/moveCurrentSnapshot.ts");
10987
11285
  Object.defineProperty(exports, "moveCurrentSnapshot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.default; } });
10988
11286
  Object.defineProperty(exports, "moveCurrentSnapsnot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.moveCurrentSnapsnot; } });
@@ -11219,9 +11517,9 @@ var NodeInlineElement = /** @class */ (function () {
11219
11517
  */
11220
11518
  NodeInlineElement.prototype.getTextContent = function () {
11221
11519
  // nodeValue is better way to retrieve content for a text. Others, just use textContent
11222
- return this.containerNode.nodeType == 3 /* Text */
11520
+ return ((this.containerNode.nodeType == 3 /* Text */
11223
11521
  ? this.containerNode.nodeValue
11224
- : this.containerNode.textContent;
11522
+ : this.containerNode.textContent) || '');
11225
11523
  };
11226
11524
  /**
11227
11525
  * Get the container node
@@ -11305,6 +11603,8 @@ var getLeafSibling_1 = __webpack_require__(/*! ../utils/getLeafSibling */ "./pac
11305
11603
  */
11306
11604
  var PartialInlineElement = /** @class */ (function () {
11307
11605
  function PartialInlineElement(inlineElement, start, end) {
11606
+ if (start === void 0) { start = null; }
11607
+ if (end === void 0) { end = null; }
11308
11608
  this.inlineElement = inlineElement;
11309
11609
  this.start = start;
11310
11610
  this.end = end;
@@ -11351,7 +11651,7 @@ var PartialInlineElement = /** @class */ (function () {
11351
11651
  * Get next partial inline element if it is not at the end boundary yet
11352
11652
  */
11353
11653
  get: function () {
11354
- return this.end && new PartialInlineElement(this.inlineElement, this.end, null);
11654
+ return this.end ? new PartialInlineElement(this.inlineElement, this.end) : null;
11355
11655
  },
11356
11656
  enumerable: false,
11357
11657
  configurable: true
@@ -11361,7 +11661,9 @@ var PartialInlineElement = /** @class */ (function () {
11361
11661
  * Get previous partial inline element if it is not at the begin boundary yet
11362
11662
  */
11363
11663
  get: function () {
11364
- return this.start && new PartialInlineElement(this.inlineElement, null, this.start);
11664
+ return this.start
11665
+ ? new PartialInlineElement(this.inlineElement, undefined, this.start)
11666
+ : null;
11365
11667
  },
11366
11668
  enumerable: false,
11367
11669
  configurable: true
@@ -11401,7 +11703,7 @@ var PartialInlineElement = /** @class */ (function () {
11401
11703
  var previousNode = (0, getLeafSibling_1.getPreviousLeafSibling)(container, to.node);
11402
11704
  to = previousNode ? new Position_1.default(previousNode, -1 /* End */) : null;
11403
11705
  }
11404
- (0, applyTextStyle_1.default)(container, styler, from, to);
11706
+ (0, applyTextStyle_1.default)(container, styler, from || undefined, to || undefined);
11405
11707
  };
11406
11708
  return PartialInlineElement;
11407
11709
  }());
@@ -11431,35 +11733,39 @@ var STYLET_AGS = 'SPAN,B,I,U,EM,STRONG,STRIKE,S,SMALL'.split(',');
11431
11733
  * Apply style using a styler function to the given container node in the given range
11432
11734
  * @param container The container node to apply style to
11433
11735
  * @param styler The styler function
11434
- * @param from From position
11435
- * @param to To position
11736
+ * @param fromPosition From position
11737
+ * @param toPosition To position
11436
11738
  */
11437
11739
  function applyTextStyle(container, styler, from, to) {
11438
11740
  if (from === void 0) { from = new Position_1.default(container, 0 /* Begin */).normalize(); }
11439
11741
  if (to === void 0) { to = new Position_1.default(container, -1 /* End */).normalize(); }
11440
11742
  var formatNodes = [];
11441
- while (from && to && to.isAfter(from)) {
11442
- var formatNode = from.node;
11743
+ var fromPosition = from;
11744
+ var toPosition = to;
11745
+ while (fromPosition && toPosition && toPosition.isAfter(fromPosition)) {
11746
+ var formatNode = fromPosition.node;
11443
11747
  var parentTag = (0, getTagOfNode_1.default)(formatNode.parentNode);
11444
11748
  // 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
11749
  var nextNode = (0, getLeafSibling_1.getNextLeafSibling)(container, formatNode);
11446
11750
  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*/);
11751
+ if (formatNode == toPosition.node && !toPosition.isAtEnd) {
11752
+ formatNode = (0, splitTextNode_1.default)(formatNode, toPosition.offset, true /*returnFirstPart*/);
11449
11753
  }
11450
- if (from.offset > 0) {
11451
- formatNode = (0, splitTextNode_1.default)(formatNode, from.offset, false /*returnFirstPart*/);
11754
+ if (fromPosition.offset > 0) {
11755
+ formatNode = (0, splitTextNode_1.default)(formatNode, fromPosition.offset, false /*returnFirstPart*/);
11452
11756
  }
11453
11757
  formatNodes.push(formatNode);
11454
11758
  }
11455
- from = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11759
+ fromPosition = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11456
11760
  }
11457
11761
  if (formatNodes.length > 0) {
11458
11762
  if (formatNodes.every(function (node) { return node.parentNode == formatNodes[0].parentNode; })) {
11459
11763
  var newNode_1 = formatNodes.shift();
11460
11764
  formatNodes.forEach(function (node) {
11461
- newNode_1.nodeValue += node.nodeValue;
11462
- node.parentNode.removeChild(node);
11765
+ var _a;
11766
+ var newNodeValue = (newNode_1.nodeValue || '') + (node.nodeValue || '');
11767
+ newNode_1.nodeValue = newNodeValue;
11768
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
11463
11769
  });
11464
11770
  formatNodes = [newNode_1];
11465
11771
  }
@@ -11628,7 +11934,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11628
11934
  return null;
11629
11935
  }
11630
11936
  position = position.normalize();
11631
- var node = position.node, offset = position.offset, isAtEnd = position.isAtEnd;
11937
+ var offset = position.offset, isAtEnd = position.isAtEnd;
11938
+ var node = position.node;
11632
11939
  var isPartial = false;
11633
11940
  if ((!isAfter && offset == 0 && !isAtEnd) || (isAfter && isAtEnd)) {
11634
11941
  node = (0, getLeafSibling_1.getLeafSibling)(root, node, isAfter);
@@ -11643,8 +11950,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11643
11950
  var inlineElement = (0, getInlineElementAtNode_1.default)(root, node);
11644
11951
  if (inlineElement && (isPartial || inlineElement.contains(position))) {
11645
11952
  inlineElement = isAfter
11646
- ? new PartialInlineElement_1.default(inlineElement, position, null)
11647
- : new PartialInlineElement_1.default(inlineElement, null, position);
11953
+ ? new PartialInlineElement_1.default(inlineElement, position, undefined)
11954
+ : new PartialInlineElement_1.default(inlineElement, undefined, position);
11648
11955
  }
11649
11956
  return inlineElement;
11650
11957
  }
@@ -11882,14 +12189,23 @@ var VList = /** @class */ (function () {
11882
12189
  }
11883
12190
  }
11884
12191
  };
11885
- VList.prototype.setIndentation = function (start, end, indentation, softOutdent) {
12192
+ VList.prototype.setIndentation = function (start, end, indentation, softOutdent, preventItemRemoval) {
12193
+ var _this = this;
12194
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12195
+ var shouldAddMargin = false;
11886
12196
  this.findListItems(start, end, function (item) {
11887
- return indentation == 1 /* Decrease */
12197
+ shouldAddMargin = shouldAddMargin || _this.items.indexOf(item) == 0;
12198
+ indentation == 1 /* Decrease */
11888
12199
  ? softOutdent && !item.isDummy()
11889
12200
  ? item.setIsDummy(true /*isDummy*/)
11890
- : item.outdent()
12201
+ : item.outdent(preventItemRemoval)
11891
12202
  : item.indent();
11892
12203
  });
12204
+ if (shouldAddMargin && preventItemRemoval) {
12205
+ for (var index = 0; index < this.items.length; index++) {
12206
+ this.items[index].addNegativeMargins();
12207
+ }
12208
+ }
11893
12209
  };
11894
12210
  /**
11895
12211
  * Change list type of the given range of this list.
@@ -11943,16 +12259,33 @@ var VList = /** @class */ (function () {
11943
12259
  };
11944
12260
  /**
11945
12261
  * Get the index of the List Item in the current List
12262
+ * If the root list is:
12263
+ * Ordered list, the listIndex start count is going to be the start property of the OL - 1,
12264
+ * @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
12265
+ * * ```html
12266
+ * <ol start="5">
12267
+ * <li>item 1</li>
12268
+ * <li>item 2</li> <!-- Node to find -->
12269
+ * <li>item 3</li>
12270
+ * </ol>
12271
+ * ```
12272
+ * Unordered list, the listIndex start count starts from 0
12273
+ * @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
12274
+ * ```html
12275
+ * <ul>
12276
+ * <li>item 1</li>
12277
+ * <li>item 2</li> <!-- Node to find -->
12278
+ * <li>item 3</li>
12279
+ * </ul>
12280
+ * ```
11946
12281
  * @param input List item to find in the root list
11947
12282
  */
11948
12283
  VList.prototype.getListItemIndex = function (input) {
11949
12284
  if (this.items) {
11950
- var listIndex = this.getStart() - 1;
12285
+ var listIndex = (this.getStart() || 1) - 1;
11951
12286
  for (var index = 0; index < this.items.length; index++) {
11952
12287
  var child = this.items[index];
11953
- if (child.getListType() == 1 /* Ordered */ &&
11954
- child.getLevel() == 1 &&
11955
- !child.isDummy()) {
12288
+ if (child.getLevel() == 1 && !child.isDummy()) {
11956
12289
  listIndex++;
11957
12290
  }
11958
12291
  if (child.getNode() == input) {
@@ -12233,6 +12566,8 @@ var toArray_1 = __webpack_require__(/*! ../utils/toArray */ "./packages/roosterj
12233
12566
  var unwrap_1 = __webpack_require__(/*! ../utils/unwrap */ "./packages/roosterjs-editor-dom/lib/utils/unwrap.ts");
12234
12567
  var wrap_1 = __webpack_require__(/*! ../utils/wrap */ "./packages/roosterjs-editor-dom/lib/utils/wrap.ts");
12235
12568
  var orderListStyles = [null, 'lower-alpha', 'lower-roman'];
12569
+ var MARGIN_BASE = '0in 0in 0in 0.5in';
12570
+ var NEGATIVE_MARGIN = '-.25in';
12236
12571
  /**
12237
12572
  * !!! Never directly create instance of this class. It should be created within VList class !!!
12238
12573
  *
@@ -12334,6 +12669,11 @@ var VListItem = /** @class */ (function () {
12334
12669
  * If this is not an list item, it will be no op
12335
12670
  */
12336
12671
  VListItem.prototype.indent = function () {
12672
+ if (this.node.style.marginLeft == NEGATIVE_MARGIN) {
12673
+ this.node.style.margin = '';
12674
+ this.node.style.marginLeft = '';
12675
+ return;
12676
+ }
12337
12677
  var listType = this.getListType();
12338
12678
  if (listType != 0 /* None */) {
12339
12679
  this.listTypes.push(listType);
@@ -12342,12 +12682,22 @@ var VListItem = /** @class */ (function () {
12342
12682
  /**
12343
12683
  * Outdent this item
12344
12684
  * If this item is already not an list item, it will be no op
12685
+ * @param preventItemRemoval Whether prevent the list item to be removed for the listItem by default false
12345
12686
  */
12346
- VListItem.prototype.outdent = function () {
12347
- if (this.listTypes.length > 1) {
12687
+ VListItem.prototype.outdent = function (preventItemRemoval) {
12688
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12689
+ var expectedLength = preventItemRemoval ? 2 : 1;
12690
+ if (this.listTypes.length > expectedLength) {
12348
12691
  this.listTypes.pop();
12349
12692
  }
12350
12693
  };
12694
+ /**
12695
+ * Add negative margin to the List item
12696
+ */
12697
+ VListItem.prototype.addNegativeMargins = function () {
12698
+ this.node.style.margin = MARGIN_BASE;
12699
+ this.node.style.marginLeft = NEGATIVE_MARGIN;
12700
+ };
12351
12701
  /**
12352
12702
  * Change list type of this item
12353
12703
  * @param targetType The target list type to change to
@@ -12883,7 +13233,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12883
13233
  var children = boundary.children, innerNode = boundary.innerNode;
12884
13234
  var regions = [];
12885
13235
  if (children.length == 0) {
12886
- regions.push(creator(innerNode));
13236
+ var region = creator(innerNode);
13237
+ if (region) {
13238
+ regions.push(region);
13239
+ }
12887
13240
  }
12888
13241
  else {
12889
13242
  // Need to run one more time to add region after all children
@@ -12891,7 +13244,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12891
13244
  var _b = children[i] || {}, outerNode = _b.outerNode, boundaries = _b.boundaries;
12892
13245
  var previousOuterNode = (_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.outerNode;
12893
13246
  if (started) {
12894
- regions.push(creator(innerNode, previousOuterNode, outerNode));
13247
+ var region = creator(innerNode, previousOuterNode, outerNode);
13248
+ if (region) {
13249
+ regions.push(region);
13250
+ }
12895
13251
  }
12896
13252
  boundaries === null || boundaries === void 0 ? void 0 : boundaries.forEach(function (child) {
12897
13253
  var _a;
@@ -12984,7 +13340,10 @@ function getSelectedBlockElementsInRegion(regionBase, createBlockIfEmpty) {
12984
13340
  if (blocks.length == 0 && regionBase && !regionBase.rootNode.firstChild && createBlockIfEmpty) {
12985
13341
  var newNode = (0, createElement_1.default)(1 /* EmptyLine */, regionBase.rootNode.ownerDocument);
12986
13342
  regionBase.rootNode.appendChild(newNode);
12987
- blocks.push((0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode));
13343
+ var block = (0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode);
13344
+ if (block) {
13345
+ blocks.push(block);
13346
+ }
12988
13347
  }
12989
13348
  return blocks;
12990
13349
  }
@@ -13038,10 +13397,8 @@ function getSelectionRangeInRegion(regionBase) {
13038
13397
  var end = fullSelectionEnd.isAfter(regionEnd) ? regionEnd : fullSelectionEnd;
13039
13398
  return (0, createRange_1.default)(start, end);
13040
13399
  }
13041
- else {
13042
- return null;
13043
- }
13044
13400
  }
13401
+ return null;
13045
13402
  }
13046
13403
  exports.default = getSelectionRangeInRegion;
13047
13404
  function isRegion(regionBase) {
@@ -13118,7 +13475,7 @@ var collapseNodes_1 = __webpack_require__(/*! ../utils/collapseNodes */ "./packa
13118
13475
  * @param targetNode The node of target block element
13119
13476
  */
13120
13477
  function mergeBlocksInRegion(region, refNode, targetNode) {
13121
- var _a, _b;
13478
+ var _a, _b, _c;
13122
13479
  var block;
13123
13480
  if (!(0, isNodeInRegion_1.default)(region, refNode) ||
13124
13481
  !(0, isNodeInRegion_1.default)(region, targetNode) ||
@@ -13142,13 +13499,13 @@ function mergeBlocksInRegion(region, refNode, targetNode) {
13142
13499
  ? blockRoot.firstChild
13143
13500
  : (0, changeElementTag_1.default)(blockRoot, 'SPAN');
13144
13501
  // Remove empty node
13145
- for (var node = nodeToMerge; (0, contains_1.default)(commonContainer, node) && node.parentNode.childNodes.length == 1; node = node.parentNode) {
13502
+ 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
13503
  // If the only child is the one which is about to be removed, this node should also be removed
13147
13504
  nodeToRemove = node.parentNode;
13148
13505
  }
13149
13506
  // 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);
13507
+ (_b = refNode.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(nodeToMerge, refNode.nextSibling);
13508
+ (_c = nodeToRemove === null || nodeToRemove === void 0 ? void 0 : nodeToRemove.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(nodeToRemove);
13152
13509
  }
13153
13510
  exports.default = mergeBlocksInRegion;
13154
13511
 
@@ -13462,8 +13819,6 @@ function getPositionFromPath(node, path) {
13462
13819
  Object.defineProperty(exports, "__esModule", { value: true });
13463
13820
  var getInnerHTML_1 = __webpack_require__(/*! ../utils/getInnerHTML */ "./packages/roosterjs-editor-dom/lib/utils/getInnerHTML.ts");
13464
13821
  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
13822
  /**
13468
13823
  * Get inner Html of a root node with a selection path which can be used for restore selection.
13469
13824
  * The result string can be used by setHtmlWithSelectionPath() to restore the HTML and selection.
@@ -13475,32 +13830,6 @@ function getHtmlWithSelectionPath(rootNode, range) {
13475
13830
  if (!rootNode) {
13476
13831
  return '';
13477
13832
  }
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
13833
  var content = (0, getInnerHTML_1.default)(rootNode);
13505
13834
  var selectionPath = range && (0, getSelectionPath_1.default)(rootNode, range);
13506
13835
  return selectionPath ? content + "<!--" + JSON.stringify(selectionPath) + "-->" : content;
@@ -13718,53 +14047,88 @@ function areAllPreviousNodesEmpty(node) {
13718
14047
  "use strict";
13719
14048
 
13720
14049
  Object.defineProperty(exports, "__esModule", { value: true });
14050
+ exports.setHtmlWithMetadata = void 0;
13721
14051
  var createRange_1 = __webpack_require__(/*! ./createRange */ "./packages/roosterjs-editor-dom/lib/selection/createRange.ts");
13722
- var LastCommentRegex = /<!--([^-]+)-->$/;
14052
+ var safeInstanceOf_1 = __webpack_require__(/*! ../utils/safeInstanceOf */ "./packages/roosterjs-editor-dom/lib/utils/safeInstanceOf.ts");
13723
14053
  /**
13724
- * Restore inner Html of a root element from given html string. If the string contains selection path,
14054
+ * @deprecated Use setHtmlWithMetadata instead
14055
+ * Restore inner HTML of a root element from given html string. If the string contains selection path,
13725
14056
  * remove the selection path and return a range represented by the path
13726
14057
  * @param root The root element
13727
- * @param html The html to restore
14058
+ * @param html The HTML to restore
14059
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
13728
14060
  * @returns A selection range if the html contains a valid selection path, otherwise null
13729
14061
  */
13730
14062
  function setHtmlWithSelectionPath(rootNode, html, trustedHTMLHandler) {
14063
+ var metadata = setHtmlWithMetadata(rootNode, html, trustedHTMLHandler);
14064
+ return (metadata === null || metadata === void 0 ? void 0 : metadata.type) == 0 /* Normal */
14065
+ ? (0, createRange_1.default)(rootNode, metadata.start, metadata.end)
14066
+ : null;
14067
+ }
14068
+ exports.default = setHtmlWithSelectionPath;
14069
+ /**
14070
+ * Restore inner HTML of a root element from given html string. If the string contains metadata,
14071
+ * remove it from DOM tree and return the metadata
14072
+ * @param root The root element
14073
+ * @param html The HTML to restore
14074
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
14075
+ * @returns Content metadata if any, or undefined
14076
+ */
14077
+ function setHtmlWithMetadata(rootNode, html, trustedHTMLHandler) {
13731
14078
  if (!rootNode) {
13732
- return null;
14079
+ return undefined;
13733
14080
  }
13734
14081
  html = html || '';
13735
- var lastComment = LastCommentRegex.exec(html);
13736
14082
  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 || '';
14083
+ var potentialMetadataComment = rootNode.lastChild;
14084
+ if ((0, safeInstanceOf_1.default)(potentialMetadataComment, 'Comment')) {
14085
+ try {
14086
+ var obj = JSON.parse(potentialMetadataComment.nodeValue || '');
14087
+ if (isContentMetadata(obj)) {
14088
+ rootNode.removeChild(potentialMetadataComment);
14089
+ return obj;
14090
+ }
14091
+ }
14092
+ catch (_a) { }
13749
14093
  }
13750
- else {
13751
- pathCommentValue = alternativeComment;
14094
+ return undefined;
14095
+ }
14096
+ exports.setHtmlWithMetadata = setHtmlWithMetadata;
14097
+ function isContentMetadata(obj) {
14098
+ if (!obj || typeof obj != 'object') {
14099
+ return false;
13752
14100
  }
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
- }
14101
+ switch (obj.type || 0 /* Normal */) {
14102
+ case 0 /* Normal */:
14103
+ var regularMetadata = obj;
14104
+ if (isNumberArray(regularMetadata.start) && isNumberArray(regularMetadata.end)) {
14105
+ obj.type = 0 /* Normal */;
14106
+ obj.isDarkMode = !!obj.isDarkMode;
14107
+ return true;
13760
14108
  }
13761
- else {
13762
- path = null;
14109
+ break;
14110
+ case 1 /* TableSelection */:
14111
+ var tableMetadata = obj;
14112
+ if (typeof tableMetadata.tableId == 'string' &&
14113
+ !!tableMetadata.tableId &&
14114
+ isCoordinates(tableMetadata.firstCell) &&
14115
+ isCoordinates(tableMetadata.lastCell)) {
14116
+ obj.isDarkMode = !!obj.isDarkMode;
14117
+ return true;
13763
14118
  }
13764
- }
13765
- catch (_d) { }
14119
+ break;
13766
14120
  }
13767
- return path;
14121
+ return false;
14122
+ }
14123
+ function isNumberArray(obj) {
14124
+ return obj && Array.isArray(obj) && obj.every(function (o) { return typeof o == 'number'; });
14125
+ }
14126
+ function isCoordinates(obj) {
14127
+ var coordinates = obj;
14128
+ return (coordinates &&
14129
+ typeof coordinates == 'object' &&
14130
+ typeof coordinates.x == 'number' &&
14131
+ typeof coordinates.y == 'number');
13768
14132
  }
13769
14133
 
13770
14134
 
@@ -13780,23 +14144,21 @@ function getSelectionPath(root, alternativeComment) {
13780
14144
  "use strict";
13781
14145
 
13782
14146
  Object.defineProperty(exports, "__esModule", { value: true });
14147
+ exports.addSnapshotV2 = void 0;
13783
14148
  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);
14149
+ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, getLength, compare) {
14150
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14151
+ compare = compare || defaultCompare;
14152
+ var currentSnapshot = snapshots.snapshots[snapshots.currentIndex];
14153
+ if (snapshots.currentIndex < 0 || !currentSnapshot || !compare(snapshot, currentSnapshot)) {
14154
+ (0, clearProceedingSnapshots_1.default)(snapshots, getLength);
13793
14155
  snapshots.snapshots.push(snapshot);
13794
14156
  snapshots.currentIndex++;
13795
- snapshots.totalSize += snapshot.length;
14157
+ snapshots.totalSize += getLength(snapshot);
13796
14158
  var removeCount = 0;
13797
14159
  while (removeCount < snapshots.snapshots.length &&
13798
14160
  snapshots.totalSize > snapshots.maxSize) {
13799
- snapshots.totalSize -= snapshots.snapshots[removeCount].length;
14161
+ snapshots.totalSize -= getLength(snapshots.snapshots[removeCount]);
13800
14162
  removeCount++;
13801
14163
  }
13802
14164
  if (removeCount > 0) {
@@ -13810,6 +14172,22 @@ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot) {
13810
14172
  }
13811
14173
  }
13812
14174
  exports.default = addSnapshot;
14175
+ /**
14176
+ * Add a new snapshot to the given snapshots data structure
14177
+ * @param snapshots The snapshots data structure to add new snapshot into
14178
+ * @param snapshot The snapshot object to add
14179
+ * @param isAutoCompleteSnapshot Whether this is a snapshot before auto complete action
14180
+ */
14181
+ function addSnapshotV2(snapshots, snapshot, isAutoCompleteSnapshot) {
14182
+ addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; }, compareSnapshots);
14183
+ }
14184
+ exports.addSnapshotV2 = addSnapshotV2;
14185
+ function compareSnapshots(s1, s2) {
14186
+ return s1.html == s2.html;
14187
+ }
14188
+ function defaultCompare(s1, s2) {
14189
+ return s1 == s2;
14190
+ }
13813
14191
 
13814
14192
 
13815
14193
  /***/ }),
@@ -13871,16 +14249,18 @@ exports.default = canUndoAutoComplete;
13871
14249
  "use strict";
13872
14250
 
13873
14251
  Object.defineProperty(exports, "__esModule", { value: true });
14252
+ exports.clearProceedingSnapshotsV2 = void 0;
13874
14253
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
13875
14254
  /**
13876
14255
  * Clear all snapshots after the current one
13877
14256
  * @param snapshots The snapshots data structure to clear
13878
14257
  */
13879
- function clearProceedingSnapshots(snapshots) {
14258
+ function clearProceedingSnapshots(snapshots, getLength) {
14259
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
13880
14260
  if ((0, canMoveCurrentSnapshot_1.default)(snapshots, 1)) {
13881
14261
  var removedSize = 0;
13882
14262
  for (var i = snapshots.currentIndex + 1; i < snapshots.snapshots.length; i++) {
13883
- removedSize += snapshots.snapshots[i].length;
14263
+ removedSize += getLength(snapshots.snapshots[i]);
13884
14264
  }
13885
14265
  snapshots.snapshots.splice(snapshots.currentIndex + 1);
13886
14266
  snapshots.totalSize -= removedSize;
@@ -13888,6 +14268,14 @@ function clearProceedingSnapshots(snapshots) {
13888
14268
  }
13889
14269
  }
13890
14270
  exports.default = clearProceedingSnapshots;
14271
+ /**
14272
+ * Clear all snapshots after the current one
14273
+ * @param snapshots The snapshots data structure to clear
14274
+ */
14275
+ function clearProceedingSnapshotsV2(snapshots) {
14276
+ clearProceedingSnapshots(snapshots, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14277
+ }
14278
+ exports.clearProceedingSnapshotsV2 = clearProceedingSnapshotsV2;
13891
14279
 
13892
14280
 
13893
14281
  /***/ }),
@@ -14083,6 +14471,18 @@ var VTable = /** @class */ (function () {
14083
14471
  */
14084
14472
  function VTable(node, normalizeSize, zoomScale) {
14085
14473
  var _this = this;
14474
+ /**
14475
+ * Virtual cells
14476
+ */
14477
+ this.cells = null;
14478
+ /**
14479
+ * Selected range of cells with the coordinates of the first and last cell selected.
14480
+ */
14481
+ this.selection = null;
14482
+ /**
14483
+ * Current format of the table
14484
+ */
14485
+ this.formatInfo = null;
14086
14486
  this.trs = [];
14087
14487
  this.table = (0, safeInstanceOf_1.default)(node, 'HTMLTableElement') ? node : getTableFromTd(node);
14088
14488
  if (this.table) {
@@ -14127,17 +14527,20 @@ var VTable = /** @class */ (function () {
14127
14527
  */
14128
14528
  VTable.prototype.writeBack = function (skipApplyFormat) {
14129
14529
  var _this = this;
14530
+ var _a;
14130
14531
  if (this.cells) {
14131
14532
  (0, moveChildNodes_1.default)(this.table);
14132
14533
  this.cells.forEach(function (row, r) {
14133
14534
  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
- });
14535
+ if (tr) {
14536
+ _this.table.appendChild(tr);
14537
+ row.forEach(function (cell, c) {
14538
+ if (cell.td) {
14539
+ _this.recalculateSpans(r, c);
14540
+ tr.appendChild(cell.td);
14541
+ }
14542
+ });
14543
+ }
14141
14544
  });
14142
14545
  if (this.formatInfo && !skipApplyFormat) {
14143
14546
  (0, tableFormatInfo_1.saveTableInfo)(this.table, this.formatInfo);
@@ -14145,7 +14548,7 @@ var VTable = /** @class */ (function () {
14145
14548
  }
14146
14549
  }
14147
14550
  else if (this.table) {
14148
- this.table.parentNode.removeChild(this.table);
14551
+ (_a = this.table.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.table);
14149
14552
  }
14150
14553
  };
14151
14554
  /**
@@ -14166,7 +14569,7 @@ var VTable = /** @class */ (function () {
14166
14569
  * @param cells
14167
14570
  */
14168
14571
  VTable.prototype.deleteCellShadeDataset = function (cells) {
14169
- cells.forEach(function (row) {
14572
+ cells === null || cells === void 0 ? void 0 : cells.forEach(function (row) {
14170
14573
  row.forEach(function (cell) {
14171
14574
  if (cell.td && cell.td.dataset[CELL_SHADE]) {
14172
14575
  delete cell.td.dataset[CELL_SHADE];
@@ -14180,77 +14583,120 @@ var VTable = /** @class */ (function () {
14180
14583
  */
14181
14584
  VTable.prototype.edit = function (operation) {
14182
14585
  var _this = this;
14183
- if (!this.table) {
14586
+ if (!this.table || !this.cells || this.row === undefined || this.col == undefined) {
14184
14587
  return;
14185
14588
  }
14186
14589
  var currentRow = this.cells[this.row];
14187
14590
  var currentCell = currentRow[this.col];
14188
- var style = currentCell.td.style;
14591
+ var firstRow = this.selection ? this.selection.firstCell.y : this.row;
14592
+ var lastRow = this.selection ? this.selection.lastCell.y : this.row;
14593
+ var firstColumn = this.selection ? this.selection.firstCell.x : this.col;
14594
+ var lastColumn = this.selection ? this.selection.lastCell.x : this.col;
14189
14595
  switch (operation) {
14190
14596
  case 0 /* InsertAbove */:
14191
- this.cells.splice(this.row, 0, currentRow.map(cloneCell));
14597
+ for (var i = firstRow; i <= lastRow; i++) {
14598
+ this.cells.splice(firstRow, 0, currentRow.map(cloneCell));
14599
+ }
14192
14600
  break;
14193
14601
  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
- }));
14602
+ var _loop_1 = function (i) {
14603
+ var newRow = lastRow + this_1.countSpanAbove(lastRow, this_1.col);
14604
+ this_1.cells.splice(newRow, 0, this_1.cells[newRow - 1].map(function (cell, colIndex) {
14605
+ var nextCell = _this.getCell(newRow, colIndex);
14606
+ if (nextCell.spanAbove) {
14607
+ return cloneCell(nextCell);
14608
+ }
14609
+ else if (cell.spanLeft) {
14610
+ var newCell = cloneCell(cell);
14611
+ newCell.spanAbove = false;
14612
+ return newCell;
14613
+ }
14614
+ else {
14615
+ return {
14616
+ td: cloneNode(_this.getTd(_this.row, colIndex)),
14617
+ };
14618
+ }
14619
+ }));
14620
+ };
14621
+ var this_1 = this;
14622
+ for (var i = firstRow; i <= lastRow; i++) {
14623
+ _loop_1(i);
14624
+ }
14211
14625
  break;
14212
14626
  case 2 /* InsertLeft */:
14213
- this.forEachCellOfCurrentColumn(function (cell, row) {
14214
- row.splice(_this.col, 0, cloneCell(cell));
14215
- });
14627
+ var _loop_2 = function (i) {
14628
+ this_2.forEachCellOfCurrentColumn(function (cell, row) {
14629
+ row.splice(i, 0, cloneCell(cell));
14630
+ });
14631
+ };
14632
+ var this_2 = this;
14633
+ for (var i = firstColumn; i <= lastColumn; i++) {
14634
+ _loop_2(i);
14635
+ }
14216
14636
  break;
14217
14637
  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
- });
14638
+ var _loop_3 = function (i) {
14639
+ var newCol = lastColumn + this_3.countSpanLeft(this_3.row, lastColumn);
14640
+ this_3.forEachCellOfColumn(newCol - 1, function (cell, row, i) {
14641
+ var nextCell = _this.getCell(i, newCol);
14642
+ var newCell;
14643
+ if (nextCell.spanLeft) {
14644
+ newCell = cloneCell(nextCell);
14645
+ }
14646
+ else if (cell.spanAbove) {
14647
+ newCell = cloneCell(cell);
14648
+ newCell.spanLeft = false;
14649
+ }
14650
+ else {
14651
+ newCell = {
14652
+ td: cloneNode(_this.getTd(i, _this.col)),
14653
+ };
14654
+ }
14655
+ row.splice(newCol, 0, newCell);
14656
+ });
14657
+ };
14658
+ var this_3 = this;
14659
+ for (var i = firstColumn; i <= lastColumn; i++) {
14660
+ _loop_3(i);
14661
+ }
14236
14662
  break;
14237
14663
  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);
14664
+ var _loop_4 = function (rowIndex) {
14665
+ this_4.forEachCellOfRow(rowIndex, function (cell, i) {
14666
+ var nextCell = _this.getCell(rowIndex + 1, i);
14667
+ if (cell.td && cell.td.rowSpan > 1 && nextCell.spanAbove) {
14668
+ nextCell.td = cell.td;
14669
+ }
14670
+ });
14671
+ };
14672
+ var this_4 = this;
14673
+ for (var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++) {
14674
+ _loop_4(rowIndex);
14675
+ }
14676
+ var removedRows = this.selection
14677
+ ? this.selection.lastCell.y - this.selection.firstCell.y
14678
+ : 0;
14679
+ this.cells.splice(firstRow, removedRows + 1);
14245
14680
  break;
14246
14681
  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
- });
14682
+ var deletedColumns_1 = 0;
14683
+ var _loop_5 = function (colIndex) {
14684
+ this_5.forEachCellOfColumn(colIndex, function (cell, row, i) {
14685
+ var nextCell = _this.getCell(i, colIndex + 1);
14686
+ if (cell.td && cell.td.colSpan > 1 && nextCell.spanLeft) {
14687
+ nextCell.td = cell.td;
14688
+ }
14689
+ var removedColumns = _this.selection
14690
+ ? colIndex - deletedColumns_1
14691
+ : _this.col;
14692
+ row.splice(removedColumns, 1);
14693
+ });
14694
+ deletedColumns_1++;
14695
+ };
14696
+ var this_5 = this;
14697
+ for (var colIndex = firstColumn; colIndex <= lastColumn; colIndex++) {
14698
+ _loop_5(colIndex);
14699
+ }
14254
14700
  break;
14255
14701
  case 7 /* MergeAbove */:
14256
14702
  case 8 /* MergeBelow */:
@@ -14260,7 +14706,9 @@ var VTable = /** @class */ (function () {
14260
14706
  if (cell.td && !cell.spanAbove) {
14261
14707
  var aboveCell = rowIndex < this.row ? cell : currentCell;
14262
14708
  var belowCell = rowIndex < this.row ? currentCell : cell;
14263
- if (aboveCell.td.colSpan == belowCell.td.colSpan) {
14709
+ if (aboveCell.td &&
14710
+ belowCell.td &&
14711
+ aboveCell.td.colSpan == belowCell.td.colSpan) {
14264
14712
  (0, moveChildNodes_1.default)(aboveCell.td, belowCell.td, true /*keepExistingChildren*/);
14265
14713
  belowCell.td = null;
14266
14714
  belowCell.spanAbove = true;
@@ -14277,7 +14725,9 @@ var VTable = /** @class */ (function () {
14277
14725
  if (cell.td && !cell.spanLeft) {
14278
14726
  var leftCell = colIndex < this.col ? cell : currentCell;
14279
14727
  var rightCell = colIndex < this.col ? currentCell : cell;
14280
- if (leftCell.td.rowSpan == rightCell.td.rowSpan) {
14728
+ if (leftCell.td &&
14729
+ rightCell.td &&
14730
+ leftCell.td.rowSpan == rightCell.td.rowSpan) {
14281
14731
  (0, moveChildNodes_1.default)(leftCell.td, rightCell.td, true /*keepExistingChildren*/);
14282
14732
  rightCell.td = null;
14283
14733
  rightCell.spanLeft = true;
@@ -14290,7 +14740,7 @@ var VTable = /** @class */ (function () {
14290
14740
  this.cells = null;
14291
14741
  break;
14292
14742
  case 12 /* SplitVertically */:
14293
- if (currentCell.td.rowSpan > 1) {
14743
+ if (currentCell.td && currentCell.td.rowSpan > 1) {
14294
14744
  this.getCell(this.row + 1, this.col).td = cloneNode(currentCell.td);
14295
14745
  }
14296
14746
  else {
@@ -14305,7 +14755,7 @@ var VTable = /** @class */ (function () {
14305
14755
  }
14306
14756
  break;
14307
14757
  case 11 /* SplitHorizontally */:
14308
- if (currentCell.td.colSpan > 1) {
14758
+ if (currentCell.td && currentCell.td.colSpan > 1) {
14309
14759
  this.getCell(this.row, this.col + 1).td = cloneNode(currentCell.td);
14310
14760
  }
14311
14761
  else {
@@ -14331,25 +14781,41 @@ var VTable = /** @class */ (function () {
14331
14781
  this.table.style.marginRight = '';
14332
14782
  break;
14333
14783
  case 17 /* AlignCellCenter */:
14334
- style.textAlign = 'center';
14784
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'center');
14335
14785
  break;
14336
14786
  case 16 /* AlignCellLeft */:
14337
- style.textAlign = 'left';
14787
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'left');
14338
14788
  break;
14339
14789
  case 18 /* AlignCellRight */:
14340
- style.textAlign = 'right';
14790
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'right');
14341
14791
  break;
14342
14792
  case 19 /* AlignCellTop */:
14343
- style.verticalAlign = 'top';
14793
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'top', true /** isVertical */);
14344
14794
  break;
14345
14795
  case 20 /* AlignCellMiddle */:
14346
- style.verticalAlign = 'middle';
14796
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'middle', true /** isVertical */);
14347
14797
  break;
14348
14798
  case 21 /* AlignCellBottom */:
14349
- style.verticalAlign = 'bottom';
14799
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'bottom', true /** isVertical */);
14350
14800
  break;
14351
14801
  }
14352
14802
  };
14803
+ VTable.prototype.setAlignmentToSelectedCells = function (firstRow, lastRow, firstColumn, lastColumn, alignmentType, isVertical) {
14804
+ var _a, _b;
14805
+ for (var i = firstRow; i <= lastRow; i++) {
14806
+ for (var j = firstColumn; j <= lastColumn; j++) {
14807
+ if (this.cells) {
14808
+ var cell = this.cells[i][j].td;
14809
+ if (isVertical && cell) {
14810
+ (_a = cell.style) === null || _a === void 0 ? void 0 : _a.setProperty('vertical-align', alignmentType);
14811
+ }
14812
+ else if (cell) {
14813
+ (_b = cell.style) === null || _b === void 0 ? void 0 : _b.setProperty('text-align', alignmentType);
14814
+ }
14815
+ }
14816
+ }
14817
+ }
14818
+ };
14353
14819
  /**
14354
14820
  * Loop each cell of current column and invoke a callback function
14355
14821
  * @param callback The callback function to invoke
@@ -14383,7 +14849,7 @@ var VTable = /** @class */ (function () {
14383
14849
  */
14384
14850
  VTable.prototype.getCellsWithBorder = function (borderPos, getLeftCells) {
14385
14851
  var cells = [];
14386
- for (var i = 0; i < this.cells.length; i++) {
14852
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14387
14853
  for (var j = 0; j < this.cells[i].length; j++) {
14388
14854
  var cell = this.getCell(i, j);
14389
14855
  if (cell.td) {
@@ -14442,7 +14908,7 @@ var VTable = /** @class */ (function () {
14442
14908
  * @param col column of the cell
14443
14909
  */
14444
14910
  VTable.prototype.getTd = function (row, col) {
14445
- if (this.cells) {
14911
+ if (this.cells && row !== undefined && col !== undefined) {
14446
14912
  row = Math.min(this.cells.length - 1, row);
14447
14913
  col = this.cells[row] ? Math.min(this.cells[row].length - 1, col) : col;
14448
14914
  if (!isNaN(row) && !isNaN(col)) {
@@ -14466,13 +14932,17 @@ var VTable = /** @class */ (function () {
14466
14932
  return null;
14467
14933
  };
14468
14934
  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);
14935
+ if (col !== undefined) {
14936
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14937
+ callback(this.getCell(i, col), this.cells[i], i);
14938
+ }
14471
14939
  }
14472
14940
  };
14473
14941
  VTable.prototype.forEachCellOfRow = function (row, callback) {
14474
- for (var i = 0; i < this.cells[row].length; i++) {
14475
- callback(this.getCell(row, i), i);
14942
+ if (row !== undefined) {
14943
+ for (var i = 0; this.cells && i < this.cells[row].length; i++) {
14944
+ callback(this.getCell(row, i), i);
14945
+ }
14476
14946
  }
14477
14947
  };
14478
14948
  VTable.prototype.recalculateSpans = function (row, col) {
@@ -14490,7 +14960,7 @@ var VTable = /** @class */ (function () {
14490
14960
  };
14491
14961
  VTable.prototype.countSpanLeft = function (row, col) {
14492
14962
  var result = 1;
14493
- for (var i = col + 1; i < this.cells[row].length; i++) {
14963
+ for (var i = col + 1; this.cells && i < this.cells[row].length; i++) {
14494
14964
  var cell = this.getCell(row, i);
14495
14965
  if (cell.td || !cell.spanLeft) {
14496
14966
  break;
@@ -14501,7 +14971,7 @@ var VTable = /** @class */ (function () {
14501
14971
  };
14502
14972
  VTable.prototype.countSpanAbove = function (row, col) {
14503
14973
  var result = 1;
14504
- for (var i = row + 1; i < this.cells.length; i++) {
14974
+ for (var i = row + 1; this.cells && i < this.cells.length; i++) {
14505
14975
  var cell = this.getCell(i, col);
14506
14976
  if (cell.td || !cell.spanAbove) {
14507
14977
  break;
@@ -14526,17 +14996,19 @@ var VTable = /** @class */ (function () {
14526
14996
  // remove width/height for each row
14527
14997
  for (var i = 0, row = void 0; (row = this.table.rows[i]); i++) {
14528
14998
  row.removeAttribute('width');
14529
- row.style.width = null;
14999
+ row.style.setProperty('width', null);
14530
15000
  row.removeAttribute('height');
14531
- row.style.height = null;
15001
+ row.style.setProperty('height', null);
14532
15002
  }
14533
15003
  // set width/height for each cell
14534
- for (var i = 0; i < this.cells.length; i++) {
15004
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14535
15005
  for (var j = 0; j < this.cells[i].length; j++) {
14536
15006
  var cell = this.cells[i][j];
14537
15007
  if (cell) {
14538
15008
  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);
15009
+ var width = cell.width || 0;
15010
+ var height = cell.height || 0;
15011
+ setHTMLElementSizeInPx(cell.td, (func === null || func === void 0 ? void 0 : func(width)) || width, (func === null || func === void 0 ? void 0 : func(height)) || height);
14540
15012
  }
14541
15013
  }
14542
15014
  }
@@ -14880,6 +15352,40 @@ function getBorderStyle(style) {
14880
15352
  }
14881
15353
 
14882
15354
 
15355
+ /***/ }),
15356
+
15357
+ /***/ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts":
15358
+ /*!*************************************************************************!*\
15359
+ !*** ./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts ***!
15360
+ \*************************************************************************/
15361
+ /*! no static exports found */
15362
+ /***/ (function(module, exports, __webpack_require__) {
15363
+
15364
+ "use strict";
15365
+
15366
+ Object.defineProperty(exports, "__esModule", { value: true });
15367
+ /**
15368
+ * Check if the whole table is selected
15369
+ * @param vTable VTable to check whether all cells are selected
15370
+ * @param selection Table selection with first cell selected and last cell selected coordinates.
15371
+ * @returns
15372
+ */
15373
+ function isWholeTableSelected(vTable, selection) {
15374
+ if (!selection || !vTable.cells) {
15375
+ return false;
15376
+ }
15377
+ var firstCell = selection.firstCell, lastCell = selection.lastCell;
15378
+ var rowsLength = vTable.cells.length - 1;
15379
+ var colIndex = vTable.cells[rowsLength].length - 1;
15380
+ var firstX = firstCell.x;
15381
+ var firstY = firstCell.y;
15382
+ var lastX = lastCell.x;
15383
+ var lastY = lastCell.y;
15384
+ return firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
15385
+ }
15386
+ exports.default = isWholeTableSelected;
15387
+
15388
+
14883
15389
  /***/ }),
14884
15390
 
14885
15391
  /***/ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts":
@@ -18109,11 +18615,14 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
18109
18615
  */
18110
18616
  var TabInTable = {
18111
18617
  keys: [9 /* TAB */],
18112
- shouldHandleEvent: cacheGetTableCell,
18618
+ shouldHandleEvent: function (event, editor) {
18619
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18620
+ },
18113
18621
  handleEvent: function (event, editor) {
18114
18622
  var shift = event.rawEvent.shiftKey;
18115
18623
  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) {
18624
+ var vtable = cacheVTable(event, td);
18625
+ for (var step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
18117
18626
  if (col < 0 || col >= vtable.cells[row].length) {
18118
18627
  row += step;
18119
18628
  if (row < 0) {
@@ -18135,13 +18644,40 @@ var TabInTable = {
18135
18644
  event.rawEvent.preventDefault();
18136
18645
  },
18137
18646
  };
18647
+ /**
18648
+ * IndentTableOnTab edit feature, provides the ability to indent the table if it is all cells are selected.
18649
+ */
18650
+ var IndentTableOnTab = {
18651
+ keys: [9 /* TAB */],
18652
+ shouldHandleEvent: function (event, editor) {
18653
+ return cacheGetTableCell(event, editor) && cacheIsWholeTableSelected(event, editor);
18654
+ },
18655
+ handleEvent: function (event, editor) {
18656
+ event.rawEvent.preventDefault();
18657
+ editor.addUndoSnapshot(function () {
18658
+ var shift = event.rawEvent.shiftKey;
18659
+ var selection = editor.getSelectionRangeEx();
18660
+ var td = cacheGetTableCell(event, editor);
18661
+ var vtable = cacheVTable(event, td);
18662
+ if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
18663
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
18664
+ }
18665
+ else if (!shift) {
18666
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
18667
+ }
18668
+ editor.select(selection.table, selection.coordinates);
18669
+ });
18670
+ },
18671
+ };
18138
18672
  /**
18139
18673
  * UpDownInTable edit feature, provides the ability to jump to cell above/below when user press UP/DOWN
18140
18674
  * in table
18141
18675
  */
18142
18676
  var UpDownInTable = {
18143
18677
  keys: [38 /* UP */, 40 /* DOWN */],
18144
- shouldHandleEvent: cacheGetTableCell,
18678
+ shouldHandleEvent: function (event, editor) {
18679
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18680
+ },
18145
18681
  handleEvent: function (event, editor) {
18146
18682
  var _a;
18147
18683
  var td = cacheGetTableCell(event, editor);
@@ -18193,12 +18729,27 @@ function cacheGetTableCell(event, editor) {
18193
18729
  return (firstTd && ((0, roosterjs_editor_dom_1.getTagOfNode)(firstTd) == 'LI' ? null : firstTd));
18194
18730
  });
18195
18731
  }
18732
+ function cacheIsWholeTableSelected(event, editor) {
18733
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
18734
+ var td = cacheGetTableCell(event, editor);
18735
+ var vtable = cacheVTable(event, td);
18736
+ var selection = editor.getSelectionRangeEx();
18737
+ return (selection.type == 1 /* TableSelection */ &&
18738
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
18739
+ });
18740
+ }
18741
+ function cacheVTable(event, td) {
18742
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'VTABLE_FOR_TABLE_FEATURES', function () {
18743
+ return new roosterjs_editor_dom_1.VTable(td);
18744
+ });
18745
+ }
18196
18746
  /**
18197
18747
  * @internal
18198
18748
  */
18199
18749
  exports.TableFeatures = {
18200
18750
  tabInTable: TabInTable,
18201
18751
  upDownInTable: UpDownInTable,
18752
+ indentTableOnTab: IndentTableOnTab,
18202
18753
  };
18203
18754
 
18204
18755
 
@@ -18319,17 +18870,27 @@ function insertTab(editor, event) {
18319
18870
  var searcher = editor.getContentSearcherOfCursor(event);
18320
18871
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
18321
18872
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
18873
+ var span2;
18322
18874
  var textContent = '';
18323
18875
  for (var index = 0; index < numberOfChars; index++) {
18324
18876
  textContent += '&ensp;';
18325
18877
  }
18326
18878
  editor.insertNode(span);
18879
+ if (span.nextElementSibling && (0, roosterjs_editor_dom_1.getTagOfNode)(span.nextElementSibling) == 'A') {
18880
+ span2 = editor.getDocument().createElement('span');
18881
+ span2.textContent = ' ';
18882
+ editor.insertNode(span2);
18883
+ editor.select((0, roosterjs_editor_dom_1.createRange)(span2, -2 /* Before */));
18884
+ }
18327
18885
  editor.insertContent(textContent, {
18328
18886
  position: 5 /* Range */,
18329
18887
  range: (0, roosterjs_editor_dom_1.createRange)(span, 0 /* Begin */),
18330
18888
  updateCursor: false,
18331
18889
  });
18332
18890
  editor.select((0, roosterjs_editor_dom_1.createRange)(span, -3 /* After */));
18891
+ if (span2) {
18892
+ editor.deleteNode(span2);
18893
+ }
18333
18894
  }
18334
18895
 
18335
18896
 
@@ -22552,6 +23113,14 @@ var TableCellSelection = /** @class */ (function () {
22552
23113
  this.handleScrollEvent();
22553
23114
  }
22554
23115
  break;
23116
+ case 20 /* BeforeSetContent */:
23117
+ if (this.tableRange) {
23118
+ this.tableRange = null;
23119
+ this.firstTable = null;
23120
+ this.tableSelection = false;
23121
+ this.editor.select(null);
23122
+ }
23123
+ break;
22555
23124
  }
22556
23125
  }
22557
23126
  };
@@ -22585,10 +23154,12 @@ var TableCellSelection = /** @class */ (function () {
22585
23154
  if (selection.type == 1 /* TableSelection */) {
22586
23155
  var clonedTable = event.clonedRoot.querySelector('table#' + selection.table.id);
22587
23156
  if (clonedTable) {
23157
+ this.tableRange = selection.coordinates;
22588
23158
  var clonedVTable = new roosterjs_editor_dom_1.VTable(clonedTable);
22589
23159
  clonedVTable.selection = this.tableRange;
22590
23160
  (0, removeCellsOutsideSelection_1.removeCellsOutsideSelection)(clonedVTable);
22591
23161
  clonedVTable.writeBack();
23162
+ clonedVTable.table.id = '';
22592
23163
  event.range.selectNode(clonedTable);
22593
23164
  if (event.isCut) {
22594
23165
  (0, forEachSelectedCell_1.forEachSelectedCell)(this.vTable, function (cell) {
@@ -22607,8 +23178,9 @@ var TableCellSelection = /** @class */ (function () {
22607
23178
  */
22608
23179
  TableCellSelection.prototype.handleKeyDownEvent = function (event) {
22609
23180
  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 */) {
23181
+ var _a = event.rawEvent, shiftKey = _a.shiftKey, ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which, defaultPrevented = _a.defaultPrevented;
23182
+ if ((shiftKey && (ctrlKey || metaKey)) || which == 16 /* SHIFT */ || defaultPrevented) {
23183
+ this.preventKeyUp = defaultPrevented;
22612
23184
  return;
22613
23185
  }
22614
23186
  if (shiftKey) {
@@ -22642,9 +23214,10 @@ var TableCellSelection = /** @class */ (function () {
22642
23214
  };
22643
23215
  TableCellSelection.prototype.handleKeyUpEvent = function (event) {
22644
23216
  var _a = event.rawEvent, shiftKey = _a.shiftKey, which = _a.which;
22645
- if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget) {
23217
+ if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget && !this.preventKeyUp) {
22646
23218
  this.clearState();
22647
23219
  }
23220
+ this.preventKeyUp = false;
22648
23221
  };
22649
23222
  TableCellSelection.prototype.handleKeySelectionInsideTable = function (event) {
22650
23223
  this.firstTarget = getCellAtCursor(this.editor, this.firstTarget);
@@ -22708,13 +23281,17 @@ var TableCellSelection = /** @class */ (function () {
22708
23281
  }
22709
23282
  }
22710
23283
  }
22711
- this.editor.getDocument().addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
22712
23284
  if (which == LEFT_CLICK && !shiftKey) {
22713
23285
  this.clearState();
22714
- this.editor
22715
- .getDocument()
22716
- .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
22717
- this.startedSelection = true;
23286
+ if (getTableAtCursor(this.editor, event.rawEvent.target)) {
23287
+ this.editor
23288
+ .getDocument()
23289
+ .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
23290
+ this.editor
23291
+ .getDocument()
23292
+ .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
23293
+ this.startedSelection = true;
23294
+ }
22718
23295
  }
22719
23296
  if (which == LEFT_CLICK && shiftKey) {
22720
23297
  this.editor.runAsync(function (editor) {
@@ -23116,24 +23693,22 @@ exports.default = normalizeTableSelection;
23116
23693
 
23117
23694
  Object.defineProperty(exports, "__esModule", { value: true });
23118
23695
  exports.removeCellsOutsideSelection = void 0;
23696
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
23119
23697
  /**
23120
23698
  * @internal
23121
23699
  * Remove the cells outside of the selection.
23122
23700
  * @param vTable VTable to remove selection
23123
23701
  */
23124
23702
  function removeCellsOutsideSelection(vTable) {
23703
+ if ((0, roosterjs_editor_dom_1.isWholeTableSelected)(vTable, vTable.selection)) {
23704
+ return;
23705
+ }
23125
23706
  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
23707
  var resultCells = [];
23129
23708
  var firstX = firstCell.x;
23130
23709
  var firstY = firstCell.y;
23131
23710
  var lastX = lastCell.x;
23132
23711
  var lastY = lastCell.y;
23133
- var selectedAllTable = firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
23134
- if (selectedAllTable) {
23135
- return;
23136
- }
23137
23712
  vTable.cells.forEach(function (row, y) {
23138
23713
  row = row.filter(function (_, x) { return y >= firstY && y <= lastY && x >= firstX && x <= lastX; });
23139
23714
  if (row.length > 0) {
@@ -23498,7 +24073,8 @@ var TableEditor = /** @class */ (function () {
23498
24073
  _this.disposeTableResizer();
23499
24074
  _this.onStartResize();
23500
24075
  };
23501
- this.onInserted = function () {
24076
+ this.onInserted = function (table) {
24077
+ _this.editor.transformToDarkColor(table);
23502
24078
  _this.disposeTableResizer();
23503
24079
  _this.onFinishEditing();
23504
24080
  };
@@ -23735,9 +24311,7 @@ var TableInsertHandler = /** @class */ (function () {
23735
24311
  }
23736
24312
  vtable.edit(_this.isHorizontal ? 1 /* InsertBelow */ : 3 /* InsertRight */);
23737
24313
  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();
24314
+ _this.onInsert(vtable.table);
23741
24315
  };
23742
24316
  this.div.addEventListener('click', this.insertTd);
23743
24317
  }