roosterjs 9.44.0 → 9.45.1

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.
@@ -2342,6 +2342,10 @@ function setModelDirection(model, direction) {
2342
2342
  item.levels.forEach(function (level) {
2343
2343
  level.format.direction = calcDirection;
2344
2344
  });
2345
+ // We already set direction on levels, no need to keep it on list item level
2346
+ delete item.format.direction;
2347
+ // Remove textAlign to let it be calculated based on direction change
2348
+ delete item.format.textAlign;
2345
2349
  item.blocks.forEach(function (block) { return internalSetDirection(block, calcDirection); });
2346
2350
  });
2347
2351
  }
@@ -4362,9 +4366,18 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
4362
4366
  exports.alignTableCellVertically = exports.alignTableCellHorizontally = void 0;
4363
4367
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
4364
4368
  var TextAlignValueMap = {
4365
- alignCellLeft: 'start',
4366
- alignCellCenter: 'center',
4367
- alignCellRight: 'end',
4369
+ alignCellLeft: {
4370
+ ltr: 'start',
4371
+ rtl: 'end',
4372
+ },
4373
+ alignCellCenter: {
4374
+ ltr: 'center',
4375
+ rtl: 'center',
4376
+ },
4377
+ alignCellRight: {
4378
+ ltr: 'end',
4379
+ rtl: 'start',
4380
+ },
4368
4381
  };
4369
4382
  var VerticalAlignValueMap = {
4370
4383
  alignCellTop: 'top',
@@ -4376,7 +4389,8 @@ var VerticalAlignValueMap = {
4376
4389
  */
4377
4390
  function alignTableCellHorizontally(table, operation) {
4378
4391
  alignTableCellInternal(table, function (cell) {
4379
- cell.format.textAlign = TextAlignValueMap[operation];
4392
+ cell.format.textAlign =
4393
+ TextAlignValueMap[operation][cell.format.direction == 'rtl' ? 'rtl' : 'ltr'];
4380
4394
  });
4381
4395
  }
4382
4396
  exports.alignTableCellHorizontally = alignTableCellHorizontally;
@@ -4539,12 +4553,12 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
4539
4553
  /**
4540
4554
  * @internal
4541
4555
  */
4542
- function createTableStructure(parent, columns, rows) {
4556
+ function createTableStructure(parent, columns, rows, cellFormat) {
4543
4557
  var table = (0, roosterjs_content_model_dom_1.createTable)(rows);
4544
4558
  (0, roosterjs_content_model_dom_1.addBlock)(parent, table);
4545
4559
  table.rows.forEach(function (row) {
4546
4560
  for (var i = 0; i < columns; i++) {
4547
- var cell = (0, roosterjs_content_model_dom_1.createTableCell)();
4561
+ var cell = (0, roosterjs_content_model_dom_1.createTableCell)(undefined /*spanLeftOrColSpan */, undefined /*spanAboveOrRowSpan */, undefined /* isHeader */, cellFormat);
4548
4562
  row.cells.push(cell);
4549
4563
  }
4550
4564
  });
@@ -7136,19 +7150,21 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
7136
7150
  * @param rows Number of rows in table
7137
7151
  * @param tableMetadataFormat (Optional) The table format that are stored as metadata. If not passed, the default format will be applied: background color: #FFF; border color: #ABABAB
7138
7152
  * @param format (Optional) The table format used for style attributes
7153
+ * @param cellFormat (Optional) custom format for table cells, except for borders styles, for borders use tableMetadataFormat
7139
7154
  */
7140
- function insertTable(editor, columns, rows, tableMetadataFormat, format) {
7155
+ function insertTable(editor, columns, rows, tableMetadataFormat, format, customCellFormat) {
7141
7156
  editor.focus();
7142
7157
  editor.formatContentModel(function (model, context) {
7143
7158
  var _a, _b, _c;
7144
7159
  var insertPosition = (0, roosterjs_content_model_dom_1.deleteSelection)(model, [], context).insertPoint;
7145
7160
  if (insertPosition) {
7146
7161
  var doc = (0, roosterjs_content_model_dom_1.createContentModelDocument)();
7147
- var table = (0, createTableStructure_1.createTableStructure)(doc, columns, rows);
7162
+ var table = (0, createTableStructure_1.createTableStructure)(doc, columns, rows, customCellFormat);
7148
7163
  if (format) {
7149
7164
  table.format = (0, tslib_1.__assign)({}, format);
7150
7165
  }
7151
7166
  (0, roosterjs_content_model_dom_1.normalizeTable)(table, editor.getPendingFormat() || insertPosition.marker.format);
7167
+ initCellWidth(table);
7152
7168
  (0, adjustIndentation_1.adjustTableIndentation)(insertPosition, table);
7153
7169
  // Assign default vertical align
7154
7170
  tableMetadataFormat = tableMetadataFormat || { verticalAlign: 'top' };
@@ -7173,6 +7189,28 @@ function insertTable(editor, columns, rows, tableMetadataFormat, format) {
7173
7189
  });
7174
7190
  }
7175
7191
  exports.insertTable = insertTable;
7192
+ function initCellWidth(table) {
7193
+ var columns = Math.max.apply(Math, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(table.rows.map(function (row) { return row.cells.length; })), false));
7194
+ for (var i = 0; i < columns; i++) {
7195
+ if (table.widths[i] === undefined) {
7196
+ table.widths[i] = getTableCellWidth(columns);
7197
+ }
7198
+ else if (table.widths[i] < roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_WIDTH) {
7199
+ table.widths[i] = roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_WIDTH;
7200
+ }
7201
+ }
7202
+ }
7203
+ function getTableCellWidth(columns) {
7204
+ if (columns <= 4) {
7205
+ return 120;
7206
+ }
7207
+ else if (columns <= 6) {
7208
+ return 100;
7209
+ }
7210
+ else {
7211
+ return 70;
7212
+ }
7213
+ }
7176
7214
 
7177
7215
 
7178
7216
  /***/ }),
@@ -8609,7 +8647,9 @@ function exportContent(editor, mode, optionsOrCallbacks) {
8609
8647
  case 'HTMLFast':
8610
8648
  var clonedRoot = editor.getDOMHelper().getClonedRoot();
8611
8649
  if (editor.isDarkMode()) {
8612
- (0, roosterjs_content_model_dom_1.transformColor)(clonedRoot, false /*includeSelf*/, 'darkToLight', editor.getColorManager());
8650
+ (0, roosterjs_content_model_dom_1.transformColor)(clonedRoot, false /*includeSelf*/, 'darkToLight', editor.getColorManager(), {
8651
+ tableBorders: editor.isExperimentalFeatureEnabled('TransformTableBorderColors'),
8652
+ });
8613
8653
  }
8614
8654
  return getHTMLFromDOM(editor, clonedRoot);
8615
8655
  case 'HTML':
@@ -10050,7 +10090,9 @@ function restoreSnapshotColors(core, snapshot) {
10050
10090
  var isDarkMode = core.lifecycle.isDarkMode;
10051
10091
  core.darkColorHandler.updateKnownColor(isDarkMode); // Pass no parameter to force update all colors
10052
10092
  if (!!snapshot.isDarkMode != !!isDarkMode) {
10053
- (0, roosterjs_content_model_dom_1.transformColor)(core.physicalRoot, false /*includeSelf*/, isDarkMode ? 'lightToDark' : 'darkToLight', core.darkColorHandler);
10093
+ (0, roosterjs_content_model_dom_1.transformColor)(core.physicalRoot, false /*includeSelf*/, isDarkMode ? 'lightToDark' : 'darkToLight', core.darkColorHandler, {
10094
+ tableBorders: core.experimentalFeatures.indexOf('TransformTableBorderColors') > -1,
10095
+ });
10054
10096
  }
10055
10097
  }
10056
10098
  exports.restoreSnapshotColors = restoreSnapshotColors;
@@ -12715,7 +12757,9 @@ var EntityPlugin = /** @class */ (function () {
12715
12757
  canPersist: eventResult === null || eventResult === void 0 ? void 0 : eventResult.shouldPersist,
12716
12758
  };
12717
12759
  if (editor.isDarkMode()) {
12718
- (0, roosterjs_content_model_dom_1.transformColor)(wrapper, true /*includeSelf*/, 'lightToDark', editor.getColorManager());
12760
+ (0, roosterjs_content_model_dom_1.transformColor)(wrapper, true /*includeSelf*/, 'lightToDark', editor.getColorManager(), {
12761
+ tableBorders: editor.isExperimentalFeatureEnabled('TransformTableBorderColors'),
12762
+ });
12719
12763
  }
12720
12764
  }
12721
12765
  else if (id) {
@@ -14984,7 +15028,9 @@ var Editor = /** @class */ (function () {
14984
15028
  var result = node.cloneNode(true /*deep*/);
14985
15029
  if (_this.isDarkMode()) {
14986
15030
  var colorHandler = _this.getColorManager();
14987
- (0, roosterjs_content_model_dom_1.transformColor)(result, true /*includeSelf*/, 'darkToLight', colorHandler);
15031
+ (0, roosterjs_content_model_dom_1.transformColor)(result, true /*includeSelf*/, 'darkToLight', colorHandler, {
15032
+ tableBorders: _this.isExperimentalFeatureEnabled('TransformTableBorderColors'),
15033
+ });
14988
15034
  result.style.color = result.style.color || 'inherit';
14989
15035
  result.style.backgroundColor = result.style.backgroundColor || 'inherit';
14990
15036
  }
@@ -15122,7 +15168,7 @@ var Editor = /** @class */ (function () {
15122
15168
  * @returns The HTML document which contains this editor
15123
15169
  */
15124
15170
  Editor.prototype.getDocument = function () {
15125
- return this.getCore().physicalRoot.ownerDocument;
15171
+ return this.getCore().environment.document;
15126
15172
  };
15127
15173
  /**
15128
15174
  * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.
@@ -15184,7 +15230,9 @@ var Editor = /** @class */ (function () {
15184
15230
  Editor.prototype.setDarkModeState = function (isDarkMode) {
15185
15231
  var core = this.getCore();
15186
15232
  if (!!isDarkMode != core.lifecycle.isDarkMode) {
15187
- (0, roosterjs_content_model_dom_1.transformColor)(core.physicalRoot, false /*includeSelf*/, isDarkMode ? 'lightToDark' : 'darkToLight', core.darkColorHandler);
15233
+ (0, roosterjs_content_model_dom_1.transformColor)(core.physicalRoot, false /*includeSelf*/, isDarkMode ? 'lightToDark' : 'darkToLight', core.darkColorHandler, {
15234
+ tableBorders: this.isExperimentalFeatureEnabled('TransformTableBorderColors'),
15235
+ });
15188
15236
  core.lifecycle.isDarkMode = !!isDarkMode;
15189
15237
  core.api.triggerEvent(core, {
15190
15238
  eventType: 'contentChanged',
@@ -15575,12 +15623,13 @@ function createEditorEnvironment(contentDiv, options) {
15575
15623
  var userAgent = (_b = navigator === null || navigator === void 0 ? void 0 : navigator.userAgent) !== null && _b !== void 0 ? _b : '';
15576
15624
  var appVersion = (_c = navigator === null || navigator === void 0 ? void 0 : navigator.appVersion) !== null && _c !== void 0 ? _c : '';
15577
15625
  return {
15626
+ document: contentDiv.ownerDocument,
15578
15627
  domToModelSettings: (0, createEditorDefaultSettings_1.createDomToModelSettings)(options),
15579
15628
  modelToDomSettings: (0, createEditorDefaultSettings_1.createModelToDomSettings)(options),
15580
15629
  isMac: appVersion.indexOf('Mac') != -1,
15581
15630
  isAndroid: /android/i.test(userAgent),
15582
15631
  isIOS: /iPad|iPhone/.test(userAgent),
15583
- isSafari: userAgent.indexOf('Safari') >= 0 &&
15632
+ isSafari: userAgent.indexOf('AppleWebKit') >= 0 &&
15584
15633
  userAgent.indexOf('Chrome') < 0 &&
15585
15634
  userAgent.indexOf('Android') < 0,
15586
15635
  isMobileOrTablet: getIsMobileOrTablet(userAgent),
@@ -17406,7 +17455,12 @@ exports.ContextStyles = [
17406
17455
  'paddingRight',
17407
17456
  ];
17408
17457
  /**
17409
- * @internal
17458
+ * Content Model Element Processor for format container elements (e.g., blockquote, div)
17459
+ * Processes elements that create FormatContainer blocks in the content model.
17460
+ * This processor can be used in processorOverride to customize how specific elements are processed.
17461
+ * @param group The parent block group
17462
+ * @param element The DOM element to process
17463
+ * @param context DOM to Content Model context
17410
17464
  */
17411
17465
  var formatContainerProcessor = function (group, element, context) {
17412
17466
  (0, stackFormat_1.stackFormat)(context, { segment: 'shallowCloneForBlock', paragraph: 'shallowClone' }, function () {
@@ -20012,25 +20066,50 @@ function process(fontFamily, result, start, end) {
20012
20066
 
20013
20067
  Object.defineProperty(exports, "__esModule", ({ value: true }));
20014
20068
  exports.transformColor = void 0;
20069
+ var borderKeys_1 = __webpack_require__(/*! ../../formatHandlers/utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
20070
+ var isElementOfType_1 = __webpack_require__(/*! ../isElementOfType */ "./packages/roosterjs-content-model-dom/lib/domUtils/isElementOfType.ts");
20015
20071
  var color_1 = __webpack_require__(/*! ../../formatHandlers/utils/color */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/color.ts");
20016
20072
  /**
20017
20073
  * Edit and transform color of elements between light mode and dark mode
20074
+ * By default, text and background colors are transformed for all elements.
20018
20075
  * @param rootNode The root DOM node to transform
20019
20076
  * @param includeSelf True to transform the root node as well, otherwise false
20020
20077
  * @param direction To specify the transform direction, light to dark, or dark to light
20021
20078
  * @param darkColorHandler The dark color handler object to help do color transformation
20079
+ * @param transformColorOptions Configuration options for controlling which elements and styles undergo color transformation.
20022
20080
  */
20023
- function transformColor(rootNode, includeSelf, direction, darkColorHandler) {
20081
+ function transformColor(rootNode, includeSelf, direction, darkColorHandler, transformColorOptions) {
20024
20082
  var toDarkMode = direction == 'lightToDark';
20083
+ var tableBorders = (transformColorOptions === null || transformColorOptions === void 0 ? void 0 : transformColorOptions.tableBorders) || false;
20025
20084
  var transformer = function (element) {
20026
20085
  var textColor = (0, color_1.getColor)(element, false /*isBackground*/, !toDarkMode, darkColorHandler);
20027
20086
  var backColor = (0, color_1.getColor)(element, true /*isBackground*/, !toDarkMode, darkColorHandler);
20028
20087
  (0, color_1.setColor)(element, textColor, false /*isBackground*/, toDarkMode, darkColorHandler);
20029
20088
  (0, color_1.setColor)(element, backColor, true /*isBackground*/, toDarkMode, darkColorHandler);
20089
+ if (tableBorders) {
20090
+ transformBorderColor(element, toDarkMode, darkColorHandler);
20091
+ }
20030
20092
  };
20031
20093
  iterateElements(rootNode, transformer, includeSelf);
20032
20094
  }
20033
20095
  exports.transformColor = transformColor;
20096
+ function transformBorderColor(element, toDarkMode, darkColorHandler) {
20097
+ if ((0, isElementOfType_1.isElementOfType)(element, 'td') || (0, isElementOfType_1.isElementOfType)(element, 'th')) {
20098
+ borderKeys_1.BorderKeys.forEach(function (key) {
20099
+ var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
20100
+ var style = element.style.getPropertyValue(borderColorProperty);
20101
+ if (style) {
20102
+ var lightColor = (0, color_1.getLightModeColor)(style, !toDarkMode, darkColorHandler);
20103
+ if (lightColor) {
20104
+ var transformedColor = (0, color_1.adaptColor)(element, lightColor, 'border', toDarkMode, darkColorHandler);
20105
+ if (transformedColor) {
20106
+ element.style.setProperty(borderColorProperty, transformedColor);
20107
+ }
20108
+ }
20109
+ }
20110
+ });
20111
+ }
20112
+ }
20034
20113
  function iterateElements(root, transformer, includeSelf) {
20035
20114
  if (includeSelf && isHTMLElement(root)) {
20036
20115
  transformer(root);
@@ -20478,30 +20557,14 @@ exports.textAlignFormatHandler = {
20478
20557
  var _a;
20479
20558
  directionFormatHandler_1.directionFormatHandler.parse(format, element, context, defaultStyle);
20480
20559
  var textAlign = element.style.textAlign || defaultStyle.textAlign;
20481
- if (element.tagName == 'LI' &&
20482
- ((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.style.display) === 'flex' &&
20483
- element.parentElement.style.flexDirection === 'column' &&
20484
- element.style.alignSelf) {
20485
- // For LI element with flex style applied, we use its "align-self" style value instead since LI has a different implementation for align
20486
- textAlign = element.style.alignSelf;
20487
- }
20488
- if (textAlign) {
20560
+ if (textAlign && ((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.style.display) !== 'flex') {
20489
20561
  format.textAlign = (0, dir_1.calcAlign)(textAlign, format.direction);
20490
20562
  }
20491
20563
  },
20492
20564
  apply: function (format, element) {
20493
20565
  var dir = format.direction == 'rtl' ? 'rtl' : 'ltr';
20494
20566
  if (format.textAlign) {
20495
- var parent_1 = element.parentElement;
20496
- var parentTag = parent_1 === null || parent_1 === void 0 ? void 0 : parent_1.tagName;
20497
- if (element.tagName == 'LI' && parent_1 && (parentTag == 'OL' || parentTag == 'UL')) {
20498
- element.style.alignSelf = format.textAlign;
20499
- element.parentElement.style.flexDirection = 'column';
20500
- element.parentElement.style.display = 'flex';
20501
- }
20502
- else {
20503
- element.style.textAlign = dir_1.ResultMap[format.textAlign][dir];
20504
- }
20567
+ element.style.textAlign = dir_1.ResultMap[format.textAlign][dir];
20505
20568
  }
20506
20569
  },
20507
20570
  };
@@ -20668,27 +20731,96 @@ exports.borderBoxFormatHandler = {
20668
20731
  };
20669
20732
 
20670
20733
 
20734
+ /***/ }),
20735
+
20736
+ /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderColorFormatHandler.ts":
20737
+ /*!****************************************************************************************************!*\
20738
+ !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderColorFormatHandler.ts ***!
20739
+ \****************************************************************************************************/
20740
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20741
+
20742
+ "use strict";
20743
+
20744
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20745
+ exports.borderColorFormatHandler = void 0;
20746
+ var color_1 = __webpack_require__(/*! ../utils/color */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/color.ts");
20747
+ var borderKeys_1 = __webpack_require__(/*! ../utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
20748
+ var borderValues_1 = __webpack_require__(/*! ../../domUtils/style/borderValues */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts");
20749
+ /**
20750
+ * Keys of border width
20751
+ */
20752
+ var BorderWidthKeyMap = {
20753
+ borderTop: 'border-top-width',
20754
+ borderRight: 'border-right-width',
20755
+ borderBottom: 'border-bottom-width',
20756
+ borderLeft: 'border-left-width',
20757
+ };
20758
+ /**
20759
+ * Keys of border styles
20760
+ */
20761
+ var BorderStyleKeyMap = {
20762
+ borderTop: 'border-top-style',
20763
+ borderRight: 'border-right-style',
20764
+ borderBottom: 'border-bottom-style',
20765
+ borderLeft: 'border-left-style',
20766
+ };
20767
+ /**
20768
+ * @internal
20769
+ */
20770
+ exports.borderColorFormatHandler = {
20771
+ parse: function (format, element, context) {
20772
+ if (context.experimentalFeatures &&
20773
+ context.experimentalFeatures.indexOf('TransformTableBorderColors') > -1) {
20774
+ borderKeys_1.BorderKeys.forEach(function (key) {
20775
+ var width = element.style.getPropertyValue(BorderWidthKeyMap[key]);
20776
+ var style = element.style.getPropertyValue(BorderStyleKeyMap[key]);
20777
+ var borderColor = (0, color_1.retrieveElementColor)(element, key);
20778
+ if (borderColor) {
20779
+ var lightModeColor = (0, color_1.getLightModeColor)(borderColor, !!context.isDarkMode, context.darkColorHandler);
20780
+ format[key] = (0, borderValues_1.combineBorderValue)({
20781
+ width: width,
20782
+ style: style,
20783
+ color: lightModeColor,
20784
+ });
20785
+ }
20786
+ });
20787
+ }
20788
+ },
20789
+ apply: function (format, element, context) {
20790
+ if (context.experimentalFeatures &&
20791
+ context.experimentalFeatures.indexOf('TransformTableBorderColors') > -1) {
20792
+ borderKeys_1.BorderKeys.forEach(function (key) {
20793
+ var value = format[key];
20794
+ if (value) {
20795
+ var borderValues = (0, borderValues_1.extractBorderValues)(value);
20796
+ if (borderValues.color) {
20797
+ var transformedColor = (0, color_1.adaptColor)(element, borderValues.color, 'border', !!context.isDarkMode, context.darkColorHandler);
20798
+ if (transformedColor) {
20799
+ var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
20800
+ element.style.setProperty(borderColorProperty, transformedColor);
20801
+ }
20802
+ }
20803
+ }
20804
+ });
20805
+ }
20806
+ },
20807
+ };
20808
+
20809
+
20671
20810
  /***/ }),
20672
20811
 
20673
20812
  /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderFormatHandler.ts":
20674
20813
  /*!***********************************************************************************************!*\
20675
20814
  !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderFormatHandler.ts ***!
20676
20815
  \***********************************************************************************************/
20677
- /***/ ((__unused_webpack_module, exports) => {
20816
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20678
20817
 
20679
20818
  "use strict";
20680
20819
 
20681
20820
  Object.defineProperty(exports, "__esModule", ({ value: true }));
20682
- exports.borderFormatHandler = exports.BorderKeys = void 0;
20683
- /**
20684
- * Keys of border items
20685
- */
20686
- exports.BorderKeys = [
20687
- 'borderTop',
20688
- 'borderRight',
20689
- 'borderBottom',
20690
- 'borderLeft',
20691
- ];
20821
+ exports.borderFormatHandler = void 0;
20822
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
20823
+ var borderKeys_1 = __webpack_require__(/*! ../utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
20692
20824
  // This array needs to match BorderKeys array
20693
20825
  var BorderWidthKeys = [
20694
20826
  'borderTopWidth',
@@ -20702,13 +20834,13 @@ var BorderRadiusKeys = [
20702
20834
  'borderBottomLeftRadius',
20703
20835
  'borderBottomRightRadius',
20704
20836
  ];
20705
- var AllKeys = exports.BorderKeys.concat(BorderRadiusKeys);
20837
+ var AllKeys = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(borderKeys_1.BorderKeys), false), (0, tslib_1.__read)(BorderRadiusKeys), false);
20706
20838
  /**
20707
20839
  * @internal
20708
20840
  */
20709
20841
  exports.borderFormatHandler = {
20710
20842
  parse: function (format, element, _, defaultStyle) {
20711
- exports.BorderKeys.forEach(function (key, i) {
20843
+ borderKeys_1.BorderKeys.forEach(function (key, i) {
20712
20844
  var _a;
20713
20845
  var value = element.style[key];
20714
20846
  var defaultWidth = (_a = defaultStyle[BorderWidthKeys[i]]) !== null && _a !== void 0 ? _a : '0px';
@@ -21063,6 +21195,7 @@ var ariaFormatHandler_1 = __webpack_require__(/*! ./common/ariaFormatHandler */
21063
21195
  var backgroundColorFormatHandler_1 = __webpack_require__(/*! ./common/backgroundColorFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/backgroundColorFormatHandler.ts");
21064
21196
  var boldFormatHandler_1 = __webpack_require__(/*! ./segment/boldFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/boldFormatHandler.ts");
21065
21197
  var borderBoxFormatHandler_1 = __webpack_require__(/*! ./common/borderBoxFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderBoxFormatHandler.ts");
21198
+ var borderColorFormatHandler_1 = __webpack_require__(/*! ./common/borderColorFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderColorFormatHandler.ts");
21066
21199
  var borderFormatHandler_1 = __webpack_require__(/*! ./common/borderFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderFormatHandler.ts");
21067
21200
  var boxShadowFormatHandler_1 = __webpack_require__(/*! ./common/boxShadowFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/boxShadowFormatHandler.ts");
21068
21201
  var datasetFormatHandler_1 = __webpack_require__(/*! ./common/datasetFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/datasetFormatHandler.ts");
@@ -21077,9 +21210,11 @@ var htmlAlignFormatHandler_1 = __webpack_require__(/*! ./block/htmlAlignFormatHa
21077
21210
  var idFormatHandler_1 = __webpack_require__(/*! ./common/idFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/idFormatHandler.ts");
21078
21211
  var imageStateFormatHandler_1 = __webpack_require__(/*! ./segment/imageStateFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/imageStateFormatHandler.ts");
21079
21212
  var italicFormatHandler_1 = __webpack_require__(/*! ./segment/italicFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/italicFormatHandler.ts");
21213
+ var legacyTableBorderFormatHandler_1 = __webpack_require__(/*! ./table/legacyTableBorderFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/table/legacyTableBorderFormatHandler.ts");
21080
21214
  var letterSpacingFormatHandler_1 = __webpack_require__(/*! ./segment/letterSpacingFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/letterSpacingFormatHandler.ts");
21081
21215
  var lineHeightFormatHandler_1 = __webpack_require__(/*! ./block/lineHeightFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/block/lineHeightFormatHandler.ts");
21082
21216
  var linkFormatHandler_1 = __webpack_require__(/*! ./segment/linkFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/linkFormatHandler.ts");
21217
+ var listItemAlignFormatHandler_1 = __webpack_require__(/*! ./list/listItemAlignFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listItemAlignFormatHandler.ts");
21083
21218
  var listItemThreadFormatHandler_1 = __webpack_require__(/*! ./list/listItemThreadFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listItemThreadFormatHandler.ts");
21084
21219
  var listLevelThreadFormatHandler_1 = __webpack_require__(/*! ./list/listLevelThreadFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listLevelThreadFormatHandler.ts");
21085
21220
  var listStyleFormatHandler_1 = __webpack_require__(/*! ./list/listStyleFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listStyleFormatHandler.ts");
@@ -21106,6 +21241,7 @@ var defaultFormatHandlerMap = {
21106
21241
  bold: boldFormatHandler_1.boldFormatHandler,
21107
21242
  border: borderFormatHandler_1.borderFormatHandler,
21108
21243
  borderBox: borderBoxFormatHandler_1.borderBoxFormatHandler,
21244
+ borderColor: borderColorFormatHandler_1.borderColorFormatHandler,
21109
21245
  boxShadow: boxShadowFormatHandler_1.boxShadowFormatHandler,
21110
21246
  dataset: datasetFormatHandler_1.datasetFormatHandler,
21111
21247
  direction: directionFormatHandler_1.directionFormatHandler,
@@ -21118,9 +21254,11 @@ var defaultFormatHandlerMap = {
21118
21254
  id: idFormatHandler_1.idFormatHandler,
21119
21255
  imageState: imageStateFormatHandler_1.imageStateFormatHandler,
21120
21256
  italic: italicFormatHandler_1.italicFormatHandler,
21257
+ legacyTableBorder: legacyTableBorderFormatHandler_1.legacyTableBorderFormatHandler,
21121
21258
  letterSpacing: letterSpacingFormatHandler_1.letterSpacingFormatHandler,
21122
21259
  lineHeight: lineHeightFormatHandler_1.lineHeightFormatHandler,
21123
21260
  link: linkFormatHandler_1.linkFormatHandler,
21261
+ listItemAlign: listItemAlignFormatHandler_1.listItemAlignFormatHandler,
21124
21262
  listItemThread: listItemThreadFormatHandler_1.listItemThreadFormatHandler,
21125
21263
  listLevelThread: listLevelThreadFormatHandler_1.listLevelThreadFormatHandler,
21126
21264
  listStyle: listStyleFormatHandler_1.listStyleFormatHandler,
@@ -21174,13 +21312,7 @@ exports.defaultFormatKeysPerCategory = {
21174
21312
  block: sharedBlockFormats,
21175
21313
  listItemThread: ['listItemThread'],
21176
21314
  listLevelThread: ['listLevelThread'],
21177
- listItemElement: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedBlockFormats), false), [
21178
- 'direction',
21179
- 'textAlign',
21180
- 'lineHeight',
21181
- 'margin',
21182
- 'listStyle',
21183
- ], false),
21315
+ listItemElement: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedBlockFormats), false), ['listItemAlign', 'margin', 'listStyle'], false),
21184
21316
  listLevel: ['direction', 'textAlign', 'margin', 'padding', 'listStyle', 'backgroundColor'],
21185
21317
  styleBasedSegment: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(styleBasedSegmentFormats), false), ['textColor', 'backgroundColor', 'lineHeight'], false),
21186
21318
  elementBasedSegment: elementBasedSegmentFormats,
@@ -21195,6 +21327,7 @@ exports.defaultFormatKeysPerCategory = {
21195
21327
  ], false),
21196
21328
  tableCell: [
21197
21329
  'border',
21330
+ 'borderColor',
21198
21331
  'backgroundColor',
21199
21332
  'padding',
21200
21333
  'verticalAlign',
@@ -21219,7 +21352,7 @@ exports.defaultFormatKeysPerCategory = {
21219
21352
  'direction',
21220
21353
  'role',
21221
21354
  ],
21222
- tableBorder: ['borderBox', 'tableSpacing'],
21355
+ tableBorder: ['borderBox', 'tableSpacing', 'legacyTableBorder'],
21223
21356
  tableCellBorder: ['borderBox'],
21224
21357
  image: [
21225
21358
  'id',
@@ -21305,6 +21438,53 @@ exports.entityFormatHandler = {
21305
21438
  };
21306
21439
 
21307
21440
 
21441
+ /***/ }),
21442
+
21443
+ /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listItemAlignFormatHandler.ts":
21444
+ /*!****************************************************************************************************!*\
21445
+ !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listItemAlignFormatHandler.ts ***!
21446
+ \****************************************************************************************************/
21447
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
21448
+
21449
+ "use strict";
21450
+
21451
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
21452
+ exports.listItemAlignFormatHandler = void 0;
21453
+ var dir_1 = __webpack_require__(/*! ../utils/dir */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/dir.ts");
21454
+ /**
21455
+ * @internal
21456
+ */
21457
+ exports.listItemAlignFormatHandler = {
21458
+ parse: function (format, element, context) {
21459
+ var _a;
21460
+ // For list, we usually use align-self to implement alignment
21461
+ if (element.style.alignSelf) {
21462
+ format.textAlign = (0, dir_1.calcAlign)(element.style.alignSelf, context.blockFormat.direction);
21463
+ }
21464
+ else if (element.style.textAlign && ((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.style.display) !== 'flex') {
21465
+ var align = element.style.textAlign;
21466
+ // For RTL environment, 'start' and 'end' in textAlign means opposite direction compared to LTR unless parent is using flex display
21467
+ if (context.blockFormat.direction === 'rtl' && (align == 'start' || align == 'end')) {
21468
+ align = align == 'start' ? 'end' : 'start';
21469
+ }
21470
+ format.textAlign = (0, dir_1.calcAlign)(align, context.blockFormat.direction);
21471
+ }
21472
+ },
21473
+ apply: function (format, element) {
21474
+ if (format.textAlign) {
21475
+ var parent_1 = element.parentElement;
21476
+ element.style.alignSelf = format.textAlign;
21477
+ // For list item we use align-self to implement textAlign rather than text-align
21478
+ element.style.removeProperty('text-align');
21479
+ if (parent_1) {
21480
+ parent_1.style.flexDirection = 'column';
21481
+ parent_1.style.display = 'flex';
21482
+ }
21483
+ }
21484
+ },
21485
+ };
21486
+
21487
+
21308
21488
  /***/ }),
21309
21489
 
21310
21490
  /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/list/listItemThreadFormatHandler.ts":
@@ -21980,6 +22160,50 @@ exports.underlineFormatHandler = {
21980
22160
  };
21981
22161
 
21982
22162
 
22163
+ /***/ }),
22164
+
22165
+ /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/table/legacyTableBorderFormatHandler.ts":
22166
+ /*!*********************************************************************************************************!*\
22167
+ !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/table/legacyTableBorderFormatHandler.ts ***!
22168
+ \*********************************************************************************************************/
22169
+ /***/ ((__unused_webpack_module, exports) => {
22170
+
22171
+ "use strict";
22172
+
22173
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
22174
+ exports.legacyTableBorderFormatHandler = void 0;
22175
+ /**
22176
+ * @internal
22177
+ */
22178
+ exports.legacyTableBorderFormatHandler = {
22179
+ parse: function (format, element) {
22180
+ var border = element.getAttribute('border');
22181
+ var cellSpacing = element.getAttribute('cellspacing');
22182
+ var cellpadding = element.getAttribute('cellpadding');
22183
+ if (border) {
22184
+ format.legacyTableBorder = border;
22185
+ }
22186
+ if (cellSpacing) {
22187
+ format.cellSpacing = cellSpacing;
22188
+ }
22189
+ if (cellpadding) {
22190
+ format.cellPadding = cellpadding;
22191
+ }
22192
+ },
22193
+ apply: function (format, element) {
22194
+ if (format.legacyTableBorder) {
22195
+ element.setAttribute('border', format.legacyTableBorder);
22196
+ }
22197
+ if (format.cellSpacing) {
22198
+ element.setAttribute('cellspacing', format.cellSpacing);
22199
+ }
22200
+ if (format.cellPadding) {
22201
+ element.setAttribute('cellpadding', format.cellPadding);
22202
+ }
22203
+ },
22204
+ };
22205
+
22206
+
21983
22207
  /***/ }),
21984
22208
 
21985
22209
  /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/table/tableLayoutFormatHandler.ts":
@@ -22024,7 +22248,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
22024
22248
  exports.tableSpacingFormatHandler = void 0;
22025
22249
  var BorderCollapsed = 'collapse';
22026
22250
  var BorderSeparate = 'separate';
22027
- var CellPadding = 'cellPadding';
22028
22251
  /**
22029
22252
  * @internal
22030
22253
  */
@@ -22033,12 +22256,6 @@ exports.tableSpacingFormatHandler = {
22033
22256
  if (element.style.borderCollapse == BorderCollapsed) {
22034
22257
  format.borderCollapse = true;
22035
22258
  }
22036
- else {
22037
- var cellPadding = element.getAttribute(CellPadding);
22038
- if (cellPadding) {
22039
- format.borderCollapse = true;
22040
- }
22041
- }
22042
22259
  if (element.style.borderCollapse == BorderSeparate) {
22043
22260
  format.borderSeparate = true;
22044
22261
  }
@@ -22086,6 +22303,38 @@ exports.textColorOnTableCellFormatHandler = {
22086
22303
  };
22087
22304
 
22088
22305
 
22306
+ /***/ }),
22307
+
22308
+ /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts":
22309
+ /*!*************************************************************************************!*\
22310
+ !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts ***!
22311
+ \*************************************************************************************/
22312
+ /***/ ((__unused_webpack_module, exports) => {
22313
+
22314
+ "use strict";
22315
+
22316
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
22317
+ exports.BorderColorKeyMap = exports.BorderKeys = void 0;
22318
+ /**
22319
+ * Keys of border items
22320
+ */
22321
+ exports.BorderKeys = [
22322
+ 'borderTop',
22323
+ 'borderRight',
22324
+ 'borderBottom',
22325
+ 'borderLeft',
22326
+ ];
22327
+ /**
22328
+ * @internal
22329
+ */
22330
+ exports.BorderColorKeyMap = {
22331
+ borderTop: 'border-top-color',
22332
+ borderRight: 'border-right-color',
22333
+ borderBottom: 'border-bottom-color',
22334
+ borderLeft: 'border-left-color',
22335
+ };
22336
+
22337
+
22089
22338
  /***/ }),
22090
22339
 
22091
22340
  /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/color.ts":
@@ -22097,8 +22346,9 @@ exports.textColorOnTableCellFormatHandler = {
22097
22346
  "use strict";
22098
22347
 
22099
22348
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22100
- exports.parseColor = exports.defaultGenerateColorKey = exports.setColor = exports.getColor = exports.DeprecatedColors = void 0;
22349
+ exports.parseColor = exports.defaultGenerateColorKey = exports.adaptColor = exports.setColor = exports.retrieveElementColor = exports.getLightModeColor = exports.getColor = exports.DeprecatedColors = void 0;
22101
22350
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
22351
+ var borderKeys_1 = __webpack_require__(/*! ./borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
22102
22352
  var getObjectKeys_1 = __webpack_require__(/*! ../../domUtils/getObjectKeys */ "./packages/roosterjs-content-model-dom/lib/domUtils/getObjectKeys.ts");
22103
22353
  /**
22104
22354
  * List of deprecated colors
@@ -22146,13 +22396,20 @@ var COLOR_VAR_PREFIX = '--darkColor';
22146
22396
  * @param fallback @optional Fallback color to use if no color is found from the element
22147
22397
  */
22148
22398
  function getColor(element, isBackground, isDarkMode, darkColorHandler, fallback) {
22149
- var color = (isBackground ? element.style.backgroundColor : element.style.color) ||
22150
- element.getAttribute(isBackground ? 'bgcolor' : 'color') ||
22151
- fallback;
22152
- if (color && exports.DeprecatedColors.indexOf(color) > -1) {
22153
- color = isBackground ? undefined : BlackColor;
22399
+ var color = retrieveElementColor(element, isBackground ? 'background' : 'text', fallback);
22400
+ return color
22401
+ ? getLightModeColor(color, isDarkMode, darkColorHandler, isBackground ? undefined : BlackColor)
22402
+ : undefined;
22403
+ }
22404
+ exports.getColor = getColor;
22405
+ /**
22406
+ * @internal
22407
+ */
22408
+ function getLightModeColor(color, isDarkMode, darkColorHandler, fallback) {
22409
+ if (exports.DeprecatedColors.indexOf(color) > -1) {
22410
+ return fallback;
22154
22411
  }
22155
- else if (darkColorHandler && color) {
22412
+ else if (darkColorHandler) {
22156
22413
  var match = color.startsWith(VARIABLE_PREFIX) ? VARIABLE_REGEX.exec(color) : null;
22157
22414
  if (match) {
22158
22415
  color = match[2] || '';
@@ -22161,12 +22418,26 @@ function getColor(element, isBackground, isDarkMode, darkColorHandler, fallback)
22161
22418
  // If editor is in dark mode but the color is not in dark color format, it is possible the color was inserted from external code
22162
22419
  // without any light color info. So we first try to see if there is a known dark color can match this color, and use its related
22163
22420
  // light color as light mode color. Otherwise we need to drop this color to avoid show "white on white" content.
22164
- color = findLightColorFromDarkColor(color, darkColorHandler.knownColors) || '';
22421
+ return findLightColorFromDarkColor(color, darkColorHandler.knownColors) || '';
22165
22422
  }
22166
22423
  }
22167
22424
  return color;
22168
22425
  }
22169
- exports.getColor = getColor;
22426
+ exports.getLightModeColor = getLightModeColor;
22427
+ /**
22428
+ * @internal
22429
+ */
22430
+ function retrieveElementColor(element, source, fallback) {
22431
+ switch (source) {
22432
+ case 'text':
22433
+ return element.style.color || element.getAttribute('color') || fallback;
22434
+ case 'background':
22435
+ return element.style.backgroundColor || element.getAttribute('bgcolor') || fallback;
22436
+ default:
22437
+ return element.style.getPropertyValue(borderKeys_1.BorderColorKeyMap[source]) || fallback;
22438
+ }
22439
+ }
22440
+ exports.retrieveElementColor = retrieveElementColor;
22170
22441
  /**
22171
22442
  * Set color to given HTML element
22172
22443
  * @param element The element to set color to
@@ -22176,12 +22447,20 @@ exports.getColor = getColor;
22176
22447
  * @param darkColorHandler @optional The dark color handler object to help manager dark mode color
22177
22448
  */
22178
22449
  function setColor(element, color, isBackground, isDarkMode, darkColorHandler) {
22450
+ var newColor = adaptColor(element, color, isBackground ? 'background' : 'text', isDarkMode, darkColorHandler);
22451
+ element.removeAttribute(isBackground ? 'bgcolor' : 'color');
22452
+ element.style.setProperty(isBackground ? 'background-color' : 'color', newColor || null);
22453
+ }
22454
+ exports.setColor = setColor;
22455
+ /**
22456
+ * @internal
22457
+ */
22458
+ function adaptColor(element, color, colorType, isDarkMode, darkColorHandler) {
22179
22459
  var _a, _b;
22180
22460
  var match = color && color.startsWith(VARIABLE_PREFIX) ? VARIABLE_REGEX.exec(color) : null;
22181
22461
  var _c = (0, tslib_1.__read)(match !== null && match !== void 0 ? match : [], 3), _ = _c[0], existingKey = _c[1], fallbackColor = _c[2];
22182
22462
  color = fallbackColor !== null && fallbackColor !== void 0 ? fallbackColor : color;
22183
22463
  if (darkColorHandler && color) {
22184
- var colorType = isBackground ? 'background' : 'text';
22185
22464
  var key = existingKey ||
22186
22465
  darkColorHandler.generateColorKey(color, undefined /*baseLValue*/, colorType, element);
22187
22466
  var darkModeColor = ((_b = (_a = darkColorHandler.knownColors) === null || _a === void 0 ? void 0 : _a[key]) === null || _b === void 0 ? void 0 : _b.darkModeColor) ||
@@ -22192,10 +22471,9 @@ function setColor(element, color, isBackground, isDarkMode, darkColorHandler) {
22192
22471
  });
22193
22472
  color = isDarkMode ? "" + VARIABLE_PREFIX + key + ", " + color + VARIABLE_POSTFIX : color;
22194
22473
  }
22195
- element.removeAttribute(isBackground ? 'bgcolor' : 'color');
22196
- element.style.setProperty(isBackground ? 'background-color' : 'color', color || null);
22474
+ return color;
22197
22475
  }
22198
- exports.setColor = setColor;
22476
+ exports.adaptColor = adaptColor;
22199
22477
  /**
22200
22478
  * Generate color key for dark color
22201
22479
  * @param lightColor The input light color
@@ -22431,10 +22709,10 @@ exports.shouldSetValue = shouldSetValue;
22431
22709
  "use strict";
22432
22710
 
22433
22711
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22434
- exports.createContentModelDocument = exports.createImage = exports.createText = exports.createTableCell = exports.createTable = exports.createSelectionMarker = exports.createParagraph = exports.createFormatContainer = exports.createListItem = exports.createBr = exports.isLinkUndeletable = exports.setLinkUndeletable = exports.scrollRectIntoView = exports.normalizeRect = exports.isWhiteSpacePreserved = exports.reuseCachedElement = exports.findClosestBlockEntityContainer = exports.isBlockEntityContainer = exports.isEntityDelimiter = exports.addDelimiters = exports.generateEntityClassNames = exports.parseEntityFormat = exports.getAllEntityWrappers = exports.findClosestEntityWrapper = exports.isEntityElement = exports.unwrap = exports.wrap = exports.wrapAllChildNodes = exports.moveChildNodes = exports.toArray = exports.getSafeIdSelector = exports.getObjectKeys = exports.isElementOfType = exports.isNodeOfType = exports.hasMetadata = exports.getMetadata = exports.updateMetadata = exports.buildSelectionMarker = exports.isBlockElement = exports.areSameFormats = exports.parseFormat = exports.getRegularSelectionOffsets = exports.tableProcessor = exports.entityProcessor = exports.processChildNode = exports.handleRegularSelection = exports.childProcessor = exports.contentModelToText = exports.contentModelToDom = exports.domToContentModel = void 0;
22435
- exports.isModifierKey = exports.isCharacterValue = exports.getDOMInsertPointRect = exports.getSelectionRootNode = exports.isBold = exports.createModelToDomConfig = exports.createModelToDomContextWithConfig = exports.createModelToDomContext = exports.createDomToModelConfig = exports.createDomToModelContextWithConfig = exports.createDomToModelContext = exports.defaultGenerateColorKey = exports.parseColor = exports.setColor = exports.getColor = exports.DeprecatedColors = exports.BorderKeys = exports.parseValueWithUnit = exports.getAutoListStyleType = exports.getOrderedListNumberStr = exports.ParagraphFormats = exports.ListFormatsToMove = exports.ListFormatsToKeep = exports.ListFormats = exports.copyFormat = exports.setParagraphNotImplicit = exports.normalizeSegmentFormat = exports.mergeTextSegments = exports.normalizeSingleSegment = exports.isEmpty = exports.addSegment = exports.unwrapBlock = exports.isGeneralSegment = exports.normalizeContentModel = exports.normalizeParagraph = exports.addTextSegment = exports.addLink = exports.addCode = exports.addBlock = exports.mutateSegment = exports.mutateSegments = exports.mutateBlock = exports.createTableRow = exports.createEmptyModel = exports.createListLevel = exports.createDivider = exports.createEntity = exports.createGeneralBlock = exports.createGeneralSegment = exports.createParagraphDecorator = void 0;
22436
- exports.updateTableCellMetadata = exports.getImageMetadata = exports.updateImageMetadata = exports.runEditSteps = exports.getClosestAncestorBlockGroupIndex = exports.getSegmentTextFormat = exports.getListStyleTypeFromString = exports.retrieveModelFormatState = exports.setTableCellBackgroundColor = exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = exports.MIN_ALLOWED_TABLE_CELL_WIDTH = exports.normalizeTable = exports.setFirstColumnFormatBorders = exports.applyTableFormat = exports.deleteBlock = exports.deleteSegment = exports.deleteSelection = exports.mergeModel = exports.cloneModel = exports.setSelection = exports.hasSelectionInBlockGroup = exports.hasSelectionInSegment = exports.hasSelectionInBlock = exports.getSelectedCells = exports.getSelectedSegmentsAndParagraphs = exports.getSelectedSegments = exports.getSelectedParagraphs = exports.getOperationalBlocks = exports.getFirstSelectedTable = exports.getFirstSelectedListItem = exports.iterateSelections = exports.isBlockGroupOfType = exports.getRangesByText = exports.getImageState = exports.setImageState = exports.getParagraphMarker = exports.setParagraphMarker = exports.cacheGetEventData = exports.extractClipboardItems = exports.normalizeFontFamily = exports.transformColor = exports.retrieveDocumentMetadata = exports.readFile = exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.isCursorMovingKey = void 0;
22437
- exports.EmptySegmentFormat = exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = exports.getTableMetadata = exports.updateTableMetadata = exports.getTableCellMetadata = void 0;
22712
+ exports.createImage = exports.createText = exports.createTableCell = exports.createTable = exports.createSelectionMarker = exports.createParagraph = exports.createFormatContainer = exports.createListItem = exports.createBr = exports.isLinkUndeletable = exports.setLinkUndeletable = exports.scrollRectIntoView = exports.normalizeRect = exports.isWhiteSpacePreserved = exports.reuseCachedElement = exports.findClosestBlockEntityContainer = exports.isBlockEntityContainer = exports.isEntityDelimiter = exports.addDelimiters = exports.generateEntityClassNames = exports.parseEntityFormat = exports.getAllEntityWrappers = exports.findClosestEntityWrapper = exports.isEntityElement = exports.unwrap = exports.wrap = exports.wrapAllChildNodes = exports.moveChildNodes = exports.toArray = exports.getSafeIdSelector = exports.getObjectKeys = exports.isElementOfType = exports.isNodeOfType = exports.hasMetadata = exports.getMetadata = exports.updateMetadata = exports.buildSelectionMarker = exports.isBlockElement = exports.areSameFormats = exports.parseFormat = exports.getRegularSelectionOffsets = exports.formatContainerProcessor = exports.tableProcessor = exports.entityProcessor = exports.processChildNode = exports.handleRegularSelection = exports.childProcessor = exports.contentModelToText = exports.contentModelToDom = exports.domToContentModel = void 0;
22713
+ exports.isCharacterValue = exports.getDOMInsertPointRect = exports.getSelectionRootNode = exports.isBold = exports.createModelToDomConfig = exports.createModelToDomContextWithConfig = exports.createModelToDomContext = exports.createDomToModelConfig = exports.createDomToModelContextWithConfig = exports.createDomToModelContext = exports.defaultGenerateColorKey = exports.parseColor = exports.setColor = exports.getColor = exports.DeprecatedColors = exports.BorderKeys = exports.parseValueWithUnit = exports.getAutoListStyleType = exports.getOrderedListNumberStr = exports.ParagraphFormats = exports.ListFormatsToMove = exports.ListFormatsToKeep = exports.ListFormats = exports.copyFormat = exports.setParagraphNotImplicit = exports.normalizeSegmentFormat = exports.mergeTextSegments = exports.normalizeSingleSegment = exports.isEmpty = exports.addSegment = exports.unwrapBlock = exports.isGeneralSegment = exports.normalizeContentModel = exports.normalizeParagraph = exports.addTextSegment = exports.addLink = exports.addCode = exports.addBlock = exports.mutateSegment = exports.mutateSegments = exports.mutateBlock = exports.createTableRow = exports.createEmptyModel = exports.createListLevel = exports.createDivider = exports.createEntity = exports.createGeneralBlock = exports.createGeneralSegment = exports.createParagraphDecorator = exports.createContentModelDocument = void 0;
22714
+ exports.getImageMetadata = exports.updateImageMetadata = exports.runEditSteps = exports.getClosestAncestorBlockGroupIndex = exports.getSegmentTextFormat = exports.getListStyleTypeFromString = exports.retrieveModelFormatState = exports.setTableCellBackgroundColor = exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = exports.MIN_ALLOWED_TABLE_CELL_WIDTH = exports.normalizeTable = exports.setFirstColumnFormatBorders = exports.applyTableFormat = exports.deleteBlock = exports.deleteSegment = exports.deleteSelection = exports.mergeModel = exports.cloneModel = exports.setSelection = exports.hasSelectionInBlockGroup = exports.hasSelectionInSegment = exports.hasSelectionInBlock = exports.getSelectedCells = exports.getSelectedSegmentsAndParagraphs = exports.getSelectedSegments = exports.getSelectedParagraphs = exports.getOperationalBlocks = exports.getFirstSelectedTable = exports.getFirstSelectedListItem = exports.iterateSelections = exports.isBlockGroupOfType = exports.getRangesByText = exports.getImageState = exports.setImageState = exports.getParagraphMarker = exports.setParagraphMarker = exports.cacheGetEventData = exports.extractClipboardItems = exports.normalizeFontFamily = exports.transformColor = exports.retrieveDocumentMetadata = exports.readFile = exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.isCursorMovingKey = exports.isModifierKey = void 0;
22715
+ exports.EmptySegmentFormat = exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = exports.getTableMetadata = exports.updateTableMetadata = exports.getTableCellMetadata = exports.updateTableCellMetadata = void 0;
22438
22716
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
22439
22717
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
22440
22718
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -22449,6 +22727,8 @@ var entityProcessor_1 = __webpack_require__(/*! ./domToModel/processors/entityPr
22449
22727
  Object.defineProperty(exports, "entityProcessor", ({ enumerable: true, get: function () { return entityProcessor_1.entityProcessor; } }));
22450
22728
  var tableProcessor_1 = __webpack_require__(/*! ./domToModel/processors/tableProcessor */ "./packages/roosterjs-content-model-dom/lib/domToModel/processors/tableProcessor.ts");
22451
22729
  Object.defineProperty(exports, "tableProcessor", ({ enumerable: true, get: function () { return tableProcessor_1.tableProcessor; } }));
22730
+ var formatContainerProcessor_1 = __webpack_require__(/*! ./domToModel/processors/formatContainerProcessor */ "./packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts");
22731
+ Object.defineProperty(exports, "formatContainerProcessor", ({ enumerable: true, get: function () { return formatContainerProcessor_1.formatContainerProcessor; } }));
22452
22732
  var getRegularSelectionOffsets_1 = __webpack_require__(/*! ./domToModel/utils/getRegularSelectionOffsets */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/getRegularSelectionOffsets.ts");
22453
22733
  Object.defineProperty(exports, "getRegularSelectionOffsets", ({ enumerable: true, get: function () { return getRegularSelectionOffsets_1.getRegularSelectionOffsets; } }));
22454
22734
  var parseFormat_1 = __webpack_require__(/*! ./domToModel/utils/parseFormat */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/parseFormat.ts");
@@ -22581,8 +22861,8 @@ var getAutoListStyleType_1 = __webpack_require__(/*! ./modelApi/list/getAutoList
22581
22861
  Object.defineProperty(exports, "getAutoListStyleType", ({ enumerable: true, get: function () { return getAutoListStyleType_1.getAutoListStyleType; } }));
22582
22862
  var parseValueWithUnit_1 = __webpack_require__(/*! ./formatHandlers/utils/parseValueWithUnit */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/parseValueWithUnit.ts");
22583
22863
  Object.defineProperty(exports, "parseValueWithUnit", ({ enumerable: true, get: function () { return parseValueWithUnit_1.parseValueWithUnit; } }));
22584
- var borderFormatHandler_1 = __webpack_require__(/*! ./formatHandlers/common/borderFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderFormatHandler.ts");
22585
- Object.defineProperty(exports, "BorderKeys", ({ enumerable: true, get: function () { return borderFormatHandler_1.BorderKeys; } }));
22864
+ var borderKeys_1 = __webpack_require__(/*! ./formatHandlers/utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
22865
+ Object.defineProperty(exports, "BorderKeys", ({ enumerable: true, get: function () { return borderKeys_1.BorderKeys; } }));
22586
22866
  var color_1 = __webpack_require__(/*! ./formatHandlers/utils/color */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/color.ts");
22587
22867
  Object.defineProperty(exports, "DeprecatedColors", ({ enumerable: true, get: function () { return color_1.DeprecatedColors; } }));
22588
22868
  Object.defineProperty(exports, "getColor", ({ enumerable: true, get: function () { return color_1.getColor; } }));
@@ -23585,10 +23865,10 @@ function normalizeLastTextSegment(paragraph, segment, lastInlineSegment) {
23585
23865
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23586
23866
  exports.normalizeSegmentFormat = void 0;
23587
23867
  var createContentModelDocument_1 = __webpack_require__(/*! ../creators/createContentModelDocument */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createContentModelDocument.ts");
23868
+ var createDomToModelContext_1 = __webpack_require__(/*! ../../domToModel/context/createDomToModelContext */ "./packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts");
23869
+ var createModelToDomContext_1 = __webpack_require__(/*! ../../modelToDom/context/createModelToDomContext */ "./packages/roosterjs-content-model-dom/lib/modelToDom/context/createModelToDomContext.ts");
23588
23870
  var createText_1 = __webpack_require__(/*! ../creators/createText */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createText.ts");
23589
23871
  var ensureParagraph_1 = __webpack_require__(/*! ./ensureParagraph */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/ensureParagraph.ts");
23590
- var createModelToDomContext_1 = __webpack_require__(/*! ../../modelToDom/context/createModelToDomContext */ "./packages/roosterjs-content-model-dom/lib/modelToDom/context/createModelToDomContext.ts");
23591
- var createDomToModelContext_1 = __webpack_require__(/*! ../../domToModel/context/createDomToModelContext */ "./packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts");
23592
23872
  /**
23593
23873
  * Some format values can be changed when apply to DOM, such as font family.
23594
23874
  * This function will normalize the format and return the same string after DOM modification.
@@ -23597,7 +23877,7 @@ var createDomToModelContext_1 = __webpack_require__(/*! ../../domToModel/context
23597
23877
  */
23598
23878
  function normalizeSegmentFormat(format, environment) {
23599
23879
  var _a, _b;
23600
- var span = document.createElement('span');
23880
+ var span = environment.document.createElement('span');
23601
23881
  var segment = (0, createText_1.createText)('text', format);
23602
23882
  var domToModelContext = (0, createDomToModelContext_1.createDomToModelContextWithConfig)(environment.domToModelSettings.calculated);
23603
23883
  var modelToDomContext = (0, createModelToDomContext_1.createModelToDomContextWithConfig)(environment.modelToDomSettings.calculated);
@@ -24234,7 +24514,7 @@ var _a;
24234
24514
  Object.defineProperty(exports, "__esModule", ({ value: true }));
24235
24515
  exports.setFirstColumnFormatBorders = exports.applyTableFormat = void 0;
24236
24516
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
24237
- var borderFormatHandler_1 = __webpack_require__(/*! ../../formatHandlers/common/borderFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/borderFormatHandler.ts");
24517
+ var borderKeys_1 = __webpack_require__(/*! ../../formatHandlers/utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
24238
24518
  var borderValues_1 = __webpack_require__(/*! ../../domUtils/style/borderValues */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts");
24239
24519
  var mutate_1 = __webpack_require__(/*! ../common/mutate */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts");
24240
24520
  var setTableCellBackgroundColor_1 = __webpack_require__(/*! ./setTableCellBackgroundColor */ "./packages/roosterjs-content-model-dom/lib/modelApi/editing/setTableCellBackgroundColor.ts");
@@ -24397,7 +24677,7 @@ function formatCells(rows, format, metaOverrides) {
24397
24677
  ];
24398
24678
  transparentBorderMatrix === null || transparentBorderMatrix === void 0 ? void 0 : transparentBorderMatrix.forEach(function (alwaysUseTransparent, i) {
24399
24679
  var borderColor = (!alwaysUseTransparent && formatColor_1[i]) || '';
24400
- cell.format[borderFormatHandler_1.BorderKeys[i]] = (0, borderValues_1.combineBorderValue)({
24680
+ cell.format[borderKeys_1.BorderKeys[i]] = (0, borderValues_1.combineBorderValue)({
24401
24681
  style: getBorderStyleFromColor(borderColor),
24402
24682
  width: '1px',
24403
24683
  color: borderColor,
@@ -25657,7 +25937,7 @@ exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = 22;
25657
25937
  * Normalize a Content Model table, make sure:
25658
25938
  * 1. Fist cells are not spanned
25659
25939
  * 2. Only first column and row can have headers
25660
- * 3. All cells have content and width
25940
+ * 3. All cells have content
25661
25941
  * 4. Table and table row have correct width/height
25662
25942
  * 5. Spanned cell has no child blocks
25663
25943
  * 6. default format is correctly applied
@@ -25667,9 +25947,10 @@ exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = 22;
25667
25947
  function normalizeTable(readonlyTable, defaultSegmentFormat) {
25668
25948
  var _a;
25669
25949
  var table = (0, mutate_1.mutateBlock)(readonlyTable);
25670
- // Always collapse border and use border box for table in roosterjs to make layout simpler
25950
+ // Collapse border and use border box for table in roosterjs to make layout simpler
25951
+ // But if this is a legacy style table (table with deprecated border attributes), we should not change its border model
25671
25952
  var format = table.format;
25672
- if (!format.borderCollapse || !format.useBorderBox) {
25953
+ if (!format.cellSpacing && !format.cellPadding && !format.legacyTableBorder) {
25673
25954
  format.borderCollapse = true;
25674
25955
  format.useBorderBox = true;
25675
25956
  }
@@ -25701,15 +25982,6 @@ function normalizeTable(readonlyTable, defaultSegmentFormat) {
25701
25982
  row.height = exports.MIN_ALLOWED_TABLE_CELL_HEIGHT;
25702
25983
  }
25703
25984
  });
25704
- var columns = Math.max.apply(Math, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(table.rows.map(function (row) { return row.cells.length; })), false));
25705
- for (var i = 0; i < columns; i++) {
25706
- if (table.widths[i] === undefined) {
25707
- table.widths[i] = getTableCellWidth(columns);
25708
- }
25709
- else if (table.widths[i] < exports.MIN_ALLOWED_TABLE_CELL_WIDTH) {
25710
- table.widths[i] = exports.MIN_ALLOWED_TABLE_CELL_WIDTH;
25711
- }
25712
- }
25713
25985
  // Move blocks from spanned cell to its main cell if any,
25714
25986
  // and remove rows/columns if all cells in it are spanned
25715
25987
  var colCount = ((_a = table.rows[0]) === null || _a === void 0 ? void 0 : _a.cells.length) || 0;
@@ -25723,7 +25995,13 @@ function normalizeTable(readonlyTable, defaultSegmentFormat) {
25723
25995
  });
25724
25996
  if (table.rows.every(function (row) { var _a; return (_a = row.cells[colIndex]) === null || _a === void 0 ? void 0 : _a.spanLeft; })) {
25725
25997
  table.rows.forEach(function (row) { return row.cells.splice(colIndex, 1); });
25726
- table.widths.splice(colIndex - 1, 2, table.widths[colIndex - 1] + table.widths[colIndex]);
25998
+ if (typeof table.widths[colIndex] === 'number' &&
25999
+ typeof table.widths[colIndex - 1] === 'number') {
26000
+ table.widths.splice(colIndex - 1, 2, table.widths[colIndex - 1] + table.widths[colIndex]);
26001
+ }
26002
+ else {
26003
+ table.widths.splice(colIndex, 1);
26004
+ }
25727
26005
  }
25728
26006
  };
25729
26007
  for (var colIndex = colCount - 1; colIndex > 0; colIndex--) {
@@ -25748,17 +26026,6 @@ function normalizeTable(readonlyTable, defaultSegmentFormat) {
25748
26026
  }
25749
26027
  }
25750
26028
  exports.normalizeTable = normalizeTable;
25751
- function getTableCellWidth(columns) {
25752
- if (columns <= 4) {
25753
- return 120;
25754
- }
25755
- else if (columns <= 6) {
25756
- return 100;
25757
- }
25758
- else {
25759
- return 70;
25760
- }
25761
- }
25762
26029
  function tryMoveBlocks(targetCell, sourceCell) {
25763
26030
  var _a;
25764
26031
  var onlyHasEmptyOrBr = sourceCell.blocks.every(function (block) { return block.blockType == 'Paragraph' && hasOnlyBrSegment(block.segments); });
@@ -28109,7 +28376,7 @@ var parseValueWithUnit_1 = __webpack_require__(/*! ../../formatHandlers/utils/pa
28109
28376
  */
28110
28377
  var handleImage = function (doc, parent, imageModel, context, segmentNodes) {
28111
28378
  var img = doc.createElement('img');
28112
- var element = document.createElement('span');
28379
+ var element = doc.createElement('span');
28113
28380
  parent.appendChild(element);
28114
28381
  element.appendChild(img);
28115
28382
  img.src = imageModel.src;
@@ -30590,8 +30857,12 @@ function retrieveStringFromParsedTable(tsInfo) {
30590
30857
  var parsedTable = tsInfo.parsedTable, firstCo = tsInfo.firstCo, lastCo = tsInfo.lastCo;
30591
30858
  var result = '';
30592
30859
  if (lastCo) {
30593
- for (var r = firstCo.row; r <= lastCo.row; r++) {
30594
- for (var c = firstCo.col; c <= lastCo.col; c++) {
30860
+ var firstCol = Math.min(firstCo.col, lastCo.col);
30861
+ var lastCol = Math.max(firstCo.col, lastCo.col);
30862
+ var firstRow = Math.min(firstCo.row, lastCo.row);
30863
+ var lastRow = Math.max(firstCo.row, lastCo.row);
30864
+ for (var r = firstRow; r <= lastRow; r++) {
30865
+ for (var c = firstCol; c <= lastCol; c++) {
30595
30866
  var cell = parsedTable[r] && parsedTable[r][c];
30596
30867
  if (cell && typeof cell != 'string') {
30597
30868
  result += ' ' + cell.innerText + ',';
@@ -30639,13 +30910,6 @@ function getIsSelectingOrUnselecting(prevTableSelection, newTableSelection) {
30639
30910
  // Same area but different positions
30640
30911
  return 'selecting';
30641
30912
  }
30642
- if (prevFirstColumn !== newFirstColumn ||
30643
- prevFirstRow !== newFirstRow ||
30644
- prevLastColumn !== newLastColumn ||
30645
- prevLastRow !== newLastRow) {
30646
- return 'selecting';
30647
- }
30648
- return null;
30649
30913
  }
30650
30914
  exports.getIsSelectingOrUnselecting = getIsSelectingOrUnselecting;
30651
30915
 
@@ -30721,8 +30985,8 @@ var AutoFormatPlugin = /** @class */ (function () {
30721
30985
  autoTel: autoTel,
30722
30986
  autoMailto: autoMailto,
30723
30987
  });
30724
- if (linkSegment) {
30725
- return createAnchor(((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
30988
+ if (linkSegment && _this.editor) {
30989
+ return createAnchor(_this.editor.getDocument(), ((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
30726
30990
  }
30727
30991
  return false;
30728
30992
  },
@@ -30951,8 +31215,8 @@ var AutoFormatPlugin = /** @class */ (function () {
30951
31215
  return AutoFormatPlugin;
30952
31216
  }());
30953
31217
  exports.AutoFormatPlugin = AutoFormatPlugin;
30954
- var createAnchor = function (url, text) {
30955
- var anchor = document.createElement('a');
31218
+ var createAnchor = function (doc, url, text) {
31219
+ var anchor = doc.createElement('a');
30956
31220
  anchor.href = url;
30957
31221
  anchor.textContent = text;
30958
31222
  return anchor;
@@ -31650,7 +31914,8 @@ var ORDINAL_LENGTH = 2;
31650
31914
  var numericValue = null;
31651
31915
  if (numberSegment &&
31652
31916
  numberSegment.segmentType == 'Text' &&
31653
- (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&
31917
+ (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) !==
31918
+ null &&
31654
31919
  getOrdinal(numericValue) === value) {
31655
31920
  shouldAddSuperScript = true;
31656
31921
  }
@@ -31658,7 +31923,7 @@ var ORDINAL_LENGTH = 2;
31658
31923
  else {
31659
31924
  var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
31660
31925
  var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =
31661
- if (numericValue && getOrdinal(numericValue) === ordinal) {
31926
+ if (numericValue !== null && getOrdinal(numericValue) === ordinal) {
31662
31927
  shouldAddSuperScript = true;
31663
31928
  }
31664
31929
  }
@@ -32387,25 +32652,55 @@ var insertNewLine = function (quote, parent, quoteIndex, paragraph) {
32387
32652
 
32388
32653
  Object.defineProperty(exports, "__esModule", ({ value: true }));
32389
32654
  exports.deleteList = void 0;
32655
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
32390
32656
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
32391
32657
  /**
32392
32658
  * @internal
32393
32659
  */
32394
32660
  var deleteList = function (context) {
32661
+ var _a, _b;
32395
32662
  if (context.deleteResult != 'notDeleted') {
32396
32663
  return;
32397
32664
  }
32398
- var _a = context.insertPoint, paragraph = _a.paragraph, marker = _a.marker, path = _a.path;
32399
- if (paragraph.segments[0] == marker) {
32400
- var index = (0, roosterjs_content_model_dom_1.getClosestAncestorBlockGroupIndex)(path, ['ListItem'], ['TableCell', 'FormatContainer']);
32401
- var item = path[index];
32402
- var lastLevel = item === null || item === void 0 ? void 0 : item.levels[item.levels.length - 1];
32403
- if (lastLevel && (item === null || item === void 0 ? void 0 : item.blocks[0]) == paragraph) {
32404
- if (lastLevel.format.displayForDummyItem == 'block') {
32405
- item.levels.pop();
32665
+ var _c = context.insertPoint, paragraph = _c.paragraph, marker = _c.marker, path = _c.path;
32666
+ var index = (0, roosterjs_content_model_dom_1.getClosestAncestorBlockGroupIndex)(path, ['ListItem'], ['TableCell', 'FormatContainer']);
32667
+ var item = path[index];
32668
+ var parent = path[index + 1];
32669
+ if ((item === null || item === void 0 ? void 0 : item.blockGroupType) == 'ListItem' &&
32670
+ item.levels.length > 0 &&
32671
+ paragraph.segments[0] == marker &&
32672
+ parent) {
32673
+ var mutableList = (0, roosterjs_content_model_dom_1.mutateBlock)(item);
32674
+ var lastLevel = mutableList.levels[mutableList.levels.length - 1];
32675
+ var listItemIndex = parent.blocks.indexOf(item);
32676
+ var previousItem = parent.blocks[listItemIndex - 1];
32677
+ // 1. If the last level is dummy, just remove it (legacy behavior)
32678
+ // 2. If focus is at the beginning of list item and previous block is a list item with the same level count,
32679
+ // merge current list item into previous one
32680
+ // 3. Otherwise, split the list item. Keep the blocks before the paragraph in the current list item,
32681
+ // move the rest to a new list item (if there are multiple levels) or directly to parent (if only one level)
32682
+ if (lastLevel.format.displayForDummyItem == 'block') {
32683
+ mutableList.levels.pop();
32684
+ context.deleteResult = 'range';
32685
+ }
32686
+ else if (item.blocks[0] == paragraph &&
32687
+ (previousItem === null || previousItem === void 0 ? void 0 : previousItem.blockType) == 'BlockGroup' &&
32688
+ previousItem.blockGroupType == 'ListItem' &&
32689
+ previousItem.levels.length == mutableList.levels.length) {
32690
+ var mutablePreviousItem = (0, roosterjs_content_model_dom_1.mutateBlock)(previousItem);
32691
+ (_a = mutablePreviousItem.blocks).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(mutableList.blocks), false));
32692
+ (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(listItemIndex, 1);
32693
+ context.deleteResult = 'range';
32694
+ }
32695
+ else {
32696
+ var removedBlocks = mutableList.blocks.splice(mutableList.blocks.indexOf(paragraph), mutableList.blocks.length);
32697
+ if (mutableList.levels.length > 1) {
32698
+ var newListItem = (0, roosterjs_content_model_dom_1.createListItem)(mutableList.levels.slice(0, -1), mutableList.format);
32699
+ newListItem.blocks = removedBlocks.map(function (block) { return (0, roosterjs_content_model_dom_1.mutateBlock)(block); });
32700
+ (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(listItemIndex + 1, 0, newListItem);
32406
32701
  }
32407
32702
  else {
32408
- lastLevel.format.displayForDummyItem = 'block';
32703
+ (_b = (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks).splice.apply(_b, (0, tslib_1.__spreadArray)([listItemIndex + 1, 0], (0, tslib_1.__read)(removedBlocks), false));
32409
32704
  }
32410
32705
  context.deleteResult = 'range';
32411
32706
  }
@@ -33678,11 +33973,12 @@ var FindReplacePlugin = /** @class */ (function () {
33678
33973
  * @param editor The editor object
33679
33974
  */
33680
33975
  FindReplacePlugin.prototype.initialize = function (editor) {
33681
- var _a;
33682
33976
  this.editor = editor;
33683
- var win = (_a = editor.getDocument().defaultView) !== null && _a !== void 0 ? _a : window;
33684
- this.context.findHighlight.initialize(win);
33685
- this.context.replaceHighlight.initialize(win);
33977
+ var win = editor.getDocument().defaultView;
33978
+ if (win) {
33979
+ this.context.findHighlight.initialize(win);
33980
+ this.context.replaceHighlight.initialize(win);
33981
+ }
33686
33982
  this.editor.setEditorStyle(constants_1.FindHighlightRuleKey, this.findHighlightStyle, [
33687
33983
  constants_1.FindHighlightSelector,
33688
33984
  ]);
@@ -36252,9 +36548,11 @@ function generateDataURL(image, editInfo) {
36252
36548
  var height = heightPx || image.clientHeight;
36253
36549
  var imageWidth = nWidth * (1 - left - right);
36254
36550
  var imageHeight = nHeight * (1 - top - bottom);
36551
+ var doc = image.ownerDocument;
36552
+ var win = doc.defaultView;
36255
36553
  // Adjust the canvas size and scaling for high display resolution
36256
- var devicePixelRatio = window.devicePixelRatio || 1;
36257
- var canvas = document.createElement('canvas');
36554
+ var devicePixelRatio = (win === null || win === void 0 ? void 0 : win.devicePixelRatio) || 1;
36555
+ var canvas = doc.createElement('canvas');
36258
36556
  var targetWidth = generatedImageSize.targetWidth, targetHeight = generatedImageSize.targetHeight;
36259
36557
  canvas.width = targetWidth * devicePixelRatio;
36260
36558
  canvas.height = targetHeight * devicePixelRatio;
@@ -40420,13 +40718,13 @@ var TableEditPlugin = /** @class */ (function () {
40420
40718
  }
40421
40719
  };
40422
40720
  this.onMouseMove = function (event) {
40423
- var _a;
40721
+ var _a, _b;
40424
40722
  var e = event;
40425
- if (e.buttons > 0 || !_this.editor) {
40723
+ var editorWindow = (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.getDocument().defaultView;
40724
+ if (e.buttons > 0 || !editorWindow) {
40426
40725
  return;
40427
40726
  }
40428
40727
  _this.ensureTableRects();
40429
- var editorWindow = _this.editor.getDocument().defaultView || window;
40430
40728
  var x = e.pageX - editorWindow.scrollX;
40431
40729
  var y = e.pageY - editorWindow.scrollY;
40432
40730
  var currentTable = null;
@@ -40445,7 +40743,7 @@ var TableEditPlugin = /** @class */ (function () {
40445
40743
  }
40446
40744
  }
40447
40745
  _this.setTableEditor(currentTable, e);
40448
- (_a = _this.tableEditor) === null || _a === void 0 ? void 0 : _a.onMouseMove(x, y);
40746
+ (_b = _this.tableEditor) === null || _b === void 0 ? void 0 : _b.onMouseMove(x, y);
40449
40747
  };
40450
40748
  this.invalidateTableRects = function () {
40451
40749
  _this.tableRectMap = null;
@@ -40565,6 +40863,7 @@ var CellResizer_1 = __webpack_require__(/*! ./features/CellResizer */ "./package
40565
40863
  var TableInserter_1 = __webpack_require__(/*! ./features/TableInserter */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableInserter.ts");
40566
40864
  var TableMover_1 = __webpack_require__(/*! ./features/TableMover */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableMover.ts");
40567
40865
  var TableResizer_1 = __webpack_require__(/*! ./features/TableResizer */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableResizer.ts");
40866
+ var TableRowColumnSelector_1 = __webpack_require__(/*! ./features/TableRowColumnSelector */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableRowColumnSelector.ts");
40568
40867
  var TableEditFeature_1 = __webpack_require__(/*! ./features/TableEditFeature */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableEditFeature.ts");
40569
40868
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
40570
40869
  var INSERTER_HOVER_OFFSET = 6;
@@ -40624,6 +40923,9 @@ var TableEditor = /** @class */ (function () {
40624
40923
  this.tableResizer = null;
40625
40924
  // 6 - Move as well as select whole table
40626
40925
  this.tableMover = null;
40926
+ // 7 - Select whole column or row
40927
+ this.tableColumnSelector = null;
40928
+ this.tableRowSelector = null;
40627
40929
  this.range = null;
40628
40930
  this.onEditorCreated = function (featureType, element) {
40629
40931
  var _a;
@@ -40665,6 +40967,7 @@ var TableEditor = /** @class */ (function () {
40665
40967
  _this.disposeTableResizer();
40666
40968
  _this.disposeTableInserter();
40667
40969
  _this.disposeCellResizers();
40970
+ _this.disposeTableSelector();
40668
40971
  };
40669
40972
  this.onEndTableMove = function (disposeHandler) {
40670
40973
  if (disposeHandler) {
@@ -40720,6 +41023,7 @@ var TableEditor = /** @class */ (function () {
40720
41023
  this.disposeCellResizers();
40721
41024
  this.disposeTableInserter();
40722
41025
  this.disposeTableMover();
41026
+ this.disposeTableSelector();
40723
41027
  };
40724
41028
  TableEditor.prototype.isEditing = function () {
40725
41029
  return this.isCurrentlyEditing;
@@ -40732,9 +41036,11 @@ var TableEditor = /** @class */ (function () {
40732
41036
  this.verticalInserter,
40733
41037
  this.horizontalResizer,
40734
41038
  this.verticalResizer,
41039
+ this.tableColumnSelector,
41040
+ this.tableRowSelector,
40735
41041
  ]
40736
41042
  .filter(function (feature) { return !!(feature === null || feature === void 0 ? void 0 : feature.div); })
40737
- .some(function (feature) { return (feature === null || feature === void 0 ? void 0 : feature.div) == node; });
41043
+ .some(function (feature) { return (feature === null || feature === void 0 ? void 0 : feature.div) == node || ((feature === null || feature === void 0 ? void 0 : feature.div) && feature.div.contains(node)); });
40738
41044
  };
40739
41045
  /**
40740
41046
  * public only for testing purposes
@@ -40810,6 +41116,17 @@ var TableEditor = /** @class */ (function () {
40810
41116
  break;
40811
41117
  }
40812
41118
  }
41119
+ if (topOrSide == 0 /* top */) {
41120
+ !this.isFeatureDisabled('TableColumnSelector') &&
41121
+ this.setSelectorRowColumn(false /*isRow*/);
41122
+ }
41123
+ else if (topOrSide == 1 /* side */) {
41124
+ !this.isFeatureDisabled('TableRowSelector') &&
41125
+ this.setSelectorRowColumn(true /*isRow*/);
41126
+ }
41127
+ else {
41128
+ this.setSelectorRowColumn(null);
41129
+ }
40813
41130
  // Create Mover and Resizer
40814
41131
  this.setEditorFeatures();
40815
41132
  };
@@ -40851,6 +41168,14 @@ var TableEditor = /** @class */ (function () {
40851
41168
  }
40852
41169
  }
40853
41170
  };
41171
+ TableEditor.prototype.setSelectorRowColumn = function (isRowSelector /*undefined means to clear both*/) {
41172
+ if (isRowSelector !== null && !this.tableRowSelector && !this.tableColumnSelector) {
41173
+ this.tableRowSelector = (0, TableRowColumnSelector_1.createTableRowColumnSelector)(this.editor, this.table, !!isRowSelector, this.anchorContainer, this.onEditorCreated);
41174
+ }
41175
+ else {
41176
+ this.disposeTableSelector();
41177
+ }
41178
+ };
40854
41179
  TableEditor.prototype.disposeTableResizer = function () {
40855
41180
  if (this.tableResizer) {
40856
41181
  (0, TableEditFeature_1.disposeTableEditFeature)(this.tableResizer);
@@ -40867,6 +41192,16 @@ var TableEditor = /** @class */ (function () {
40867
41192
  this.verticalInserter = null;
40868
41193
  }
40869
41194
  };
41195
+ TableEditor.prototype.disposeTableSelector = function () {
41196
+ if (this.tableColumnSelector) {
41197
+ (0, TableEditFeature_1.disposeTableEditFeature)(this.tableColumnSelector);
41198
+ this.tableColumnSelector = null;
41199
+ }
41200
+ if (this.tableRowSelector) {
41201
+ (0, TableEditFeature_1.disposeTableEditFeature)(this.tableRowSelector);
41202
+ this.tableRowSelector = null;
41203
+ }
41204
+ };
40870
41205
  TableEditor.prototype.disposeCellResizers = function () {
40871
41206
  if (this.horizontalResizer) {
40872
41207
  (0, TableEditFeature_1.disposeTableEditFeature)(this.horizontalResizer);
@@ -40983,40 +41318,61 @@ function onDragStart(context, event) {
40983
41318
  var td = context.td, onStart = context.onStart;
40984
41319
  var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(td.getBoundingClientRect());
40985
41320
  // Get cell coordinates
40986
- var columnIndex = td.cellIndex;
40987
- var row = td.parentElement && (0, roosterjs_content_model_dom_1.isElementOfType)(td.parentElement, 'tr') ? td.parentElement : undefined;
40988
- var rowIndex = row === null || row === void 0 ? void 0 : row.rowIndex;
40989
- if (rowIndex == undefined) {
40990
- return {
40991
- cmTable: undefined,
40992
- anchorColumn: undefined,
40993
- anchorRow: undefined,
40994
- anchorRowHeight: -1,
40995
- allWidths: [],
40996
- }; // Just a fallback
40997
- }
41321
+ var rowIndex;
41322
+ var columnIndex;
41323
+ var nextColumnIndex = -1;
40998
41324
  var editor = context.editor, table = context.table;
40999
41325
  // Get Table block in content model
41000
41326
  var cmTable = (0, getTableFromContentModel_1.getCMTableFromTable)(editor, table);
41001
41327
  if (rect && cmTable) {
41328
+ for (var r = 0; r < (cmTable === null || cmTable === void 0 ? void 0 : cmTable.rows.length); r++) {
41329
+ for (var c = 0; c < cmTable.rows[r].cells.length; c++) {
41330
+ var cell = cmTable.rows[r].cells[c];
41331
+ if (cell.cachedElement == td) {
41332
+ // Target cell found, record its position
41333
+ rowIndex = r;
41334
+ columnIndex = c;
41335
+ }
41336
+ else if (rowIndex != undefined && columnIndex != undefined) {
41337
+ // rowIndex and columnIndex are already found, we can find nextColumnIndex now
41338
+ if (!cell.cachedElement) {
41339
+ // No cached element means this cell is merged, so this could potentially be the right side of column
41340
+ // We are trying to find the last merged cell so we can modify its width later
41341
+ columnIndex = c;
41342
+ }
41343
+ else {
41344
+ // Since we already found the target cell, the first cell with cachedElement after that must be the next column
41345
+ nextColumnIndex = c;
41346
+ break;
41347
+ }
41348
+ }
41349
+ }
41350
+ // As long as rowIndex is found, we can break here, no matter if nextColumnIndex is found or not
41351
+ // because for the last column case, nextColumnIndex will be -1
41352
+ if (rowIndex != undefined) {
41353
+ break;
41354
+ }
41355
+ }
41002
41356
  onStart();
41003
- return {
41004
- cmTable: cmTable,
41005
- anchorColumn: columnIndex,
41006
- anchorRow: rowIndex,
41007
- anchorRowHeight: cmTable.rows[rowIndex].height,
41008
- allWidths: (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(cmTable.widths), false),
41009
- };
41010
- }
41011
- else {
41012
- return {
41013
- cmTable: cmTable,
41014
- anchorColumn: undefined,
41015
- anchorRow: undefined,
41016
- anchorRowHeight: -1,
41017
- allWidths: [],
41018
- }; // Just a fallback
41357
+ if (rowIndex !== undefined) {
41358
+ return {
41359
+ cmTable: cmTable,
41360
+ anchorColumn: columnIndex,
41361
+ nextColumn: nextColumnIndex,
41362
+ anchorRow: rowIndex,
41363
+ anchorRowHeight: cmTable.rows[rowIndex].height,
41364
+ allWidths: (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(cmTable.widths), false),
41365
+ };
41366
+ }
41019
41367
  }
41368
+ return {
41369
+ cmTable: cmTable,
41370
+ anchorColumn: undefined,
41371
+ anchorRow: undefined,
41372
+ anchorRowHeight: -1,
41373
+ allWidths: [],
41374
+ nextColumn: -1,
41375
+ }; // Just a fallback
41020
41376
  }
41021
41377
  exports.onDragStart = onDragStart;
41022
41378
  /**
@@ -41024,7 +41380,6 @@ exports.onDragStart = onDragStart;
41024
41380
  * Exported for testing
41025
41381
  */
41026
41382
  function onDraggingHorizontal(context, event, initValue, deltaX, deltaY) {
41027
- var table = context.table;
41028
41383
  var cmTable = initValue.cmTable, anchorRow = initValue.anchorRow, anchorRowHeight = initValue.anchorRowHeight;
41029
41384
  // Assign new widths and heights to the CM table
41030
41385
  if (cmTable && anchorRow != undefined && cmTable.rows[anchorRow] != undefined) {
@@ -41033,11 +41388,13 @@ function onDraggingHorizontal(context, event, initValue, deltaX, deltaY) {
41033
41388
  // Normalize the new height value
41034
41389
  var newHeight = Math.max(cmTable.rows[anchorRow].height, roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_HEIGHT);
41035
41390
  // Writeback CM Table size changes to DOM Table
41036
- var tableRow = table.rows[anchorRow];
41037
- for (var col = 0; col < tableRow.cells.length; col++) {
41038
- var td = tableRow.cells[col];
41039
- td.style.height = newHeight + 'px';
41040
- td.style.boxSizing = 'border-box';
41391
+ var tableRow = cmTable.rows[anchorRow].cells;
41392
+ for (var col = 0; col < tableRow.length; col++) {
41393
+ var td = tableRow[col].cachedElement;
41394
+ if (td) {
41395
+ td.style.height = newHeight + 'px';
41396
+ td.style.boxSizing = 'border-box';
41397
+ }
41041
41398
  }
41042
41399
  return true;
41043
41400
  }
@@ -41052,15 +41409,13 @@ exports.onDraggingHorizontal = onDraggingHorizontal;
41052
41409
  */
41053
41410
  function onDraggingVertical(context, event, initValue, deltaX) {
41054
41411
  var table = context.table, isRTL = context.isRTL;
41055
- var cmTable = initValue.cmTable, anchorColumn = initValue.anchorColumn, allWidths = initValue.allWidths;
41412
+ var cmTable = initValue.cmTable, anchorColumn = initValue.anchorColumn, nextColumn = initValue.nextColumn, allWidths = initValue.allWidths;
41056
41413
  // Assign new widths and heights to the CM table
41057
41414
  if (cmTable && anchorColumn != undefined) {
41058
41415
  var mutableTable = (0, roosterjs_content_model_dom_1.mutateBlock)(cmTable);
41059
- // Modify the CM Table size
41060
- var lastColumn = anchorColumn == cmTable.widths.length - 1;
41061
41416
  var change = deltaX * (isRTL ? -1 : 1);
41062
41417
  // This is the last column
41063
- if (lastColumn) {
41418
+ if (nextColumn == -1) {
41064
41419
  // Only the last column changes
41065
41420
  // Normalize the new width value
41066
41421
  var newWidth = Math.max(allWidths[anchorColumn] + change, roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_WIDTH);
@@ -41069,21 +41424,37 @@ function onDraggingVertical(context, event, initValue, deltaX) {
41069
41424
  else {
41070
41425
  // Any other two columns
41071
41426
  var anchorChange = allWidths[anchorColumn] + change;
41072
- var nextAnchorChange = allWidths[anchorColumn + 1] - change;
41427
+ var nextAnchorChange = allWidths[nextColumn] - change;
41073
41428
  if (anchorChange < roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_WIDTH ||
41074
41429
  nextAnchorChange < roosterjs_content_model_dom_1.MIN_ALLOWED_TABLE_CELL_WIDTH) {
41075
41430
  return false;
41076
41431
  }
41077
41432
  mutableTable.widths[anchorColumn] = anchorChange;
41078
- mutableTable.widths[anchorColumn + 1] = nextAnchorChange;
41433
+ mutableTable.widths[nextColumn] = nextAnchorChange;
41079
41434
  }
41080
- // Writeback CM Table size changes to DOM Table
41081
- for (var row = 0; row < table.rows.length; row++) {
41082
- var tableRow = table.rows[row];
41083
- for (var col = 0; col < tableRow.cells.length; col++) {
41084
- var td = tableRow.cells[col];
41085
- td.style.width = cmTable.widths[col] + 'px';
41086
- td.style.boxSizing = 'border-box';
41435
+ // Write back CM Table size changes to DOM Table
41436
+ for (var row = 0; row < cmTable.rows.length; row++) {
41437
+ var tableRow = cmTable.rows[row].cells;
41438
+ var lastTd = null;
41439
+ var lastWidth = 0;
41440
+ for (var col = 0; col < tableRow.length; col++) {
41441
+ var td = tableRow[col].cachedElement;
41442
+ if (td) {
41443
+ td.style.boxSizing = 'border-box';
41444
+ lastTd = td;
41445
+ lastWidth = cmTable.widths[col];
41446
+ }
41447
+ else if (lastTd && tableRow[col].spanLeft) {
41448
+ lastWidth += cmTable.widths[col];
41449
+ }
41450
+ else if (tableRow[col].spanAbove) {
41451
+ // For span above case, we don't need to adjust width, just clear lastTd and lastWidth
41452
+ lastTd = null;
41453
+ lastWidth = 0;
41454
+ }
41455
+ if (lastTd) {
41456
+ lastTd.style.width = lastWidth + 'px';
41457
+ }
41087
41458
  }
41088
41459
  }
41089
41460
  if (context.originalWidth > 0) {
@@ -41302,8 +41673,8 @@ var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement
41302
41673
  var DragAndDropHelper_1 = __webpack_require__(/*! ../../../pluginUtils/DragAndDrop/DragAndDropHelper */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/DragAndDrop/DragAndDropHelper.ts");
41303
41674
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
41304
41675
  var getTableFromContentModel_1 = __webpack_require__(/*! ../utils/getTableFromContentModel */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/utils/getTableFromContentModel.ts");
41305
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
41306
41676
  var getNodePositionFromEvent_1 = __webpack_require__(/*! ../../../utils/getNodePositionFromEvent */ "./packages/roosterjs-content-model-plugins/lib/utils/getNodePositionFromEvent.ts");
41677
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
41307
41678
  var TABLE_MOVER_LENGTH = 12;
41308
41679
  /**
41309
41680
  * @internal
@@ -41403,7 +41774,7 @@ function onDragStart(context) {
41403
41774
  tag: 'div',
41404
41775
  style: 'position: fixed; user-select: none; border: 1px solid #808080',
41405
41776
  };
41406
- var tableRect = (0, createElement_1.createElement)(createElementData, document);
41777
+ var tableRect = (0, createElement_1.createElement)(createElementData, editor.getDocument());
41407
41778
  tableRect.style.width = trect.width + "px";
41408
41779
  tableRect.style.height = trect.height + "px";
41409
41780
  tableRect.style.top = trect.top + "px";
@@ -41731,6 +42102,239 @@ function isTableBottomVisible(editor, rect, contentDiv) {
41731
42102
  }
41732
42103
 
41733
42104
 
42105
+ /***/ }),
42106
+
42107
+ /***/ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableRowColumnSelector.ts":
42108
+ /*!***********************************************************************************************************!*\
42109
+ !*** ./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableRowColumnSelector.ts ***!
42110
+ \***********************************************************************************************************/
42111
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
42112
+
42113
+ "use strict";
42114
+
42115
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
42116
+ exports.onDragEnd = exports.onDragging = exports.onDragStart = exports.createTableRowColumnSelector = void 0;
42117
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
42118
+ var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement/createElement */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/CreateElement/createElement.ts");
42119
+ var DragAndDropHelper_1 = __webpack_require__(/*! ../../../pluginUtils/DragAndDrop/DragAndDropHelper */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/DragAndDrop/DragAndDropHelper.ts");
42120
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
42121
+ var STABLE_DOWN_ARROW_CURSOR = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij48dGV4dCB4PSI4IiB5PSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNCIgZmlsbD0iYmxhY2siPiYjMTI5MDk1OzwvdGV4dD48L3N2Zz4=';
42122
+ var STABLE_RIGHT_ARROW_CURSOR = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij48dGV4dCB4PSI4IiB5PSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNCIgZmlsbD0iYmxhY2siIHRyYW5zZm9ybT0icm90YXRlKC05MCA4IDgpIj4mIzEyOTA5NTs8L3RleHQ+PC9zdmc+';
42123
+ /**
42124
+ * @internal
42125
+ */
42126
+ function createTableRowColumnSelector(editor, table, isRowSelector, anchorContainer, onTableEditorCreated) {
42127
+ var _a;
42128
+ var doc = editor.getDocument();
42129
+ var zoomScale = editor.getDOMHelper().calculateZoomScale();
42130
+ var containerDiv = doc.createElement('div');
42131
+ containerDiv.style.cssText = 'position: fixed; pointer-events: none;';
42132
+ var cells = isRowSelector
42133
+ ? Array.from(table.rows)
42134
+ .map(function (row) { return row.cells[0]; })
42135
+ .filter(function (cell) { return cell; })
42136
+ : Array.from(((_a = table.rows[0]) === null || _a === void 0 ? void 0 : _a.cells) || []);
42137
+ var handlers = [];
42138
+ cells.forEach(function (cell) {
42139
+ var cellRect = (0, roosterjs_content_model_dom_1.normalizeRect)(cell.getBoundingClientRect());
42140
+ if (cellRect) {
42141
+ var createElementData = getInsertElementData(cellRect, isRowSelector);
42142
+ var cellDiv = (0, createElement_1.createElement)(createElementData, doc);
42143
+ containerDiv.appendChild(cellDiv);
42144
+ var context = {
42145
+ table: table,
42146
+ zoomScale: zoomScale,
42147
+ editor: editor,
42148
+ div: cellDiv,
42149
+ isRow: isRowSelector,
42150
+ };
42151
+ var handler = new TableRowColumnSelectorHandler(cellDiv, isRowSelector, context, {
42152
+ onDragStart: onDragStart,
42153
+ onDragging: onDragging,
42154
+ onDragEnd: onDragEnd,
42155
+ }, zoomScale, onTableEditorCreated, editor.getEnvironment().isMobileOrTablet);
42156
+ handlers.push(handler);
42157
+ }
42158
+ });
42159
+ (anchorContainer || doc.body).appendChild(containerDiv);
42160
+ var compositeHandler = {
42161
+ dispose: function () {
42162
+ handlers.forEach(function (h) { return h.dispose(); });
42163
+ },
42164
+ };
42165
+ return { div: containerDiv, featureHandler: compositeHandler, node: table };
42166
+ }
42167
+ exports.createTableRowColumnSelector = createTableRowColumnSelector;
42168
+ var TableRowColumnSelectorHandler = /** @class */ (function (_super) {
42169
+ (0, tslib_1.__extends)(TableRowColumnSelectorHandler, _super);
42170
+ function TableRowColumnSelectorHandler(div, isRow, context, handler, zoomScale, onTableEditorCreated, forceMobile) {
42171
+ var _this = _super.call(this, div, context, function () { }, handler, zoomScale, forceMobile) || this;
42172
+ _this.isRow = isRow;
42173
+ _this.disposer = onTableEditorCreated === null || onTableEditorCreated === void 0 ? void 0 : onTableEditorCreated(_this.isRow ? 'TableRowSelector' : 'TableColumnSelector', div);
42174
+ return _this;
42175
+ }
42176
+ TableRowColumnSelectorHandler.prototype.dispose = function () {
42177
+ var _a;
42178
+ (_a = this.disposer) === null || _a === void 0 ? void 0 : _a.call(this);
42179
+ this.disposer = undefined;
42180
+ };
42181
+ return TableRowColumnSelectorHandler;
42182
+ }(DragAndDropHelper_1.DragAndDropHelper));
42183
+ /**
42184
+ * @internal
42185
+ * Helper function to calculate current row/column index from mouse coordinates during drag
42186
+ */
42187
+ function getCurrentIndexFromMouse(table, x, y, isRow) {
42188
+ if (isRow) {
42189
+ for (var i = 0; i < table.rows.length; i++) {
42190
+ var row = table.rows[i];
42191
+ for (var j = 0; j < row.cells.length; j++) {
42192
+ var cell = row.cells[j];
42193
+ var cellRect = (0, roosterjs_content_model_dom_1.normalizeRect)(cell.getBoundingClientRect());
42194
+ if (cellRect && y >= cellRect.top && y <= cellRect.bottom) {
42195
+ return i;
42196
+ }
42197
+ }
42198
+ }
42199
+ return Math.max(0, table.rows.length - 1);
42200
+ }
42201
+ else {
42202
+ if (!table.rows[0]) {
42203
+ return 0;
42204
+ }
42205
+ var firstRow = table.rows[0];
42206
+ for (var i = 0; i < firstRow.cells.length; i++) {
42207
+ var cell = firstRow.cells[i];
42208
+ var cellRect = (0, roosterjs_content_model_dom_1.normalizeRect)(cell.getBoundingClientRect());
42209
+ if (cellRect && x >= cellRect.left && x <= cellRect.right) {
42210
+ return i;
42211
+ }
42212
+ }
42213
+ return firstRow.cells.length - 1;
42214
+ }
42215
+ }
42216
+ /**
42217
+ * @internal
42218
+ * Exported for testing
42219
+ */
42220
+ function onDragStart(context, event) {
42221
+ var table = context.table, editor = context.editor, isRow = context.isRow;
42222
+ editor.setDOMSelection(null);
42223
+ var parsedTable = (0, roosterjs_content_model_dom_1.parseTableCells)(table);
42224
+ var startIndex = getCurrentIndexFromMouse(table, event.clientX, event.clientY, isRow);
42225
+ if (isRow) {
42226
+ var columnNumber = parsedTable[startIndex].length - 1;
42227
+ var initialSelection = {
42228
+ type: 'table',
42229
+ table: table,
42230
+ firstRow: startIndex,
42231
+ lastRow: startIndex,
42232
+ firstColumn: 0,
42233
+ lastColumn: columnNumber,
42234
+ };
42235
+ return {
42236
+ cmTable: undefined,
42237
+ initialSelection: initialSelection,
42238
+ parsedTable: parsedTable,
42239
+ startIndex: startIndex,
42240
+ };
42241
+ }
42242
+ else {
42243
+ var rowNumber = parsedTable.length - 1;
42244
+ var initialSelection = {
42245
+ type: 'table',
42246
+ table: table,
42247
+ firstRow: 0,
42248
+ lastRow: rowNumber,
42249
+ firstColumn: startIndex,
42250
+ lastColumn: startIndex,
42251
+ };
42252
+ return {
42253
+ cmTable: undefined,
42254
+ initialSelection: initialSelection,
42255
+ parsedTable: parsedTable,
42256
+ startIndex: startIndex,
42257
+ };
42258
+ }
42259
+ }
42260
+ exports.onDragStart = onDragStart;
42261
+ /**
42262
+ * @internal
42263
+ * Exported for testing
42264
+ */
42265
+ function onDragging(context, event, initValue) {
42266
+ if (!initValue) {
42267
+ return false;
42268
+ }
42269
+ var table = context.table, editor = context.editor, isRow = context.isRow;
42270
+ var parsedTable = initValue.parsedTable, startIndex = initValue.startIndex;
42271
+ var currentIndex = getCurrentIndexFromMouse(table, event.clientX, event.clientY, isRow);
42272
+ if (isRow) {
42273
+ var columnNumber = parsedTable[startIndex].length - 1;
42274
+ var firstRow = Math.min(startIndex, currentIndex);
42275
+ var lastRow = Math.max(startIndex, currentIndex);
42276
+ editor.setDOMSelection({
42277
+ type: 'table',
42278
+ table: table,
42279
+ firstRow: firstRow,
42280
+ firstColumn: 0,
42281
+ lastRow: lastRow,
42282
+ lastColumn: columnNumber,
42283
+ });
42284
+ }
42285
+ else {
42286
+ var firstColumn = Math.min(startIndex, currentIndex);
42287
+ var lastColumn = Math.max(startIndex, currentIndex);
42288
+ var rowNumber = parsedTable.length - 1;
42289
+ editor.setDOMSelection({
42290
+ type: 'table',
42291
+ table: table,
42292
+ firstRow: 0,
42293
+ firstColumn: firstColumn,
42294
+ lastColumn: lastColumn,
42295
+ lastRow: rowNumber,
42296
+ });
42297
+ }
42298
+ return true;
42299
+ }
42300
+ exports.onDragging = onDragging;
42301
+ /**
42302
+ * @internal
42303
+ * Exported for testing
42304
+ */
42305
+ function onDragEnd(context, event, initValue) {
42306
+ if (!initValue) {
42307
+ return false;
42308
+ }
42309
+ var editor = context.editor;
42310
+ var selection = editor.getDOMSelection();
42311
+ if ((selection === null || selection === void 0 ? void 0 : selection.type) !== 'table') {
42312
+ editor.setDOMSelection(initValue.initialSelection);
42313
+ }
42314
+ return true;
42315
+ }
42316
+ exports.onDragEnd = onDragEnd;
42317
+ function getInsertElementData(rect, isRowSelector) {
42318
+ var MIN_DISTANCE_FROM_BOUNDARY = 5;
42319
+ var GAP_FROM_CELL = 5;
42320
+ var cellLength = isRowSelector ? rect.bottom - rect.top : rect.right - rect.left;
42321
+ var maxSelectorSize = Math.max(16, cellLength - MIN_DISTANCE_FROM_BOUNDARY * 2);
42322
+ var SELECTOR_SIZE = cellLength >= 32 ? Math.min(cellLength - 16, maxSelectorSize) : 16;
42323
+ var centerOffset = (cellLength - SELECTOR_SIZE) / 2;
42324
+ var size = isRowSelector
42325
+ ? "width: 5px; height: " + SELECTOR_SIZE + "px; top: " + (rect.top + centerOffset) + "px; left: " + (rect.left - 5 - GAP_FROM_CELL) + "px"
42326
+ : "width: " + SELECTOR_SIZE + "px; height: 5px; top: " + (rect.top - 5 - GAP_FROM_CELL) + "px; left: " + (rect.left + centerOffset) + "px";
42327
+ var cursor = isRowSelector
42328
+ ? "url(\"" + STABLE_RIGHT_ARROW_CURSOR + "\"), auto"
42329
+ : "url(\"" + STABLE_DOWN_ARROW_CURSOR + "\") , auto";
42330
+ var outerDivStyle = "position: fixed; " + size + "; background-color: transparent; cursor: " + cursor + "; pointer-events: auto;";
42331
+ return {
42332
+ tag: 'div',
42333
+ style: outerDivStyle,
42334
+ };
42335
+ }
42336
+
42337
+
41734
42338
  /***/ }),
41735
42339
 
41736
42340
  /***/ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/utils/getTableFromContentModel.ts":
@@ -41753,6 +42357,7 @@ function getCMTableFromTable(editor, table) {
41753
42357
  var context = (0, roosterjs_content_model_dom_1.createDomToModelContext)({
41754
42358
  zoomScale: editor.getDOMHelper().calculateZoomScale(),
41755
42359
  recalculateTableSize: true,
42360
+ allowCacheElement: true, // We need this cache so we can retrieve TD element and update TD width and height when resizing table
41756
42361
  });
41757
42362
  context.elementProcessors.element(model, table, context);
41758
42363
  var firstBlock = model.blocks[0];
@@ -41822,7 +42427,7 @@ var TouchPlugin = /** @class */ (function () {
41822
42427
  */
41823
42428
  TouchPlugin.prototype.onPluginEvent = function (event) {
41824
42429
  var _this = this;
41825
- var _a, _b, _c, _d;
42430
+ var _a, _b, _c;
41826
42431
  if (!this.editor) {
41827
42432
  return;
41828
42433
  }
@@ -41831,57 +42436,59 @@ var TouchPlugin = /** @class */ (function () {
41831
42436
  this.isDblClicked = false;
41832
42437
  this.isTouchPenPointerEvent = true;
41833
42438
  event.originalEvent.preventDefault();
41834
- var targetWindow = ((_a = this.editor.getDocument()) === null || _a === void 0 ? void 0 : _a.defaultView) || window;
41835
- if (this.timer) {
41836
- targetWindow.clearTimeout(this.timer);
41837
- }
41838
- this.timer = targetWindow.setTimeout(function () {
41839
- _this.timer = 0;
41840
- if (_this.editor) {
41841
- if (!_this.isDblClicked) {
41842
- _this.editor.focus();
41843
- var caretPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(_this.editor, event.rawEvent.x, event.rawEvent.y);
41844
- var newRange = _this.editor.getDocument().createRange();
41845
- if (caretPosition) {
41846
- var node = caretPosition.node, offset = caretPosition.offset;
41847
- // Place cursor at same position of browser handler by default
41848
- newRange.setStart(node, offset);
41849
- newRange.setEnd(node, offset);
41850
- var nodeTextContent = node.textContent || '';
41851
- var charAtSelection = nodeTextContent[offset];
41852
- if (node.nodeType === Node.TEXT_NODE &&
41853
- charAtSelection &&
41854
- !SPACE_MATCHING_REGEX.test(charAtSelection) &&
41855
- !PUNCTUATION_MATCHING_REGEX.test(charAtSelection)) {
41856
- var _a = findWordBoundaries(nodeTextContent, offset), wordStart = _a.wordStart, wordEnd = _a.wordEnd;
41857
- // Move cursor to the calculated offset
41858
- var leftCursorWordLength = offset - wordStart;
41859
- var rightCursorWordLength = wordEnd - offset;
41860
- var movingOffset = leftCursorWordLength >= rightCursorWordLength
41861
- ? rightCursorWordLength
41862
- : -leftCursorWordLength;
41863
- movingOffset =
41864
- Math.abs(movingOffset) > MAX_TOUCH_MOVE_DISTANCE
41865
- ? 0
41866
- : movingOffset;
41867
- var newOffsetPosition = offset + movingOffset;
41868
- if (movingOffset !== 0 &&
41869
- nodeTextContent.length >= newOffsetPosition) {
41870
- newRange.setStart(node, newOffsetPosition);
41871
- newRange.setEnd(node, newOffsetPosition);
42439
+ var targetWindow = this.editor.getDocument().defaultView;
42440
+ if (targetWindow) {
42441
+ if (this.timer) {
42442
+ targetWindow.clearTimeout(this.timer);
42443
+ }
42444
+ this.timer = targetWindow.setTimeout(function () {
42445
+ _this.timer = 0;
42446
+ if (_this.editor) {
42447
+ if (!_this.isDblClicked) {
42448
+ _this.editor.focus();
42449
+ var caretPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(_this.editor, event.rawEvent.x, event.rawEvent.y);
42450
+ var newRange = _this.editor.getDocument().createRange();
42451
+ if (caretPosition) {
42452
+ var node = caretPosition.node, offset = caretPosition.offset;
42453
+ // Place cursor at same position of browser handler by default
42454
+ newRange.setStart(node, offset);
42455
+ newRange.setEnd(node, offset);
42456
+ var nodeTextContent = node.textContent || '';
42457
+ var charAtSelection = nodeTextContent[offset];
42458
+ if (node.nodeType === Node.TEXT_NODE &&
42459
+ charAtSelection &&
42460
+ !SPACE_MATCHING_REGEX.test(charAtSelection) &&
42461
+ !PUNCTUATION_MATCHING_REGEX.test(charAtSelection)) {
42462
+ var _a = findWordBoundaries(nodeTextContent, offset), wordStart = _a.wordStart, wordEnd = _a.wordEnd;
42463
+ // Move cursor to the calculated offset
42464
+ var leftCursorWordLength = offset - wordStart;
42465
+ var rightCursorWordLength = wordEnd - offset;
42466
+ var movingOffset = leftCursorWordLength >= rightCursorWordLength
42467
+ ? rightCursorWordLength
42468
+ : -leftCursorWordLength;
42469
+ movingOffset =
42470
+ Math.abs(movingOffset) > MAX_TOUCH_MOVE_DISTANCE
42471
+ ? 0
42472
+ : movingOffset;
42473
+ var newOffsetPosition = offset + movingOffset;
42474
+ if (movingOffset !== 0 &&
42475
+ nodeTextContent.length >= newOffsetPosition) {
42476
+ newRange.setStart(node, newOffsetPosition);
42477
+ newRange.setEnd(node, newOffsetPosition);
42478
+ }
41872
42479
  }
41873
42480
  }
42481
+ _this.editor.setDOMSelection({
42482
+ type: 'range',
42483
+ range: newRange,
42484
+ isReverted: false,
42485
+ });
42486
+ // reset values
42487
+ _this.isTouchPenPointerEvent = false;
41874
42488
  }
41875
- _this.editor.setDOMSelection({
41876
- type: 'range',
41877
- range: newRange,
41878
- isReverted: false,
41879
- });
41880
- // reset values
41881
- _this.isTouchPenPointerEvent = false;
41882
42489
  }
41883
- }
41884
- }, POINTER_DETECTION_DELAY);
42490
+ }, POINTER_DETECTION_DELAY);
42491
+ }
41885
42492
  break;
41886
42493
  case 'doubleClick':
41887
42494
  if (this.isTouchPenPointerEvent) {
@@ -41897,7 +42504,7 @@ var TouchPlugin = /** @class */ (function () {
41897
42504
  var char = nodeTextContent.charAt(offset);
41898
42505
  // Check if the clicked character is a punctuation mark, then highlight that character only
41899
42506
  if (PUNCTUATION_MATCHING_REGEX.test(char)) {
41900
- var newRange = (_b = this.editor.getDocument()) === null || _b === void 0 ? void 0 : _b.createRange();
42507
+ var newRange = (_a = this.editor.getDocument()) === null || _a === void 0 ? void 0 : _a.createRange();
41901
42508
  if (newRange) {
41902
42509
  newRange.setStart(node, offset);
41903
42510
  newRange.setEnd(node, offset + 1);
@@ -41919,7 +42526,7 @@ var TouchPlugin = /** @class */ (function () {
41919
42526
  SPACE_MATCHING_REGEX.test(nodeTextContent.charAt(start - 1))) {
41920
42527
  start--;
41921
42528
  }
41922
- var newRange = (_c = this.editor.getDocument()) === null || _c === void 0 ? void 0 : _c.createRange();
42529
+ var newRange = (_b = this.editor.getDocument()) === null || _b === void 0 ? void 0 : _b.createRange();
41923
42530
  if (newRange) {
41924
42531
  newRange.setStart(node, start);
41925
42532
  newRange.setEnd(node, start + 1);
@@ -41932,8 +42539,8 @@ var TouchPlugin = /** @class */ (function () {
41932
42539
  }
41933
42540
  }
41934
42541
  else {
41935
- var _e = findWordBoundaries(nodeTextContent, offset), wordStart = _e.wordStart, wordEnd = _e.wordEnd;
41936
- var newRange = (_d = this.editor.getDocument()) === null || _d === void 0 ? void 0 : _d.createRange();
42542
+ var _d = findWordBoundaries(nodeTextContent, offset), wordStart = _d.wordStart, wordEnd = _d.wordEnd;
42543
+ var newRange = (_c = this.editor.getDocument()) === null || _c === void 0 ? void 0 : _c.createRange();
41937
42544
  if (newRange) {
41938
42545
  newRange.setStart(node, wordStart);
41939
42546
  newRange.setEnd(node, wordEnd);