roosterjs 9.49.0 → 9.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rooster.js CHANGED
@@ -7891,25 +7891,21 @@ exports.setTableCellShade = setTableCellShade;
7891
7891
  /*!******************************************************************************!*\
7892
7892
  !*** ./packages/roosterjs-content-model-api/lib/publicApi/utils/checkXss.ts ***!
7893
7893
  \******************************************************************************/
7894
- (__unused_webpack_module, exports, __webpack_require__) {
7894
+ (__unused_webpack_module, exports) {
7895
7895
 
7896
7896
  "use strict";
7897
7897
 
7898
7898
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7899
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");
7901
7900
  /**
7902
7901
  * @internal Check if there is XSS attack in the link
7903
7902
  * @param link The link to be checked
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,
7903
+ * @returns The safe link, or empty string if there is XSS attack
7904
+ * @remarks This function checks for patterns like s\nc\nr\ni\np\nt: to prevent XSS attacks. This may block some valid links,
7907
7905
  * but it is necessary for security reasons. We treat the word "script" as safe if there are "/" before it.
7908
7906
  */
7909
7907
  function checkXss(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;
7908
+ return link.match(/^[^\/]*s\n*c\n*r\n*i\n*p\n*t\n*:/i) ? '' : link;
7913
7909
  }
7914
7910
  exports.checkXss = checkXss;
7915
7911
 
@@ -12998,17 +12994,24 @@ var DOMEventPlugin = /** @class */ (function () {
12998
12994
  dragEvent.preventDefault();
12999
12995
  }
13000
12996
  };
13001
- this.onDrop = function () {
13002
- var _a, _b;
13003
- var doc = (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.getDocument();
13004
- (_b = doc === null || doc === void 0 ? void 0 : doc.defaultView) === null || _b === void 0 ? void 0 : _b.requestAnimationFrame(function () {
13005
- if (_this.editor) {
13006
- _this.editor.takeSnapshot();
13007
- _this.editor.triggerEvent('contentChanged', {
13008
- source: roosterjs_content_model_dom_1.ChangeSource.Drop,
12997
+ this.onDrop = function (e) {
12998
+ var _a;
12999
+ if (_this.editor) {
13000
+ var beforeDropEvent = _this.editor.triggerEvent('beforeDrop', {
13001
+ rawEvent: e,
13002
+ });
13003
+ if (!(beforeDropEvent === null || beforeDropEvent === void 0 ? void 0 : beforeDropEvent.rawEvent.defaultPrevented)) {
13004
+ var doc = _this.editor.getDocument();
13005
+ (_a = doc === null || doc === void 0 ? void 0 : doc.defaultView) === null || _a === void 0 ? void 0 : _a.requestAnimationFrame(function () {
13006
+ if (_this.editor) {
13007
+ _this.editor.takeSnapshot();
13008
+ _this.editor.triggerEvent('contentChanged', {
13009
+ source: roosterjs_content_model_dom_1.ChangeSource.Drop,
13010
+ });
13011
+ }
13009
13012
  });
13010
13013
  }
13011
- });
13014
+ }
13012
13015
  };
13013
13016
  this.onScroll = function (e) {
13014
13017
  var _a;
@@ -13144,7 +13147,7 @@ var DOMEventPlugin = /** @class */ (function () {
13144
13147
  compositionend: { beforeDispatch: this.onCompositionEnd },
13145
13148
  // 4. Drag and Drop event
13146
13149
  dragstart: { beforeDispatch: this.onDragStart },
13147
- drop: { beforeDispatch: this.onDrop },
13150
+ drop: { beforeDispatch: function (event) { return _this.onDrop(event); } },
13148
13151
  // 5. Pointer event
13149
13152
  pointerdown: { beforeDispatch: function (event) { return _this.onPointerDown(event); } },
13150
13153
  };
@@ -15627,7 +15630,6 @@ var Editor = /** @class */ (function () {
15627
15630
  };
15628
15631
  this.core = (0, createEditorCore_1.createEditorCore)(contentDiv, options);
15629
15632
  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);
15631
15633
  this.core.api.setContentModel(this.core, initialModel, { ignoreSelection: true }, undefined /*onNodeCreated*/, true /*isInitializing*/);
15632
15634
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
15633
15635
  }
@@ -20801,38 +20803,6 @@ function normalizeText(txt, isForward) {
20801
20803
  exports.normalizeText = normalizeText;
20802
20804
 
20803
20805
 
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
-
20836
20806
  /***/ },
20837
20807
 
20838
20808
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts"
@@ -23629,9 +23599,9 @@ exports.shouldSetValue = shouldSetValue;
23629
23599
 
23630
23600
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23631
23601
  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;
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;
23602
+ 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;
23603
+ 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;
23604
+ 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;
23635
23605
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
23636
23606
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
23637
23607
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -23752,8 +23722,6 @@ var normalizeParagraph_1 = __webpack_require__(/*! ./modelApi/common/normalizePa
23752
23722
  Object.defineProperty(exports, "normalizeParagraph", ({ enumerable: true, get: function () { return normalizeParagraph_1.normalizeParagraph; } }));
23753
23723
  var normalizeContentModel_1 = __webpack_require__(/*! ./modelApi/common/normalizeContentModel */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeContentModel.ts");
23754
23724
  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; } }));
23757
23725
  var isGeneralSegment_1 = __webpack_require__(/*! ./modelApi/typeCheck/isGeneralSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isGeneralSegment.ts");
23758
23726
  Object.defineProperty(exports, "isGeneralSegment", ({ enumerable: true, get: function () { return isGeneralSegment_1.isGeneralSegment; } }));
23759
23727
  var unwrapBlock_1 = __webpack_require__(/*! ./modelApi/common/unwrapBlock */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts");
@@ -23819,8 +23787,6 @@ var stringUtil_1 = __webpack_require__(/*! ./domUtils/stringUtil */ "./packages/
23819
23787
  Object.defineProperty(exports, "isPunctuation", ({ enumerable: true, get: function () { return stringUtil_1.isPunctuation; } }));
23820
23788
  Object.defineProperty(exports, "isSpace", ({ enumerable: true, get: function () { return stringUtil_1.isSpace; } }));
23821
23789
  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; } }));
23824
23790
  var parseTableCells_1 = __webpack_require__(/*! ./domUtils/table/parseTableCells */ "./packages/roosterjs-content-model-dom/lib/domUtils/table/parseTableCells.ts");
23825
23791
  Object.defineProperty(exports, "parseTableCells", ({ enumerable: true, get: function () { return parseTableCells_1.parseTableCells; } }));
23826
23792
  var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts");
@@ -24819,134 +24785,6 @@ function normalizeSegmentFormat(format, environment) {
24819
24785
  exports.normalizeSegmentFormat = normalizeSegmentFormat;
24820
24786
 
24821
24787
 
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
-
24950
24788
  /***/ },
24951
24789
 
24952
24790
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts"
@@ -31533,16 +31371,43 @@ exports.isMarkdownTable = isMarkdownTable;
31533
31371
 
31534
31372
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31535
31373
  exports.splitParagraphSegments = void 0;
31536
- var linkRegex = /(\[([^\[]+)\]\((https?:\/\/[^\)]+)\))|(\!\[([^\[]+)\]\((https?:\/\/[^\)]+)\))/g;
31374
+ // Matches markdown links and images in a string.
31375
+ // Group 1 (full link): [text](url) e.g. [Click here](https://example.com)
31376
+ // Group 2: link text e.g. "Click here"
31377
+ // Group 3: link url e.g. "https://example.com"
31378
+ // Group 4 (full image): ![alt](url) e.g. ![Logo](https://example.com/logo.png)
31379
+ // Group 5: alt text e.g. "Logo"
31380
+ // Group 6: image url e.g. "https://example.com/logo.png"
31381
+ var linkRegex = /(\[([^\[]+)\]\(([^\)]+)\))|(\!\[([^\[]+)\]\(([^\)]+)\))/g;
31537
31382
  var isValidUrl = function (url) {
31538
- try {
31539
- new URL(url);
31383
+ if (!url) {
31384
+ return false;
31385
+ }
31386
+ // Accept common non-http schemes and relative paths
31387
+ if (url.startsWith('data:') ||
31388
+ url.startsWith('blob:') ||
31389
+ url.startsWith('/') ||
31390
+ url.startsWith('./') ||
31391
+ url.startsWith('../')) {
31540
31392
  return true;
31541
31393
  }
31394
+ try {
31395
+ var parsed = new URL(url);
31396
+ return parsed.protocol === 'http:' || parsed.protocol === 'https:';
31397
+ }
31542
31398
  catch (_) {
31543
31399
  return false;
31544
31400
  }
31545
31401
  };
31402
+ function pushText(result, text) {
31403
+ var last = result[result.length - 1];
31404
+ if (last && last.type === 'text') {
31405
+ last.text += text;
31406
+ }
31407
+ else {
31408
+ result.push({ type: 'text', text: text, url: '' });
31409
+ }
31410
+ }
31546
31411
  /**
31547
31412
  * @internal
31548
31413
  */
@@ -31552,22 +31417,28 @@ function splitParagraphSegments(text) {
31552
31417
  var match = null;
31553
31418
  while ((match = linkRegex.exec(text)) !== null) {
31554
31419
  if (match.index > lastIndex) {
31555
- result.push({ type: 'text', text: text.slice(lastIndex, match.index), url: '' });
31420
+ pushText(result, text.slice(lastIndex, match.index));
31556
31421
  }
31557
31422
  if (match[2] && match[3]) {
31558
- result.push(isValidUrl(match[3])
31559
- ? { type: 'link', text: match[2], url: match[3] }
31560
- : { type: 'text', text: match[0], url: '' });
31423
+ if (isValidUrl(match[3])) {
31424
+ result.push({ type: 'link', text: match[2], url: match[3] });
31425
+ }
31426
+ else {
31427
+ pushText(result, match[0]);
31428
+ }
31561
31429
  }
31562
31430
  else if (match[5] && match[6]) {
31563
- result.push(isValidUrl(match[6])
31564
- ? { type: 'image', text: match[5], url: match[6] }
31565
- : { type: 'text', text: match[0], url: '' });
31431
+ if (isValidUrl(match[6])) {
31432
+ result.push({ type: 'image', text: match[5], url: match[6] });
31433
+ }
31434
+ else {
31435
+ pushText(result, match[0]);
31436
+ }
31566
31437
  }
31567
31438
  lastIndex = linkRegex.lastIndex;
31568
31439
  }
31569
31440
  if (lastIndex < text.length) {
31570
- result.push({ type: 'text', text: text.slice(lastIndex), url: '' });
31441
+ pushText(result, text.slice(lastIndex));
31571
31442
  }
31572
31443
  return result;
31573
31444
  }
@@ -33392,6 +33263,192 @@ var CustomReplacePlugin = /** @class */ (function () {
33392
33263
  exports.CustomReplacePlugin = CustomReplacePlugin;
33393
33264
 
33394
33265
 
33266
+ /***/ },
33267
+
33268
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts"
33269
+ /*!***************************************************************************************!*\
33270
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts ***!
33271
+ \***************************************************************************************/
33272
+ (__unused_webpack_module, exports, __webpack_require__) {
33273
+
33274
+ "use strict";
33275
+
33276
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33277
+ exports.DragAndDropPlugin = void 0;
33278
+ var handleDroppedContent_1 = __webpack_require__(/*! ./utils/handleDroppedContent */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts");
33279
+ var DefaultOptions = {
33280
+ forbiddenElements: ['iframe'],
33281
+ };
33282
+ /**
33283
+ * DragAndDrop plugin, handles ContentChanged event when change source is "Drop"
33284
+ * to sanitize dropped content, similar to how PastePlugin sanitizes pasted content.
33285
+ */
33286
+ var DragAndDropPlugin = /** @class */ (function () {
33287
+ /**
33288
+ * Construct a new instance of DragAndDropPlugin
33289
+ */
33290
+ function DragAndDropPlugin(options) {
33291
+ if (options === void 0) { options = DefaultOptions; }
33292
+ var _a;
33293
+ this.editor = null;
33294
+ this.forbiddenElements = [];
33295
+ this.isInternalDragging = false;
33296
+ this.disposer = null;
33297
+ this.forbiddenElements = (_a = options.forbiddenElements) !== null && _a !== void 0 ? _a : [];
33298
+ }
33299
+ /**
33300
+ * Get name of this plugin
33301
+ */
33302
+ DragAndDropPlugin.prototype.getName = function () {
33303
+ return 'DragAndDrop';
33304
+ };
33305
+ /**
33306
+ * The first method that editor will call to a plugin when editor is initializing.
33307
+ * It will pass in the editor instance, plugin should take this chance to save the
33308
+ * editor reference so that it can call to any editor method or format API later.
33309
+ * @param editor The editor object
33310
+ */
33311
+ DragAndDropPlugin.prototype.initialize = function (editor) {
33312
+ var _this = this;
33313
+ this.editor = editor;
33314
+ this.disposer = editor.attachDomEvent({
33315
+ dragstart: {
33316
+ beforeDispatch: function (_ev) {
33317
+ _this.isInternalDragging = true;
33318
+ },
33319
+ },
33320
+ });
33321
+ };
33322
+ /**
33323
+ * The last method that editor will call to a plugin before it is disposed.
33324
+ * Plugin can take this chance to clear the reference to editor. After this method is
33325
+ * called, plugin should not call to any editor method since it will result in error.
33326
+ */
33327
+ DragAndDropPlugin.prototype.dispose = function () {
33328
+ this.editor = null;
33329
+ if (this.disposer) {
33330
+ this.disposer();
33331
+ this.disposer = null;
33332
+ }
33333
+ this.isInternalDragging = false;
33334
+ this.forbiddenElements = [];
33335
+ };
33336
+ /**
33337
+ * Core method for a plugin. Once an event happens in editor, editor will call this
33338
+ * method of each plugin to handle the event as long as the event is not handled
33339
+ * exclusively by another plugin.
33340
+ * @param event The event to handle:
33341
+ */
33342
+ DragAndDropPlugin.prototype.onPluginEvent = function (event) {
33343
+ var _a;
33344
+ if (this.editor && event.eventType == 'beforeDrop') {
33345
+ if (this.isInternalDragging) {
33346
+ this.isInternalDragging = false;
33347
+ }
33348
+ else {
33349
+ var dropEvent = event.rawEvent;
33350
+ var html = (_a = dropEvent.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData('text/html');
33351
+ if (html) {
33352
+ (0, handleDroppedContent_1.handleDroppedContent)(this.editor, dropEvent, html, this.forbiddenElements);
33353
+ }
33354
+ }
33355
+ return;
33356
+ }
33357
+ };
33358
+ return DragAndDropPlugin;
33359
+ }());
33360
+ exports.DragAndDropPlugin = DragAndDropPlugin;
33361
+
33362
+
33363
+ /***/ },
33364
+
33365
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts"
33366
+ /*!**************************************************************************************************!*\
33367
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts ***!
33368
+ \**************************************************************************************************/
33369
+ (__unused_webpack_module, exports, __webpack_require__) {
33370
+
33371
+ "use strict";
33372
+
33373
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33374
+ exports.cleanForbiddenElements = void 0;
33375
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
33376
+ /**
33377
+ * @internal
33378
+ * Remove all forbidden elements from a parsed HTML document
33379
+ * @param doc The parsed HTML document to clean
33380
+ * @param forbiddenElements Array of tag names to remove (e.g., ['iframe', 'script'])
33381
+ */
33382
+ function cleanForbiddenElements(doc, forbiddenElements) {
33383
+ var e_1, _a;
33384
+ var _b;
33385
+ if (forbiddenElements.length === 0) {
33386
+ return;
33387
+ }
33388
+ var selector = forbiddenElements.join(',');
33389
+ var elements = Array.from(doc.body.querySelectorAll(selector));
33390
+ try {
33391
+ 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()) {
33392
+ var element = elements_1_1.value;
33393
+ (_b = element.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(element);
33394
+ }
33395
+ }
33396
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
33397
+ finally {
33398
+ try {
33399
+ if (elements_1_1 && !elements_1_1.done && (_a = elements_1.return)) _a.call(elements_1);
33400
+ }
33401
+ finally { if (e_1) throw e_1.error; }
33402
+ }
33403
+ }
33404
+ exports.cleanForbiddenElements = cleanForbiddenElements;
33405
+
33406
+
33407
+ /***/ },
33408
+
33409
+ /***/ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts"
33410
+ /*!************************************************************************************************!*\
33411
+ !*** ./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/handleDroppedContent.ts ***!
33412
+ \************************************************************************************************/
33413
+ (__unused_webpack_module, exports, __webpack_require__) {
33414
+
33415
+ "use strict";
33416
+
33417
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
33418
+ exports.handleDroppedContent = void 0;
33419
+ var cleanForbiddenElements_1 = __webpack_require__(/*! ./cleanForbiddenElements */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/utils/cleanForbiddenElements.ts");
33420
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
33421
+ /**
33422
+ * @internal
33423
+ * Handle dropped HTML content by inserting it at the drop position
33424
+ */
33425
+ function handleDroppedContent(editor, event, html, forbiddenElements) {
33426
+ var doc = editor.getDocument();
33427
+ var domPosition = (0, roosterjs_content_model_dom_1.getNodePositionFromEvent)(doc, editor.getDOMHelper(), event.x, event.y);
33428
+ if (domPosition) {
33429
+ event.preventDefault();
33430
+ event.stopPropagation();
33431
+ var range = doc.createRange();
33432
+ range.setStart(domPosition.node, domPosition.offset);
33433
+ range.collapse(true);
33434
+ var parsedHtml = editor.getDOMCreator().htmlToDOM(html);
33435
+ (0, cleanForbiddenElements_1.cleanForbiddenElements)(parsedHtml, forbiddenElements);
33436
+ var droppedModel_1 = (0, roosterjs_content_model_dom_1.domToContentModel)(parsedHtml.body, (0, roosterjs_content_model_dom_1.createDomToModelContext)());
33437
+ editor.formatContentModel(function (model, context) {
33438
+ (0, roosterjs_content_model_dom_1.mergeModel)(model, droppedModel_1, context);
33439
+ return true;
33440
+ }, {
33441
+ selectionOverride: {
33442
+ type: 'range',
33443
+ range: range,
33444
+ isReverted: false,
33445
+ },
33446
+ });
33447
+ }
33448
+ }
33449
+ exports.handleDroppedContent = handleDroppedContent;
33450
+
33451
+
33395
33452
  /***/ },
33396
33453
 
33397
33454
  /***/ "./packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts"
@@ -38396,7 +38453,7 @@ exports.updateWrapper = updateWrapper;
38396
38453
  "use strict";
38397
38454
 
38398
38455
  Object.defineProperty(exports, "__esModule", ({ value: true }));
38399
- 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;
38456
+ 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;
38400
38457
  var TableEditPlugin_1 = __webpack_require__(/*! ./tableEdit/TableEditPlugin */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/TableEditPlugin.ts");
38401
38458
  Object.defineProperty(exports, "TableEditPlugin", ({ enumerable: true, get: function () { return TableEditPlugin_1.TableEditPlugin; } }));
38402
38459
  var PastePlugin_1 = __webpack_require__(/*! ./paste/PastePlugin */ "./packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts");
@@ -38457,6 +38514,8 @@ var moveHighlight_1 = __webpack_require__(/*! ./findReplace/moveHighlight */ "./
38457
38514
  Object.defineProperty(exports, "moveHighlight", ({ enumerable: true, get: function () { return moveHighlight_1.moveHighlight; } }));
38458
38515
  var AnnouncePlugin_1 = __webpack_require__(/*! ./announce/AnnouncePlugin */ "./packages/roosterjs-content-model-plugins/lib/announce/AnnouncePlugin.ts");
38459
38516
  Object.defineProperty(exports, "AnnouncePlugin", ({ enumerable: true, get: function () { return AnnouncePlugin_1.AnnouncePlugin; } }));
38517
+ var DragAndDropPlugin_1 = __webpack_require__(/*! ./dragAndDrop/DragAndDropPlugin */ "./packages/roosterjs-content-model-plugins/lib/dragAndDrop/DragAndDropPlugin.ts");
38518
+ Object.defineProperty(exports, "DragAndDropPlugin", ({ enumerable: true, get: function () { return DragAndDropPlugin_1.DragAndDropPlugin; } }));
38460
38519
 
38461
38520
 
38462
38521
  /***/ },