roosterjs 9.48.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.
@@ -1,4 +1,4 @@
1
- // Type definitions for roosterjs (Version 9.48.0)
1
+ // Type definitions for roosterjs (Version 9.49.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -3158,6 +3158,12 @@ export interface ModelToDomListContext {
3158
3158
  * A stack of current list element chain, start from the parent node of top level list
3159
3159
  */
3160
3160
  nodeStack: ModelToDomListStackItem[];
3161
+ /**
3162
+ * Current level of list item being processed, start from 0
3163
+ * This is used by metadata applier to determine which level of list item is being processed,
3164
+ * so it can apply correct list style for that level. It will be updated by list handler before processing each list item, and reset to 0 when processing a new list.
3165
+ */
3166
+ currentLevel: number;
3161
3167
  }
3162
3168
 
3163
3169
  /**
@@ -7408,6 +7414,15 @@ export function normalizeParagraph(paragraph: ReadonlyContentModelParagraph): vo
7408
7414
  */
7409
7415
  export function normalizeContentModel(group: ReadonlyContentModelBlockGroup): void;
7410
7416
 
7417
+ /**
7418
+ * Strip invisible Unicode characters from all text and link hrefs in a content model.
7419
+ * This sanitizes the model at initialization time to prevent hidden content in links
7420
+ * or text (e.g. zero-width chars, bidirectional marks, Unicode Tags).
7421
+ * For General segments, all Text nodes under the element are also sanitized.
7422
+ * @param model The content model document to sanitize in-place
7423
+ */
7424
+ export function sanitizeInvisibleUnicode(model: ContentModelDocument): void;
7425
+
7411
7426
  /**
7412
7427
  * Check if the given block group is a general segment
7413
7428
  * @param group The group to check
@@ -7725,6 +7740,19 @@ export function isSpace(char: string): boolean;
7725
7740
  */
7726
7741
  export function normalizeText(txt: string, isForward: boolean): string;
7727
7742
 
7743
+ /**
7744
+ * Strip invisible Unicode characters from a string.
7745
+ * This removes zero-width characters, bidirectional marks, Unicode Tags (U+E0001-U+E00FF),
7746
+ * interlinear annotation anchors, Mongolian free variation selectors,
7747
+ * and other invisible formatting characters that can be used to hide content in links.
7748
+ *
7749
+ * @remarks This function strips ZWJ (U+200D) which may affect emoji sequences.
7750
+ * It should only be applied to href attributes, not to visible text content.
7751
+ * @param value The string to strip invisible characters from
7752
+ * @returns The string with invisible characters removed
7753
+ */
7754
+ export function stripInvisibleUnicode(value: string): string;
7755
+
7728
7756
  /**
7729
7757
  * Parse a table into a two dimensions array of TD elements. For those merged cells, the value will be null.
7730
7758
  * @param table Input HTML Table element
@@ -7909,6 +7937,14 @@ export function getSelectedParagraphs(model: ContentModelDocument): ContentModel
7909
7937
  */
7910
7938
  export function getSelectedParagraphs(model: ReadonlyContentModelDocument, mutate: true): ShallowMutableContentModelParagraph[];
7911
7939
 
7940
+ /**
7941
+ * Get any array of selected paragraphs from a content model, return mutable paragraphs
7942
+ * @param model The Content Model to get selection from
7943
+ * @param mutate Set to true to indicate we will mutate the selected paragraphs
7944
+ * @param removeUnmeaningful True to remove unmeaningful selection like only selection marker is selected, or head/tail paragraph is selected with selection marker at the wrong place
7945
+ */
7946
+ export function getSelectedParagraphs(model: ReadonlyContentModelDocument, mutate: true, removeUnmeaningful: boolean): ShallowMutableContentModelParagraph[];
7947
+
7912
7948
  /**
7913
7949
  * Get any array of selected paragraphs from a content model (Readonly)
7914
7950
  * @param model The Content Model to get selection from
@@ -4309,6 +4309,10 @@ function setListType(model, listType, removeMargins) {
4309
4309
  fontSize: segmentFormat.fontSize,
4310
4310
  textColor: segmentFormat.textColor,
4311
4311
  });
4312
+ if (removeMargins) {
4313
+ newListItem.format.marginBottom = '0px';
4314
+ newListItem.format.marginTop = '0px';
4315
+ }
4312
4316
  if (block.blockType == 'Paragraph') {
4313
4317
  (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(block);
4314
4318
  }
@@ -7886,21 +7890,25 @@ exports.setTableCellShade = setTableCellShade;
7886
7890
  /*!******************************************************************************!*\
7887
7891
  !*** ./packages/roosterjs-content-model-api/lib/publicApi/utils/checkXss.ts ***!
7888
7892
  \******************************************************************************/
7889
- (__unused_webpack_module, exports) {
7893
+ (__unused_webpack_module, exports, __webpack_require__) {
7890
7894
 
7891
7895
  "use strict";
7892
7896
 
7893
7897
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7894
7898
  exports.checkXss = void 0;
7899
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
7895
7900
  /**
7896
7901
  * @internal Check if there is XSS attack in the link
7897
7902
  * @param link The link to be checked
7898
- * @returns The safe link, or empty string if there is XSS attack
7899
- * @remarks This function checks for patterns like s\nc\nr\ni\np\nt: to prevent XSS attacks. This may block some valid links,
7903
+ * @returns The safe link with invisible Unicode characters stripped, or empty string if there is XSS attack
7904
+ * @remarks This function strips invisible Unicode characters (zero-width chars, Unicode Tags, etc.)
7905
+ * and checks for patterns like s\nc\nr\ni\np\nt: to prevent XSS attacks. This may block some valid links,
7900
7906
  * but it is necessary for security reasons. We treat the word "script" as safe if there are "/" before it.
7901
7907
  */
7902
7908
  function checkXss(link) {
7903
- return link.match(/^[^\/]*s\n*c\n*r\n*i\n*p\n*t\n*:/i) ? '' : link;
7909
+ // Defense-in-depth: strip invisible Unicode even if already handled elsewhere
7910
+ var sanitized = (0, roosterjs_content_model_dom_1.stripInvisibleUnicode)(link);
7911
+ return sanitized.match(/^[^\/]*s\n*c\n*r\n*i\n*p\n*t\n*:/i) ? '' : sanitized;
7904
7912
  }
7905
7913
  exports.checkXss = checkXss;
7906
7914
 
@@ -8138,7 +8146,7 @@ var splitSelectedParagraphByBr_1 = __webpack_require__(/*! ../../modelApi/block/
8138
8146
  function formatParagraphWithContentModel(editor, apiName, setStyleCallback) {
8139
8147
  editor.formatContentModel(function (model, context) {
8140
8148
  (0, splitSelectedParagraphByBr_1.splitSelectedParagraphByBr)(model);
8141
- var paragraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true /*mutate*/);
8149
+ var paragraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true /*mutate*/, false /*removeUnmeaningful*/);
8142
8150
  paragraphs.forEach(setStyleCallback);
8143
8151
  context.newPendingFormat = 'preserve';
8144
8152
  return paragraphs.length > 0;
@@ -15618,6 +15626,7 @@ var Editor = /** @class */ (function () {
15618
15626
  };
15619
15627
  this.core = (0, createEditorCore_1.createEditorCore)(contentDiv, options);
15620
15628
  var initialModel = (_a = options.initialModel) !== null && _a !== void 0 ? _a : (0, roosterjs_content_model_dom_1.createEmptyModel)(this.core.format.defaultFormat);
15629
+ (0, roosterjs_content_model_dom_1.sanitizeInvisibleUnicode)(initialModel);
15621
15630
  this.core.api.setContentModel(this.core, initialModel, { ignoreSelection: true }, undefined /*onNodeCreated*/, true /*isInitializing*/);
15622
15631
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
15623
15632
  }
@@ -16393,10 +16402,10 @@ function shouldApplyToItem(listStyleType, listType) {
16393
16402
  exports.listItemMetadataApplier = {
16394
16403
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16395
16404
  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
16405
+ var _a, _b;
16406
+ var depth = context.listFormat.currentLevel;
16398
16407
  if (depth >= 0) {
16399
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16408
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16400
16409
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16401
16410
  if (listStyleType !== undefined) {
16402
16411
  if (shouldApplyToItem(listStyleType, listType)) {
@@ -16415,10 +16424,10 @@ exports.listItemMetadataApplier = {
16415
16424
  exports.listLevelMetadataApplier = {
16416
16425
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16417
16426
  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
16427
+ var _a, _b;
16428
+ var depth = context.listFormat.currentLevel;
16420
16429
  if (depth >= 0) {
16421
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16430
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16422
16431
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16423
16432
  if (listStyleType !== undefined) {
16424
16433
  if (!shouldApplyToItem(listStyleType, listType)) {
@@ -20791,6 +20800,38 @@ function normalizeText(txt, isForward) {
20791
20800
  exports.normalizeText = normalizeText;
20792
20801
 
20793
20802
 
20803
+ /***/ },
20804
+
20805
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts"
20806
+ /*!************************************************************************************!*\
20807
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts ***!
20808
+ \************************************************************************************/
20809
+ (__unused_webpack_module, exports) {
20810
+
20811
+ "use strict";
20812
+
20813
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20814
+ exports.stripInvisibleUnicode = void 0;
20815
+ var INVISIBLE_UNICODE_REGEX =
20816
+ // eslint-disable-next-line no-misleading-character-class
20817
+ /[\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;
20818
+ /**
20819
+ * Strip invisible Unicode characters from a string.
20820
+ * This removes zero-width characters, bidirectional marks, Unicode Tags (U+E0001-U+E00FF),
20821
+ * interlinear annotation anchors, Mongolian free variation selectors,
20822
+ * and other invisible formatting characters that can be used to hide content in links.
20823
+ *
20824
+ * @remarks This function strips ZWJ (U+200D) which may affect emoji sequences.
20825
+ * It should only be applied to href attributes, not to visible text content.
20826
+ * @param value The string to strip invisible characters from
20827
+ * @returns The string with invisible characters removed
20828
+ */
20829
+ function stripInvisibleUnicode(value) {
20830
+ return value.replace(INVISIBLE_UNICODE_REGEX, '');
20831
+ }
20832
+ exports.stripInvisibleUnicode = stripInvisibleUnicode;
20833
+
20834
+
20794
20835
  /***/ },
20795
20836
 
20796
20837
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts"
@@ -21634,6 +21675,7 @@ var BorderStyleKeyMap = {
21634
21675
  borderBottom: 'border-bottom-style',
21635
21676
  borderLeft: 'border-left-style',
21636
21677
  };
21678
+ var DEFAULT_COLOR = '#000000';
21637
21679
  /**
21638
21680
  * @internal
21639
21681
  */
@@ -21644,7 +21686,8 @@ exports.borderColorFormatHandler = {
21644
21686
  borderKeys_1.BorderKeys.forEach(function (key) {
21645
21687
  var width = element.style.getPropertyValue(BorderWidthKeyMap[key]);
21646
21688
  var style = element.style.getPropertyValue(BorderStyleKeyMap[key]);
21647
- var borderColor = (0, color_1.retrieveElementColor)(element, key);
21689
+ var color = (0, color_1.retrieveElementColor)(element, key);
21690
+ var borderColor = color == 'initial' ? DEFAULT_COLOR : color;
21648
21691
  if (borderColor) {
21649
21692
  var lightModeColor = (0, color_1.getLightModeColor)(borderColor, !!context.isDarkMode, context.darkColorHandler);
21650
21693
  format[key] = (0, borderValues_1.combineBorderValue)({
@@ -21663,10 +21706,10 @@ exports.borderColorFormatHandler = {
21663
21706
  var value = format[key];
21664
21707
  if (value) {
21665
21708
  var borderValues = (0, borderValues_1.extractBorderValues)(value);
21709
+ var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21666
21710
  if (borderValues.color) {
21667
21711
  var transformedColor = (0, color_1.adaptColor)(element, borderValues.color, 'border', !!context.isDarkMode, context.darkColorHandler);
21668
21712
  if (transformedColor) {
21669
- var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21670
21713
  element.style.setProperty(borderColorProperty, transformedColor);
21671
21714
  }
21672
21715
  }
@@ -23585,9 +23628,9 @@ exports.shouldSetValue = shouldSetValue;
23585
23628
 
23586
23629
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23587
23630
  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;
23588
- 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;
23589
- 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;
23590
- 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;
23631
+ 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;
23632
+ 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;
23633
+ 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;
23591
23634
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
23592
23635
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
23593
23636
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -23708,6 +23751,8 @@ var normalizeParagraph_1 = __webpack_require__(/*! ./modelApi/common/normalizePa
23708
23751
  Object.defineProperty(exports, "normalizeParagraph", ({ enumerable: true, get: function () { return normalizeParagraph_1.normalizeParagraph; } }));
23709
23752
  var normalizeContentModel_1 = __webpack_require__(/*! ./modelApi/common/normalizeContentModel */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeContentModel.ts");
23710
23753
  Object.defineProperty(exports, "normalizeContentModel", ({ enumerable: true, get: function () { return normalizeContentModel_1.normalizeContentModel; } }));
23754
+ var sanitizeInvisibleUnicode_1 = __webpack_require__(/*! ./modelApi/common/sanitizeInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts");
23755
+ Object.defineProperty(exports, "sanitizeInvisibleUnicode", ({ enumerable: true, get: function () { return sanitizeInvisibleUnicode_1.sanitizeInvisibleUnicode; } }));
23711
23756
  var isGeneralSegment_1 = __webpack_require__(/*! ./modelApi/typeCheck/isGeneralSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isGeneralSegment.ts");
23712
23757
  Object.defineProperty(exports, "isGeneralSegment", ({ enumerable: true, get: function () { return isGeneralSegment_1.isGeneralSegment; } }));
23713
23758
  var unwrapBlock_1 = __webpack_require__(/*! ./modelApi/common/unwrapBlock */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts");
@@ -23773,6 +23818,8 @@ var stringUtil_1 = __webpack_require__(/*! ./domUtils/stringUtil */ "./packages/
23773
23818
  Object.defineProperty(exports, "isPunctuation", ({ enumerable: true, get: function () { return stringUtil_1.isPunctuation; } }));
23774
23819
  Object.defineProperty(exports, "isSpace", ({ enumerable: true, get: function () { return stringUtil_1.isSpace; } }));
23775
23820
  Object.defineProperty(exports, "normalizeText", ({ enumerable: true, get: function () { return stringUtil_1.normalizeText; } }));
23821
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ./domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
23822
+ Object.defineProperty(exports, "stripInvisibleUnicode", ({ enumerable: true, get: function () { return stripInvisibleUnicode_1.stripInvisibleUnicode; } }));
23776
23823
  var parseTableCells_1 = __webpack_require__(/*! ./domUtils/table/parseTableCells */ "./packages/roosterjs-content-model-dom/lib/domUtils/table/parseTableCells.ts");
23777
23824
  Object.defineProperty(exports, "parseTableCells", ({ enumerable: true, get: function () { return parseTableCells_1.parseTableCells; } }));
23778
23825
  var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts");
@@ -23903,6 +23950,8 @@ exports.ListFormatsToKeep = [
23903
23950
  'direction',
23904
23951
  'textAlign',
23905
23952
  'htmlAlign',
23953
+ 'marginBottom',
23954
+ 'marginTop',
23906
23955
  ];
23907
23956
  /**
23908
23957
  * When copy format from one block to another, these are all the formats that we can copy
@@ -24769,6 +24818,134 @@ function normalizeSegmentFormat(format, environment) {
24769
24818
  exports.normalizeSegmentFormat = normalizeSegmentFormat;
24770
24819
 
24771
24820
 
24821
+ /***/ },
24822
+
24823
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts"
24824
+ /*!**********************************************************************************************!*\
24825
+ !*** ./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts ***!
24826
+ \**********************************************************************************************/
24827
+ (__unused_webpack_module, exports, __webpack_require__) {
24828
+
24829
+ "use strict";
24830
+
24831
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
24832
+ exports.sanitizeInvisibleUnicode = void 0;
24833
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
24834
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ../../domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
24835
+ /**
24836
+ * Strip invisible Unicode characters from all text and link hrefs in a content model.
24837
+ * This sanitizes the model at initialization time to prevent hidden content in links
24838
+ * or text (e.g. zero-width chars, bidirectional marks, Unicode Tags).
24839
+ * For General segments, all Text nodes under the element are also sanitized.
24840
+ * @param model The content model document to sanitize in-place
24841
+ */
24842
+ function sanitizeInvisibleUnicode(model) {
24843
+ sanitizeBlockGroup(model);
24844
+ }
24845
+ exports.sanitizeInvisibleUnicode = sanitizeInvisibleUnicode;
24846
+ function sanitizeBlockGroup(group) {
24847
+ var e_1, _a;
24848
+ try {
24849
+ for (var _b = (0, tslib_1.__values)(group.blocks), _c = _b.next(); !_c.done; _c = _b.next()) {
24850
+ var block = _c.value;
24851
+ sanitizeBlock(block);
24852
+ }
24853
+ }
24854
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
24855
+ finally {
24856
+ try {
24857
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
24858
+ }
24859
+ finally { if (e_1) throw e_1.error; }
24860
+ }
24861
+ }
24862
+ function sanitizeBlock(block) {
24863
+ var e_2, _a, e_3, _b, e_4, _c;
24864
+ switch (block.blockType) {
24865
+ case 'Paragraph':
24866
+ try {
24867
+ for (var _d = (0, tslib_1.__values)(block.segments), _e = _d.next(); !_e.done; _e = _d.next()) {
24868
+ var segment = _e.value;
24869
+ sanitizeSegment(segment);
24870
+ }
24871
+ }
24872
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
24873
+ finally {
24874
+ try {
24875
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
24876
+ }
24877
+ finally { if (e_2) throw e_2.error; }
24878
+ }
24879
+ break;
24880
+ case 'Table':
24881
+ try {
24882
+ for (var _f = (0, tslib_1.__values)(block.rows), _g = _f.next(); !_g.done; _g = _f.next()) {
24883
+ var row = _g.value;
24884
+ try {
24885
+ for (var _h = (e_4 = void 0, (0, tslib_1.__values)(row.cells)), _j = _h.next(); !_j.done; _j = _h.next()) {
24886
+ var cell = _j.value;
24887
+ sanitizeBlockGroup(cell);
24888
+ }
24889
+ }
24890
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
24891
+ finally {
24892
+ try {
24893
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
24894
+ }
24895
+ finally { if (e_4) throw e_4.error; }
24896
+ }
24897
+ }
24898
+ }
24899
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
24900
+ finally {
24901
+ try {
24902
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
24903
+ }
24904
+ finally { if (e_3) throw e_3.error; }
24905
+ }
24906
+ break;
24907
+ case 'BlockGroup':
24908
+ sanitizeBlockGroup(block);
24909
+ if (block.blockGroupType === 'General' && block.element) {
24910
+ sanitizeTextNodes(block.element);
24911
+ }
24912
+ break;
24913
+ case 'Entity':
24914
+ case 'Divider':
24915
+ break;
24916
+ }
24917
+ }
24918
+ function sanitizeSegment(segment) {
24919
+ var _a;
24920
+ if ((_a = segment.link) === null || _a === void 0 ? void 0 : _a.format.href) {
24921
+ segment.link.format.href = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.link.format.href);
24922
+ }
24923
+ switch (segment.segmentType) {
24924
+ case 'Text':
24925
+ segment.text = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.text);
24926
+ break;
24927
+ case 'General':
24928
+ sanitizeTextNodes(segment.element);
24929
+ sanitizeBlockGroup(segment);
24930
+ break;
24931
+ case 'Image':
24932
+ case 'Entity':
24933
+ case 'Br':
24934
+ case 'SelectionMarker':
24935
+ break;
24936
+ }
24937
+ }
24938
+ function sanitizeTextNodes(element) {
24939
+ var walker = element.ownerDocument.createTreeWalker(element, NodeFilter.SHOW_TEXT);
24940
+ var node;
24941
+ while ((node = walker.nextNode())) {
24942
+ if (node.nodeValue) {
24943
+ node.nodeValue = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(node.nodeValue);
24944
+ }
24945
+ }
24946
+ }
24947
+
24948
+
24772
24949
  /***/ },
24773
24950
 
24774
24951
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts"
@@ -28118,10 +28295,13 @@ function getSelectedSegments(model, includingFormatHolder, mutate) {
28118
28295
  return segments.map(function (x) { return x[0]; });
28119
28296
  }
28120
28297
  exports.getSelectedSegments = getSelectedSegments;
28121
- function getSelectedParagraphs(model, mutate) {
28298
+ function getSelectedParagraphs(model, mutate, removeUnmeaningful) {
28299
+ if (removeUnmeaningful === void 0) { removeUnmeaningful = true; }
28122
28300
  var selections = collectSelections(model, { includeListFormatHolder: 'never' });
28123
28301
  var result = [];
28124
- removeUnmeaningfulSelections(selections);
28302
+ if (removeUnmeaningful) {
28303
+ removeUnmeaningfulSelections(selections);
28304
+ }
28125
28305
  selections.forEach(function (_a) {
28126
28306
  var block = _a.block;
28127
28307
  if ((block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph') {
@@ -28895,6 +29075,7 @@ function createModelToDomFormatContext() {
28895
29075
  listFormat: {
28896
29076
  threadItemCounts: [],
28897
29077
  nodeStack: [],
29078
+ currentLevel: 0,
28898
29079
  },
28899
29080
  implicitFormat: {},
28900
29081
  };
@@ -29469,6 +29650,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29469
29650
  var parentLevel = nodeStack[layer];
29470
29651
  var stackLevel = nodeStack[layer + 1];
29471
29652
  var itemLevel = listItem.levels[layer];
29653
+ context.listFormat.currentLevel = layer;
29472
29654
  if (stackLevel.listType != itemLevel.listType ||
29473
29655
  ((_a = stackLevel.dataset) === null || _a === void 0 ? void 0 : _a.editingInfo) != itemLevel.dataset.editingInfo ||
29474
29656
  (itemLevel.listType == 'OL' &&
@@ -29504,6 +29686,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29504
29686
  var newList = void 0;
29505
29687
  var isNewlyCreated = false;
29506
29688
  var levelRefNode = (_c = nodeStack[layer].refNode) !== null && _c !== void 0 ? _c : null;
29689
+ context.listFormat.currentLevel = layer;
29507
29690
  if (context.allowCacheListItem && level.cachedElement) {
29508
29691
  newList = level.cachedElement;
29509
29692
  nodeStack[layer].refNode = (0, reuseCachedElement_1.reuseCachedElement)(lastParent, level.cachedElement, levelRefNode, context.rewriteFromModel);