roosterjs 9.47.0 → 9.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rooster.js CHANGED
@@ -4310,6 +4310,10 @@ function setListType(model, listType, removeMargins) {
4310
4310
  fontSize: segmentFormat.fontSize,
4311
4311
  textColor: segmentFormat.textColor,
4312
4312
  });
4313
+ if (removeMargins) {
4314
+ newListItem.format.marginBottom = '0px';
4315
+ newListItem.format.marginTop = '0px';
4316
+ }
4313
4317
  if (block.blockType == 'Paragraph') {
4314
4318
  (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(block);
4315
4319
  }
@@ -7887,21 +7891,25 @@ exports.setTableCellShade = setTableCellShade;
7887
7891
  /*!******************************************************************************!*\
7888
7892
  !*** ./packages/roosterjs-content-model-api/lib/publicApi/utils/checkXss.ts ***!
7889
7893
  \******************************************************************************/
7890
- (__unused_webpack_module, exports) {
7894
+ (__unused_webpack_module, exports, __webpack_require__) {
7891
7895
 
7892
7896
  "use strict";
7893
7897
 
7894
7898
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7895
7899
  exports.checkXss = void 0;
7900
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
7896
7901
  /**
7897
7902
  * @internal Check if there is XSS attack in the link
7898
7903
  * @param link The link to be checked
7899
- * @returns The safe link, or empty string if there is XSS attack
7900
- * @remarks This function checks for patterns like s\nc\nr\ni\np\nt: to prevent XSS attacks. This may block some valid links,
7904
+ * @returns The safe link with invisible Unicode characters stripped, or empty string if there is XSS attack
7905
+ * @remarks This function strips invisible Unicode characters (zero-width chars, Unicode Tags, etc.)
7906
+ * and checks for patterns like s\nc\nr\ni\np\nt: to prevent XSS attacks. This may block some valid links,
7901
7907
  * but it is necessary for security reasons. We treat the word "script" as safe if there are "/" before it.
7902
7908
  */
7903
7909
  function checkXss(link) {
7904
- return link.match(/^[^\/]*s\n*c\n*r\n*i\n*p\n*t\n*:/i) ? '' : link;
7910
+ // Defense-in-depth: strip invisible Unicode even if already handled elsewhere
7911
+ var sanitized = (0, roosterjs_content_model_dom_1.stripInvisibleUnicode)(link);
7912
+ return sanitized.match(/^[^\/]*s\n*c\n*r\n*i\n*p\n*t\n*:/i) ? '' : sanitized;
7905
7913
  }
7906
7914
  exports.checkXss = checkXss;
7907
7915
 
@@ -8139,7 +8147,7 @@ var splitSelectedParagraphByBr_1 = __webpack_require__(/*! ../../modelApi/block/
8139
8147
  function formatParagraphWithContentModel(editor, apiName, setStyleCallback) {
8140
8148
  editor.formatContentModel(function (model, context) {
8141
8149
  (0, splitSelectedParagraphByBr_1.splitSelectedParagraphByBr)(model);
8142
- var paragraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true /*mutate*/);
8150
+ var paragraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true /*mutate*/, false /*removeUnmeaningful*/);
8143
8151
  paragraphs.forEach(setStyleCallback);
8144
8152
  context.newPendingFormat = 'preserve';
8145
8153
  return paragraphs.length > 0;
@@ -11684,17 +11692,18 @@ var CachePlugin = /** @class */ (function () {
11684
11692
  if (contentModel) {
11685
11693
  (0, updateCache_1.updateCache)(this.state, contentModel, selection);
11686
11694
  }
11687
- else {
11688
- this.invalidateCache();
11689
- }
11690
11695
  break;
11691
11696
  }
11692
11697
  };
11693
11698
  CachePlugin.prototype.invalidateCache = function () {
11694
11699
  var _a, _b;
11695
11700
  if (!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isInShadowEdit())) {
11696
- this.state.cachedModel = undefined;
11697
- this.state.cachedSelection = undefined;
11701
+ if (this.state.cachedModel) {
11702
+ this.state.cachedModel = undefined;
11703
+ }
11704
+ if (this.state.cachedSelection) {
11705
+ this.state.cachedSelection = undefined;
11706
+ }
11698
11707
  // Clear paragraph indexer to prevent stale references to old paragraphs
11699
11708
  // It will be rebuild next time when we create a new Content Model
11700
11709
  (_b = this.state.paragraphMap) === null || _b === void 0 ? void 0 : _b.clear();
@@ -14916,7 +14925,7 @@ var SelectionPlugin = /** @class */ (function () {
14916
14925
  : undefined;
14917
14926
  var rect = td === null || td === void 0 ? void 0 : td.getBoundingClientRect();
14918
14927
  var textOffset = cursorRect && rect
14919
- ? (0, roosterjs_content_model_dom_1.getNodePositionFromEvent)(doc, editor.getDOMHelper(), cursorRect.left, isKeyUp ? rect.top - 1 : rect.top + 1)
14928
+ ? (0, roosterjs_content_model_dom_1.getNodePositionFromEvent)(doc, editor.getDOMHelper(), cursorRect.left, isKeyUp ? rect.top : rect.top + 1)
14920
14929
  : null;
14921
14930
  return textOffset;
14922
14931
  };
@@ -15618,6 +15627,7 @@ var Editor = /** @class */ (function () {
15618
15627
  };
15619
15628
  this.core = (0, createEditorCore_1.createEditorCore)(contentDiv, options);
15620
15629
  var initialModel = (_a = options.initialModel) !== null && _a !== void 0 ? _a : (0, roosterjs_content_model_dom_1.createEmptyModel)(this.core.format.defaultFormat);
15630
+ (0, roosterjs_content_model_dom_1.sanitizeInvisibleUnicode)(initialModel);
15621
15631
  this.core.api.setContentModel(this.core, initialModel, { ignoreSelection: true }, undefined /*onNodeCreated*/, true /*isInitializing*/);
15622
15632
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
15623
15633
  }
@@ -16393,10 +16403,10 @@ function shouldApplyToItem(listStyleType, listType) {
16393
16403
  exports.listItemMetadataApplier = {
16394
16404
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16395
16405
  applierFunction: function (metadata, format, context) {
16396
- var _a;
16397
- var depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
16406
+ var _a, _b;
16407
+ var depth = context.listFormat.currentLevel;
16398
16408
  if (depth >= 0) {
16399
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16409
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16400
16410
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16401
16411
  if (listStyleType !== undefined) {
16402
16412
  if (shouldApplyToItem(listStyleType, listType)) {
@@ -16415,10 +16425,10 @@ exports.listItemMetadataApplier = {
16415
16425
  exports.listLevelMetadataApplier = {
16416
16426
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16417
16427
  applierFunction: function (metadata, format, context) {
16418
- var _a;
16419
- var depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
16428
+ var _a, _b;
16429
+ var depth = context.listFormat.currentLevel;
16420
16430
  if (depth >= 0) {
16421
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16431
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16422
16432
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16423
16433
  if (listStyleType !== undefined) {
16424
16434
  if (!shouldApplyToItem(listStyleType, listType)) {
@@ -20791,6 +20801,38 @@ function normalizeText(txt, isForward) {
20791
20801
  exports.normalizeText = normalizeText;
20792
20802
 
20793
20803
 
20804
+ /***/ },
20805
+
20806
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts"
20807
+ /*!************************************************************************************!*\
20808
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts ***!
20809
+ \************************************************************************************/
20810
+ (__unused_webpack_module, exports) {
20811
+
20812
+ "use strict";
20813
+
20814
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20815
+ exports.stripInvisibleUnicode = void 0;
20816
+ var INVISIBLE_UNICODE_REGEX =
20817
+ // eslint-disable-next-line no-misleading-character-class
20818
+ /[\u00AD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180B-\u180E\u200B-\u200F\u202A-\u202E\u2028\u2029\u2060-\u2064\u2066-\u2069\u3164\uFEFF\uFFA0\uFFF9-\uFFFB]|\uDB40[\uDC01-\uDCFF]/g;
20819
+ /**
20820
+ * Strip invisible Unicode characters from a string.
20821
+ * This removes zero-width characters, bidirectional marks, Unicode Tags (U+E0001-U+E00FF),
20822
+ * interlinear annotation anchors, Mongolian free variation selectors,
20823
+ * and other invisible formatting characters that can be used to hide content in links.
20824
+ *
20825
+ * @remarks This function strips ZWJ (U+200D) which may affect emoji sequences.
20826
+ * It should only be applied to href attributes, not to visible text content.
20827
+ * @param value The string to strip invisible characters from
20828
+ * @returns The string with invisible characters removed
20829
+ */
20830
+ function stripInvisibleUnicode(value) {
20831
+ return value.replace(INVISIBLE_UNICODE_REGEX, '');
20832
+ }
20833
+ exports.stripInvisibleUnicode = stripInvisibleUnicode;
20834
+
20835
+
20794
20836
  /***/ },
20795
20837
 
20796
20838
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts"
@@ -21634,6 +21676,7 @@ var BorderStyleKeyMap = {
21634
21676
  borderBottom: 'border-bottom-style',
21635
21677
  borderLeft: 'border-left-style',
21636
21678
  };
21679
+ var DEFAULT_COLOR = '#000000';
21637
21680
  /**
21638
21681
  * @internal
21639
21682
  */
@@ -21644,7 +21687,8 @@ exports.borderColorFormatHandler = {
21644
21687
  borderKeys_1.BorderKeys.forEach(function (key) {
21645
21688
  var width = element.style.getPropertyValue(BorderWidthKeyMap[key]);
21646
21689
  var style = element.style.getPropertyValue(BorderStyleKeyMap[key]);
21647
- var borderColor = (0, color_1.retrieveElementColor)(element, key);
21690
+ var color = (0, color_1.retrieveElementColor)(element, key);
21691
+ var borderColor = color == 'initial' ? DEFAULT_COLOR : color;
21648
21692
  if (borderColor) {
21649
21693
  var lightModeColor = (0, color_1.getLightModeColor)(borderColor, !!context.isDarkMode, context.darkColorHandler);
21650
21694
  format[key] = (0, borderValues_1.combineBorderValue)({
@@ -21663,10 +21707,10 @@ exports.borderColorFormatHandler = {
21663
21707
  var value = format[key];
21664
21708
  if (value) {
21665
21709
  var borderValues = (0, borderValues_1.extractBorderValues)(value);
21710
+ var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21666
21711
  if (borderValues.color) {
21667
21712
  var transformedColor = (0, color_1.adaptColor)(element, borderValues.color, 'border', !!context.isDarkMode, context.darkColorHandler);
21668
21713
  if (transformedColor) {
21669
- var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21670
21714
  element.style.setProperty(borderColorProperty, transformedColor);
21671
21715
  }
21672
21716
  }
@@ -22155,13 +22199,15 @@ var styleBasedSegmentFormats = [
22155
22199
  'fontFamily',
22156
22200
  'fontSize',
22157
22201
  ];
22158
- var elementBasedSegmentFormats = [
22202
+ var sizeNeutralElementBasedSegmentFormats = [
22159
22203
  'strike',
22160
22204
  'underline',
22161
- 'superOrSubScript',
22162
22205
  'italic',
22163
22206
  'bold',
22164
22207
  ];
22208
+ var elementBasedSegmentFormats = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sizeNeutralElementBasedSegmentFormats), false), [
22209
+ 'superOrSubScript',
22210
+ ], false);
22165
22211
  var sharedBlockFormats = [
22166
22212
  'direction',
22167
22213
  'textAlign',
@@ -22185,7 +22231,8 @@ exports.defaultFormatKeysPerCategory = {
22185
22231
  listItemElement: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedBlockFormats), false), ['listItemAlign', 'margin', 'listStyle'], false),
22186
22232
  listLevel: ['direction', 'textAlign', 'margin', 'padding', 'listStyle', 'backgroundColor'],
22187
22233
  styleBasedSegment: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(styleBasedSegmentFormats), false), ['textColor', 'backgroundColor', 'lineHeight'], false),
22188
- elementBasedSegment: elementBasedSegmentFormats,
22234
+ elementBasedSegment: sizeNeutralElementBasedSegmentFormats,
22235
+ superOrSubScript: ['superOrSubScript'],
22189
22236
  segment: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(styleBasedSegmentFormats), false), (0, tslib_1.__read)(elementBasedSegmentFormats), false), [
22190
22237
  'textColor',
22191
22238
  'backgroundColor',
@@ -23582,9 +23629,9 @@ exports.shouldSetValue = shouldSetValue;
23582
23629
 
23583
23630
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23584
23631
  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;
23585
- exports.trimModelForSelection = 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;
23586
- 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.getNodePositionFromEvent = exports.isCursorMovingKey = exports.isModifierKey = exports.isCharacterValue = void 0;
23587
- 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 = exports.getImageMetadata = exports.updateImageMetadata = void 0;
23632
+ 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.sanitizeInvisibleUnicode = 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;
23633
+ 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.stripInvisibleUnicode = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.getNodePositionFromEvent = exports.isCursorMovingKey = exports.isModifierKey = exports.isCharacterValue = exports.trimModelForSelection = void 0;
23634
+ 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 = exports.getImageMetadata = exports.updateImageMetadata = exports.runEditSteps = exports.getClosestAncestorBlockGroupIndex = void 0;
23588
23635
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
23589
23636
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
23590
23637
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -23705,6 +23752,8 @@ var normalizeParagraph_1 = __webpack_require__(/*! ./modelApi/common/normalizePa
23705
23752
  Object.defineProperty(exports, "normalizeParagraph", ({ enumerable: true, get: function () { return normalizeParagraph_1.normalizeParagraph; } }));
23706
23753
  var normalizeContentModel_1 = __webpack_require__(/*! ./modelApi/common/normalizeContentModel */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeContentModel.ts");
23707
23754
  Object.defineProperty(exports, "normalizeContentModel", ({ enumerable: true, get: function () { return normalizeContentModel_1.normalizeContentModel; } }));
23755
+ var sanitizeInvisibleUnicode_1 = __webpack_require__(/*! ./modelApi/common/sanitizeInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts");
23756
+ Object.defineProperty(exports, "sanitizeInvisibleUnicode", ({ enumerable: true, get: function () { return sanitizeInvisibleUnicode_1.sanitizeInvisibleUnicode; } }));
23708
23757
  var isGeneralSegment_1 = __webpack_require__(/*! ./modelApi/typeCheck/isGeneralSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isGeneralSegment.ts");
23709
23758
  Object.defineProperty(exports, "isGeneralSegment", ({ enumerable: true, get: function () { return isGeneralSegment_1.isGeneralSegment; } }));
23710
23759
  var unwrapBlock_1 = __webpack_require__(/*! ./modelApi/common/unwrapBlock */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts");
@@ -23770,6 +23819,8 @@ var stringUtil_1 = __webpack_require__(/*! ./domUtils/stringUtil */ "./packages/
23770
23819
  Object.defineProperty(exports, "isPunctuation", ({ enumerable: true, get: function () { return stringUtil_1.isPunctuation; } }));
23771
23820
  Object.defineProperty(exports, "isSpace", ({ enumerable: true, get: function () { return stringUtil_1.isSpace; } }));
23772
23821
  Object.defineProperty(exports, "normalizeText", ({ enumerable: true, get: function () { return stringUtil_1.normalizeText; } }));
23822
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ./domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
23823
+ Object.defineProperty(exports, "stripInvisibleUnicode", ({ enumerable: true, get: function () { return stripInvisibleUnicode_1.stripInvisibleUnicode; } }));
23773
23824
  var parseTableCells_1 = __webpack_require__(/*! ./domUtils/table/parseTableCells */ "./packages/roosterjs-content-model-dom/lib/domUtils/table/parseTableCells.ts");
23774
23825
  Object.defineProperty(exports, "parseTableCells", ({ enumerable: true, get: function () { return parseTableCells_1.parseTableCells; } }));
23775
23826
  var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts");
@@ -23900,6 +23951,8 @@ exports.ListFormatsToKeep = [
23900
23951
  'direction',
23901
23952
  'textAlign',
23902
23953
  'htmlAlign',
23954
+ 'marginBottom',
23955
+ 'marginTop',
23903
23956
  ];
23904
23957
  /**
23905
23958
  * When copy format from one block to another, these are all the formats that we can copy
@@ -24766,6 +24819,134 @@ function normalizeSegmentFormat(format, environment) {
24766
24819
  exports.normalizeSegmentFormat = normalizeSegmentFormat;
24767
24820
 
24768
24821
 
24822
+ /***/ },
24823
+
24824
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts"
24825
+ /*!**********************************************************************************************!*\
24826
+ !*** ./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts ***!
24827
+ \**********************************************************************************************/
24828
+ (__unused_webpack_module, exports, __webpack_require__) {
24829
+
24830
+ "use strict";
24831
+
24832
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
24833
+ exports.sanitizeInvisibleUnicode = void 0;
24834
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
24835
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ../../domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
24836
+ /**
24837
+ * Strip invisible Unicode characters from all text and link hrefs in a content model.
24838
+ * This sanitizes the model at initialization time to prevent hidden content in links
24839
+ * or text (e.g. zero-width chars, bidirectional marks, Unicode Tags).
24840
+ * For General segments, all Text nodes under the element are also sanitized.
24841
+ * @param model The content model document to sanitize in-place
24842
+ */
24843
+ function sanitizeInvisibleUnicode(model) {
24844
+ sanitizeBlockGroup(model);
24845
+ }
24846
+ exports.sanitizeInvisibleUnicode = sanitizeInvisibleUnicode;
24847
+ function sanitizeBlockGroup(group) {
24848
+ var e_1, _a;
24849
+ try {
24850
+ for (var _b = (0, tslib_1.__values)(group.blocks), _c = _b.next(); !_c.done; _c = _b.next()) {
24851
+ var block = _c.value;
24852
+ sanitizeBlock(block);
24853
+ }
24854
+ }
24855
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
24856
+ finally {
24857
+ try {
24858
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
24859
+ }
24860
+ finally { if (e_1) throw e_1.error; }
24861
+ }
24862
+ }
24863
+ function sanitizeBlock(block) {
24864
+ var e_2, _a, e_3, _b, e_4, _c;
24865
+ switch (block.blockType) {
24866
+ case 'Paragraph':
24867
+ try {
24868
+ for (var _d = (0, tslib_1.__values)(block.segments), _e = _d.next(); !_e.done; _e = _d.next()) {
24869
+ var segment = _e.value;
24870
+ sanitizeSegment(segment);
24871
+ }
24872
+ }
24873
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
24874
+ finally {
24875
+ try {
24876
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
24877
+ }
24878
+ finally { if (e_2) throw e_2.error; }
24879
+ }
24880
+ break;
24881
+ case 'Table':
24882
+ try {
24883
+ for (var _f = (0, tslib_1.__values)(block.rows), _g = _f.next(); !_g.done; _g = _f.next()) {
24884
+ var row = _g.value;
24885
+ try {
24886
+ for (var _h = (e_4 = void 0, (0, tslib_1.__values)(row.cells)), _j = _h.next(); !_j.done; _j = _h.next()) {
24887
+ var cell = _j.value;
24888
+ sanitizeBlockGroup(cell);
24889
+ }
24890
+ }
24891
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
24892
+ finally {
24893
+ try {
24894
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
24895
+ }
24896
+ finally { if (e_4) throw e_4.error; }
24897
+ }
24898
+ }
24899
+ }
24900
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
24901
+ finally {
24902
+ try {
24903
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
24904
+ }
24905
+ finally { if (e_3) throw e_3.error; }
24906
+ }
24907
+ break;
24908
+ case 'BlockGroup':
24909
+ sanitizeBlockGroup(block);
24910
+ if (block.blockGroupType === 'General' && block.element) {
24911
+ sanitizeTextNodes(block.element);
24912
+ }
24913
+ break;
24914
+ case 'Entity':
24915
+ case 'Divider':
24916
+ break;
24917
+ }
24918
+ }
24919
+ function sanitizeSegment(segment) {
24920
+ var _a;
24921
+ if ((_a = segment.link) === null || _a === void 0 ? void 0 : _a.format.href) {
24922
+ segment.link.format.href = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.link.format.href);
24923
+ }
24924
+ switch (segment.segmentType) {
24925
+ case 'Text':
24926
+ segment.text = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.text);
24927
+ break;
24928
+ case 'General':
24929
+ sanitizeTextNodes(segment.element);
24930
+ sanitizeBlockGroup(segment);
24931
+ break;
24932
+ case 'Image':
24933
+ case 'Entity':
24934
+ case 'Br':
24935
+ case 'SelectionMarker':
24936
+ break;
24937
+ }
24938
+ }
24939
+ function sanitizeTextNodes(element) {
24940
+ var walker = element.ownerDocument.createTreeWalker(element, NodeFilter.SHOW_TEXT);
24941
+ var node;
24942
+ while ((node = walker.nextNode())) {
24943
+ if (node.nodeValue) {
24944
+ node.nodeValue = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(node.nodeValue);
24945
+ }
24946
+ }
24947
+ }
24948
+
24949
+
24769
24950
  /***/ },
24770
24951
 
24771
24952
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts"
@@ -25531,7 +25712,7 @@ var BorderFormatters = (_a = {},
25531
25712
  * Apply vertical align, borders, and background color to all cells in the table
25532
25713
  */
25533
25714
  function formatCells(rows, format, metaOverrides) {
25534
- var hasBandedRows = format.hasBandedRows, hasBandedColumns = format.hasBandedColumns, bgColorOdd = format.bgColorOdd, bgColorEven = format.bgColorEven, hasFirstColumn = format.hasFirstColumn;
25715
+ var hasBandedRows = format.hasBandedRows, hasBandedColumns = format.hasBandedColumns, bgColorOdd = format.bgColorOdd, bgColorEven = format.bgColorEven, hasFirstColumn = format.hasFirstColumn, hasHeaderRow = format.hasHeaderRow;
25535
25716
  rows.forEach(function (row, rowIndex) {
25536
25717
  row.cells.forEach(function (readonlyCell, colIndex) {
25537
25718
  var _a;
@@ -25562,19 +25743,14 @@ function formatCells(rows, format, metaOverrides) {
25562
25743
  }
25563
25744
  // Format Background Color
25564
25745
  if (!metaOverrides.bgColorOverrides[rowIndex][colIndex]) {
25565
- var color = void 0;
25566
- if (hasFirstColumn && colIndex == 0 && rowIndex > 0) {
25567
- color = null;
25568
- }
25569
- else {
25570
- color =
25571
- hasBandedRows || hasBandedColumns
25572
- ? (hasBandedColumns && colIndex % 2 != 0) ||
25573
- (hasBandedRows && rowIndex % 2 != 0)
25574
- ? bgColorOdd
25575
- : bgColorEven
25576
- : bgColorEven; /* bgColorEven is the default color */
25577
- }
25746
+ var bandedColumnMod = hasFirstColumn ? 0 : 1;
25747
+ var bandedRowMod = hasHeaderRow ? 0 : 1;
25748
+ var color = hasBandedRows || hasBandedColumns
25749
+ ? (hasBandedColumns && colIndex % 2 != bandedColumnMod) ||
25750
+ (hasBandedRows && rowIndex % 2 != bandedRowMod)
25751
+ ? bgColorOdd
25752
+ : bgColorEven
25753
+ : bgColorEven; /* bgColorEven is the default color */
25578
25754
  (0, setTableCellBackgroundColor_1.setTableCellBackgroundColor)(cell, color, false /*isColorOverride*/, true /*applyToSegments*/);
25579
25755
  }
25580
25756
  // Format Vertical Align
@@ -25592,6 +25768,7 @@ function formatCells(rows, format, metaOverrides) {
25592
25768
  * @param format The table metadata format
25593
25769
  */
25594
25770
  function setFirstColumnFormatBorders(rows, format) {
25771
+ var customStyles = format.hasFirstColumn ? format.firstColumnCustomStyles : undefined;
25595
25772
  rows.forEach(function (row, rowIndex) {
25596
25773
  row.cells.forEach(function (readonlyCell, cellIndex) {
25597
25774
  var e_1, _a, e_2, _b;
@@ -25600,6 +25777,16 @@ function setFirstColumnFormatBorders(rows, format) {
25600
25777
  if (rowIndex == 0) {
25601
25778
  cell.isHeader = !!format.hasHeaderRow;
25602
25779
  }
25780
+ if (format.hasFirstColumn && customStyles) {
25781
+ setStyleIfDefined(cell.format, 'textAlign', customStyles.textAlign);
25782
+ setBorderColorIfExists(cell.format, 'borderTop', customStyles.borderTopColor);
25783
+ setBorderColorIfExists(cell.format, 'borderRight', customStyles.borderRightColor);
25784
+ setBorderColorIfExists(cell.format, 'borderBottom', customStyles.borderBottomColor);
25785
+ setBorderColorIfExists(cell.format, 'borderLeft', customStyles.borderLeftColor);
25786
+ if (customStyles.backgroundColor) {
25787
+ (0, setTableCellBackgroundColor_1.setTableCellBackgroundColor)(cell, customStyles.backgroundColor, false /*isColorOverride*/, true /*applyToSegments*/);
25788
+ }
25789
+ }
25603
25790
  try {
25604
25791
  for (var _c = (0, tslib_1.__values)(cell.blocks), _d = _c.next(); !_d.done; _d = _c.next()) {
25605
25792
  var block = _d.value;
@@ -25608,9 +25795,12 @@ function setFirstColumnFormatBorders(rows, format) {
25608
25795
  for (var _e = (e_2 = void 0, (0, tslib_1.__values)(block.segments)), _f = _e.next(); !_f.done; _f = _e.next()) {
25609
25796
  var segment = _f.value;
25610
25797
  (0, mutate_1.mutateSegment)(block, segment, function (cellSegment) {
25798
+ var _a, _b;
25611
25799
  if (format.hasFirstColumn) {
25612
- cellSegment.format.fontWeight = 'bold';
25613
- cell.format.fontWeight = 'bold';
25800
+ setStyleIfDefined(cellSegment.format, 'fontWeight', (_a = customStyles === null || customStyles === void 0 ? void 0 : customStyles.fontWeight) !== null && _a !== void 0 ? _a : 'bold');
25801
+ setStyleIfDefined(cell.format, 'textAlign', customStyles === null || customStyles === void 0 ? void 0 : customStyles.textAlign);
25802
+ setStyleIfDefined(cell.format, 'fontWeight', (_b = customStyles === null || customStyles === void 0 ? void 0 : customStyles.fontWeight) !== null && _b !== void 0 ? _b : 'bold');
25803
+ setStyleIfDefined(cellSegment.format, 'italic', customStyles === null || customStyles === void 0 ? void 0 : customStyles.italic);
25614
25804
  }
25615
25805
  else if (cellSegment.format.fontWeight == 'bold' &&
25616
25806
  cell.format.fontWeight == 'bold') {
@@ -25642,24 +25832,74 @@ function setFirstColumnFormatBorders(rows, format) {
25642
25832
  });
25643
25833
  }
25644
25834
  exports.setFirstColumnFormatBorders = setFirstColumnFormatBorders;
25835
+ function setBorderColorIfExists(format, key, value) {
25836
+ if (value !== undefined) {
25837
+ setBorderColor(format, key, value);
25838
+ }
25839
+ }
25840
+ function setStyleIfDefined(format, key, value) {
25841
+ if (value !== undefined) {
25842
+ format[key] = value;
25843
+ }
25844
+ }
25645
25845
  function setHeaderRowFormat(rows, format, metaOverrides) {
25646
25846
  var _a;
25647
- // Exit early if hasHeaderRow is not set
25648
25847
  if (!format.hasHeaderRow) {
25649
25848
  return;
25650
25849
  }
25651
25850
  var rowIndex = 0;
25851
+ var customStyles = format.headerRowCustomStyles;
25652
25852
  (_a = rows[rowIndex]) === null || _a === void 0 ? void 0 : _a.cells.forEach(function (readonlyCell, cellIndex) {
25853
+ var e_3, _a, e_4, _b;
25854
+ var _c, _d, _e, _f;
25653
25855
  var cell = (0, mutate_1.mutateBlock)(readonlyCell);
25654
25856
  cell.isHeader = true;
25655
- cell.format.fontWeight = 'bold';
25857
+ cell.format.fontWeight = (_c = customStyles === null || customStyles === void 0 ? void 0 : customStyles.fontWeight) !== null && _c !== void 0 ? _c : 'bold';
25656
25858
  if (format.headerRowColor) {
25657
25859
  if (!metaOverrides.bgColorOverrides[rowIndex][cellIndex]) {
25658
25860
  (0, setTableCellBackgroundColor_1.setTableCellBackgroundColor)(cell, format.headerRowColor, false /*isColorOverride*/, true /*applyToSegments*/);
25659
25861
  }
25660
- setBorderColor(cell.format, 'borderTop', format.headerRowColor);
25661
- setBorderColor(cell.format, 'borderRight', format.headerRowColor);
25662
- setBorderColor(cell.format, 'borderLeft', format.headerRowColor);
25862
+ setBorderColor(cell.format, 'borderTop', (_d = customStyles === null || customStyles === void 0 ? void 0 : customStyles.borderTopColor) !== null && _d !== void 0 ? _d : format.headerRowColor);
25863
+ setBorderColor(cell.format, 'borderRight', (_e = customStyles === null || customStyles === void 0 ? void 0 : customStyles.borderRightColor) !== null && _e !== void 0 ? _e : format.headerRowColor);
25864
+ setBorderColor(cell.format, 'borderLeft', (_f = customStyles === null || customStyles === void 0 ? void 0 : customStyles.borderLeftColor) !== null && _f !== void 0 ? _f : format.headerRowColor);
25865
+ }
25866
+ if (customStyles) {
25867
+ setStyleIfDefined(cell.format, 'textAlign', customStyles.textAlign);
25868
+ setBorderColorIfExists(cell.format, 'borderBottom', customStyles.borderBottomColor);
25869
+ try {
25870
+ for (var _g = (0, tslib_1.__values)(cell.blocks), _h = _g.next(); !_h.done; _h = _g.next()) {
25871
+ var block = _h.value;
25872
+ if (block.blockType == 'Paragraph') {
25873
+ try {
25874
+ for (var _j = (e_4 = void 0, (0, tslib_1.__values)(block.segments)), _k = _j.next(); !_k.done; _k = _j.next()) {
25875
+ var segment = _k.value;
25876
+ (0, mutate_1.mutateSegment)(block, segment, function (cellSegment) {
25877
+ if (customStyles.italic) {
25878
+ cellSegment.format.italic = customStyles.italic;
25879
+ }
25880
+ else if (cellSegment.format.italic) {
25881
+ delete cellSegment.format.italic;
25882
+ }
25883
+ });
25884
+ }
25885
+ }
25886
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
25887
+ finally {
25888
+ try {
25889
+ if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
25890
+ }
25891
+ finally { if (e_4) throw e_4.error; }
25892
+ }
25893
+ }
25894
+ }
25895
+ }
25896
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
25897
+ finally {
25898
+ try {
25899
+ if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
25900
+ }
25901
+ finally { if (e_3) throw e_3.error; }
25902
+ }
25663
25903
  }
25664
25904
  });
25665
25905
  }
@@ -26573,7 +26813,7 @@ function mergeParagraph(markerPosition, newPara, mergeToCurrentParagraph, contex
26573
26813
  }
26574
26814
  }
26575
26815
  function mergeTables(markerPosition, newTable, source) {
26576
- var _a, _b, _c, _d, _e;
26816
+ var _a, _b, _c, _d, _e, _f;
26577
26817
  var tableContext = markerPosition.tableContext, marker = markerPosition.marker;
26578
26818
  if (tableContext && source.blocks.length == 1 && source.blocks[0] == newTable) {
26579
26819
  var readonlyTable = tableContext.table, colIndex = tableContext.colIndex, rowIndex = tableContext.rowIndex;
@@ -26610,12 +26850,30 @@ function mergeTables(markerPosition, newTable, source) {
26610
26850
  }
26611
26851
  }
26612
26852
  }
26853
+ var logicalRowOffsets = [];
26854
+ var logicalRowCount = 0;
26855
+ for (var i = 0; i < newTableRowCount; i++) {
26856
+ logicalRowOffsets[i] = logicalRowCount;
26857
+ var row = newTable.rows[i];
26858
+ if (row && row.cells.some(function (cell) { return !cell.spanAbove; })) {
26859
+ logicalRowCount++;
26860
+ }
26861
+ }
26613
26862
  for (var i = 0; i < newTable.rows.length; i++) {
26614
- var targetRowIndex = getTargetRowIndex(table, rowIndex, i, colIndex);
26863
+ var sourceRow = newTable.rows[i];
26864
+ var targetRowIndex = getTargetRowIndex(table, rowIndex, logicalRowOffsets[i], colIndex);
26865
+ var logicalColOffsets = [];
26866
+ var logicalColCount = 0;
26867
+ for (var j = 0; j < sourceRow.cells.length; j++) {
26868
+ logicalColOffsets[j] = logicalColCount;
26869
+ if (!((_e = sourceRow.cells[j]) === null || _e === void 0 ? void 0 : _e.spanLeft)) {
26870
+ logicalColCount++;
26871
+ }
26872
+ }
26615
26873
  for (var j = 0; j < newTable.rows[i].cells.length; j++) {
26616
- var newCell = newTable.rows[i].cells[j];
26617
- var targetColIndex = getTargetColIndex(table, targetRowIndex, colIndex, j);
26618
- var oldCell = (_e = table.rows[targetRowIndex]) === null || _e === void 0 ? void 0 : _e.cells[targetColIndex];
26874
+ var newCell = sourceRow.cells[j];
26875
+ var targetColIndex = getTargetColIndex(table, targetRowIndex, colIndex, logicalColOffsets[j]);
26876
+ var oldCell = (_f = table.rows[targetRowIndex]) === null || _f === void 0 ? void 0 : _f.cells[targetColIndex];
26619
26877
  table.rows[targetRowIndex].cells[targetColIndex] = newCell;
26620
26878
  if (i == 0 && j == 0) {
26621
26879
  var newMarker = (0, createSelectionMarker_1.createSelectionMarker)(marker.format);
@@ -27854,14 +28112,28 @@ var updateMetadata_1 = __webpack_require__(/*! ./updateMetadata */ "./packages/r
27854
28112
  var TableBorderFormat_1 = __webpack_require__(/*! ../../constants/TableBorderFormat */ "./packages/roosterjs-content-model-dom/lib/constants/TableBorderFormat.ts");
27855
28113
  var definitionCreators_1 = __webpack_require__(/*! ./definitionCreators */ "./packages/roosterjs-content-model-dom/lib/modelApi/metadata/definitionCreators.ts");
27856
28114
  var NullStringDefinition = (0, definitionCreators_1.createStringDefinition)(false /** isOptional */, undefined /** value */, true /** allowNull */);
28115
+ var OptionalStringDefinition = (0, definitionCreators_1.createStringDefinition)(true /** isOptional */);
28116
+ var OptionalBooleanDefinition = (0, definitionCreators_1.createBooleanDefinition)(true /** isOptional */);
27857
28117
  var BooleanDefinition = (0, definitionCreators_1.createBooleanDefinition)(false /** isOptional */);
28118
+ var TableSpecialCellFormatDefinition = (0, definitionCreators_1.createObjectDefinition)({
28119
+ fontWeight: OptionalStringDefinition,
28120
+ italic: OptionalBooleanDefinition,
28121
+ borderTopColor: OptionalStringDefinition,
28122
+ borderRightColor: OptionalStringDefinition,
28123
+ borderBottomColor: OptionalStringDefinition,
28124
+ borderLeftColor: OptionalStringDefinition,
28125
+ textAlign: OptionalStringDefinition,
28126
+ backgroundColor: OptionalStringDefinition,
28127
+ }, true /* isOptional */, true /** allowNull */);
27858
28128
  var TableFormatDefinition = (0, definitionCreators_1.createObjectDefinition)({
27859
28129
  topBorderColor: NullStringDefinition,
27860
28130
  bottomBorderColor: NullStringDefinition,
27861
28131
  verticalBorderColor: NullStringDefinition,
27862
28132
  hasHeaderRow: BooleanDefinition,
27863
28133
  headerRowColor: NullStringDefinition,
28134
+ headerRowCustomStyles: TableSpecialCellFormatDefinition,
27864
28135
  hasFirstColumn: BooleanDefinition,
28136
+ firstColumnCustomStyles: TableSpecialCellFormatDefinition,
27865
28137
  hasBandedColumns: BooleanDefinition,
27866
28138
  hasBandedRows: BooleanDefinition,
27867
28139
  bgColorEven: NullStringDefinition,
@@ -28024,10 +28296,13 @@ function getSelectedSegments(model, includingFormatHolder, mutate) {
28024
28296
  return segments.map(function (x) { return x[0]; });
28025
28297
  }
28026
28298
  exports.getSelectedSegments = getSelectedSegments;
28027
- function getSelectedParagraphs(model, mutate) {
28299
+ function getSelectedParagraphs(model, mutate, removeUnmeaningful) {
28300
+ if (removeUnmeaningful === void 0) { removeUnmeaningful = true; }
28028
28301
  var selections = collectSelections(model, { includeListFormatHolder: 'never' });
28029
28302
  var result = [];
28030
- removeUnmeaningfulSelections(selections);
28303
+ if (removeUnmeaningful) {
28304
+ removeUnmeaningfulSelections(selections);
28305
+ }
28031
28306
  selections.forEach(function (_a) {
28032
28307
  var block = _a.block;
28033
28308
  if ((block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph') {
@@ -28801,6 +29076,7 @@ function createModelToDomFormatContext() {
28801
29076
  listFormat: {
28802
29077
  threadItemCounts: [],
28803
29078
  nodeStack: [],
29079
+ currentLevel: 0,
28804
29080
  },
28805
29081
  implicitFormat: {},
28806
29082
  };
@@ -29375,6 +29651,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29375
29651
  var parentLevel = nodeStack[layer];
29376
29652
  var stackLevel = nodeStack[layer + 1];
29377
29653
  var itemLevel = listItem.levels[layer];
29654
+ context.listFormat.currentLevel = layer;
29378
29655
  if (stackLevel.listType != itemLevel.listType ||
29379
29656
  ((_a = stackLevel.dataset) === null || _a === void 0 ? void 0 : _a.editingInfo) != itemLevel.dataset.editingInfo ||
29380
29657
  (itemLevel.listType == 'OL' &&
@@ -29410,6 +29687,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29410
29687
  var newList = void 0;
29411
29688
  var isNewlyCreated = false;
29412
29689
  var levelRefNode = (_c = nodeStack[layer].refNode) !== null && _c !== void 0 ? _c : null;
29690
+ context.listFormat.currentLevel = layer;
29413
29691
  if (context.allowCacheListItem && level.cachedElement) {
29414
29692
  newList = level.cachedElement;
29415
29693
  nodeStack[layer].refNode = (0, reuseCachedElement_1.reuseCachedElement)(lastParent, level.cachedElement, levelRefNode, context.rewriteFromModel);
@@ -30210,8 +30488,9 @@ function handleSegmentCommon(doc, segmentNode, containerNode, segment, context,
30210
30488
  }
30211
30489
  (0, applyFormat_1.applyFormat)(containerNode, context.formatAppliers.styleBasedSegment, segment.format, context);
30212
30490
  segmentNodes === null || segmentNodes === void 0 ? void 0 : segmentNodes.push(segmentNode);
30213
- context.modelHandlers.segmentDecorator(doc, containerNode, segment, context, segmentNodes);
30214
30491
  (0, applyFormat_1.applyFormat)(containerNode, context.formatAppliers.elementBasedSegment, segment.format, context);
30492
+ context.modelHandlers.segmentDecorator(doc, containerNode, segment, context, segmentNodes);
30493
+ (0, applyFormat_1.applyFormat)(containerNode, context.formatAppliers.superOrSubScript, segment.format, context);
30215
30494
  (_a = context.onNodeCreated) === null || _a === void 0 ? void 0 : _a.call(context, segment, segmentNode);
30216
30495
  }
30217
30496
  exports.handleSegmentCommon = handleSegmentCommon;
@@ -36426,7 +36705,7 @@ var ImageEditPlugin = /** @class */ (function () {
36426
36705
  operation === 'crop');
36427
36706
  };
36428
36707
  ImageEditPlugin.prototype.canRegenerateImage = function (image) {
36429
- return (0, canRegenerateImage_1.canRegenerateImage)(image);
36708
+ return (0, canRegenerateImage_1.canRegenerateImage)(image, this.options.resolveImageSource);
36430
36709
  };
36431
36710
  ImageEditPlugin.prototype.startCropMode = function (editor, image, isRTL) {
36432
36711
  var _this = this;
@@ -37187,12 +37466,21 @@ exports.canRegenerateImage = void 0;
37187
37466
  * Check if we can regenerate edited image from the source image.
37188
37467
  * An image can't regenerate result when there is CORS issue of the source content.
37189
37468
  * @param img The image element to test
37469
+ * @param resolveImageSource Optional callback to resolve an image `src` into a canvas-safe URL (e.g., a data URL).
37190
37470
  * @returns True when we can regenerate the edited image, otherwise false
37191
37471
  */
37192
- function canRegenerateImage(img) {
37472
+ function canRegenerateImage(img, resolveImageSource) {
37193
37473
  if (!img) {
37194
37474
  return false;
37195
37475
  }
37476
+ // If a resolveImageSource callback is provided, the image source should be resolved to a
37477
+ // canvas-compatible URL when editing starts, so we can assume the image can be regenerated.
37478
+ if (resolveImageSource && img.src) {
37479
+ var resolved = resolveImageSource(img.src);
37480
+ if (resolved && resolved !== img.src) {
37481
+ return true;
37482
+ }
37483
+ }
37196
37484
  try {
37197
37485
  var canvas = img.ownerDocument.createElement('canvas');
37198
37486
  canvas.width = 10;
@@ -37296,7 +37584,7 @@ var IMAGE_EDIT_SHADOW_ROOT = 'ImageEditShadowRoot';
37296
37584
  * @internal
37297
37585
  */
37298
37586
  function createImageWrapper(editor, image, options, editInfo, htmlOptions, operation) {
37299
- var imageClone = cloneImage(image, editInfo);
37587
+ var imageClone = cloneImage(image, editInfo, options.resolveImageSource);
37300
37588
  var doc = editor.getDocument();
37301
37589
  var rotators = [];
37302
37590
  if (!options.disableRotate && operation.indexOf('rotate') > -1) {
@@ -37362,11 +37650,12 @@ var createBorder = function (editor, borderColor) {
37362
37650
  resizeBorder.setAttribute("style", "position:absolute;left:0;right:0;top:0;bottom:0;border:solid 2px " + borderColor + ";pointer-events:none;");
37363
37651
  return resizeBorder;
37364
37652
  };
37365
- var cloneImage = function (image, editInfo) {
37653
+ var cloneImage = function (image, editInfo, resolveImageSource) {
37654
+ var _a;
37366
37655
  var imageClone = image.cloneNode(true);
37367
37656
  imageClone.style.removeProperty('transform');
37368
37657
  if (editInfo.src) {
37369
- imageClone.src = editInfo.src;
37658
+ imageClone.src = (_a = resolveImageSource === null || resolveImageSource === void 0 ? void 0 : resolveImageSource(editInfo.src)) !== null && _a !== void 0 ? _a : editInfo.src;
37370
37659
  imageClone.removeAttribute('id');
37371
37660
  imageClone.style.removeProperty('max-width');
37372
37661
  imageClone.style.removeProperty('max-height');
@@ -39031,6 +39320,7 @@ var LIST_ELEMENT_TAGS = ['UL', 'OL', 'LI'];
39031
39320
  var LIST_ELEMENT_SELECTOR = LIST_ELEMENT_TAGS.join(',');
39032
39321
  var END_OF_PARAGRAPH = 'EOP';
39033
39322
  var SELECTED_CLASS = 'Selected';
39323
+ var BASE_PADDING_WAC_LISTS = '1em';
39034
39324
  /**
39035
39325
  * Wac components do not use sub and super tags, instead only add vertical align to a span.
39036
39326
  * This parser normalize the content for content model
@@ -39128,15 +39418,13 @@ var wacListItemParser = function (format, element) {
39128
39418
  if (element.style.display === 'block') {
39129
39419
  format.displayForDummyItem = undefined;
39130
39420
  }
39131
- format.marginLeft = undefined;
39132
- format.marginRight = undefined;
39133
39421
  };
39134
39422
  /**
39135
39423
  * Wac usually adds padding to lists which is unwanted so remove it.
39136
39424
  */
39137
39425
  var wacListLevelParser = function (format) {
39138
39426
  format.marginLeft = undefined;
39139
- format.paddingLeft = undefined;
39427
+ format.paddingLeft = BASE_PADDING_WAC_LISTS;
39140
39428
  };
39141
39429
  /**
39142
39430
  * This function returns whether we need to clear the list format.