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.
package/dist/rooster.js CHANGED
@@ -3032,7 +3032,7 @@ function setAlignment(editor, alignment) {
3032
3032
  editor.addUndoSnapshot(function () {
3033
3033
  if (editor.isFeatureEnabled("TableAlignment" /* TableAlignment */) &&
3034
3034
  isATable &&
3035
- isWholeTableSelected(selection)) {
3035
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3036
3036
  alignTable(selection, alignment);
3037
3037
  }
3038
3038
  else {
@@ -3084,25 +3084,6 @@ function alignText(editor, alignment) {
3084
3084
  (0, execCommand_1.default)(editor, command);
3085
3085
  editor.queryElements('[align]', 1 /* OnSelection */, function (node) { return (node.style.textAlign = align); });
3086
3086
  }
3087
- /**
3088
- * Check if the whole table is selected
3089
- * @param selection
3090
- * @returns
3091
- */
3092
- function isWholeTableSelected(selection) {
3093
- if (!selection) {
3094
- return false;
3095
- }
3096
- var vTable = new roosterjs_editor_dom_1.VTable(selection.table);
3097
- var _a = selection.coordinates, firstCell = _a.firstCell, lastCell = _a.lastCell;
3098
- var rowsLength = vTable.cells.length - 1;
3099
- var colIndex = vTable.cells[rowsLength].length - 1;
3100
- var firstX = firstCell.x;
3101
- var firstY = firstCell.y;
3102
- var lastX = lastCell.x;
3103
- var lastY = lastCell.y;
3104
- return firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
3105
- }
3106
3087
 
3107
3088
 
3108
3089
  /***/ }),
@@ -3289,7 +3270,6 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
3289
3270
  function setIndentation(editor, indentation) {
3290
3271
  var handler = indentation == 0 /* Increase */ ? indent : outdent;
3291
3272
  (0, blockFormat_1.default)(editor, function (region, start, end) {
3292
- var _a;
3293
3273
  var blocks = (0, roosterjs_editor_dom_1.getSelectedBlockElementsInRegion)(region, true /*createBlockIfEmpty*/);
3294
3274
  var blockGroups = [[]];
3295
3275
  for (var i = 0; i < blocks.length; i++) {
@@ -3299,15 +3279,18 @@ function setIndentation(editor, indentation) {
3299
3279
  while (blocks[i + 1] && vList.contains(blocks[i + 1].getStartNode())) {
3300
3280
  i++;
3301
3281
  }
3302
- if (((_a = vList.items[0]) === null || _a === void 0 ? void 0 : _a.getNode()) == startNode &&
3303
- vList.getListItemIndex(startNode) == vList.getStart() &&
3304
- (indentation == 0 /* Increase */ ||
3305
- editor.getElementAtCursor('blockquote', startNode))) {
3282
+ var isTabKeyTextFeaturesEnabled = editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */);
3283
+ vList.rootList.style.listStylePosition = 'inside';
3284
+ if (isTabKeyTextFeaturesEnabled &&
3285
+ isFirstItem(vList, startNode) &&
3286
+ shouldHandleWithBlockquotes(indentation, editor, startNode)) {
3306
3287
  var block = editor.getBlockElementAtNode(vList.rootList);
3307
3288
  blockGroups.push([block]);
3308
3289
  }
3309
3290
  else {
3310
- vList.setIndentation(start, end, indentation);
3291
+ indentation == 1 /* Decrease */
3292
+ ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3293
+ : vList.setIndentation(start, end, indentation);
3311
3294
  vList.writeBack();
3312
3295
  blockGroups.push([]);
3313
3296
  }
@@ -3317,6 +3300,20 @@ function setIndentation(editor, indentation) {
3317
3300
  }
3318
3301
  }
3319
3302
  blockGroups.forEach(function (group) { return handler(region, group); });
3303
+ }, function () {
3304
+ var selection = editor.getSelectionRangeEx();
3305
+ if (selection.type == 1 /* TableSelection */ &&
3306
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3307
+ if (indentation == 1 /* Decrease */) {
3308
+ var quote = editor.getElementAtCursor('blockquote', selection.table);
3309
+ (0, roosterjs_editor_dom_1.unwrap)(quote);
3310
+ }
3311
+ else if (indentation == 0 /* Increase */) {
3312
+ (0, roosterjs_editor_dom_1.wrap)(selection.table, 2 /* BlockquoteWrapper */);
3313
+ }
3314
+ return false;
3315
+ }
3316
+ return true;
3320
3317
  });
3321
3318
  }
3322
3319
  exports.default = setIndentation;
@@ -3341,6 +3338,14 @@ function outdent(region, blocks) {
3341
3338
  }
3342
3339
  });
3343
3340
  }
3341
+ function isFirstItem(vList, startNode) {
3342
+ var _a;
3343
+ return (((_a = vList.items[0]) === null || _a === void 0 ? void 0 : _a.getNode()) == startNode &&
3344
+ vList.getListItemIndex(startNode) == (vList.getStart() || 1));
3345
+ }
3346
+ function shouldHandleWithBlockquotes(indentation, editor, startNode) {
3347
+ return (indentation == 0 /* Increase */ || editor.getElementAtCursor('blockquote', startNode));
3348
+ }
3344
3349
 
3345
3350
 
3346
3351
  /***/ }),
@@ -3917,12 +3922,12 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
3917
3922
  function editTable(editor, operation) {
3918
3923
  var td = editor.getElementAtCursor('TD,TH');
3919
3924
  if (td) {
3920
- editor.addUndoSnapshot(function (start, end) {
3925
+ editor.addUndoSnapshot(function () {
3921
3926
  var vtable = new roosterjs_editor_dom_1.VTable(td);
3927
+ saveTableSelection(editor, vtable);
3922
3928
  vtable.edit(operation);
3923
3929
  vtable.writeBack();
3924
- //Adding replaceNode to transform color when the theme is switched to dark.
3925
- editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
3930
+ editor.transformToDarkColor(vtable.table);
3926
3931
  editor.focus();
3927
3932
  var cellToSelect = calculateCellToSelect(operation, vtable.row, vtable.col);
3928
3933
  editor.select(vtable.getCell(cellToSelect.newRow, cellToSelect.newCol).td, 0 /* Begin */);
@@ -3954,6 +3959,12 @@ function calculateCellToSelect(operation, currentRow, currentCol) {
3954
3959
  newCol: newCol,
3955
3960
  };
3956
3961
  }
3962
+ function saveTableSelection(editor, vtable) {
3963
+ var selection = editor.getSelectionRangeEx();
3964
+ if (selection && selection.type === 1 /* TableSelection */) {
3965
+ vtable.selection = selection.coordinates;
3966
+ }
3967
+ }
3957
3968
 
3958
3969
 
3959
3970
  /***/ }),
@@ -3982,8 +3993,7 @@ function formatTable(editor, format, table) {
3982
3993
  var vtable = new roosterjs_editor_dom_1.VTable(table);
3983
3994
  vtable.applyFormat(format);
3984
3995
  vtable.writeBack();
3985
- //Adding replaceNode to transform color when the theme is switched to dark.
3986
- editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
3996
+ editor.transformToDarkColor(vtable.table);
3987
3997
  editor.focus();
3988
3998
  editor.select(start, end);
3989
3999
  }, "Format" /* Format */);
@@ -4411,6 +4421,9 @@ function toggleListType(editor, listType, startNumber, includeSiblingLists) {
4411
4421
  : (0, roosterjs_editor_dom_1.createVListFromRegion)(region, includeSiblingLists);
4412
4422
  if (vList) {
4413
4423
  vList.changeListType(start, end, listType);
4424
+ if (editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */)) {
4425
+ vList.rootList.style.listStylePosition = 'inside';
4426
+ }
4414
4427
  vList.writeBack();
4415
4428
  }
4416
4429
  });
@@ -4429,6 +4442,17 @@ exports.default = toggleListType;
4429
4442
 
4430
4443
  "use strict";
4431
4444
 
4445
+ var __assign = (this && this.__assign) || function () {
4446
+ __assign = Object.assign || function(t) {
4447
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4448
+ s = arguments[i];
4449
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
4450
+ t[p] = s[p];
4451
+ }
4452
+ return t;
4453
+ };
4454
+ return __assign.apply(this, arguments);
4455
+ };
4432
4456
  Object.defineProperty(exports, "__esModule", { value: true });
4433
4457
  exports.addUndoSnapshot = void 0;
4434
4458
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
@@ -4444,22 +4468,17 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
4444
4468
  var addUndoSnapshot = function (core, callback, changeSource, canUndoByBackspace) {
4445
4469
  var undoState = core.undo;
4446
4470
  var isNested = undoState.isNested;
4447
- var isShadowEdit = !!core.lifecycle.shadowEditFragment;
4448
4471
  var data;
4449
4472
  if (!isNested) {
4450
4473
  undoState.isNested = true;
4451
- if (!isShadowEdit) {
4452
- undoState.snapshotsService.addSnapshot(core.api.getContent(core, 2 /* RawHTMLWithSelection */), canUndoByBackspace);
4453
- undoState.hasNewContent = false;
4454
- }
4474
+ addUndoSnapshotInternal(core, canUndoByBackspace);
4455
4475
  }
4456
4476
  try {
4457
4477
  if (callback) {
4458
4478
  var range = core.api.getSelectionRange(core, true /*tryGetFromCache*/);
4459
4479
  data = callback(range && roosterjs_editor_dom_1.Position.getStart(range).normalize(), range && roosterjs_editor_dom_1.Position.getEnd(range).normalize());
4460
- if (!isNested && !isShadowEdit) {
4461
- undoState.snapshotsService.addSnapshot(core.api.getContent(core, 2 /* RawHTMLWithSelection */), false /*isAutoCompleteSnapshot*/);
4462
- undoState.hasNewContent = false;
4480
+ if (!isNested) {
4481
+ addUndoSnapshotInternal(core, false /*isAutoCompleteSnapshot*/);
4463
4482
  }
4464
4483
  }
4465
4484
  }
@@ -4485,6 +4504,19 @@ var addUndoSnapshot = function (core, callback, changeSource, canUndoByBackspace
4485
4504
  }
4486
4505
  };
4487
4506
  exports.addUndoSnapshot = addUndoSnapshot;
4507
+ function addUndoSnapshotInternal(core, canUndoByBackspace) {
4508
+ if (!core.lifecycle.shadowEditFragment) {
4509
+ var rangeEx = core.api.getSelectionRangeEx(core);
4510
+ var isDarkMode = core.lifecycle.isDarkMode;
4511
+ var metadata = (rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 1 /* TableSelection */
4512
+ ? __assign({ type: 1 /* TableSelection */, tableId: rangeEx.table.id, isDarkMode: isDarkMode }, rangeEx.coordinates) : __assign({ type: 0 /* Normal */, isDarkMode: isDarkMode, start: [], end: [] }, ((0, roosterjs_editor_dom_1.getSelectionPath)(core.contentDiv, rangeEx.ranges[0]) || {}));
4513
+ core.undo.snapshotsService.addSnapshot({
4514
+ html: core.contentDiv.innerHTML,
4515
+ metadata: metadata,
4516
+ }, canUndoByBackspace);
4517
+ core.undo.hasNewContent = false;
4518
+ }
4519
+ }
4488
4520
 
4489
4521
 
4490
4522
  /***/ }),
@@ -5424,10 +5456,10 @@ var restoreUndoSnapshot = function (core, step) {
5424
5456
  core.api.addUndoSnapshot(core, null /*callback*/, null /*changeSource*/, false /*canUndoByBackspace*/);
5425
5457
  }
5426
5458
  var snapshot = core.undo.snapshotsService.move(step);
5427
- if (snapshot != null) {
5459
+ if (snapshot && snapshot.html != null) {
5428
5460
  try {
5429
5461
  core.undo.isRestoring = true;
5430
- core.api.setContent(core, snapshot, true /*triggerContentChangedEvent*/);
5462
+ core.api.setContent(core, snapshot.html, true /*triggerContentChangedEvent*/, snapshot.metadata);
5431
5463
  }
5432
5464
  finally {
5433
5465
  core.undo.isRestoring = false;
@@ -5709,6 +5741,7 @@ function isValidCoordinate(input) {
5709
5741
  Object.defineProperty(exports, "__esModule", { value: true });
5710
5742
  exports.setContent = void 0;
5711
5743
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5744
+ var roosterjs_editor_dom_2 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
5712
5745
  /**
5713
5746
  * @internal
5714
5747
  * Set HTML content to this editor. All existing content will be replaced. A ContentChanged event will be triggered
@@ -5717,20 +5750,24 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
5717
5750
  * @param content HTML content to set in
5718
5751
  * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
5719
5752
  */
5720
- var setContent = function (core, content, triggerContentChangedEvent) {
5753
+ var setContent = function (core, content, triggerContentChangedEvent, metadata) {
5721
5754
  var contentChanged = false;
5722
5755
  if (core.contentDiv.innerHTML != content) {
5723
5756
  core.api.triggerEvent(core, {
5724
5757
  eventType: 20 /* BeforeSetContent */,
5725
5758
  newContent: content,
5726
5759
  }, true /*broadcast*/);
5727
- var range = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(core.contentDiv, content, core.trustedHTMLHandler);
5728
- core.api.selectRange(core, range);
5760
+ var metadataFromContent = (0, roosterjs_editor_dom_2.setHtmlWithMetadata)(core.contentDiv, content, core.trustedHTMLHandler);
5761
+ metadata = metadata || metadataFromContent;
5762
+ selectContentMetadata(core, metadata);
5763
+ contentChanged = true;
5764
+ }
5765
+ var isDarkMode = core.lifecycle.isDarkMode;
5766
+ if ((!metadata && isDarkMode) || (metadata && !!metadata.isDarkMode != !!isDarkMode)) {
5767
+ core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, isDarkMode ? 0 /* LightToDark */ : 1 /* DarkToLight */, true /*forceTransform*/);
5729
5768
  contentChanged = true;
5730
5769
  }
5731
- // Convert content even if it hasn't changed.
5732
- core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
5733
- if (triggerContentChangedEvent && (contentChanged || core.lifecycle.isDarkMode)) {
5770
+ if (triggerContentChangedEvent && contentChanged) {
5734
5771
  core.api.triggerEvent(core, {
5735
5772
  eventType: 7 /* ContentChanged */,
5736
5773
  source: "SetContent" /* SetContent */,
@@ -5738,6 +5775,20 @@ var setContent = function (core, content, triggerContentChangedEvent) {
5738
5775
  }
5739
5776
  };
5740
5777
  exports.setContent = setContent;
5778
+ function selectContentMetadata(core, metadata) {
5779
+ switch (metadata === null || metadata === void 0 ? void 0 : metadata.type) {
5780
+ case 0 /* Normal */:
5781
+ var range = (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, metadata.start, metadata.end);
5782
+ core.api.selectRange(core, range);
5783
+ break;
5784
+ case 1 /* TableSelection */:
5785
+ var table = (0, roosterjs_editor_dom_1.queryElements)(core.contentDiv, '#' + metadata.tableId)[0];
5786
+ if (table) {
5787
+ core.api.selectTable(core, table, metadata);
5788
+ }
5789
+ break;
5790
+ }
5791
+ }
5741
5792
 
5742
5793
 
5743
5794
  /***/ }),
@@ -5848,52 +5899,70 @@ var ColorAttributeName = [
5848
5899
  * @param includeSelf True to transform the root node as well, otherwise false
5849
5900
  * @param callback The callback function to invoke before do color transformation
5850
5901
  * @param direction To specify the transform direction, light to dark, or dark to light
5902
+ * @param forceTransform By default this function will only work when editor core is in dark mode.
5903
+ * Pass true to this value to force do color transformation even editor core is in light mode
5851
5904
  */
5852
- var transformColor = function (core, rootNode, includeSelf, callback, direction) {
5853
- var elementsToTransform = core.lifecycle.isDarkMode ? getAll(rootNode, includeSelf) : [];
5854
- var transformFunction = direction == 1 /* DarkToLight */
5855
- ? transformToLightMode
5856
- : core.lifecycle.onExternalContentTransform ||
5857
- (function (element) { return transformToDarkMode(element, core.lifecycle.getDarkColor); });
5905
+ var transformColor = function (core, rootNode, includeSelf, callback, direction, forceTransform) {
5906
+ var elements = forceTransform || core.lifecycle.isDarkMode ? getAll(rootNode, includeSelf) : [];
5858
5907
  callback === null || callback === void 0 ? void 0 : callback();
5859
- elementsToTransform.forEach(function (element) { return (element === null || element === void 0 ? void 0 : element.dataset) && element.style && transformFunction(element); });
5908
+ if (direction == 1 /* DarkToLight */) {
5909
+ transformToLightMode(elements);
5910
+ }
5911
+ else if (core.lifecycle.onExternalContentTransform) {
5912
+ elements.forEach(function (element) { return core.lifecycle.onExternalContentTransform(element); });
5913
+ }
5914
+ else {
5915
+ transformToDarkMode(elements, core.lifecycle.getDarkColor);
5916
+ }
5860
5917
  };
5861
5918
  exports.transformColor = transformColor;
5862
- function transformToLightMode(element) {
5863
- ColorAttributeName.forEach(function (names) {
5864
- // Reset color styles based on the content of the ogsc/ogsb data element.
5865
- // If those data properties are empty or do not exist, set them anyway to clear the content.
5866
- element.style.setProperty(names[0 /* CssColor */], getValueOrDefault(element.dataset[names[2 /* CssDataSet */]], ''));
5867
- delete element.dataset[names[2 /* CssDataSet */]];
5868
- // Some elements might have set attribute colors. We need to reset these as well.
5869
- var value = element.dataset[names[3 /* HtmlDataSet */]];
5870
- if (getValueOrDefault(value, null)) {
5871
- element.setAttribute(names[1 /* HtmlColor */], value);
5872
- }
5873
- else {
5874
- element.removeAttribute(names[1 /* HtmlColor */]);
5875
- }
5876
- delete element.dataset[names[3 /* HtmlDataSet */]];
5919
+ function transformToLightMode(elements) {
5920
+ elements.forEach(function (element) {
5921
+ ColorAttributeName.forEach(function (names) {
5922
+ // Reset color styles based on the content of the ogsc/ogsb data element.
5923
+ // If those data properties are empty or do not exist, set them anyway to clear the content.
5924
+ element.style.setProperty(names[0 /* CssColor */], getValueOrDefault(element.dataset[names[2 /* CssDataSet */]], ''));
5925
+ delete element.dataset[names[2 /* CssDataSet */]];
5926
+ // Some elements might have set attribute colors. We need to reset these as well.
5927
+ var value = element.dataset[names[3 /* HtmlDataSet */]];
5928
+ if (getValueOrDefault(value, null)) {
5929
+ element.setAttribute(names[1 /* HtmlColor */], value);
5930
+ }
5931
+ else {
5932
+ element.removeAttribute(names[1 /* HtmlColor */]);
5933
+ }
5934
+ delete element.dataset[names[3 /* HtmlDataSet */]];
5935
+ });
5877
5936
  });
5878
5937
  }
5879
- function transformToDarkMode(element, getDarkColor) {
5880
- var computedValues = (0, roosterjs_editor_dom_1.getComputedStyles)(element, ['color', 'background-color']);
5881
- ColorAttributeName.forEach(function (names, index) {
5882
- var styleColor = element.style.getPropertyValue(names[0 /* CssColor */]);
5883
- var attrColor = element.getAttribute(names[1 /* HtmlColor */]);
5884
- if (!element.dataset[names[2 /* CssDataSet */]] &&
5885
- !element.dataset[names[3 /* HtmlDataSet */]] &&
5886
- (styleColor || attrColor) &&
5887
- styleColor != 'inherit' // For inherit style, no need to change it and let it keep inherit from parent element
5888
- ) {
5889
- var newColor = getDarkColor(computedValues[index] || styleColor || attrColor);
5938
+ function transformToDarkMode(elements, getDarkColor) {
5939
+ ColorAttributeName.forEach(function (names) {
5940
+ elements
5941
+ .map(function (element) {
5942
+ var styleColor = element.style.getPropertyValue(names[0 /* CssColor */]);
5943
+ var attrColor = element.getAttribute(names[1 /* HtmlColor */]);
5944
+ return !element.dataset[names[2 /* CssDataSet */]] &&
5945
+ !element.dataset[names[3 /* HtmlDataSet */]] &&
5946
+ (styleColor || attrColor) &&
5947
+ styleColor != 'inherit' // For inherit style, no need to change it and let it keep inherit from parent element
5948
+ ? {
5949
+ element: element,
5950
+ styleColor: styleColor,
5951
+ attrColor: attrColor,
5952
+ newColor: getDarkColor(styleColor || attrColor),
5953
+ }
5954
+ : null;
5955
+ })
5956
+ .filter(function (x) { return !!x; })
5957
+ .forEach(function (_a) {
5958
+ var element = _a.element, styleColor = _a.styleColor, attrColor = _a.attrColor, newColor = _a.newColor;
5890
5959
  element.style.setProperty(names[0 /* CssColor */], newColor, 'important');
5891
5960
  element.dataset[names[2 /* CssDataSet */]] = styleColor || '';
5892
5961
  if (attrColor) {
5893
5962
  element.setAttribute(names[1 /* HtmlColor */], newColor);
5894
5963
  element.dataset[names[3 /* HtmlDataSet */]] = attrColor;
5895
5964
  }
5896
- }
5965
+ });
5897
5966
  });
5898
5967
  }
5899
5968
  function getValueOrDefault(value, defaultValue) {
@@ -5912,7 +5981,14 @@ function getAll(rootNode, includeSelf) {
5912
5981
  var allChildren = rootNode.querySelectorAll('*');
5913
5982
  (0, roosterjs_editor_dom_1.arrayPush)(result, (0, roosterjs_editor_dom_1.toArray)(allChildren));
5914
5983
  }
5915
- return result;
5984
+ return result.filter(isHTMLElement);
5985
+ }
5986
+ // This is not a strict check, we just need to make sure this element has style so that we can set style to it
5987
+ // We don't use safeInstanceOf() here since this function will be called very frequently when extract html content
5988
+ // in dark mode, so we need to make sure this check is fast enough
5989
+ function isHTMLElement(element) {
5990
+ var htmlElement = element;
5991
+ return !!htmlElement.style && !!htmlElement.dataset;
5916
5992
  }
5917
5993
 
5918
5994
 
@@ -6043,7 +6119,6 @@ var CopyPastePlugin = /** @class */ (function () {
6043
6119
  var _this = this;
6044
6120
  var selection = this.editor.getSelectionRangeEx();
6045
6121
  if (selection && !selection.areAllCollapsed) {
6046
- var originalRange_1 = selection.ranges[0];
6047
6122
  var html = this.editor.getContent(2 /* RawHTMLWithSelection */);
6048
6123
  var tempDiv_1 = this.getTempDiv(true /*forceInLightMode*/);
6049
6124
  var newRange = (0, roosterjs_editor_dom_1.setHtmlWithSelectionPath)(tempDiv_1, html, this.editor.getTrustedHTMLHandler());
@@ -6057,7 +6132,7 @@ var CopyPastePlugin = /** @class */ (function () {
6057
6132
  isCut: isCut,
6058
6133
  });
6059
6134
  this.editor.runAsync(function (editor) {
6060
- _this.cleanUpAndRestoreSelection(tempDiv_1, originalRange_1, !isCut /* isCopy */);
6135
+ _this.cleanUpAndRestoreSelection(tempDiv_1, selection, !isCut /* isCopy */);
6061
6136
  if (isCut) {
6062
6137
  editor.addUndoSnapshot(function () {
6063
6138
  var position = _this.editor.deleteSelectedContent();
@@ -6086,15 +6161,35 @@ var CopyPastePlugin = /** @class */ (function () {
6086
6161
  return div;
6087
6162
  };
6088
6163
  CopyPastePlugin.prototype.cleanUpAndRestoreSelection = function (tempDiv, range, isCopy) {
6089
- if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6090
- range.collapse();
6164
+ var _a, _b;
6165
+ if (!!((_a = range) === null || _a === void 0 ? void 0 : _a.type)) {
6166
+ var selection = range;
6167
+ switch (selection.type) {
6168
+ case 1 /* TableSelection */:
6169
+ this.editor.select(selection.table, selection.coordinates);
6170
+ break;
6171
+ case 0 /* Normal */:
6172
+ var range_1 = (_b = selection.ranges) === null || _b === void 0 ? void 0 : _b[0];
6173
+ this.restoreRange(range_1, isCopy);
6174
+ break;
6175
+ }
6176
+ }
6177
+ else {
6178
+ this.restoreRange(range, isCopy);
6091
6179
  }
6092
- this.editor.select(range);
6093
6180
  tempDiv.style.backgroundColor = '';
6094
6181
  tempDiv.style.color = '';
6095
6182
  tempDiv.style.display = 'none';
6096
6183
  (0, roosterjs_editor_dom_1.moveChildNodes)(tempDiv);
6097
6184
  };
6185
+ CopyPastePlugin.prototype.restoreRange = function (range, isCopy) {
6186
+ if (range) {
6187
+ if (isCopy && roosterjs_editor_dom_1.Browser.isAndroid) {
6188
+ range.collapse();
6189
+ }
6190
+ this.editor.select(range);
6191
+ }
6192
+ };
6098
6193
  return CopyPastePlugin;
6099
6194
  }());
6100
6195
  exports.default = CopyPastePlugin;
@@ -7039,6 +7134,140 @@ var MouseUpPlugin = /** @class */ (function () {
7039
7134
  exports.default = MouseUpPlugin;
7040
7135
 
7041
7136
 
7137
+ /***/ }),
7138
+
7139
+ /***/ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts":
7140
+ /*!********************************************************************************!*\
7141
+ !*** ./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts ***!
7142
+ \********************************************************************************/
7143
+ /*! no static exports found */
7144
+ /***/ (function(module, exports, __webpack_require__) {
7145
+
7146
+ "use strict";
7147
+
7148
+ Object.defineProperty(exports, "__esModule", { value: true });
7149
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7150
+ /**
7151
+ * @internal
7152
+ * NormalizeTable plugin makes sure each table in editor has TBODY/THEAD/TFOOT tag around TR tags
7153
+ *
7154
+ * When we retrieve HTML content using innerHTML, browser will always add TBODY around TR nodes if there is not.
7155
+ * This causes some issue when we restore the HTML content with selection path since the selection path is
7156
+ * deeply coupled with DOM structure. So we need to always make sure there is already TBODY tag whenever
7157
+ * new table is inserted, to make sure the selection path we created is correct.
7158
+ */
7159
+ var NormalizeTablePlugin = /** @class */ (function () {
7160
+ function NormalizeTablePlugin() {
7161
+ }
7162
+ /**
7163
+ * Get a friendly name of this plugin
7164
+ */
7165
+ NormalizeTablePlugin.prototype.getName = function () {
7166
+ return 'NormalizeTable';
7167
+ };
7168
+ /**
7169
+ * The first method that editor will call to a plugin when editor is initializing.
7170
+ * It will pass in the editor instance, plugin should take this chance to save the
7171
+ * editor reference so that it can call to any editor method or format API later.
7172
+ * @param editor The editor object
7173
+ */
7174
+ NormalizeTablePlugin.prototype.initialize = function (editor) {
7175
+ this.editor = editor;
7176
+ };
7177
+ /**
7178
+ * The last method that editor will call to a plugin before it is disposed.
7179
+ * Plugin can take this chance to clear the reference to editor. After this method is
7180
+ * called, plugin should not call to any editor method since it will result in error.
7181
+ */
7182
+ NormalizeTablePlugin.prototype.dispose = function () {
7183
+ this.editor = null;
7184
+ };
7185
+ /**
7186
+ * Core method for a plugin. Once an event happens in editor, editor will call this
7187
+ * method of each plugin to handle the event as long as the event is not handled
7188
+ * exclusively by another plugin.
7189
+ * @param event The event to handle:
7190
+ */
7191
+ NormalizeTablePlugin.prototype.onPluginEvent = function (event) {
7192
+ switch (event.eventType) {
7193
+ case 11 /* EditorReady */:
7194
+ case 7 /* ContentChanged */:
7195
+ this.normalizeTables(this.editor.queryElements('table'));
7196
+ break;
7197
+ case 10 /* BeforePaste */:
7198
+ this.normalizeTables((0, roosterjs_editor_dom_1.toArray)(event.fragment.querySelectorAll('table')));
7199
+ break;
7200
+ case 5 /* MouseDown */:
7201
+ this.normalizeTableFromEvent(event.rawEvent);
7202
+ break;
7203
+ case 0 /* KeyDown */:
7204
+ if (event.rawEvent.shiftKey) {
7205
+ this.normalizeTableFromEvent(event.rawEvent);
7206
+ }
7207
+ break;
7208
+ }
7209
+ };
7210
+ NormalizeTablePlugin.prototype.normalizeTableFromEvent = function (event) {
7211
+ var table = this.editor.getElementAtCursor('table', event.target);
7212
+ if (table) {
7213
+ this.normalizeTables([table]);
7214
+ }
7215
+ };
7216
+ NormalizeTablePlugin.prototype.normalizeTables = function (tables) {
7217
+ if (tables.length > 0) {
7218
+ var rangeEx = this.editor.getSelectionRangeEx();
7219
+ 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;
7220
+ var isChanged = normalizeTables(tables);
7221
+ if (isChanged) {
7222
+ if (startContainer && endContainer) {
7223
+ this.editor.select(startContainer, startOffset, endContainer, endOffset);
7224
+ }
7225
+ else if ((rangeEx === null || rangeEx === void 0 ? void 0 : rangeEx.type) == 1 /* TableSelection */) {
7226
+ this.editor.select(rangeEx.table, rangeEx.coordinates);
7227
+ }
7228
+ }
7229
+ }
7230
+ };
7231
+ return NormalizeTablePlugin;
7232
+ }());
7233
+ exports.default = NormalizeTablePlugin;
7234
+ function normalizeTables(tables) {
7235
+ var isDOMChanged = false;
7236
+ tables.forEach(function (table) {
7237
+ var tbody = null;
7238
+ for (var child = table.firstChild; child; child = child.nextSibling) {
7239
+ var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(child);
7240
+ switch (tag) {
7241
+ case 'TR':
7242
+ if (!tbody) {
7243
+ tbody = table.ownerDocument.createElement('tbody');
7244
+ table.insertBefore(tbody, child);
7245
+ }
7246
+ tbody.appendChild(child);
7247
+ child = tbody;
7248
+ isDOMChanged = true;
7249
+ break;
7250
+ case 'TBODY':
7251
+ if (tbody) {
7252
+ (0, roosterjs_editor_dom_1.moveChildNodes)(tbody, child, true /*keepExistingChildren*/);
7253
+ child.parentNode.removeChild(child);
7254
+ child = tbody;
7255
+ isDOMChanged = true;
7256
+ }
7257
+ else {
7258
+ tbody = child;
7259
+ }
7260
+ break;
7261
+ default:
7262
+ tbody = null;
7263
+ break;
7264
+ }
7265
+ }
7266
+ });
7267
+ return isDOMChanged;
7268
+ }
7269
+
7270
+
7042
7271
  /***/ }),
7043
7272
 
7044
7273
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts":
@@ -7231,7 +7460,9 @@ var UndoPlugin = /** @class */ (function () {
7231
7460
  */
7232
7461
  function UndoPlugin(options) {
7233
7462
  this.state = {
7234
- snapshotsService: options.undoSnapshotService || createUndoSnapshots(),
7463
+ snapshotsService: options.undoMetadataSnapshotService ||
7464
+ createUndoSnapshotServiceBridge(options.undoSnapshotService) ||
7465
+ createUndoSnapshots(),
7235
7466
  isRestoring: false,
7236
7467
  hasNewContent: false,
7237
7468
  isNested: false,
@@ -7301,7 +7532,9 @@ var UndoPlugin = /** @class */ (function () {
7301
7532
  this.addUndoSnapshot();
7302
7533
  break;
7303
7534
  case 7 /* ContentChanged */:
7304
- if (!this.state.isRestoring) {
7535
+ if (!(this.state.isRestoring ||
7536
+ event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
7537
+ event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
7305
7538
  this.clearRedoForInput();
7306
7539
  }
7307
7540
  break;
@@ -7387,12 +7620,26 @@ function createUndoSnapshots() {
7387
7620
  canMove: function (delta) { return (0, roosterjs_editor_dom_1.canMoveCurrentSnapshot)(snapshots, delta); },
7388
7621
  move: function (delta) { return (0, roosterjs_editor_dom_1.moveCurrentSnapshot)(snapshots, delta); },
7389
7622
  addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7390
- return (0, roosterjs_editor_dom_1.addSnapshot)(snapshots, snapshot, isAutoCompleteSnapshot);
7623
+ return (0, roosterjs_editor_dom_1.addSnapshotV2)(snapshots, snapshot, isAutoCompleteSnapshot);
7391
7624
  },
7392
- clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshots)(snapshots); },
7625
+ clearRedo: function () { return (0, roosterjs_editor_dom_1.clearProceedingSnapshotsV2)(snapshots); },
7393
7626
  canUndoAutoComplete: function () { return (0, roosterjs_editor_dom_1.canUndoAutoComplete)(snapshots); },
7394
7627
  };
7395
7628
  }
7629
+ function createUndoSnapshotServiceBridge(service) {
7630
+ return service
7631
+ ? {
7632
+ canMove: function (delta) { return service.canMove(delta); },
7633
+ move: function (delta) { return ({ html: service.move(delta), metadata: null }); },
7634
+ addSnapshot: function (snapshot, isAutoCompleteSnapshot) {
7635
+ return service.addSnapshot(snapshot.html +
7636
+ (snapshot.metadata ? "<!--" + JSON.stringify(snapshot.metadata) + "-->" : ''), isAutoCompleteSnapshot);
7637
+ },
7638
+ clearRedo: function () { return service.clearRedo(); },
7639
+ canUndoAutoComplete: function () { return service.canUndoAutoComplete(); },
7640
+ }
7641
+ : undefined;
7642
+ }
7396
7643
 
7397
7644
 
7398
7645
  /***/ }),
@@ -7414,6 +7661,7 @@ var EditPlugin_1 = __webpack_require__(/*! ./EditPlugin */ "./packages/roosterjs
7414
7661
  var EntityPlugin_1 = __webpack_require__(/*! ./EntityPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/EntityPlugin.ts");
7415
7662
  var LifecyclePlugin_1 = __webpack_require__(/*! ./LifecyclePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/LifecyclePlugin.ts");
7416
7663
  var MouseUpPlugin_1 = __webpack_require__(/*! ./MouseUpPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/MouseUpPlugin.ts");
7664
+ var NormalizeTablePlugin_1 = __webpack_require__(/*! ./NormalizeTablePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/NormalizeTablePlugin.ts");
7417
7665
  var PendingFormatStatePlugin_1 = __webpack_require__(/*! ./PendingFormatStatePlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/PendingFormatStatePlugin.ts");
7418
7666
  var TypeInContainerPlugin_1 = __webpack_require__(/*! ./TypeInContainerPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/TypeInContainerPlugin.ts");
7419
7667
  var UndoPlugin_1 = __webpack_require__(/*! ./UndoPlugin */ "./packages/roosterjs-editor-core/lib/corePlugins/UndoPlugin.ts");
@@ -7438,6 +7686,7 @@ function createCorePlugins(contentDiv, options) {
7438
7686
  mouseUp: map.mouseUp || new MouseUpPlugin_1.default(),
7439
7687
  copyPaste: map.copyPaste || new CopyPastePlugin_1.default(options),
7440
7688
  entity: map.entity || new EntityPlugin_1.default(),
7689
+ normalizeTable: map.normalizeTable || new NormalizeTablePlugin_1.default(),
7441
7690
  lifecycle: map.lifecycle || new LifecyclePlugin_1.default(options, contentDiv),
7442
7691
  };
7443
7692
  }
@@ -8094,12 +8343,13 @@ var Editor = /** @class */ (function () {
8094
8343
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
8095
8344
  */
8096
8345
  Editor.prototype.setDarkModeState = function (nextDarkMode) {
8097
- if (this.isDarkMode() == nextDarkMode) {
8346
+ if (this.isDarkMode() == !!nextDarkMode) {
8098
8347
  return;
8099
8348
  }
8100
- var currentContent = this.getContent(0 /* CleanHTML */);
8349
+ this.core.api.transformColor(this.core, this.core.contentDiv, false /*includeSelf*/, null /*callback*/, nextDarkMode
8350
+ ? 0 /* LightToDark */
8351
+ : 1 /* DarkToLight */, true /*forceTransform*/);
8101
8352
  this.triggerContentChangedEvent(nextDarkMode ? "SwitchToDarkMode" /* SwitchToDarkMode */ : "SwitchToLightMode" /* SwitchToLightMode */);
8102
- this.setContent(currentContent);
8103
8353
  };
8104
8354
  /**
8105
8355
  * Check if the editor is in dark mode
@@ -8108,6 +8358,13 @@ var Editor = /** @class */ (function () {
8108
8358
  Editor.prototype.isDarkMode = function () {
8109
8359
  return this.core.lifecycle.isDarkMode;
8110
8360
  };
8361
+ /**
8362
+ * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
8363
+ * @param node The node to transform
8364
+ */
8365
+ Editor.prototype.transformToDarkColor = function (node) {
8366
+ this.core.api.transformColor(this.core, node, true /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
8367
+ };
8111
8368
  /**
8112
8369
  * Make the editor in "Shadow Edit" mode.
8113
8370
  * In Shadow Edit mode, all format change will finally be ignored.
@@ -8272,7 +8529,8 @@ var NodeBlockElement = /** @class */ (function () {
8272
8529
  * Get the text content of this block element
8273
8530
  */
8274
8531
  NodeBlockElement.prototype.getTextContent = function () {
8275
- return this.element ? this.element.textContent : '';
8532
+ var _a;
8533
+ return ((_a = this.element) === null || _a === void 0 ? void 0 : _a.textContent) || '';
8276
8534
  };
8277
8535
  return NodeBlockElement;
8278
8536
  }());
@@ -8316,10 +8574,11 @@ var StartEndBlockElement = /** @class */ (function () {
8316
8574
  this.endNode = endNode;
8317
8575
  }
8318
8576
  StartEndBlockElement.getBlockContext = function (node) {
8319
- while (node && !(0, isBlockElement_1.default)(node)) {
8320
- node = node.parentNode;
8577
+ var currentNode = node;
8578
+ while (currentNode && !(0, isBlockElement_1.default)(currentNode)) {
8579
+ currentNode = currentNode.parentNode;
8321
8580
  }
8322
- return node;
8581
+ return currentNode;
8323
8582
  };
8324
8583
  /**
8325
8584
  * Collapse this element to a single DOM element.
@@ -8327,7 +8586,10 @@ var StartEndBlockElement = /** @class */ (function () {
8327
8586
  * If the content nodes are included in root node with other nodes, split root node
8328
8587
  */
8329
8588
  StartEndBlockElement.prototype.collapseToSingleElement = function () {
8330
- var nodes = (0, collapseNodes_1.default)(StartEndBlockElement.getBlockContext(this.startNode), this.startNode, this.endNode, true /*canSplitParent*/);
8589
+ var nodeContext = StartEndBlockElement.getBlockContext(this.startNode);
8590
+ var nodes = nodeContext
8591
+ ? (0, collapseNodes_1.default)(nodeContext, this.startNode, this.endNode, true /*canSplitParent*/)
8592
+ : [];
8331
8593
  var blockContext = StartEndBlockElement.getBlockContext(this.startNode);
8332
8594
  while (nodes[0] &&
8333
8595
  nodes[0] != blockContext &&
@@ -8435,7 +8697,10 @@ function getBlockElementAtNode(rootNode, node) {
8435
8697
  // NOTE: this container block could be just the rootNode,
8436
8698
  // which cannot be used to create block element. We will special case handle it later on
8437
8699
  var containerBlockNode = StartEndBlockElement_1.default.getBlockContext(node);
8438
- if (containerBlockNode == node) {
8700
+ if (!containerBlockNode) {
8701
+ return null;
8702
+ }
8703
+ else if (containerBlockNode == node) {
8439
8704
  return new NodeBlockElement_1.default(containerBlockNode);
8440
8705
  }
8441
8706
  // Find the head and leaf node in the block
@@ -8465,7 +8730,7 @@ function getBlockElementAtNode(rootNode, node) {
8465
8730
  }
8466
8731
  break;
8467
8732
  }
8468
- else if (parentNode != rootNode) {
8733
+ else if (parentNode && parentNode != rootNode) {
8469
8734
  // Continue collapsing to parent
8470
8735
  headNode = tailNode = parentNode;
8471
8736
  }
@@ -8495,7 +8760,7 @@ function findHeadTailLeafNode(node, containerBlockNode, isTail) {
8495
8760
  }
8496
8761
  while (result) {
8497
8762
  var sibling = node;
8498
- while (!(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8763
+ while (node.parentNode && !(sibling = isTail ? node.nextSibling : node.previousSibling)) {
8499
8764
  node = node.parentNode;
8500
8765
  if (node == containerBlockNode) {
8501
8766
  return result;
@@ -8541,7 +8806,7 @@ function getFirstLastBlockElement(rootNode, isFirst) {
8541
8806
  do {
8542
8807
  node = node && (isFirst ? node.firstChild : node.lastChild);
8543
8808
  } while (node && node.firstChild);
8544
- return node && (0, getBlockElementAtNode_1.default)(rootNode, node);
8809
+ return (node && (0, getBlockElementAtNode_1.default)(rootNode, node)) || null;
8545
8810
  }
8546
8811
  exports.default = getFirstLastBlockElement;
8547
8812
 
@@ -8652,6 +8917,7 @@ function extractClipboardItems(items, options) {
8652
8917
  types: [],
8653
8918
  text: '',
8654
8919
  image: null,
8920
+ files: [],
8655
8921
  rawHtml: null,
8656
8922
  customValues: {},
8657
8923
  };
@@ -8676,6 +8942,16 @@ function extractClipboardItems(items, options) {
8676
8942
  }
8677
8943
  });
8678
8944
  }
8945
+ else if (item.kind == 'file') {
8946
+ return new Promise(function (resolve) {
8947
+ var file = item.getAsFile();
8948
+ if (!!file) {
8949
+ data.types.push(type);
8950
+ data.files.push(file);
8951
+ }
8952
+ resolve();
8953
+ });
8954
+ }
8679
8955
  else {
8680
8956
  var customType_1 = getAllowedCustomType(type, options === null || options === void 0 ? void 0 : options.allowedCustomPasteType);
8681
8957
  var handler_1 = contentHandlers[type] || (customType_1 ? contentHandlers[OTHER_TEXT_TYPE] : null);
@@ -8756,6 +9032,7 @@ function extractClipboardItemsForIE(dataTransfer, callback, options) {
8756
9032
  types: dataTransfer.types ? (0, toArray_1.default)(dataTransfer.types) : [],
8757
9033
  text: dataTransfer.getData('text'),
8758
9034
  image: null,
9035
+ files: [],
8759
9036
  rawHtml: null,
8760
9037
  customValues: {},
8761
9038
  };
@@ -8897,6 +9174,8 @@ var ContentTraverser = /** @class */ (function () {
8897
9174
  function ContentTraverser(scoper, skipTags) {
8898
9175
  this.scoper = scoper;
8899
9176
  this.skipTags = skipTags;
9177
+ this.currentInline = null;
9178
+ this.currentBlock = null;
8900
9179
  }
8901
9180
  /**
8902
9181
  * Create a content traverser for the whole body of given root node
@@ -9087,8 +9366,20 @@ var PositionContentSearcher = /** @class */ (function () {
9087
9366
  this.position = position;
9088
9367
  // The cached text before position that has been read so far
9089
9368
  this.text = '';
9369
+ // The cached word before position
9370
+ this.word = '';
9371
+ // The inline element before position
9372
+ this.inlineBefore = null;
9373
+ // The inline element after position
9374
+ this.inlineAfter = null;
9375
+ // The content traverser used to traverse backwards
9376
+ this.traverser = null;
9377
+ // Backward parsing has completed
9378
+ this.traversingComplete = false;
9090
9379
  // All inline elements before position that have been read so far
9091
9380
  this.inlineElements = [];
9381
+ // First non-text inline before position
9382
+ this.nearestNonTextInlineElement = null;
9092
9383
  }
9093
9384
  /**
9094
9385
  * Get the word before position. The word is determined by scanning backwards till the first white space, the portion
@@ -9100,7 +9391,7 @@ var PositionContentSearcher = /** @class */ (function () {
9100
9391
  if (!this.word) {
9101
9392
  this.traverse(function () { return _this.word; });
9102
9393
  }
9103
- return this.word;
9394
+ return this.word || '';
9104
9395
  };
9105
9396
  /**
9106
9397
  * Get the inline element before position
@@ -9147,8 +9438,8 @@ var PositionContentSearcher = /** @class */ (function () {
9147
9438
  if (!text) {
9148
9439
  return null;
9149
9440
  }
9150
- var startPosition;
9151
- var endPosition;
9441
+ var startPosition = null;
9442
+ var endPosition = null;
9152
9443
  var textIndex = text.length - 1;
9153
9444
  this.forEachTextInlineElement(function (textInline) {
9154
9445
  var nodeContent = textInline.getTextContent() || '';
@@ -9389,6 +9680,8 @@ var SelectionScoper = /** @class */ (function () {
9389
9680
  */
9390
9681
  function SelectionScoper(rootNode, range) {
9391
9682
  this.rootNode = rootNode;
9683
+ this.startBlock = null;
9684
+ this.startInline = null;
9392
9685
  this.start = Position_1.default.getStart(range).normalize();
9393
9686
  this.end = Position_1.default.getEnd(range).normalize();
9394
9687
  }
@@ -9421,7 +9714,7 @@ var SelectionScoper = /** @class */ (function () {
9421
9714
  var inScope = false;
9422
9715
  var selStartBlock = this.getStartBlockElement();
9423
9716
  if (this.start.equalTo(this.end)) {
9424
- inScope = selStartBlock && selStartBlock.equals(block);
9717
+ inScope = !!selStartBlock && selStartBlock.equals(block);
9425
9718
  }
9426
9719
  else {
9427
9720
  var selEndBlock = (0, getBlockElementAtNode_1.default)(this.rootNode, this.end.node);
@@ -9430,8 +9723,8 @@ var SelectionScoper = /** @class */ (function () {
9430
9723
  // 2) The end of selection falls on the block
9431
9724
  // 3) the block falls in-between selection start and end
9432
9725
  inScope =
9433
- selStartBlock &&
9434
- selEndBlock &&
9726
+ !!selStartBlock &&
9727
+ !!selEndBlock &&
9435
9728
  (block.equals(selStartBlock) ||
9436
9729
  block.equals(selEndBlock) ||
9437
9730
  (block.isAfter(selStartBlock) && selEndBlock.isAfter(block)));
@@ -9466,7 +9759,7 @@ var SelectionScoper = /** @class */ (function () {
9466
9759
  return start.isAfter(end) || start.equalTo(end)
9467
9760
  ? null
9468
9761
  : startPartial || endPartial
9469
- ? new PartialInlineElement_1.default(inline, startPartial && start, endPartial && end)
9762
+ ? new PartialInlineElement_1.default(inline, startPartial ? start : undefined, endPartial ? end : undefined)
9470
9763
  : inline;
9471
9764
  };
9472
9765
  return SelectionScoper;
@@ -10579,7 +10872,6 @@ var HTML_TAG_REPLACEMENT = {
10579
10872
  table: '*',
10580
10873
  tbody: '*',
10581
10874
  td: '*',
10582
- template: '*',
10583
10875
  textarea: '*',
10584
10876
  tfoot: '*',
10585
10877
  th: '*',
@@ -10612,6 +10904,7 @@ var HTML_TAG_REPLACEMENT = {
10612
10904
  slot: null,
10613
10905
  source: null,
10614
10906
  style: null,
10907
+ template: null,
10615
10908
  title: null,
10616
10909
  track: null,
10617
10910
  video: null,
@@ -10842,7 +11135,7 @@ exports.default = getPredefinedCssForElement;
10842
11135
 
10843
11136
  Object.defineProperty(exports, "__esModule", { value: true });
10844
11137
  exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.toArray = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.arrayPush = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
10845
- exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.VTable = exports.moveChildNodes = void 0;
11138
+ exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.moveChildNodes = void 0;
10846
11139
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
10847
11140
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
10848
11141
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -10940,6 +11233,8 @@ var moveChildNodes_1 = __webpack_require__(/*! ./utils/moveChildNodes */ "./pack
10940
11233
  Object.defineProperty(exports, "moveChildNodes", { enumerable: true, get: function () { return moveChildNodes_1.default; } });
10941
11234
  var VTable_1 = __webpack_require__(/*! ./table/VTable */ "./packages/roosterjs-editor-dom/lib/table/VTable.ts");
10942
11235
  Object.defineProperty(exports, "VTable", { enumerable: true, get: function () { return VTable_1.default; } });
11236
+ var isWholeTableSelected_1 = __webpack_require__(/*! ./table/isWholeTableSelected */ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts");
11237
+ Object.defineProperty(exports, "isWholeTableSelected", { enumerable: true, get: function () { return isWholeTableSelected_1.default; } });
10943
11238
  var VList_1 = __webpack_require__(/*! ./list/VList */ "./packages/roosterjs-editor-dom/lib/list/VList.ts");
10944
11239
  Object.defineProperty(exports, "VList", { enumerable: true, get: function () { return VList_1.default; } });
10945
11240
  var VListItem_1 = __webpack_require__(/*! ./list/VListItem */ "./packages/roosterjs-editor-dom/lib/list/VListItem.ts");
@@ -10976,14 +11271,17 @@ var getHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/getHtmlWith
10976
11271
  Object.defineProperty(exports, "getHtmlWithSelectionPath", { enumerable: true, get: function () { return getHtmlWithSelectionPath_1.default; } });
10977
11272
  var setHtmlWithSelectionPath_1 = __webpack_require__(/*! ./selection/setHtmlWithSelectionPath */ "./packages/roosterjs-editor-dom/lib/selection/setHtmlWithSelectionPath.ts");
10978
11273
  Object.defineProperty(exports, "setHtmlWithSelectionPath", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.default; } });
11274
+ Object.defineProperty(exports, "setHtmlWithMetadata", { enumerable: true, get: function () { return setHtmlWithSelectionPath_1.setHtmlWithMetadata; } });
10979
11275
  var addRangeToSelection_1 = __webpack_require__(/*! ./selection/addRangeToSelection */ "./packages/roosterjs-editor-dom/lib/selection/addRangeToSelection.ts");
10980
11276
  Object.defineProperty(exports, "addRangeToSelection", { enumerable: true, get: function () { return addRangeToSelection_1.default; } });
10981
11277
  var addSnapshot_1 = __webpack_require__(/*! ./snapshots/addSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/addSnapshot.ts");
10982
11278
  Object.defineProperty(exports, "addSnapshot", { enumerable: true, get: function () { return addSnapshot_1.default; } });
11279
+ Object.defineProperty(exports, "addSnapshotV2", { enumerable: true, get: function () { return addSnapshot_1.addSnapshotV2; } });
10983
11280
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
10984
11281
  Object.defineProperty(exports, "canMoveCurrentSnapshot", { enumerable: true, get: function () { return canMoveCurrentSnapshot_1.default; } });
10985
11282
  var clearProceedingSnapshots_1 = __webpack_require__(/*! ./snapshots/clearProceedingSnapshots */ "./packages/roosterjs-editor-dom/lib/snapshots/clearProceedingSnapshots.ts");
10986
11283
  Object.defineProperty(exports, "clearProceedingSnapshots", { enumerable: true, get: function () { return clearProceedingSnapshots_1.default; } });
11284
+ Object.defineProperty(exports, "clearProceedingSnapshotsV2", { enumerable: true, get: function () { return clearProceedingSnapshots_1.clearProceedingSnapshotsV2; } });
10987
11285
  var moveCurrentSnapshot_1 = __webpack_require__(/*! ./snapshots/moveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/moveCurrentSnapshot.ts");
10988
11286
  Object.defineProperty(exports, "moveCurrentSnapshot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.default; } });
10989
11287
  Object.defineProperty(exports, "moveCurrentSnapsnot", { enumerable: true, get: function () { return moveCurrentSnapshot_1.moveCurrentSnapsnot; } });
@@ -11220,9 +11518,9 @@ var NodeInlineElement = /** @class */ (function () {
11220
11518
  */
11221
11519
  NodeInlineElement.prototype.getTextContent = function () {
11222
11520
  // nodeValue is better way to retrieve content for a text. Others, just use textContent
11223
- return this.containerNode.nodeType == 3 /* Text */
11521
+ return ((this.containerNode.nodeType == 3 /* Text */
11224
11522
  ? this.containerNode.nodeValue
11225
- : this.containerNode.textContent;
11523
+ : this.containerNode.textContent) || '');
11226
11524
  };
11227
11525
  /**
11228
11526
  * Get the container node
@@ -11306,6 +11604,8 @@ var getLeafSibling_1 = __webpack_require__(/*! ../utils/getLeafSibling */ "./pac
11306
11604
  */
11307
11605
  var PartialInlineElement = /** @class */ (function () {
11308
11606
  function PartialInlineElement(inlineElement, start, end) {
11607
+ if (start === void 0) { start = null; }
11608
+ if (end === void 0) { end = null; }
11309
11609
  this.inlineElement = inlineElement;
11310
11610
  this.start = start;
11311
11611
  this.end = end;
@@ -11352,7 +11652,7 @@ var PartialInlineElement = /** @class */ (function () {
11352
11652
  * Get next partial inline element if it is not at the end boundary yet
11353
11653
  */
11354
11654
  get: function () {
11355
- return this.end && new PartialInlineElement(this.inlineElement, this.end, null);
11655
+ return this.end ? new PartialInlineElement(this.inlineElement, this.end) : null;
11356
11656
  },
11357
11657
  enumerable: false,
11358
11658
  configurable: true
@@ -11362,7 +11662,9 @@ var PartialInlineElement = /** @class */ (function () {
11362
11662
  * Get previous partial inline element if it is not at the begin boundary yet
11363
11663
  */
11364
11664
  get: function () {
11365
- return this.start && new PartialInlineElement(this.inlineElement, null, this.start);
11665
+ return this.start
11666
+ ? new PartialInlineElement(this.inlineElement, undefined, this.start)
11667
+ : null;
11366
11668
  },
11367
11669
  enumerable: false,
11368
11670
  configurable: true
@@ -11402,7 +11704,7 @@ var PartialInlineElement = /** @class */ (function () {
11402
11704
  var previousNode = (0, getLeafSibling_1.getPreviousLeafSibling)(container, to.node);
11403
11705
  to = previousNode ? new Position_1.default(previousNode, -1 /* End */) : null;
11404
11706
  }
11405
- (0, applyTextStyle_1.default)(container, styler, from, to);
11707
+ (0, applyTextStyle_1.default)(container, styler, from || undefined, to || undefined);
11406
11708
  };
11407
11709
  return PartialInlineElement;
11408
11710
  }());
@@ -11432,35 +11734,39 @@ var STYLET_AGS = 'SPAN,B,I,U,EM,STRONG,STRIKE,S,SMALL'.split(',');
11432
11734
  * Apply style using a styler function to the given container node in the given range
11433
11735
  * @param container The container node to apply style to
11434
11736
  * @param styler The styler function
11435
- * @param from From position
11436
- * @param to To position
11737
+ * @param fromPosition From position
11738
+ * @param toPosition To position
11437
11739
  */
11438
11740
  function applyTextStyle(container, styler, from, to) {
11439
11741
  if (from === void 0) { from = new Position_1.default(container, 0 /* Begin */).normalize(); }
11440
11742
  if (to === void 0) { to = new Position_1.default(container, -1 /* End */).normalize(); }
11441
11743
  var formatNodes = [];
11442
- while (from && to && to.isAfter(from)) {
11443
- var formatNode = from.node;
11744
+ var fromPosition = from;
11745
+ var toPosition = to;
11746
+ while (fromPosition && toPosition && toPosition.isAfter(fromPosition)) {
11747
+ var formatNode = fromPosition.node;
11444
11748
  var parentTag = (0, getTagOfNode_1.default)(formatNode.parentNode);
11445
11749
  // The code below modifies DOM. Need to get the next sibling first otherwise you won't be able to reliably get a good next sibling node
11446
11750
  var nextNode = (0, getLeafSibling_1.getNextLeafSibling)(container, formatNode);
11447
11751
  if (formatNode.nodeType == 3 /* Text */ && ['TR', 'TABLE'].indexOf(parentTag) < 0) {
11448
- if (formatNode == to.node && !to.isAtEnd) {
11449
- formatNode = (0, splitTextNode_1.default)(formatNode, to.offset, true /*returnFirstPart*/);
11752
+ if (formatNode == toPosition.node && !toPosition.isAtEnd) {
11753
+ formatNode = (0, splitTextNode_1.default)(formatNode, toPosition.offset, true /*returnFirstPart*/);
11450
11754
  }
11451
- if (from.offset > 0) {
11452
- formatNode = (0, splitTextNode_1.default)(formatNode, from.offset, false /*returnFirstPart*/);
11755
+ if (fromPosition.offset > 0) {
11756
+ formatNode = (0, splitTextNode_1.default)(formatNode, fromPosition.offset, false /*returnFirstPart*/);
11453
11757
  }
11454
11758
  formatNodes.push(formatNode);
11455
11759
  }
11456
- from = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11760
+ fromPosition = nextNode && new Position_1.default(nextNode, 0 /* Begin */);
11457
11761
  }
11458
11762
  if (formatNodes.length > 0) {
11459
11763
  if (formatNodes.every(function (node) { return node.parentNode == formatNodes[0].parentNode; })) {
11460
11764
  var newNode_1 = formatNodes.shift();
11461
11765
  formatNodes.forEach(function (node) {
11462
- newNode_1.nodeValue += node.nodeValue;
11463
- node.parentNode.removeChild(node);
11766
+ var _a;
11767
+ var newNodeValue = (newNode_1.nodeValue || '') + (node.nodeValue || '');
11768
+ newNode_1.nodeValue = newNodeValue;
11769
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
11464
11770
  });
11465
11771
  formatNodes = [newNode_1];
11466
11772
  }
@@ -11629,7 +11935,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11629
11935
  return null;
11630
11936
  }
11631
11937
  position = position.normalize();
11632
- var node = position.node, offset = position.offset, isAtEnd = position.isAtEnd;
11938
+ var offset = position.offset, isAtEnd = position.isAtEnd;
11939
+ var node = position.node;
11633
11940
  var isPartial = false;
11634
11941
  if ((!isAfter && offset == 0 && !isAtEnd) || (isAfter && isAtEnd)) {
11635
11942
  node = (0, getLeafSibling_1.getLeafSibling)(root, node, isAfter);
@@ -11644,8 +11951,8 @@ function getInlineElementBeforeAfter(root, position, isAfter) {
11644
11951
  var inlineElement = (0, getInlineElementAtNode_1.default)(root, node);
11645
11952
  if (inlineElement && (isPartial || inlineElement.contains(position))) {
11646
11953
  inlineElement = isAfter
11647
- ? new PartialInlineElement_1.default(inlineElement, position, null)
11648
- : new PartialInlineElement_1.default(inlineElement, null, position);
11954
+ ? new PartialInlineElement_1.default(inlineElement, position, undefined)
11955
+ : new PartialInlineElement_1.default(inlineElement, undefined, position);
11649
11956
  }
11650
11957
  return inlineElement;
11651
11958
  }
@@ -11883,14 +12190,23 @@ var VList = /** @class */ (function () {
11883
12190
  }
11884
12191
  }
11885
12192
  };
11886
- VList.prototype.setIndentation = function (start, end, indentation, softOutdent) {
12193
+ VList.prototype.setIndentation = function (start, end, indentation, softOutdent, preventItemRemoval) {
12194
+ var _this = this;
12195
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12196
+ var shouldAddMargin = false;
11887
12197
  this.findListItems(start, end, function (item) {
11888
- return indentation == 1 /* Decrease */
12198
+ shouldAddMargin = shouldAddMargin || _this.items.indexOf(item) == 0;
12199
+ indentation == 1 /* Decrease */
11889
12200
  ? softOutdent && !item.isDummy()
11890
12201
  ? item.setIsDummy(true /*isDummy*/)
11891
- : item.outdent()
12202
+ : item.outdent(preventItemRemoval)
11892
12203
  : item.indent();
11893
12204
  });
12205
+ if (shouldAddMargin && preventItemRemoval) {
12206
+ for (var index = 0; index < this.items.length; index++) {
12207
+ this.items[index].addNegativeMargins();
12208
+ }
12209
+ }
11894
12210
  };
11895
12211
  /**
11896
12212
  * Change list type of the given range of this list.
@@ -11944,16 +12260,33 @@ var VList = /** @class */ (function () {
11944
12260
  };
11945
12261
  /**
11946
12262
  * Get the index of the List Item in the current List
12263
+ * If the root list is:
12264
+ * Ordered list, the listIndex start count is going to be the start property of the OL - 1,
12265
+ * @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
12266
+ * * ```html
12267
+ * <ol start="5">
12268
+ * <li>item 1</li>
12269
+ * <li>item 2</li> <!-- Node to find -->
12270
+ * <li>item 3</li>
12271
+ * </ol>
12272
+ * ```
12273
+ * Unordered list, the listIndex start count starts from 0
12274
+ * @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
12275
+ * ```html
12276
+ * <ul>
12277
+ * <li>item 1</li>
12278
+ * <li>item 2</li> <!-- Node to find -->
12279
+ * <li>item 3</li>
12280
+ * </ul>
12281
+ * ```
11947
12282
  * @param input List item to find in the root list
11948
12283
  */
11949
12284
  VList.prototype.getListItemIndex = function (input) {
11950
12285
  if (this.items) {
11951
- var listIndex = this.getStart() - 1;
12286
+ var listIndex = (this.getStart() || 1) - 1;
11952
12287
  for (var index = 0; index < this.items.length; index++) {
11953
12288
  var child = this.items[index];
11954
- if (child.getListType() == 1 /* Ordered */ &&
11955
- child.getLevel() == 1 &&
11956
- !child.isDummy()) {
12289
+ if (child.getLevel() == 1 && !child.isDummy()) {
11957
12290
  listIndex++;
11958
12291
  }
11959
12292
  if (child.getNode() == input) {
@@ -12234,6 +12567,8 @@ var toArray_1 = __webpack_require__(/*! ../utils/toArray */ "./packages/roosterj
12234
12567
  var unwrap_1 = __webpack_require__(/*! ../utils/unwrap */ "./packages/roosterjs-editor-dom/lib/utils/unwrap.ts");
12235
12568
  var wrap_1 = __webpack_require__(/*! ../utils/wrap */ "./packages/roosterjs-editor-dom/lib/utils/wrap.ts");
12236
12569
  var orderListStyles = [null, 'lower-alpha', 'lower-roman'];
12570
+ var MARGIN_BASE = '0in 0in 0in 0.5in';
12571
+ var NEGATIVE_MARGIN = '-.25in';
12237
12572
  /**
12238
12573
  * !!! Never directly create instance of this class. It should be created within VList class !!!
12239
12574
  *
@@ -12335,6 +12670,11 @@ var VListItem = /** @class */ (function () {
12335
12670
  * If this is not an list item, it will be no op
12336
12671
  */
12337
12672
  VListItem.prototype.indent = function () {
12673
+ if (this.node.style.marginLeft == NEGATIVE_MARGIN) {
12674
+ this.node.style.margin = '';
12675
+ this.node.style.marginLeft = '';
12676
+ return;
12677
+ }
12338
12678
  var listType = this.getListType();
12339
12679
  if (listType != 0 /* None */) {
12340
12680
  this.listTypes.push(listType);
@@ -12343,12 +12683,22 @@ var VListItem = /** @class */ (function () {
12343
12683
  /**
12344
12684
  * Outdent this item
12345
12685
  * If this item is already not an list item, it will be no op
12686
+ * @param preventItemRemoval Whether prevent the list item to be removed for the listItem by default false
12346
12687
  */
12347
- VListItem.prototype.outdent = function () {
12348
- if (this.listTypes.length > 1) {
12688
+ VListItem.prototype.outdent = function (preventItemRemoval) {
12689
+ if (preventItemRemoval === void 0) { preventItemRemoval = false; }
12690
+ var expectedLength = preventItemRemoval ? 2 : 1;
12691
+ if (this.listTypes.length > expectedLength) {
12349
12692
  this.listTypes.pop();
12350
12693
  }
12351
12694
  };
12695
+ /**
12696
+ * Add negative margin to the List item
12697
+ */
12698
+ VListItem.prototype.addNegativeMargins = function () {
12699
+ this.node.style.margin = MARGIN_BASE;
12700
+ this.node.style.marginLeft = NEGATIVE_MARGIN;
12701
+ };
12352
12702
  /**
12353
12703
  * Change list type of this item
12354
12704
  * @param targetType The target list type to change to
@@ -12884,7 +13234,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12884
13234
  var children = boundary.children, innerNode = boundary.innerNode;
12885
13235
  var regions = [];
12886
13236
  if (children.length == 0) {
12887
- regions.push(creator(innerNode));
13237
+ var region = creator(innerNode);
13238
+ if (region) {
13239
+ regions.push(region);
13240
+ }
12888
13241
  }
12889
13242
  else {
12890
13243
  // Need to run one more time to add region after all children
@@ -12892,7 +13245,10 @@ function iterateNodes(creator, boundary, start, end, started) {
12892
13245
  var _b = children[i] || {}, outerNode = _b.outerNode, boundaries = _b.boundaries;
12893
13246
  var previousOuterNode = (_a = children[i - 1]) === null || _a === void 0 ? void 0 : _a.outerNode;
12894
13247
  if (started) {
12895
- regions.push(creator(innerNode, previousOuterNode, outerNode));
13248
+ var region = creator(innerNode, previousOuterNode, outerNode);
13249
+ if (region) {
13250
+ regions.push(region);
13251
+ }
12896
13252
  }
12897
13253
  boundaries === null || boundaries === void 0 ? void 0 : boundaries.forEach(function (child) {
12898
13254
  var _a;
@@ -12985,7 +13341,10 @@ function getSelectedBlockElementsInRegion(regionBase, createBlockIfEmpty) {
12985
13341
  if (blocks.length == 0 && regionBase && !regionBase.rootNode.firstChild && createBlockIfEmpty) {
12986
13342
  var newNode = (0, createElement_1.default)(1 /* EmptyLine */, regionBase.rootNode.ownerDocument);
12987
13343
  regionBase.rootNode.appendChild(newNode);
12988
- blocks.push((0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode));
13344
+ var block = (0, getBlockElementAtNode_1.default)(regionBase.rootNode, newNode);
13345
+ if (block) {
13346
+ blocks.push(block);
13347
+ }
12989
13348
  }
12990
13349
  return blocks;
12991
13350
  }
@@ -13039,10 +13398,8 @@ function getSelectionRangeInRegion(regionBase) {
13039
13398
  var end = fullSelectionEnd.isAfter(regionEnd) ? regionEnd : fullSelectionEnd;
13040
13399
  return (0, createRange_1.default)(start, end);
13041
13400
  }
13042
- else {
13043
- return null;
13044
- }
13045
13401
  }
13402
+ return null;
13046
13403
  }
13047
13404
  exports.default = getSelectionRangeInRegion;
13048
13405
  function isRegion(regionBase) {
@@ -13119,7 +13476,7 @@ var collapseNodes_1 = __webpack_require__(/*! ../utils/collapseNodes */ "./packa
13119
13476
  * @param targetNode The node of target block element
13120
13477
  */
13121
13478
  function mergeBlocksInRegion(region, refNode, targetNode) {
13122
- var _a, _b;
13479
+ var _a, _b, _c;
13123
13480
  var block;
13124
13481
  if (!(0, isNodeInRegion_1.default)(region, refNode) ||
13125
13482
  !(0, isNodeInRegion_1.default)(region, targetNode) ||
@@ -13143,13 +13500,13 @@ function mergeBlocksInRegion(region, refNode, targetNode) {
13143
13500
  ? blockRoot.firstChild
13144
13501
  : (0, changeElementTag_1.default)(blockRoot, 'SPAN');
13145
13502
  // Remove empty node
13146
- for (var node = nodeToMerge; (0, contains_1.default)(commonContainer, node) && node.parentNode.childNodes.length == 1; node = node.parentNode) {
13503
+ for (var node = nodeToMerge; (0, contains_1.default)(commonContainer, node) && ((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.childNodes.length) == 1; node = node.parentNode) {
13147
13504
  // If the only child is the one which is about to be removed, this node should also be removed
13148
13505
  nodeToRemove = node.parentNode;
13149
13506
  }
13150
13507
  // Finally, merge blocks, and remove empty nodes
13151
- (_a = refNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(nodeToMerge, refNode.nextSibling);
13152
- (_b = nodeToRemove === null || nodeToRemove === void 0 ? void 0 : nodeToRemove.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(nodeToRemove);
13508
+ (_b = refNode.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(nodeToMerge, refNode.nextSibling);
13509
+ (_c = nodeToRemove === null || nodeToRemove === void 0 ? void 0 : nodeToRemove.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(nodeToRemove);
13153
13510
  }
13154
13511
  exports.default = mergeBlocksInRegion;
13155
13512
 
@@ -13463,8 +13820,6 @@ function getPositionFromPath(node, path) {
13463
13820
  Object.defineProperty(exports, "__esModule", { value: true });
13464
13821
  var getInnerHTML_1 = __webpack_require__(/*! ../utils/getInnerHTML */ "./packages/roosterjs-editor-dom/lib/utils/getInnerHTML.ts");
13465
13822
  var getSelectionPath_1 = __webpack_require__(/*! ./getSelectionPath */ "./packages/roosterjs-editor-dom/lib/selection/getSelectionPath.ts");
13466
- var getTagOfNode_1 = __webpack_require__(/*! ../utils/getTagOfNode */ "./packages/roosterjs-editor-dom/lib/utils/getTagOfNode.ts");
13467
- var queryElements_1 = __webpack_require__(/*! ../utils/queryElements */ "./packages/roosterjs-editor-dom/lib/utils/queryElements.ts");
13468
13823
  /**
13469
13824
  * Get inner Html of a root node with a selection path which can be used for restore selection.
13470
13825
  * The result string can be used by setHtmlWithSelectionPath() to restore the HTML and selection.
@@ -13476,32 +13831,6 @@ function getHtmlWithSelectionPath(rootNode, range) {
13476
13831
  if (!rootNode) {
13477
13832
  return '';
13478
13833
  }
13479
- var _a = range || {}, startContainer = _a.startContainer, endContainer = _a.endContainer, startOffset = _a.startOffset, endOffset = _a.endOffset;
13480
- var isDOMChanged = false;
13481
- (0, queryElements_1.default)(rootNode, 'table', function (table) {
13482
- var tbody = null;
13483
- for (var child = table.firstChild; child; child = child.nextSibling) {
13484
- if ((0, getTagOfNode_1.default)(child) == 'TR') {
13485
- if (!tbody) {
13486
- tbody = table.ownerDocument.createElement('tbody');
13487
- table.insertBefore(tbody, child);
13488
- }
13489
- tbody.appendChild(child);
13490
- child = tbody;
13491
- isDOMChanged = true;
13492
- }
13493
- else {
13494
- tbody = null;
13495
- }
13496
- }
13497
- });
13498
- if (range && isDOMChanged) {
13499
- try {
13500
- range.setStart(startContainer, startOffset);
13501
- range.setEnd(endContainer, endOffset);
13502
- }
13503
- catch (_b) { }
13504
- }
13505
13834
  var content = (0, getInnerHTML_1.default)(rootNode);
13506
13835
  var selectionPath = range && (0, getSelectionPath_1.default)(rootNode, range);
13507
13836
  return selectionPath ? content + "<!--" + JSON.stringify(selectionPath) + "-->" : content;
@@ -13719,53 +14048,88 @@ function areAllPreviousNodesEmpty(node) {
13719
14048
  "use strict";
13720
14049
 
13721
14050
  Object.defineProperty(exports, "__esModule", { value: true });
14051
+ exports.setHtmlWithMetadata = void 0;
13722
14052
  var createRange_1 = __webpack_require__(/*! ./createRange */ "./packages/roosterjs-editor-dom/lib/selection/createRange.ts");
13723
- var LastCommentRegex = /<!--([^-]+)-->$/;
14053
+ var safeInstanceOf_1 = __webpack_require__(/*! ../utils/safeInstanceOf */ "./packages/roosterjs-editor-dom/lib/utils/safeInstanceOf.ts");
13724
14054
  /**
13725
- * Restore inner Html of a root element from given html string. If the string contains selection path,
14055
+ * @deprecated Use setHtmlWithMetadata instead
14056
+ * Restore inner HTML of a root element from given html string. If the string contains selection path,
13726
14057
  * remove the selection path and return a range represented by the path
13727
14058
  * @param root The root element
13728
- * @param html The html to restore
14059
+ * @param html The HTML to restore
14060
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
13729
14061
  * @returns A selection range if the html contains a valid selection path, otherwise null
13730
14062
  */
13731
14063
  function setHtmlWithSelectionPath(rootNode, html, trustedHTMLHandler) {
14064
+ var metadata = setHtmlWithMetadata(rootNode, html, trustedHTMLHandler);
14065
+ return (metadata === null || metadata === void 0 ? void 0 : metadata.type) == 0 /* Normal */
14066
+ ? (0, createRange_1.default)(rootNode, metadata.start, metadata.end)
14067
+ : null;
14068
+ }
14069
+ exports.default = setHtmlWithSelectionPath;
14070
+ /**
14071
+ * Restore inner HTML of a root element from given html string. If the string contains metadata,
14072
+ * remove it from DOM tree and return the metadata
14073
+ * @param root The root element
14074
+ * @param html The HTML to restore
14075
+ * @param trustedHTMLHandler An optional trusted HTML handler to convert HTML string to security string
14076
+ * @returns Content metadata if any, or undefined
14077
+ */
14078
+ function setHtmlWithMetadata(rootNode, html, trustedHTMLHandler) {
13732
14079
  if (!rootNode) {
13733
- return null;
14080
+ return undefined;
13734
14081
  }
13735
14082
  html = html || '';
13736
- var lastComment = LastCommentRegex.exec(html);
13737
14083
  rootNode.innerHTML = (trustedHTMLHandler === null || trustedHTMLHandler === void 0 ? void 0 : trustedHTMLHandler(html)) || html;
13738
- var path = getSelectionPath(rootNode, (lastComment === null || lastComment === void 0 ? void 0 : lastComment[1]) || '');
13739
- return path && (0, createRange_1.default)(rootNode, path.start, path.end);
13740
- }
13741
- exports.default = setHtmlWithSelectionPath;
13742
- function getSelectionPath(root, alternativeComment) {
13743
- var _a, _b, _c;
13744
- var pathCommentValue = '';
13745
- var pathCommentNode = null;
13746
- var path = null;
13747
- if (((_a = root.lastChild) === null || _a === void 0 ? void 0 : _a.nodeType) == 8 /* Comment */) {
13748
- pathCommentNode = root.lastChild;
13749
- pathCommentValue = pathCommentNode.nodeValue || '';
14084
+ var potentialMetadataComment = rootNode.lastChild;
14085
+ if ((0, safeInstanceOf_1.default)(potentialMetadataComment, 'Comment')) {
14086
+ try {
14087
+ var obj = JSON.parse(potentialMetadataComment.nodeValue || '');
14088
+ if (isContentMetadata(obj)) {
14089
+ rootNode.removeChild(potentialMetadataComment);
14090
+ return obj;
14091
+ }
14092
+ }
14093
+ catch (_a) { }
13750
14094
  }
13751
- else {
13752
- pathCommentValue = alternativeComment;
14095
+ return undefined;
14096
+ }
14097
+ exports.setHtmlWithMetadata = setHtmlWithMetadata;
14098
+ function isContentMetadata(obj) {
14099
+ if (!obj || typeof obj != 'object') {
14100
+ return false;
13753
14101
  }
13754
- if (pathCommentValue) {
13755
- try {
13756
- path = JSON.parse(pathCommentValue);
13757
- if (path && ((_b = path.start) === null || _b === void 0 ? void 0 : _b.length) > 0 && ((_c = path.end) === null || _c === void 0 ? void 0 : _c.length) > 0) {
13758
- if (pathCommentNode) {
13759
- root.removeChild(pathCommentNode);
13760
- }
14102
+ switch (obj.type || 0 /* Normal */) {
14103
+ case 0 /* Normal */:
14104
+ var regularMetadata = obj;
14105
+ if (isNumberArray(regularMetadata.start) && isNumberArray(regularMetadata.end)) {
14106
+ obj.type = 0 /* Normal */;
14107
+ obj.isDarkMode = !!obj.isDarkMode;
14108
+ return true;
13761
14109
  }
13762
- else {
13763
- path = null;
14110
+ break;
14111
+ case 1 /* TableSelection */:
14112
+ var tableMetadata = obj;
14113
+ if (typeof tableMetadata.tableId == 'string' &&
14114
+ !!tableMetadata.tableId &&
14115
+ isCoordinates(tableMetadata.firstCell) &&
14116
+ isCoordinates(tableMetadata.lastCell)) {
14117
+ obj.isDarkMode = !!obj.isDarkMode;
14118
+ return true;
13764
14119
  }
13765
- }
13766
- catch (_d) { }
14120
+ break;
13767
14121
  }
13768
- return path;
14122
+ return false;
14123
+ }
14124
+ function isNumberArray(obj) {
14125
+ return obj && Array.isArray(obj) && obj.every(function (o) { return typeof o == 'number'; });
14126
+ }
14127
+ function isCoordinates(obj) {
14128
+ var coordinates = obj;
14129
+ return (coordinates &&
14130
+ typeof coordinates == 'object' &&
14131
+ typeof coordinates.x == 'number' &&
14132
+ typeof coordinates.y == 'number');
13769
14133
  }
13770
14134
 
13771
14135
 
@@ -13781,23 +14145,21 @@ function getSelectionPath(root, alternativeComment) {
13781
14145
  "use strict";
13782
14146
 
13783
14147
  Object.defineProperty(exports, "__esModule", { value: true });
14148
+ exports.addSnapshotV2 = void 0;
13784
14149
  var clearProceedingSnapshots_1 = __webpack_require__(/*! ./clearProceedingSnapshots */ "./packages/roosterjs-editor-dom/lib/snapshots/clearProceedingSnapshots.ts");
13785
- /**
13786
- * Add a new snapshot to the given snapshots data structure
13787
- * @param snapshots The snapshots data structure to add new snapshot into
13788
- * @param snapshot The snapshot to add
13789
- * @param isAutoCompleteSnapshot Whether this is a snapshot before auto complete action
13790
- */
13791
- function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot) {
13792
- if (snapshots.currentIndex < 0 || snapshot != snapshots.snapshots[snapshots.currentIndex]) {
13793
- (0, clearProceedingSnapshots_1.default)(snapshots);
14150
+ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, getLength, compare) {
14151
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14152
+ compare = compare || defaultCompare;
14153
+ var currentSnapshot = snapshots.snapshots[snapshots.currentIndex];
14154
+ if (snapshots.currentIndex < 0 || !currentSnapshot || !compare(snapshot, currentSnapshot)) {
14155
+ (0, clearProceedingSnapshots_1.default)(snapshots, getLength);
13794
14156
  snapshots.snapshots.push(snapshot);
13795
14157
  snapshots.currentIndex++;
13796
- snapshots.totalSize += snapshot.length;
14158
+ snapshots.totalSize += getLength(snapshot);
13797
14159
  var removeCount = 0;
13798
14160
  while (removeCount < snapshots.snapshots.length &&
13799
14161
  snapshots.totalSize > snapshots.maxSize) {
13800
- snapshots.totalSize -= snapshots.snapshots[removeCount].length;
14162
+ snapshots.totalSize -= getLength(snapshots.snapshots[removeCount]);
13801
14163
  removeCount++;
13802
14164
  }
13803
14165
  if (removeCount > 0) {
@@ -13811,6 +14173,22 @@ function addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot) {
13811
14173
  }
13812
14174
  }
13813
14175
  exports.default = addSnapshot;
14176
+ /**
14177
+ * Add a new snapshot to the given snapshots data structure
14178
+ * @param snapshots The snapshots data structure to add new snapshot into
14179
+ * @param snapshot The snapshot object to add
14180
+ * @param isAutoCompleteSnapshot Whether this is a snapshot before auto complete action
14181
+ */
14182
+ function addSnapshotV2(snapshots, snapshot, isAutoCompleteSnapshot) {
14183
+ addSnapshot(snapshots, snapshot, isAutoCompleteSnapshot, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; }, compareSnapshots);
14184
+ }
14185
+ exports.addSnapshotV2 = addSnapshotV2;
14186
+ function compareSnapshots(s1, s2) {
14187
+ return s1.html == s2.html;
14188
+ }
14189
+ function defaultCompare(s1, s2) {
14190
+ return s1 == s2;
14191
+ }
13814
14192
 
13815
14193
 
13816
14194
  /***/ }),
@@ -13872,16 +14250,18 @@ exports.default = canUndoAutoComplete;
13872
14250
  "use strict";
13873
14251
 
13874
14252
  Object.defineProperty(exports, "__esModule", { value: true });
14253
+ exports.clearProceedingSnapshotsV2 = void 0;
13875
14254
  var canMoveCurrentSnapshot_1 = __webpack_require__(/*! ./canMoveCurrentSnapshot */ "./packages/roosterjs-editor-dom/lib/snapshots/canMoveCurrentSnapshot.ts");
13876
14255
  /**
13877
14256
  * Clear all snapshots after the current one
13878
14257
  * @param snapshots The snapshots data structure to clear
13879
14258
  */
13880
- function clearProceedingSnapshots(snapshots) {
14259
+ function clearProceedingSnapshots(snapshots, getLength) {
14260
+ getLength = getLength || (function (str) { var _a; return ((_a = str) === null || _a === void 0 ? void 0 : _a.length) || 0; });
13881
14261
  if ((0, canMoveCurrentSnapshot_1.default)(snapshots, 1)) {
13882
14262
  var removedSize = 0;
13883
14263
  for (var i = snapshots.currentIndex + 1; i < snapshots.snapshots.length; i++) {
13884
- removedSize += snapshots.snapshots[i].length;
14264
+ removedSize += getLength(snapshots.snapshots[i]);
13885
14265
  }
13886
14266
  snapshots.snapshots.splice(snapshots.currentIndex + 1);
13887
14267
  snapshots.totalSize -= removedSize;
@@ -13889,6 +14269,14 @@ function clearProceedingSnapshots(snapshots) {
13889
14269
  }
13890
14270
  }
13891
14271
  exports.default = clearProceedingSnapshots;
14272
+ /**
14273
+ * Clear all snapshots after the current one
14274
+ * @param snapshots The snapshots data structure to clear
14275
+ */
14276
+ function clearProceedingSnapshotsV2(snapshots) {
14277
+ clearProceedingSnapshots(snapshots, function (s) { var _a; return ((_a = s.html) === null || _a === void 0 ? void 0 : _a.length) || 0; });
14278
+ }
14279
+ exports.clearProceedingSnapshotsV2 = clearProceedingSnapshotsV2;
13892
14280
 
13893
14281
 
13894
14282
  /***/ }),
@@ -14084,6 +14472,18 @@ var VTable = /** @class */ (function () {
14084
14472
  */
14085
14473
  function VTable(node, normalizeSize, zoomScale) {
14086
14474
  var _this = this;
14475
+ /**
14476
+ * Virtual cells
14477
+ */
14478
+ this.cells = null;
14479
+ /**
14480
+ * Selected range of cells with the coordinates of the first and last cell selected.
14481
+ */
14482
+ this.selection = null;
14483
+ /**
14484
+ * Current format of the table
14485
+ */
14486
+ this.formatInfo = null;
14087
14487
  this.trs = [];
14088
14488
  this.table = (0, safeInstanceOf_1.default)(node, 'HTMLTableElement') ? node : getTableFromTd(node);
14089
14489
  if (this.table) {
@@ -14128,17 +14528,20 @@ var VTable = /** @class */ (function () {
14128
14528
  */
14129
14529
  VTable.prototype.writeBack = function (skipApplyFormat) {
14130
14530
  var _this = this;
14531
+ var _a;
14131
14532
  if (this.cells) {
14132
14533
  (0, moveChildNodes_1.default)(this.table);
14133
14534
  this.cells.forEach(function (row, r) {
14134
14535
  var tr = cloneNode(_this.trs[r % 2] || _this.trs[0]);
14135
- _this.table.appendChild(tr);
14136
- row.forEach(function (cell, c) {
14137
- if (cell.td) {
14138
- _this.recalculateSpans(r, c);
14139
- tr.appendChild(cell.td);
14140
- }
14141
- });
14536
+ if (tr) {
14537
+ _this.table.appendChild(tr);
14538
+ row.forEach(function (cell, c) {
14539
+ if (cell.td) {
14540
+ _this.recalculateSpans(r, c);
14541
+ tr.appendChild(cell.td);
14542
+ }
14543
+ });
14544
+ }
14142
14545
  });
14143
14546
  if (this.formatInfo && !skipApplyFormat) {
14144
14547
  (0, tableFormatInfo_1.saveTableInfo)(this.table, this.formatInfo);
@@ -14146,7 +14549,7 @@ var VTable = /** @class */ (function () {
14146
14549
  }
14147
14550
  }
14148
14551
  else if (this.table) {
14149
- this.table.parentNode.removeChild(this.table);
14552
+ (_a = this.table.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.table);
14150
14553
  }
14151
14554
  };
14152
14555
  /**
@@ -14167,7 +14570,7 @@ var VTable = /** @class */ (function () {
14167
14570
  * @param cells
14168
14571
  */
14169
14572
  VTable.prototype.deleteCellShadeDataset = function (cells) {
14170
- cells.forEach(function (row) {
14573
+ cells === null || cells === void 0 ? void 0 : cells.forEach(function (row) {
14171
14574
  row.forEach(function (cell) {
14172
14575
  if (cell.td && cell.td.dataset[CELL_SHADE]) {
14173
14576
  delete cell.td.dataset[CELL_SHADE];
@@ -14181,77 +14584,120 @@ var VTable = /** @class */ (function () {
14181
14584
  */
14182
14585
  VTable.prototype.edit = function (operation) {
14183
14586
  var _this = this;
14184
- if (!this.table) {
14587
+ if (!this.table || !this.cells || this.row === undefined || this.col == undefined) {
14185
14588
  return;
14186
14589
  }
14187
14590
  var currentRow = this.cells[this.row];
14188
14591
  var currentCell = currentRow[this.col];
14189
- var style = currentCell.td.style;
14592
+ var firstRow = this.selection ? this.selection.firstCell.y : this.row;
14593
+ var lastRow = this.selection ? this.selection.lastCell.y : this.row;
14594
+ var firstColumn = this.selection ? this.selection.firstCell.x : this.col;
14595
+ var lastColumn = this.selection ? this.selection.lastCell.x : this.col;
14190
14596
  switch (operation) {
14191
14597
  case 0 /* InsertAbove */:
14192
- this.cells.splice(this.row, 0, currentRow.map(cloneCell));
14598
+ for (var i = firstRow; i <= lastRow; i++) {
14599
+ this.cells.splice(firstRow, 0, currentRow.map(cloneCell));
14600
+ }
14193
14601
  break;
14194
14602
  case 1 /* InsertBelow */:
14195
- var newRow_1 = this.row + this.countSpanAbove(this.row, this.col);
14196
- this.cells.splice(newRow_1, 0, this.cells[newRow_1 - 1].map(function (cell, colIndex) {
14197
- var nextCell = _this.getCell(newRow_1, colIndex);
14198
- if (nextCell.spanAbove) {
14199
- return cloneCell(nextCell);
14200
- }
14201
- else if (cell.spanLeft) {
14202
- var newCell = cloneCell(cell);
14203
- newCell.spanAbove = false;
14204
- return newCell;
14205
- }
14206
- else {
14207
- return {
14208
- td: cloneNode(_this.getTd(_this.row, colIndex)),
14209
- };
14210
- }
14211
- }));
14603
+ var _loop_1 = function (i) {
14604
+ var newRow = lastRow + this_1.countSpanAbove(lastRow, this_1.col);
14605
+ this_1.cells.splice(newRow, 0, this_1.cells[newRow - 1].map(function (cell, colIndex) {
14606
+ var nextCell = _this.getCell(newRow, colIndex);
14607
+ if (nextCell.spanAbove) {
14608
+ return cloneCell(nextCell);
14609
+ }
14610
+ else if (cell.spanLeft) {
14611
+ var newCell = cloneCell(cell);
14612
+ newCell.spanAbove = false;
14613
+ return newCell;
14614
+ }
14615
+ else {
14616
+ return {
14617
+ td: cloneNode(_this.getTd(_this.row, colIndex)),
14618
+ };
14619
+ }
14620
+ }));
14621
+ };
14622
+ var this_1 = this;
14623
+ for (var i = firstRow; i <= lastRow; i++) {
14624
+ _loop_1(i);
14625
+ }
14212
14626
  break;
14213
14627
  case 2 /* InsertLeft */:
14214
- this.forEachCellOfCurrentColumn(function (cell, row) {
14215
- row.splice(_this.col, 0, cloneCell(cell));
14216
- });
14628
+ var _loop_2 = function (i) {
14629
+ this_2.forEachCellOfCurrentColumn(function (cell, row) {
14630
+ row.splice(i, 0, cloneCell(cell));
14631
+ });
14632
+ };
14633
+ var this_2 = this;
14634
+ for (var i = firstColumn; i <= lastColumn; i++) {
14635
+ _loop_2(i);
14636
+ }
14217
14637
  break;
14218
14638
  case 3 /* InsertRight */:
14219
- var newCol_1 = this.col + this.countSpanLeft(this.row, this.col);
14220
- this.forEachCellOfColumn(newCol_1 - 1, function (cell, row, i) {
14221
- var nextCell = _this.getCell(i, newCol_1);
14222
- var newCell;
14223
- if (nextCell.spanLeft) {
14224
- newCell = cloneCell(nextCell);
14225
- }
14226
- else if (cell.spanAbove) {
14227
- newCell = cloneCell(cell);
14228
- newCell.spanLeft = false;
14229
- }
14230
- else {
14231
- newCell = {
14232
- td: cloneNode(_this.getTd(i, _this.col)),
14233
- };
14234
- }
14235
- row.splice(newCol_1, 0, newCell);
14236
- });
14639
+ var _loop_3 = function (i) {
14640
+ var newCol = lastColumn + this_3.countSpanLeft(this_3.row, lastColumn);
14641
+ this_3.forEachCellOfColumn(newCol - 1, function (cell, row, i) {
14642
+ var nextCell = _this.getCell(i, newCol);
14643
+ var newCell;
14644
+ if (nextCell.spanLeft) {
14645
+ newCell = cloneCell(nextCell);
14646
+ }
14647
+ else if (cell.spanAbove) {
14648
+ newCell = cloneCell(cell);
14649
+ newCell.spanLeft = false;
14650
+ }
14651
+ else {
14652
+ newCell = {
14653
+ td: cloneNode(_this.getTd(i, _this.col)),
14654
+ };
14655
+ }
14656
+ row.splice(newCol, 0, newCell);
14657
+ });
14658
+ };
14659
+ var this_3 = this;
14660
+ for (var i = firstColumn; i <= lastColumn; i++) {
14661
+ _loop_3(i);
14662
+ }
14237
14663
  break;
14238
14664
  case 6 /* DeleteRow */:
14239
- this.forEachCellOfCurrentRow(function (cell, i) {
14240
- var nextCell = _this.getCell(_this.row + 1, i);
14241
- if (cell.td && cell.td.rowSpan > 1 && nextCell.spanAbove) {
14242
- nextCell.td = cell.td;
14243
- }
14244
- });
14245
- this.cells.splice(this.row, 1);
14665
+ var _loop_4 = function (rowIndex) {
14666
+ this_4.forEachCellOfRow(rowIndex, function (cell, i) {
14667
+ var nextCell = _this.getCell(rowIndex + 1, i);
14668
+ if (cell.td && cell.td.rowSpan > 1 && nextCell.spanAbove) {
14669
+ nextCell.td = cell.td;
14670
+ }
14671
+ });
14672
+ };
14673
+ var this_4 = this;
14674
+ for (var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++) {
14675
+ _loop_4(rowIndex);
14676
+ }
14677
+ var removedRows = this.selection
14678
+ ? this.selection.lastCell.y - this.selection.firstCell.y
14679
+ : 0;
14680
+ this.cells.splice(firstRow, removedRows + 1);
14246
14681
  break;
14247
14682
  case 5 /* DeleteColumn */:
14248
- this.forEachCellOfCurrentColumn(function (cell, row, i) {
14249
- var nextCell = _this.getCell(i, _this.col + 1);
14250
- if (cell.td && cell.td.colSpan > 1 && nextCell.spanLeft) {
14251
- nextCell.td = cell.td;
14252
- }
14253
- row.splice(_this.col, 1);
14254
- });
14683
+ var deletedColumns_1 = 0;
14684
+ var _loop_5 = function (colIndex) {
14685
+ this_5.forEachCellOfColumn(colIndex, function (cell, row, i) {
14686
+ var nextCell = _this.getCell(i, colIndex + 1);
14687
+ if (cell.td && cell.td.colSpan > 1 && nextCell.spanLeft) {
14688
+ nextCell.td = cell.td;
14689
+ }
14690
+ var removedColumns = _this.selection
14691
+ ? colIndex - deletedColumns_1
14692
+ : _this.col;
14693
+ row.splice(removedColumns, 1);
14694
+ });
14695
+ deletedColumns_1++;
14696
+ };
14697
+ var this_5 = this;
14698
+ for (var colIndex = firstColumn; colIndex <= lastColumn; colIndex++) {
14699
+ _loop_5(colIndex);
14700
+ }
14255
14701
  break;
14256
14702
  case 7 /* MergeAbove */:
14257
14703
  case 8 /* MergeBelow */:
@@ -14261,7 +14707,9 @@ var VTable = /** @class */ (function () {
14261
14707
  if (cell.td && !cell.spanAbove) {
14262
14708
  var aboveCell = rowIndex < this.row ? cell : currentCell;
14263
14709
  var belowCell = rowIndex < this.row ? currentCell : cell;
14264
- if (aboveCell.td.colSpan == belowCell.td.colSpan) {
14710
+ if (aboveCell.td &&
14711
+ belowCell.td &&
14712
+ aboveCell.td.colSpan == belowCell.td.colSpan) {
14265
14713
  (0, moveChildNodes_1.default)(aboveCell.td, belowCell.td, true /*keepExistingChildren*/);
14266
14714
  belowCell.td = null;
14267
14715
  belowCell.spanAbove = true;
@@ -14278,7 +14726,9 @@ var VTable = /** @class */ (function () {
14278
14726
  if (cell.td && !cell.spanLeft) {
14279
14727
  var leftCell = colIndex < this.col ? cell : currentCell;
14280
14728
  var rightCell = colIndex < this.col ? currentCell : cell;
14281
- if (leftCell.td.rowSpan == rightCell.td.rowSpan) {
14729
+ if (leftCell.td &&
14730
+ rightCell.td &&
14731
+ leftCell.td.rowSpan == rightCell.td.rowSpan) {
14282
14732
  (0, moveChildNodes_1.default)(leftCell.td, rightCell.td, true /*keepExistingChildren*/);
14283
14733
  rightCell.td = null;
14284
14734
  rightCell.spanLeft = true;
@@ -14291,7 +14741,7 @@ var VTable = /** @class */ (function () {
14291
14741
  this.cells = null;
14292
14742
  break;
14293
14743
  case 12 /* SplitVertically */:
14294
- if (currentCell.td.rowSpan > 1) {
14744
+ if (currentCell.td && currentCell.td.rowSpan > 1) {
14295
14745
  this.getCell(this.row + 1, this.col).td = cloneNode(currentCell.td);
14296
14746
  }
14297
14747
  else {
@@ -14306,7 +14756,7 @@ var VTable = /** @class */ (function () {
14306
14756
  }
14307
14757
  break;
14308
14758
  case 11 /* SplitHorizontally */:
14309
- if (currentCell.td.colSpan > 1) {
14759
+ if (currentCell.td && currentCell.td.colSpan > 1) {
14310
14760
  this.getCell(this.row, this.col + 1).td = cloneNode(currentCell.td);
14311
14761
  }
14312
14762
  else {
@@ -14332,25 +14782,41 @@ var VTable = /** @class */ (function () {
14332
14782
  this.table.style.marginRight = '';
14333
14783
  break;
14334
14784
  case 17 /* AlignCellCenter */:
14335
- style.textAlign = 'center';
14785
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'center');
14336
14786
  break;
14337
14787
  case 16 /* AlignCellLeft */:
14338
- style.textAlign = 'left';
14788
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'left');
14339
14789
  break;
14340
14790
  case 18 /* AlignCellRight */:
14341
- style.textAlign = 'right';
14791
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'right');
14342
14792
  break;
14343
14793
  case 19 /* AlignCellTop */:
14344
- style.verticalAlign = 'top';
14794
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'top', true /** isVertical */);
14345
14795
  break;
14346
14796
  case 20 /* AlignCellMiddle */:
14347
- style.verticalAlign = 'middle';
14797
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'middle', true /** isVertical */);
14348
14798
  break;
14349
14799
  case 21 /* AlignCellBottom */:
14350
- style.verticalAlign = 'bottom';
14800
+ this.setAlignmentToSelectedCells(firstRow, lastRow, firstColumn, lastColumn, 'bottom', true /** isVertical */);
14351
14801
  break;
14352
14802
  }
14353
14803
  };
14804
+ VTable.prototype.setAlignmentToSelectedCells = function (firstRow, lastRow, firstColumn, lastColumn, alignmentType, isVertical) {
14805
+ var _a, _b;
14806
+ for (var i = firstRow; i <= lastRow; i++) {
14807
+ for (var j = firstColumn; j <= lastColumn; j++) {
14808
+ if (this.cells) {
14809
+ var cell = this.cells[i][j].td;
14810
+ if (isVertical && cell) {
14811
+ (_a = cell.style) === null || _a === void 0 ? void 0 : _a.setProperty('vertical-align', alignmentType);
14812
+ }
14813
+ else if (cell) {
14814
+ (_b = cell.style) === null || _b === void 0 ? void 0 : _b.setProperty('text-align', alignmentType);
14815
+ }
14816
+ }
14817
+ }
14818
+ }
14819
+ };
14354
14820
  /**
14355
14821
  * Loop each cell of current column and invoke a callback function
14356
14822
  * @param callback The callback function to invoke
@@ -14384,7 +14850,7 @@ var VTable = /** @class */ (function () {
14384
14850
  */
14385
14851
  VTable.prototype.getCellsWithBorder = function (borderPos, getLeftCells) {
14386
14852
  var cells = [];
14387
- for (var i = 0; i < this.cells.length; i++) {
14853
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14388
14854
  for (var j = 0; j < this.cells[i].length; j++) {
14389
14855
  var cell = this.getCell(i, j);
14390
14856
  if (cell.td) {
@@ -14443,7 +14909,7 @@ var VTable = /** @class */ (function () {
14443
14909
  * @param col column of the cell
14444
14910
  */
14445
14911
  VTable.prototype.getTd = function (row, col) {
14446
- if (this.cells) {
14912
+ if (this.cells && row !== undefined && col !== undefined) {
14447
14913
  row = Math.min(this.cells.length - 1, row);
14448
14914
  col = this.cells[row] ? Math.min(this.cells[row].length - 1, col) : col;
14449
14915
  if (!isNaN(row) && !isNaN(col)) {
@@ -14467,13 +14933,17 @@ var VTable = /** @class */ (function () {
14467
14933
  return null;
14468
14934
  };
14469
14935
  VTable.prototype.forEachCellOfColumn = function (col, callback) {
14470
- for (var i = 0; i < this.cells.length; i++) {
14471
- callback(this.getCell(i, col), this.cells[i], i);
14936
+ if (col !== undefined) {
14937
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14938
+ callback(this.getCell(i, col), this.cells[i], i);
14939
+ }
14472
14940
  }
14473
14941
  };
14474
14942
  VTable.prototype.forEachCellOfRow = function (row, callback) {
14475
- for (var i = 0; i < this.cells[row].length; i++) {
14476
- callback(this.getCell(row, i), i);
14943
+ if (row !== undefined) {
14944
+ for (var i = 0; this.cells && i < this.cells[row].length; i++) {
14945
+ callback(this.getCell(row, i), i);
14946
+ }
14477
14947
  }
14478
14948
  };
14479
14949
  VTable.prototype.recalculateSpans = function (row, col) {
@@ -14491,7 +14961,7 @@ var VTable = /** @class */ (function () {
14491
14961
  };
14492
14962
  VTable.prototype.countSpanLeft = function (row, col) {
14493
14963
  var result = 1;
14494
- for (var i = col + 1; i < this.cells[row].length; i++) {
14964
+ for (var i = col + 1; this.cells && i < this.cells[row].length; i++) {
14495
14965
  var cell = this.getCell(row, i);
14496
14966
  if (cell.td || !cell.spanLeft) {
14497
14967
  break;
@@ -14502,7 +14972,7 @@ var VTable = /** @class */ (function () {
14502
14972
  };
14503
14973
  VTable.prototype.countSpanAbove = function (row, col) {
14504
14974
  var result = 1;
14505
- for (var i = row + 1; i < this.cells.length; i++) {
14975
+ for (var i = row + 1; this.cells && i < this.cells.length; i++) {
14506
14976
  var cell = this.getCell(i, col);
14507
14977
  if (cell.td || !cell.spanAbove) {
14508
14978
  break;
@@ -14527,17 +14997,19 @@ var VTable = /** @class */ (function () {
14527
14997
  // remove width/height for each row
14528
14998
  for (var i = 0, row = void 0; (row = this.table.rows[i]); i++) {
14529
14999
  row.removeAttribute('width');
14530
- row.style.width = null;
15000
+ row.style.setProperty('width', null);
14531
15001
  row.removeAttribute('height');
14532
- row.style.height = null;
15002
+ row.style.setProperty('height', null);
14533
15003
  }
14534
15004
  // set width/height for each cell
14535
- for (var i = 0; i < this.cells.length; i++) {
15005
+ for (var i = 0; this.cells && i < this.cells.length; i++) {
14536
15006
  for (var j = 0; j < this.cells[i].length; j++) {
14537
15007
  var cell = this.cells[i][j];
14538
15008
  if (cell) {
14539
15009
  var func = typeof zoomScale == 'number' ? function (n) { return n / zoomScale; } : zoomScale;
14540
- setHTMLElementSizeInPx(cell.td, (func === null || func === void 0 ? void 0 : func(cell.width)) || cell.width, (func === null || func === void 0 ? void 0 : func(cell.height)) || cell.height);
15010
+ var width = cell.width || 0;
15011
+ var height = cell.height || 0;
15012
+ setHTMLElementSizeInPx(cell.td, (func === null || func === void 0 ? void 0 : func(width)) || width, (func === null || func === void 0 ? void 0 : func(height)) || height);
14541
15013
  }
14542
15014
  }
14543
15015
  }
@@ -14881,6 +15353,40 @@ function getBorderStyle(style) {
14881
15353
  }
14882
15354
 
14883
15355
 
15356
+ /***/ }),
15357
+
15358
+ /***/ "./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts":
15359
+ /*!*************************************************************************!*\
15360
+ !*** ./packages/roosterjs-editor-dom/lib/table/isWholeTableSelected.ts ***!
15361
+ \*************************************************************************/
15362
+ /*! no static exports found */
15363
+ /***/ (function(module, exports, __webpack_require__) {
15364
+
15365
+ "use strict";
15366
+
15367
+ Object.defineProperty(exports, "__esModule", { value: true });
15368
+ /**
15369
+ * Check if the whole table is selected
15370
+ * @param vTable VTable to check whether all cells are selected
15371
+ * @param selection Table selection with first cell selected and last cell selected coordinates.
15372
+ * @returns
15373
+ */
15374
+ function isWholeTableSelected(vTable, selection) {
15375
+ if (!selection || !vTable.cells) {
15376
+ return false;
15377
+ }
15378
+ var firstCell = selection.firstCell, lastCell = selection.lastCell;
15379
+ var rowsLength = vTable.cells.length - 1;
15380
+ var colIndex = vTable.cells[rowsLength].length - 1;
15381
+ var firstX = firstCell.x;
15382
+ var firstY = firstCell.y;
15383
+ var lastX = lastCell.x;
15384
+ var lastY = lastCell.y;
15385
+ return firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
15386
+ }
15387
+ exports.default = isWholeTableSelected;
15388
+
15389
+
14884
15390
  /***/ }),
14885
15391
 
14886
15392
  /***/ "./packages/roosterjs-editor-dom/lib/table/tableFormatInfo.ts":
@@ -18110,11 +18616,14 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
18110
18616
  */
18111
18617
  var TabInTable = {
18112
18618
  keys: [9 /* TAB */],
18113
- shouldHandleEvent: cacheGetTableCell,
18619
+ shouldHandleEvent: function (event, editor) {
18620
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18621
+ },
18114
18622
  handleEvent: function (event, editor) {
18115
18623
  var shift = event.rawEvent.shiftKey;
18116
18624
  var td = cacheGetTableCell(event, editor);
18117
- for (var vtable = new roosterjs_editor_dom_1.VTable(td), step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
18625
+ var vtable = cacheVTable(event, td);
18626
+ for (var step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
18118
18627
  if (col < 0 || col >= vtable.cells[row].length) {
18119
18628
  row += step;
18120
18629
  if (row < 0) {
@@ -18136,13 +18645,40 @@ var TabInTable = {
18136
18645
  event.rawEvent.preventDefault();
18137
18646
  },
18138
18647
  };
18648
+ /**
18649
+ * IndentTableOnTab edit feature, provides the ability to indent the table if it is all cells are selected.
18650
+ */
18651
+ var IndentTableOnTab = {
18652
+ keys: [9 /* TAB */],
18653
+ shouldHandleEvent: function (event, editor) {
18654
+ return cacheGetTableCell(event, editor) && cacheIsWholeTableSelected(event, editor);
18655
+ },
18656
+ handleEvent: function (event, editor) {
18657
+ event.rawEvent.preventDefault();
18658
+ editor.addUndoSnapshot(function () {
18659
+ var shift = event.rawEvent.shiftKey;
18660
+ var selection = editor.getSelectionRangeEx();
18661
+ var td = cacheGetTableCell(event, editor);
18662
+ var vtable = cacheVTable(event, td);
18663
+ if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
18664
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
18665
+ }
18666
+ else if (!shift) {
18667
+ (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
18668
+ }
18669
+ editor.select(selection.table, selection.coordinates);
18670
+ });
18671
+ },
18672
+ };
18139
18673
  /**
18140
18674
  * UpDownInTable edit feature, provides the ability to jump to cell above/below when user press UP/DOWN
18141
18675
  * in table
18142
18676
  */
18143
18677
  var UpDownInTable = {
18144
18678
  keys: [38 /* UP */, 40 /* DOWN */],
18145
- shouldHandleEvent: cacheGetTableCell,
18679
+ shouldHandleEvent: function (event, editor) {
18680
+ return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
18681
+ },
18146
18682
  handleEvent: function (event, editor) {
18147
18683
  var _a;
18148
18684
  var td = cacheGetTableCell(event, editor);
@@ -18194,12 +18730,27 @@ function cacheGetTableCell(event, editor) {
18194
18730
  return (firstTd && ((0, roosterjs_editor_dom_1.getTagOfNode)(firstTd) == 'LI' ? null : firstTd));
18195
18731
  });
18196
18732
  }
18733
+ function cacheIsWholeTableSelected(event, editor) {
18734
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
18735
+ var td = cacheGetTableCell(event, editor);
18736
+ var vtable = cacheVTable(event, td);
18737
+ var selection = editor.getSelectionRangeEx();
18738
+ return (selection.type == 1 /* TableSelection */ &&
18739
+ (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
18740
+ });
18741
+ }
18742
+ function cacheVTable(event, td) {
18743
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'VTABLE_FOR_TABLE_FEATURES', function () {
18744
+ return new roosterjs_editor_dom_1.VTable(td);
18745
+ });
18746
+ }
18197
18747
  /**
18198
18748
  * @internal
18199
18749
  */
18200
18750
  exports.TableFeatures = {
18201
18751
  tabInTable: TabInTable,
18202
18752
  upDownInTable: UpDownInTable,
18753
+ indentTableOnTab: IndentTableOnTab,
18203
18754
  };
18204
18755
 
18205
18756
 
@@ -18320,17 +18871,27 @@ function insertTab(editor, event) {
18320
18871
  var searcher = editor.getContentSearcherOfCursor(event);
18321
18872
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
18322
18873
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
18874
+ var span2;
18323
18875
  var textContent = '';
18324
18876
  for (var index = 0; index < numberOfChars; index++) {
18325
18877
  textContent += '&ensp;';
18326
18878
  }
18327
18879
  editor.insertNode(span);
18880
+ if (span.nextElementSibling && (0, roosterjs_editor_dom_1.getTagOfNode)(span.nextElementSibling) == 'A') {
18881
+ span2 = editor.getDocument().createElement('span');
18882
+ span2.textContent = ' ';
18883
+ editor.insertNode(span2);
18884
+ editor.select((0, roosterjs_editor_dom_1.createRange)(span2, -2 /* Before */));
18885
+ }
18328
18886
  editor.insertContent(textContent, {
18329
18887
  position: 5 /* Range */,
18330
18888
  range: (0, roosterjs_editor_dom_1.createRange)(span, 0 /* Begin */),
18331
18889
  updateCursor: false,
18332
18890
  });
18333
18891
  editor.select((0, roosterjs_editor_dom_1.createRange)(span, -3 /* After */));
18892
+ if (span2) {
18893
+ editor.deleteNode(span2);
18894
+ }
18334
18895
  }
18335
18896
 
18336
18897
 
@@ -22553,6 +23114,14 @@ var TableCellSelection = /** @class */ (function () {
22553
23114
  this.handleScrollEvent();
22554
23115
  }
22555
23116
  break;
23117
+ case 20 /* BeforeSetContent */:
23118
+ if (this.tableRange) {
23119
+ this.tableRange = null;
23120
+ this.firstTable = null;
23121
+ this.tableSelection = false;
23122
+ this.editor.select(null);
23123
+ }
23124
+ break;
22556
23125
  }
22557
23126
  }
22558
23127
  };
@@ -22586,10 +23155,12 @@ var TableCellSelection = /** @class */ (function () {
22586
23155
  if (selection.type == 1 /* TableSelection */) {
22587
23156
  var clonedTable = event.clonedRoot.querySelector('table#' + selection.table.id);
22588
23157
  if (clonedTable) {
23158
+ this.tableRange = selection.coordinates;
22589
23159
  var clonedVTable = new roosterjs_editor_dom_1.VTable(clonedTable);
22590
23160
  clonedVTable.selection = this.tableRange;
22591
23161
  (0, removeCellsOutsideSelection_1.removeCellsOutsideSelection)(clonedVTable);
22592
23162
  clonedVTable.writeBack();
23163
+ clonedVTable.table.id = '';
22593
23164
  event.range.selectNode(clonedTable);
22594
23165
  if (event.isCut) {
22595
23166
  (0, forEachSelectedCell_1.forEachSelectedCell)(this.vTable, function (cell) {
@@ -22608,8 +23179,9 @@ var TableCellSelection = /** @class */ (function () {
22608
23179
  */
22609
23180
  TableCellSelection.prototype.handleKeyDownEvent = function (event) {
22610
23181
  var _this = this;
22611
- var _a = event.rawEvent, shiftKey = _a.shiftKey, ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which;
22612
- if ((shiftKey && (ctrlKey || metaKey)) || which == 16 /* SHIFT */) {
23182
+ var _a = event.rawEvent, shiftKey = _a.shiftKey, ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which, defaultPrevented = _a.defaultPrevented;
23183
+ if ((shiftKey && (ctrlKey || metaKey)) || which == 16 /* SHIFT */ || defaultPrevented) {
23184
+ this.preventKeyUp = defaultPrevented;
22613
23185
  return;
22614
23186
  }
22615
23187
  if (shiftKey) {
@@ -22643,9 +23215,10 @@ var TableCellSelection = /** @class */ (function () {
22643
23215
  };
22644
23216
  TableCellSelection.prototype.handleKeyUpEvent = function (event) {
22645
23217
  var _a = event.rawEvent, shiftKey = _a.shiftKey, which = _a.which;
22646
- if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget) {
23218
+ if (!shiftKey && which != 16 /* SHIFT */ && this.firstTarget && !this.preventKeyUp) {
22647
23219
  this.clearState();
22648
23220
  }
23221
+ this.preventKeyUp = false;
22649
23222
  };
22650
23223
  TableCellSelection.prototype.handleKeySelectionInsideTable = function (event) {
22651
23224
  this.firstTarget = getCellAtCursor(this.editor, this.firstTarget);
@@ -22709,13 +23282,17 @@ var TableCellSelection = /** @class */ (function () {
22709
23282
  }
22710
23283
  }
22711
23284
  }
22712
- this.editor.getDocument().addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
22713
23285
  if (which == LEFT_CLICK && !shiftKey) {
22714
23286
  this.clearState();
22715
- this.editor
22716
- .getDocument()
22717
- .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
22718
- this.startedSelection = true;
23287
+ if (getTableAtCursor(this.editor, event.rawEvent.target)) {
23288
+ this.editor
23289
+ .getDocument()
23290
+ .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);
23291
+ this.editor
23292
+ .getDocument()
23293
+ .addEventListener('mousemove', this.onMouseMove, true /*setCapture*/);
23294
+ this.startedSelection = true;
23295
+ }
22719
23296
  }
22720
23297
  if (which == LEFT_CLICK && shiftKey) {
22721
23298
  this.editor.runAsync(function (editor) {
@@ -23117,24 +23694,22 @@ exports.default = normalizeTableSelection;
23117
23694
 
23118
23695
  Object.defineProperty(exports, "__esModule", { value: true });
23119
23696
  exports.removeCellsOutsideSelection = void 0;
23697
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
23120
23698
  /**
23121
23699
  * @internal
23122
23700
  * Remove the cells outside of the selection.
23123
23701
  * @param vTable VTable to remove selection
23124
23702
  */
23125
23703
  function removeCellsOutsideSelection(vTable) {
23704
+ if ((0, roosterjs_editor_dom_1.isWholeTableSelected)(vTable, vTable.selection)) {
23705
+ return;
23706
+ }
23126
23707
  var _a = vTable.selection, firstCell = _a.firstCell, lastCell = _a.lastCell;
23127
- var rowsLength = vTable.cells.length - 1;
23128
- var colIndex = vTable.cells[rowsLength].length - 1;
23129
23708
  var resultCells = [];
23130
23709
  var firstX = firstCell.x;
23131
23710
  var firstY = firstCell.y;
23132
23711
  var lastX = lastCell.x;
23133
23712
  var lastY = lastCell.y;
23134
- var selectedAllTable = firstX == 0 && firstY == 0 && lastX == colIndex && lastY == rowsLength;
23135
- if (selectedAllTable) {
23136
- return;
23137
- }
23138
23713
  vTable.cells.forEach(function (row, y) {
23139
23714
  row = row.filter(function (_, x) { return y >= firstY && y <= lastY && x >= firstX && x <= lastX; });
23140
23715
  if (row.length > 0) {
@@ -23499,7 +24074,8 @@ var TableEditor = /** @class */ (function () {
23499
24074
  _this.disposeTableResizer();
23500
24075
  _this.onStartResize();
23501
24076
  };
23502
- this.onInserted = function () {
24077
+ this.onInserted = function (table) {
24078
+ _this.editor.transformToDarkColor(table);
23503
24079
  _this.disposeTableResizer();
23504
24080
  _this.onFinishEditing();
23505
24081
  };
@@ -23736,9 +24312,7 @@ var TableInsertHandler = /** @class */ (function () {
23736
24312
  }
23737
24313
  vtable.edit(_this.isHorizontal ? 1 /* InsertBelow */ : 3 /* InsertRight */);
23738
24314
  vtable.writeBack();
23739
- //Adding replaceNode to transform color when the theme is switched to dark.
23740
- _this.editor.replaceNode(vtable.table, vtable.table, true /**transformColorForDarkMode*/);
23741
- _this.onInsert();
24315
+ _this.onInsert(vtable.table);
23742
24316
  };
23743
24317
  this.div.addEventListener('click', this.insertTd);
23744
24318
  }