roosterjs 9.48.0 → 9.50.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;
@@ -12990,17 +12998,24 @@ var DOMEventPlugin = /** @class */ (function () {
12990
12998
  dragEvent.preventDefault();
12991
12999
  }
12992
13000
  };
12993
- this.onDrop = function () {
12994
- var _a, _b;
12995
- var doc = (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.getDocument();
12996
- (_b = doc === null || doc === void 0 ? void 0 : doc.defaultView) === null || _b === void 0 ? void 0 : _b.requestAnimationFrame(function () {
12997
- if (_this.editor) {
12998
- _this.editor.takeSnapshot();
12999
- _this.editor.triggerEvent('contentChanged', {
13000
- source: roosterjs_content_model_dom_1.ChangeSource.Drop,
13001
+ this.onDrop = function (e) {
13002
+ var _a;
13003
+ if (_this.editor) {
13004
+ var beforeDropEvent = _this.editor.triggerEvent('beforeDrop', {
13005
+ rawEvent: e,
13006
+ });
13007
+ if (!(beforeDropEvent === null || beforeDropEvent === void 0 ? void 0 : beforeDropEvent.rawEvent.defaultPrevented)) {
13008
+ var doc = _this.editor.getDocument();
13009
+ (_a = doc === null || doc === void 0 ? void 0 : doc.defaultView) === null || _a === void 0 ? void 0 : _a.requestAnimationFrame(function () {
13010
+ if (_this.editor) {
13011
+ _this.editor.takeSnapshot();
13012
+ _this.editor.triggerEvent('contentChanged', {
13013
+ source: roosterjs_content_model_dom_1.ChangeSource.Drop,
13014
+ });
13015
+ }
13001
13016
  });
13002
13017
  }
13003
- });
13018
+ }
13004
13019
  };
13005
13020
  this.onScroll = function (e) {
13006
13021
  var _a;
@@ -13136,7 +13151,7 @@ var DOMEventPlugin = /** @class */ (function () {
13136
13151
  compositionend: { beforeDispatch: this.onCompositionEnd },
13137
13152
  // 4. Drag and Drop event
13138
13153
  dragstart: { beforeDispatch: this.onDragStart },
13139
- drop: { beforeDispatch: this.onDrop },
13154
+ drop: { beforeDispatch: function (event) { return _this.onDrop(event); } },
13140
13155
  // 5. Pointer event
13141
13156
  pointerdown: { beforeDispatch: function (event) { return _this.onPointerDown(event); } },
13142
13157
  };
@@ -15619,6 +15634,7 @@ var Editor = /** @class */ (function () {
15619
15634
  };
15620
15635
  this.core = (0, createEditorCore_1.createEditorCore)(contentDiv, options);
15621
15636
  var initialModel = (_a = options.initialModel) !== null && _a !== void 0 ? _a : (0, roosterjs_content_model_dom_1.createEmptyModel)(this.core.format.defaultFormat);
15637
+ (0, roosterjs_content_model_dom_1.sanitizeInvisibleUnicode)(initialModel);
15622
15638
  this.core.api.setContentModel(this.core, initialModel, { ignoreSelection: true }, undefined /*onNodeCreated*/, true /*isInitializing*/);
15623
15639
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
15624
15640
  }
@@ -16394,10 +16410,10 @@ function shouldApplyToItem(listStyleType, listType) {
16394
16410
  exports.listItemMetadataApplier = {
16395
16411
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16396
16412
  applierFunction: function (metadata, format, context) {
16397
- var _a;
16398
- var depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
16413
+ var _a, _b;
16414
+ var depth = context.listFormat.currentLevel;
16399
16415
  if (depth >= 0) {
16400
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16416
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16401
16417
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16402
16418
  if (listStyleType !== undefined) {
16403
16419
  if (shouldApplyToItem(listStyleType, listType)) {
@@ -16416,10 +16432,10 @@ exports.listItemMetadataApplier = {
16416
16432
  exports.listLevelMetadataApplier = {
16417
16433
  metadataDefinition: roosterjs_content_model_dom_1.ListMetadataDefinition,
16418
16434
  applierFunction: function (metadata, format, context) {
16419
- var _a;
16420
- var depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
16435
+ var _a, _b;
16436
+ var depth = context.listFormat.currentLevel;
16421
16437
  if (depth >= 0) {
16422
- var listType = (_a = context.listFormat.nodeStack[depth + 1].listType) !== null && _a !== void 0 ? _a : 'OL';
16438
+ var listType = (_b = (_a = context.listFormat.nodeStack[depth + 1]) === null || _a === void 0 ? void 0 : _a.listType) !== null && _b !== void 0 ? _b : 'OL';
16423
16439
  var listStyleType = (0, roosterjs_content_model_dom_1.getAutoListStyleType)(listType, metadata !== null && metadata !== void 0 ? metadata : {}, depth);
16424
16440
  if (listStyleType !== undefined) {
16425
16441
  if (!shouldApplyToItem(listStyleType, listType)) {
@@ -20792,6 +20808,38 @@ function normalizeText(txt, isForward) {
20792
20808
  exports.normalizeText = normalizeText;
20793
20809
 
20794
20810
 
20811
+ /***/ },
20812
+
20813
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts"
20814
+ /*!************************************************************************************!*\
20815
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts ***!
20816
+ \************************************************************************************/
20817
+ (__unused_webpack_module, exports) {
20818
+
20819
+ "use strict";
20820
+
20821
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20822
+ exports.stripInvisibleUnicode = void 0;
20823
+ var INVISIBLE_UNICODE_REGEX =
20824
+ // eslint-disable-next-line no-misleading-character-class
20825
+ /[\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;
20826
+ /**
20827
+ * Strip invisible Unicode characters from a string.
20828
+ * This removes zero-width characters, bidirectional marks, Unicode Tags (U+E0001-U+E00FF),
20829
+ * interlinear annotation anchors, Mongolian free variation selectors,
20830
+ * and other invisible formatting characters that can be used to hide content in links.
20831
+ *
20832
+ * @remarks This function strips ZWJ (U+200D) which may affect emoji sequences.
20833
+ * It should only be applied to href attributes, not to visible text content.
20834
+ * @param value The string to strip invisible characters from
20835
+ * @returns The string with invisible characters removed
20836
+ */
20837
+ function stripInvisibleUnicode(value) {
20838
+ return value.replace(INVISIBLE_UNICODE_REGEX, '');
20839
+ }
20840
+ exports.stripInvisibleUnicode = stripInvisibleUnicode;
20841
+
20842
+
20795
20843
  /***/ },
20796
20844
 
20797
20845
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts"
@@ -21635,6 +21683,7 @@ var BorderStyleKeyMap = {
21635
21683
  borderBottom: 'border-bottom-style',
21636
21684
  borderLeft: 'border-left-style',
21637
21685
  };
21686
+ var DEFAULT_COLOR = '#000000';
21638
21687
  /**
21639
21688
  * @internal
21640
21689
  */
@@ -21645,7 +21694,8 @@ exports.borderColorFormatHandler = {
21645
21694
  borderKeys_1.BorderKeys.forEach(function (key) {
21646
21695
  var width = element.style.getPropertyValue(BorderWidthKeyMap[key]);
21647
21696
  var style = element.style.getPropertyValue(BorderStyleKeyMap[key]);
21648
- var borderColor = (0, color_1.retrieveElementColor)(element, key);
21697
+ var color = (0, color_1.retrieveElementColor)(element, key);
21698
+ var borderColor = color == 'initial' ? DEFAULT_COLOR : color;
21649
21699
  if (borderColor) {
21650
21700
  var lightModeColor = (0, color_1.getLightModeColor)(borderColor, !!context.isDarkMode, context.darkColorHandler);
21651
21701
  format[key] = (0, borderValues_1.combineBorderValue)({
@@ -21664,10 +21714,10 @@ exports.borderColorFormatHandler = {
21664
21714
  var value = format[key];
21665
21715
  if (value) {
21666
21716
  var borderValues = (0, borderValues_1.extractBorderValues)(value);
21717
+ var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21667
21718
  if (borderValues.color) {
21668
21719
  var transformedColor = (0, color_1.adaptColor)(element, borderValues.color, 'border', !!context.isDarkMode, context.darkColorHandler);
21669
21720
  if (transformedColor) {
21670
- var borderColorProperty = borderKeys_1.BorderColorKeyMap[key];
21671
21721
  element.style.setProperty(borderColorProperty, transformedColor);
21672
21722
  }
21673
21723
  }
@@ -23586,9 +23636,9 @@ exports.shouldSetValue = shouldSetValue;
23586
23636
 
23587
23637
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23588
23638
  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;
23589
- 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;
23590
- 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;
23591
- 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;
23639
+ 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;
23640
+ 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;
23641
+ 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;
23592
23642
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
23593
23643
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
23594
23644
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -23709,6 +23759,8 @@ var normalizeParagraph_1 = __webpack_require__(/*! ./modelApi/common/normalizePa
23709
23759
  Object.defineProperty(exports, "normalizeParagraph", ({ enumerable: true, get: function () { return normalizeParagraph_1.normalizeParagraph; } }));
23710
23760
  var normalizeContentModel_1 = __webpack_require__(/*! ./modelApi/common/normalizeContentModel */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeContentModel.ts");
23711
23761
  Object.defineProperty(exports, "normalizeContentModel", ({ enumerable: true, get: function () { return normalizeContentModel_1.normalizeContentModel; } }));
23762
+ var sanitizeInvisibleUnicode_1 = __webpack_require__(/*! ./modelApi/common/sanitizeInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts");
23763
+ Object.defineProperty(exports, "sanitizeInvisibleUnicode", ({ enumerable: true, get: function () { return sanitizeInvisibleUnicode_1.sanitizeInvisibleUnicode; } }));
23712
23764
  var isGeneralSegment_1 = __webpack_require__(/*! ./modelApi/typeCheck/isGeneralSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isGeneralSegment.ts");
23713
23765
  Object.defineProperty(exports, "isGeneralSegment", ({ enumerable: true, get: function () { return isGeneralSegment_1.isGeneralSegment; } }));
23714
23766
  var unwrapBlock_1 = __webpack_require__(/*! ./modelApi/common/unwrapBlock */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts");
@@ -23774,6 +23826,8 @@ var stringUtil_1 = __webpack_require__(/*! ./domUtils/stringUtil */ "./packages/
23774
23826
  Object.defineProperty(exports, "isPunctuation", ({ enumerable: true, get: function () { return stringUtil_1.isPunctuation; } }));
23775
23827
  Object.defineProperty(exports, "isSpace", ({ enumerable: true, get: function () { return stringUtil_1.isSpace; } }));
23776
23828
  Object.defineProperty(exports, "normalizeText", ({ enumerable: true, get: function () { return stringUtil_1.normalizeText; } }));
23829
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ./domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
23830
+ Object.defineProperty(exports, "stripInvisibleUnicode", ({ enumerable: true, get: function () { return stripInvisibleUnicode_1.stripInvisibleUnicode; } }));
23777
23831
  var parseTableCells_1 = __webpack_require__(/*! ./domUtils/table/parseTableCells */ "./packages/roosterjs-content-model-dom/lib/domUtils/table/parseTableCells.ts");
23778
23832
  Object.defineProperty(exports, "parseTableCells", ({ enumerable: true, get: function () { return parseTableCells_1.parseTableCells; } }));
23779
23833
  var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts");
@@ -23904,6 +23958,8 @@ exports.ListFormatsToKeep = [
23904
23958
  'direction',
23905
23959
  'textAlign',
23906
23960
  'htmlAlign',
23961
+ 'marginBottom',
23962
+ 'marginTop',
23907
23963
  ];
23908
23964
  /**
23909
23965
  * When copy format from one block to another, these are all the formats that we can copy
@@ -24770,6 +24826,134 @@ function normalizeSegmentFormat(format, environment) {
24770
24826
  exports.normalizeSegmentFormat = normalizeSegmentFormat;
24771
24827
 
24772
24828
 
24829
+ /***/ },
24830
+
24831
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts"
24832
+ /*!**********************************************************************************************!*\
24833
+ !*** ./packages/roosterjs-content-model-dom/lib/modelApi/common/sanitizeInvisibleUnicode.ts ***!
24834
+ \**********************************************************************************************/
24835
+ (__unused_webpack_module, exports, __webpack_require__) {
24836
+
24837
+ "use strict";
24838
+
24839
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
24840
+ exports.sanitizeInvisibleUnicode = void 0;
24841
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
24842
+ var stripInvisibleUnicode_1 = __webpack_require__(/*! ../../domUtils/stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/domUtils/stripInvisibleUnicode.ts");
24843
+ /**
24844
+ * Strip invisible Unicode characters from all text and link hrefs in a content model.
24845
+ * This sanitizes the model at initialization time to prevent hidden content in links
24846
+ * or text (e.g. zero-width chars, bidirectional marks, Unicode Tags).
24847
+ * For General segments, all Text nodes under the element are also sanitized.
24848
+ * @param model The content model document to sanitize in-place
24849
+ */
24850
+ function sanitizeInvisibleUnicode(model) {
24851
+ sanitizeBlockGroup(model);
24852
+ }
24853
+ exports.sanitizeInvisibleUnicode = sanitizeInvisibleUnicode;
24854
+ function sanitizeBlockGroup(group) {
24855
+ var e_1, _a;
24856
+ try {
24857
+ for (var _b = (0, tslib_1.__values)(group.blocks), _c = _b.next(); !_c.done; _c = _b.next()) {
24858
+ var block = _c.value;
24859
+ sanitizeBlock(block);
24860
+ }
24861
+ }
24862
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
24863
+ finally {
24864
+ try {
24865
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
24866
+ }
24867
+ finally { if (e_1) throw e_1.error; }
24868
+ }
24869
+ }
24870
+ function sanitizeBlock(block) {
24871
+ var e_2, _a, e_3, _b, e_4, _c;
24872
+ switch (block.blockType) {
24873
+ case 'Paragraph':
24874
+ try {
24875
+ for (var _d = (0, tslib_1.__values)(block.segments), _e = _d.next(); !_e.done; _e = _d.next()) {
24876
+ var segment = _e.value;
24877
+ sanitizeSegment(segment);
24878
+ }
24879
+ }
24880
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
24881
+ finally {
24882
+ try {
24883
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
24884
+ }
24885
+ finally { if (e_2) throw e_2.error; }
24886
+ }
24887
+ break;
24888
+ case 'Table':
24889
+ try {
24890
+ for (var _f = (0, tslib_1.__values)(block.rows), _g = _f.next(); !_g.done; _g = _f.next()) {
24891
+ var row = _g.value;
24892
+ try {
24893
+ for (var _h = (e_4 = void 0, (0, tslib_1.__values)(row.cells)), _j = _h.next(); !_j.done; _j = _h.next()) {
24894
+ var cell = _j.value;
24895
+ sanitizeBlockGroup(cell);
24896
+ }
24897
+ }
24898
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
24899
+ finally {
24900
+ try {
24901
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
24902
+ }
24903
+ finally { if (e_4) throw e_4.error; }
24904
+ }
24905
+ }
24906
+ }
24907
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
24908
+ finally {
24909
+ try {
24910
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
24911
+ }
24912
+ finally { if (e_3) throw e_3.error; }
24913
+ }
24914
+ break;
24915
+ case 'BlockGroup':
24916
+ sanitizeBlockGroup(block);
24917
+ if (block.blockGroupType === 'General' && block.element) {
24918
+ sanitizeTextNodes(block.element);
24919
+ }
24920
+ break;
24921
+ case 'Entity':
24922
+ case 'Divider':
24923
+ break;
24924
+ }
24925
+ }
24926
+ function sanitizeSegment(segment) {
24927
+ var _a;
24928
+ if ((_a = segment.link) === null || _a === void 0 ? void 0 : _a.format.href) {
24929
+ segment.link.format.href = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.link.format.href);
24930
+ }
24931
+ switch (segment.segmentType) {
24932
+ case 'Text':
24933
+ segment.text = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(segment.text);
24934
+ break;
24935
+ case 'General':
24936
+ sanitizeTextNodes(segment.element);
24937
+ sanitizeBlockGroup(segment);
24938
+ break;
24939
+ case 'Image':
24940
+ case 'Entity':
24941
+ case 'Br':
24942
+ case 'SelectionMarker':
24943
+ break;
24944
+ }
24945
+ }
24946
+ function sanitizeTextNodes(element) {
24947
+ var walker = element.ownerDocument.createTreeWalker(element, NodeFilter.SHOW_TEXT);
24948
+ var node;
24949
+ while ((node = walker.nextNode())) {
24950
+ if (node.nodeValue) {
24951
+ node.nodeValue = (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(node.nodeValue);
24952
+ }
24953
+ }
24954
+ }
24955
+
24956
+
24773
24957
  /***/ },
24774
24958
 
24775
24959
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts"
@@ -28119,10 +28303,13 @@ function getSelectedSegments(model, includingFormatHolder, mutate) {
28119
28303
  return segments.map(function (x) { return x[0]; });
28120
28304
  }
28121
28305
  exports.getSelectedSegments = getSelectedSegments;
28122
- function getSelectedParagraphs(model, mutate) {
28306
+ function getSelectedParagraphs(model, mutate, removeUnmeaningful) {
28307
+ if (removeUnmeaningful === void 0) { removeUnmeaningful = true; }
28123
28308
  var selections = collectSelections(model, { includeListFormatHolder: 'never' });
28124
28309
  var result = [];
28125
- removeUnmeaningfulSelections(selections);
28310
+ if (removeUnmeaningful) {
28311
+ removeUnmeaningfulSelections(selections);
28312
+ }
28126
28313
  selections.forEach(function (_a) {
28127
28314
  var block = _a.block;
28128
28315
  if ((block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph') {
@@ -28896,6 +29083,7 @@ function createModelToDomFormatContext() {
28896
29083
  listFormat: {
28897
29084
  threadItemCounts: [],
28898
29085
  nodeStack: [],
29086
+ currentLevel: 0,
28899
29087
  },
28900
29088
  implicitFormat: {},
28901
29089
  };
@@ -29470,6 +29658,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29470
29658
  var parentLevel = nodeStack[layer];
29471
29659
  var stackLevel = nodeStack[layer + 1];
29472
29660
  var itemLevel = listItem.levels[layer];
29661
+ context.listFormat.currentLevel = layer;
29473
29662
  if (stackLevel.listType != itemLevel.listType ||
29474
29663
  ((_a = stackLevel.dataset) === null || _a === void 0 ? void 0 : _a.editingInfo) != itemLevel.dataset.editingInfo ||
29475
29664
  (itemLevel.listType == 'OL' &&
@@ -29505,6 +29694,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29505
29694
  var newList = void 0;
29506
29695
  var isNewlyCreated = false;
29507
29696
  var levelRefNode = (_c = nodeStack[layer].refNode) !== null && _c !== void 0 ? _c : null;
29697
+ context.listFormat.currentLevel = layer;
29508
29698
  if (context.allowCacheListItem && level.cachedElement) {
29509
29699
  newList = level.cachedElement;
29510
29700
  nodeStack[layer].refNode = (0, reuseCachedElement_1.reuseCachedElement)(lastParent, level.cachedElement, levelRefNode, context.rewriteFromModel);
@@ -31350,16 +31540,43 @@ exports.isMarkdownTable = isMarkdownTable;
31350
31540
 
31351
31541
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31352
31542
  exports.splitParagraphSegments = void 0;
31353
- var linkRegex = /(\[([^\[]+)\]\((https?:\/\/[^\)]+)\))|(\!\[([^\[]+)\]\((https?:\/\/[^\)]+)\))/g;
31543
+ // Matches markdown links and images in a string.
31544
+ // Group 1 (full link): [text](url) e.g. [Click here](https://example.com)
31545
+ // Group 2: link text e.g. "Click here"
31546
+ // Group 3: link url e.g. "https://example.com"
31547
+ // Group 4 (full image): ![alt](url) e.g. ![Logo](https://example.com/logo.png)
31548
+ // Group 5: alt text e.g. "Logo"
31549
+ // Group 6: image url e.g. "https://example.com/logo.png"
31550
+ var linkRegex = /(\[([^\[]+)\]\(([^\)]+)\))|(\!\[([^\[]+)\]\(([^\)]+)\))/g;
31354
31551
  var isValidUrl = function (url) {
31355
- try {
31356
- new URL(url);
31552
+ if (!url) {
31553
+ return false;
31554
+ }
31555
+ // Accept common non-http schemes and relative paths
31556
+ if (url.startsWith('data:') ||
31557
+ url.startsWith('blob:') ||
31558
+ url.startsWith('/') ||
31559
+ url.startsWith('./') ||
31560
+ url.startsWith('../')) {
31357
31561
  return true;
31358
31562
  }
31563
+ try {
31564
+ var parsed = new URL(url);
31565
+ return parsed.protocol === 'http:' || parsed.protocol === 'https:';
31566
+ }
31359
31567
  catch (_) {
31360
31568
  return false;
31361
31569
  }
31362
31570
  };
31571
+ function pushText(result, text) {
31572
+ var last = result[result.length - 1];
31573
+ if (last && last.type === 'text') {
31574
+ last.text += text;
31575
+ }
31576
+ else {
31577
+ result.push({ type: 'text', text: text, url: '' });
31578
+ }
31579
+ }
31363
31580
  /**
31364
31581
  * @internal
31365
31582
  */
@@ -31369,22 +31586,28 @@ function splitParagraphSegments(text) {
31369
31586
  var match = null;
31370
31587
  while ((match = linkRegex.exec(text)) !== null) {
31371
31588
  if (match.index > lastIndex) {
31372
- result.push({ type: 'text', text: text.slice(lastIndex, match.index), url: '' });
31589
+ pushText(result, text.slice(lastIndex, match.index));
31373
31590
  }
31374
31591
  if (match[2] && match[3]) {
31375
- result.push(isValidUrl(match[3])
31376
- ? { type: 'link', text: match[2], url: match[3] }
31377
- : { type: 'text', text: match[0], url: '' });
31592
+ if (isValidUrl(match[3])) {
31593
+ result.push({ type: 'link', text: match[2], url: match[3] });
31594
+ }
31595
+ else {
31596
+ pushText(result, match[0]);
31597
+ }
31378
31598
  }
31379
31599
  else if (match[5] && match[6]) {
31380
- result.push(isValidUrl(match[6])
31381
- ? { type: 'image', text: match[5], url: match[6] }
31382
- : { type: 'text', text: match[0], url: '' });
31600
+ if (isValidUrl(match[6])) {
31601
+ result.push({ type: 'image', text: match[5], url: match[6] });
31602
+ }
31603
+ else {
31604
+ pushText(result, match[0]);
31605
+ }
31383
31606
  }
31384
31607
  lastIndex = linkRegex.lastIndex;
31385
31608
  }
31386
31609
  if (lastIndex < text.length) {
31387
- result.push({ type: 'text', text: text.slice(lastIndex), url: '' });
31610
+ pushText(result, text.slice(lastIndex));
31388
31611
  }
31389
31612
  return result;
31390
31613
  }
@@ -33209,6 +33432,192 @@ var CustomReplacePlugin = /** @class */ (function () {
33209
33432
  exports.CustomReplacePlugin = CustomReplacePlugin;
33210
33433
 
33211
33434
 
33435
+ /***/ },
33436
+
33437
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts"
33438
+ /*!***************************************************************************************!*\
33439
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts ***!
33440
+ \***************************************************************************************/
33441
+ (__unused_webpack_module, exports, __webpack_require__) {
33442
+
33443
+ "use strict";
33444
+
33445
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33446
+ exports.DragAndDropPlugin = void 0;
33447
+ var handleDroppedContent_1 = __webpack_require__(/*! ./utils/handleDroppedContent */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts");
33448
+ var DefaultOptions = {
33449
+ forbiddenElements: ['iframe'],
33450
+ };
33451
+ /**
33452
+ * DragAndDrop plugin, handles ContentChanged event when change source is "Drop"
33453
+ * to sanitize dropped content, similar to how PastePlugin sanitizes pasted content.
33454
+ */
33455
+ var DragAndDropPlugin = /** @class */ (function () {
33456
+ /**
33457
+ * Construct a new instance of DragAndDropPlugin
33458
+ */
33459
+ function DragAndDropPlugin(options) {
33460
+ if (options === void 0) { options = DefaultOptions; }
33461
+ var _a;
33462
+ this.editor = null;
33463
+ this.forbiddenElements = [];
33464
+ this.isInternalDragging = false;
33465
+ this.disposer = null;
33466
+ this.forbiddenElements = (_a = options.forbiddenElements) !== null && _a !== void 0 ? _a : [];
33467
+ }
33468
+ /**
33469
+ * Get name of this plugin
33470
+ */
33471
+ DragAndDropPlugin.prototype.getName = function () {
33472
+ return 'DragAndDrop';
33473
+ };
33474
+ /**
33475
+ * The first method that editor will call to a plugin when editor is initializing.
33476
+ * It will pass in the editor instance, plugin should take this chance to save the
33477
+ * editor reference so that it can call to any editor method or format API later.
33478
+ * @param editor The editor object
33479
+ */
33480
+ DragAndDropPlugin.prototype.initialize = function (editor) {
33481
+ var _this = this;
33482
+ this.editor = editor;
33483
+ this.disposer = editor.attachDomEvent({
33484
+ dragstart: {
33485
+ beforeDispatch: function (_ev) {
33486
+ _this.isInternalDragging = true;
33487
+ },
33488
+ },
33489
+ });
33490
+ };
33491
+ /**
33492
+ * The last method that editor will call to a plugin before it is disposed.
33493
+ * Plugin can take this chance to clear the reference to editor. After this method is
33494
+ * called, plugin should not call to any editor method since it will result in error.
33495
+ */
33496
+ DragAndDropPlugin.prototype.dispose = function () {
33497
+ this.editor = null;
33498
+ if (this.disposer) {
33499
+ this.disposer();
33500
+ this.disposer = null;
33501
+ }
33502
+ this.isInternalDragging = false;
33503
+ this.forbiddenElements = [];
33504
+ };
33505
+ /**
33506
+ * Core method for a plugin. Once an event happens in editor, editor will call this
33507
+ * method of each plugin to handle the event as long as the event is not handled
33508
+ * exclusively by another plugin.
33509
+ * @param event The event to handle:
33510
+ */
33511
+ DragAndDropPlugin.prototype.onPluginEvent = function (event) {
33512
+ var _a;
33513
+ if (this.editor && event.eventType == 'beforeDrop') {
33514
+ if (this.isInternalDragging) {
33515
+ this.isInternalDragging = false;
33516
+ }
33517
+ else {
33518
+ var dropEvent = event.rawEvent;
33519
+ var html = (_a = dropEvent.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData('text/html');
33520
+ if (html) {
33521
+ (0, handleDroppedContent_1.handleDroppedContent)(this.editor, dropEvent, html, this.forbiddenElements);
33522
+ }
33523
+ }
33524
+ return;
33525
+ }
33526
+ };
33527
+ return DragAndDropPlugin;
33528
+ }());
33529
+ exports.DragAndDropPlugin = DragAndDropPlugin;
33530
+
33531
+
33532
+ /***/ },
33533
+
33534
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts"
33535
+ /*!**************************************************************************************************!*\
33536
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts ***!
33537
+ \**************************************************************************************************/
33538
+ (__unused_webpack_module, exports, __webpack_require__) {
33539
+
33540
+ "use strict";
33541
+
33542
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33543
+ exports.cleanForbiddenElements = void 0;
33544
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
33545
+ /**
33546
+ * @internal
33547
+ * Remove all forbidden elements from a parsed HTML document
33548
+ * @param doc The parsed HTML document to clean
33549
+ * @param forbiddenElements Array of tag names to remove (e.g., ['iframe', 'script'])
33550
+ */
33551
+ function cleanForbiddenElements(doc, forbiddenElements) {
33552
+ var e_1, _a;
33553
+ var _b;
33554
+ if (forbiddenElements.length === 0) {
33555
+ return;
33556
+ }
33557
+ var selector = forbiddenElements.join(',');
33558
+ var elements = Array.from(doc.body.querySelectorAll(selector));
33559
+ try {
33560
+ for (var elements_1 = (0, tslib_1.__values)(elements), elements_1_1 = elements_1.next(); !elements_1_1.done; elements_1_1 = elements_1.next()) {
33561
+ var element = elements_1_1.value;
33562
+ (_b = element.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(element);
33563
+ }
33564
+ }
33565
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
33566
+ finally {
33567
+ try {
33568
+ if (elements_1_1 && !elements_1_1.done && (_a = elements_1.return)) _a.call(elements_1);
33569
+ }
33570
+ finally { if (e_1) throw e_1.error; }
33571
+ }
33572
+ }
33573
+ exports.cleanForbiddenElements = cleanForbiddenElements;
33574
+
33575
+
33576
+ /***/ },
33577
+
33578
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts"
33579
+ /*!************************************************************************************************!*\
33580
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts ***!
33581
+ \************************************************************************************************/
33582
+ (__unused_webpack_module, exports, __webpack_require__) {
33583
+
33584
+ "use strict";
33585
+
33586
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33587
+ exports.handleDroppedContent = void 0;
33588
+ var cleanForbiddenElements_1 = __webpack_require__(/*! ./cleanForbiddenElements */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts");
33589
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
33590
+ /**
33591
+ * @internal
33592
+ * Handle dropped HTML content by inserting it at the drop position
33593
+ */
33594
+ function handleDroppedContent(editor, event, html, forbiddenElements) {
33595
+ var doc = editor.getDocument();
33596
+ var domPosition = (0, roosterjs_content_model_dom_1.getNodePositionFromEvent)(doc, editor.getDOMHelper(), event.x, event.y);
33597
+ if (domPosition) {
33598
+ event.preventDefault();
33599
+ event.stopPropagation();
33600
+ var range = doc.createRange();
33601
+ range.setStart(domPosition.node, domPosition.offset);
33602
+ range.collapse(true);
33603
+ var parsedHtml = editor.getDOMCreator().htmlToDOM(html);
33604
+ (0, cleanForbiddenElements_1.cleanForbiddenElements)(parsedHtml, forbiddenElements);
33605
+ var droppedModel_1 = (0, roosterjs_content_model_dom_1.domToContentModel)(parsedHtml.body, (0, roosterjs_content_model_dom_1.createDomToModelContext)());
33606
+ editor.formatContentModel(function (model, context) {
33607
+ (0, roosterjs_content_model_dom_1.mergeModel)(model, droppedModel_1, context);
33608
+ return true;
33609
+ }, {
33610
+ selectionOverride: {
33611
+ type: 'range',
33612
+ range: range,
33613
+ isReverted: false,
33614
+ },
33615
+ });
33616
+ }
33617
+ }
33618
+ exports.handleDroppedContent = handleDroppedContent;
33619
+
33620
+
33212
33621
  /***/ },
33213
33622
 
33214
33623
  /***/ "./packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts"
@@ -38213,7 +38622,7 @@ exports.updateWrapper = updateWrapper;
38213
38622
  "use strict";
38214
38623
 
38215
38624
  Object.defineProperty(exports, "__esModule", ({ value: true }));
38216
- exports.AnnouncePlugin = exports.moveHighlight = exports.replace = exports.find = exports.createFindReplaceContext = exports.FindReplacePlugin = exports.TouchPlugin = exports.HiddenPropertyPlugin = exports.ImageEditPlugin = exports.CustomReplacePlugin = exports.PickerPlugin = exports.HyperlinkPlugin = exports.MarkdownPlugin = exports.isModelEmptyFast = exports.WatermarkPlugin = exports.ContextMenuPluginBase = exports.ShortcutPlugin = exports.ShortcutOutdentList = exports.ShortcutIndentList = exports.ShortcutDecreaseFont = exports.ShortcutIncreaseFont = exports.ShortcutNumbering = exports.ShortcutBullet = exports.ShortcutRedoMacOS = exports.ShortcutRedoAlt = exports.ShortcutRedo = exports.ShortcutUndo2 = exports.ShortcutUndo = exports.ShortcutClearFormat = exports.ShortcutUnderline = exports.ShortcutItalic = exports.ShortcutBold = exports.AutoFormatPlugin = exports.EditPlugin = exports.DefaultSanitizers = exports.PastePlugin = exports.TableEditPlugin = void 0;
38625
+ exports.DragAndDropPlugin = exports.AnnouncePlugin = exports.moveHighlight = exports.replace = exports.find = exports.createFindReplaceContext = exports.FindReplacePlugin = exports.TouchPlugin = exports.HiddenPropertyPlugin = exports.ImageEditPlugin = exports.CustomReplacePlugin = exports.PickerPlugin = exports.HyperlinkPlugin = exports.MarkdownPlugin = exports.isModelEmptyFast = exports.WatermarkPlugin = exports.ContextMenuPluginBase = exports.ShortcutPlugin = exports.ShortcutOutdentList = exports.ShortcutIndentList = exports.ShortcutDecreaseFont = exports.ShortcutIncreaseFont = exports.ShortcutNumbering = exports.ShortcutBullet = exports.ShortcutRedoMacOS = exports.ShortcutRedoAlt = exports.ShortcutRedo = exports.ShortcutUndo2 = exports.ShortcutUndo = exports.ShortcutClearFormat = exports.ShortcutUnderline = exports.ShortcutItalic = exports.ShortcutBold = exports.AutoFormatPlugin = exports.EditPlugin = exports.DefaultSanitizers = exports.PastePlugin = exports.TableEditPlugin = void 0;
38217
38626
  var TableEditPlugin_1 = __webpack_require__(/*! ./tableEdit/TableEditPlugin */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/TableEditPlugin.ts");
38218
38627
  Object.defineProperty(exports, "TableEditPlugin", ({ enumerable: true, get: function () { return TableEditPlugin_1.TableEditPlugin; } }));
38219
38628
  var PastePlugin_1 = __webpack_require__(/*! ./paste/PastePlugin */ "./packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts");
@@ -38274,6 +38683,8 @@ var moveHighlight_1 = __webpack_require__(/*! ./findReplace/moveHighlight */ "./
38274
38683
  Object.defineProperty(exports, "moveHighlight", ({ enumerable: true, get: function () { return moveHighlight_1.moveHighlight; } }));
38275
38684
  var AnnouncePlugin_1 = __webpack_require__(/*! ./announce/AnnouncePlugin */ "./packages/roosterjs-content-model-plugins/lib/announce/AnnouncePlugin.ts");
38276
38685
  Object.defineProperty(exports, "AnnouncePlugin", ({ enumerable: true, get: function () { return AnnouncePlugin_1.AnnouncePlugin; } }));
38686
+ var DragAndDropPlugin_1 = __webpack_require__(/*! ./dragAndDrop/DragAndDropPlugin */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts");
38687
+ Object.defineProperty(exports, "DragAndDropPlugin", ({ enumerable: true, get: function () { return DragAndDropPlugin_1.DragAndDropPlugin; } }));
38277
38688
 
38278
38689
 
38279
38690
  /***/ },