roosterjs 9.26.0 → 9.29.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
@@ -2094,8 +2094,8 @@ exports["default"] = getDarkColor;
2094
2094
  "use strict";
2095
2095
 
2096
2096
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2097
- exports.formatSegmentWithContentModel = exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.splitTextSegment = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2098
- exports.queryContentModelBlocks = exports.getListAnnounceData = exports.promoteLink = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = void 0;
2097
+ exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.createEditorContextForEntity = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.splitTextSegment = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2098
+ exports.queryContentModelBlocks = exports.getListAnnounceData = exports.promoteLink = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = exports.formatSegmentWithContentModel = void 0;
2099
2099
  var insertTable_1 = __webpack_require__(/*! ./publicApi/table/insertTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts");
2100
2100
  Object.defineProperty(exports, "insertTable", ({ enumerable: true, get: function () { return insertTable_1.insertTable; } }));
2101
2101
  var formatTable_1 = __webpack_require__(/*! ./publicApi/table/formatTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/formatTable.ts");
@@ -2188,6 +2188,8 @@ var insertTableColumn_1 = __webpack_require__(/*! ./modelApi/table/insertTableCo
2188
2188
  Object.defineProperty(exports, "insertTableColumn", ({ enumerable: true, get: function () { return insertTableColumn_1.insertTableColumn; } }));
2189
2189
  var clearSelectedCells_1 = __webpack_require__(/*! ./modelApi/table/clearSelectedCells */ "./packages/roosterjs-content-model-api/lib/modelApi/table/clearSelectedCells.ts");
2190
2190
  Object.defineProperty(exports, "clearSelectedCells", ({ enumerable: true, get: function () { return clearSelectedCells_1.clearSelectedCells; } }));
2191
+ var createEditorContextForEntity_1 = __webpack_require__(/*! ./publicApi/utils/createEditorContextForEntity */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/createEditorContextForEntity.ts");
2192
+ Object.defineProperty(exports, "createEditorContextForEntity", ({ enumerable: true, get: function () { return createEditorContextForEntity_1.createEditorContextForEntity; } }));
2191
2193
  var formatTableWithContentModel_1 = __webpack_require__(/*! ./publicApi/utils/formatTableWithContentModel */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/formatTableWithContentModel.ts");
2192
2194
  Object.defineProperty(exports, "formatTableWithContentModel", ({ enumerable: true, get: function () { return formatTableWithContentModel_1.formatTableWithContentModel; } }));
2193
2195
  var formatImageWithContentModel_1 = __webpack_require__(/*! ./publicApi/utils/formatImageWithContentModel */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/formatImageWithContentModel.ts");
@@ -2853,14 +2855,16 @@ function isWholeBlockSelected(block) {
2853
2855
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2854
2856
  exports.queryContentModelBlocks = void 0;
2855
2857
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
2858
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
2856
2859
  /**
2857
2860
  * Query content model blocks
2858
2861
  * @param group The block group to query
2859
2862
  * @param type The type of block to query
2860
2863
  * @param filter Optional selector to filter the blocks
2861
2864
  * @param findFirstOnly True to return the first block only, false to return all blocks
2865
+ * @param shouldExpandEntity Optional function to determine if an entity's children should be recursively queried, should return a EditorContext if the entity should be expanded, or null if not
2862
2866
  */
2863
- function queryContentModelBlocks(group, type, filter, findFirstOnly) {
2867
+ function queryContentModelBlocks(group, type, filter, findFirstOnly, shouldExpandEntity) {
2864
2868
  var e_1, _a, e_2, _b;
2865
2869
  var elements = [];
2866
2870
  for (var i = 0; i < group.blocks.length; i++) {
@@ -2875,12 +2879,21 @@ function queryContentModelBlocks(group, type, filter, findFirstOnly) {
2875
2879
  if (isExpectedBlockType(block, type, filter)) {
2876
2880
  elements.push(block);
2877
2881
  }
2882
+ if (block.blockType == 'Entity' && shouldExpandEntity) {
2883
+ var editorContext = shouldExpandEntity(block);
2884
+ if (editorContext) {
2885
+ var context = (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext);
2886
+ var model = (0, roosterjs_content_model_dom_1.domToContentModel)(block.wrapper, context);
2887
+ var results_1 = queryContentModelBlocks(model, type, filter, findFirstOnly, shouldExpandEntity);
2888
+ elements.push.apply(elements, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(results_1), false));
2889
+ }
2890
+ }
2878
2891
  break;
2879
2892
  case 'BlockGroup':
2880
2893
  if (isExpectedBlockType(block, type, filter)) {
2881
2894
  elements.push(block);
2882
2895
  }
2883
- var results = queryContentModelBlocks(block, type, filter, findFirstOnly);
2896
+ var results = queryContentModelBlocks(block, type, filter, findFirstOnly, shouldExpandEntity);
2884
2897
  elements.push.apply(elements, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(results), false));
2885
2898
  break;
2886
2899
  case 'Table':
@@ -2893,8 +2906,8 @@ function queryContentModelBlocks(group, type, filter, findFirstOnly) {
2893
2906
  try {
2894
2907
  for (var _e = (e_2 = void 0, (0, tslib_1.__values)(row.cells)), _f = _e.next(); !_f.done; _f = _e.next()) {
2895
2908
  var cell = _f.value;
2896
- var results_1 = queryContentModelBlocks(cell, type, filter, findFirstOnly);
2897
- elements.push.apply(elements, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(results_1), false));
2909
+ var results_2 = queryContentModelBlocks(cell, type, filter, findFirstOnly, shouldExpandEntity);
2910
+ elements.push.apply(elements, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(results_2), false));
2898
2911
  }
2899
2912
  }
2900
2913
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -3682,17 +3695,9 @@ function setListType(model, listType, removeMargins) {
3682
3695
  (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(block.blocks[0]);
3683
3696
  }
3684
3697
  if (alreadyInExpectedType) {
3685
- //if the list item has margins or textAlign, we need to apply them to the block to preserve the indention and alignment
3698
+ // if the list item has margins or textAlign, we need to apply them to the block to preserve the indention and alignment
3686
3699
  block.blocks.forEach(function (x) {
3687
- if (block.format.marginLeft) {
3688
- x.format.marginLeft = block.format.marginLeft;
3689
- }
3690
- if (block.format.marginRight) {
3691
- x.format.marginRight = block.format.marginRight;
3692
- }
3693
- if (block.format.textAlign) {
3694
- x.format.textAlign = block.format.textAlign;
3695
- }
3700
+ (0, roosterjs_content_model_dom_1.copyFormat)(x.format, block.format, roosterjs_content_model_dom_1.ListFormats);
3696
3701
  });
3697
3702
  }
3698
3703
  }
@@ -3727,17 +3732,8 @@ function setListType(model, listType, removeMargins) {
3727
3732
  }
3728
3733
  var mutableBlock = (0, roosterjs_content_model_dom_1.mutateBlock)(block);
3729
3734
  newListItem.blocks.push(mutableBlock);
3730
- if (mutableBlock.format.marginRight) {
3731
- newListItem.format.marginRight = mutableBlock.format.marginRight;
3732
- mutableBlock.format.marginRight = undefined;
3733
- }
3734
- if (mutableBlock.format.marginLeft) {
3735
- newListItem.format.marginLeft = mutableBlock.format.marginLeft;
3736
- mutableBlock.format.marginLeft = undefined;
3737
- }
3738
- if (mutableBlock.format.textAlign) {
3739
- newListItem.format.textAlign = mutableBlock.format.textAlign;
3740
- }
3735
+ (0, roosterjs_content_model_dom_1.copyFormat)(newListItem.format, mutableBlock.format, roosterjs_content_model_dom_1.ListFormatsToMove, true /*deleteOriginalFormat*/);
3736
+ (0, roosterjs_content_model_dom_1.copyFormat)(newListItem.format, mutableBlock.format, roosterjs_content_model_dom_1.ListFormatsToKeep);
3741
3737
  (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(index, 1, newListItem);
3742
3738
  existingListItems.push(newListItem);
3743
3739
  var levelIndex = newListItem.levels.length - 1;
@@ -5615,8 +5611,9 @@ function insertLink(editor, link, anchorTitle, displayText, target) {
5615
5611
  .map(function (x) { return (x.segmentType == 'Text' ? x.text : ''); })
5616
5612
  .join('');
5617
5613
  var text = displayText || originalText || '';
5618
- if (segments.some(function (x) { return x.segmentType != 'SelectionMarker'; }) &&
5619
- originalText == text) {
5614
+ if ((segments.some(function (x) { return x.segmentType != 'SelectionMarker'; }) &&
5615
+ originalText == text) ||
5616
+ (segments.length == 1 && segments[0].segmentType == 'Image')) {
5620
5617
  segments.forEach(function (x) {
5621
5618
  var link = createLink(linkUrl_1, anchorTitle, target, x.segmentType == 'Text');
5622
5619
  (0, roosterjs_content_model_dom_1.addLink)(x, link);
@@ -6995,6 +6992,46 @@ function setTableCellShade(editor, color) {
6995
6992
  exports.setTableCellShade = setTableCellShade;
6996
6993
 
6997
6994
 
6995
+ /***/ }),
6996
+
6997
+ /***/ "./packages/roosterjs-content-model-api/lib/publicApi/utils/createEditorContextForEntity.ts":
6998
+ /*!**************************************************************************************************!*\
6999
+ !*** ./packages/roosterjs-content-model-api/lib/publicApi/utils/createEditorContextForEntity.ts ***!
7000
+ \**************************************************************************************************/
7001
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
7002
+
7003
+ "use strict";
7004
+
7005
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7006
+ exports.createEditorContextForEntity = void 0;
7007
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
7008
+ /**
7009
+ * Create an EditorContext for an entity
7010
+ * @param editor The editor object
7011
+ * @param entity The entity to create the context for
7012
+ * @returns The generated EditorContext for the entity
7013
+ */
7014
+ function createEditorContextForEntity(editor, entity) {
7015
+ var _a;
7016
+ var domHelper = editor.getDOMHelper();
7017
+ var context = {
7018
+ isDarkMode: editor.isDarkMode(),
7019
+ defaultFormat: (0, tslib_1.__assign)({}, entity.format),
7020
+ darkColorHandler: editor.getColorManager(),
7021
+ addDelimiterForEntity: false,
7022
+ allowCacheElement: false,
7023
+ domIndexer: undefined,
7024
+ zoomScale: domHelper.calculateZoomScale(),
7025
+ experimentalFeatures: [],
7026
+ };
7027
+ if (((_a = editor.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getComputedStyle(entity.wrapper).direction) == 'rtl') {
7028
+ context.isRootRtl = true;
7029
+ }
7030
+ return context;
7031
+ }
7032
+ exports.createEditorContextForEntity = createEditorContextForEntity;
7033
+
7034
+
6998
7035
  /***/ }),
6999
7036
 
7000
7037
  /***/ "./packages/roosterjs-content-model-api/lib/publicApi/utils/formatImageWithContentModel.ts":
@@ -7212,8 +7249,9 @@ exports.formatParagraphWithContentModel = formatParagraphWithContentModel;
7212
7249
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7213
7250
  exports.formatSegmentWithContentModel = void 0;
7214
7251
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
7215
- var adjustWordSelection_1 = __webpack_require__(/*! ../../modelApi/selection/adjustWordSelection */ "./packages/roosterjs-content-model-api/lib/modelApi/selection/adjustWordSelection.ts");
7216
7252
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
7253
+ var adjustWordSelection_1 = __webpack_require__(/*! ../../modelApi/selection/adjustWordSelection */ "./packages/roosterjs-content-model-api/lib/modelApi/selection/adjustWordSelection.ts");
7254
+ var createEditorContextForEntity_1 = __webpack_require__(/*! ./createEditorContextForEntity */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/createEditorContextForEntity.ts");
7217
7255
  /**
7218
7256
  * Invoke a callback to format the selected segment using Content Model
7219
7257
  * @param editor The editor object
@@ -7287,24 +7325,6 @@ function formatSegmentWithContentModel(editor, apiName, toggleStyleCallback, seg
7287
7325
  });
7288
7326
  }
7289
7327
  exports.formatSegmentWithContentModel = formatSegmentWithContentModel;
7290
- function createEditorContextForEntity(editor, entity) {
7291
- var _a;
7292
- var domHelper = editor.getDOMHelper();
7293
- var context = {
7294
- isDarkMode: editor.isDarkMode(),
7295
- defaultFormat: (0, tslib_1.__assign)({}, entity.format),
7296
- darkColorHandler: editor.getColorManager(),
7297
- addDelimiterForEntity: false,
7298
- allowCacheElement: false,
7299
- domIndexer: undefined,
7300
- zoomScale: domHelper.calculateZoomScale(),
7301
- experimentalFeatures: [],
7302
- };
7303
- if (((_a = editor.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getComputedStyle(entity.wrapper).direction) == 'rtl') {
7304
- context.isRootRtl = true;
7305
- }
7306
- return context;
7307
- }
7308
7328
  function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEntities) {
7309
7329
  var _a = entity.entityFormat, id = _a.id, type = _a.entityType, isReadonly = _a.isReadonly;
7310
7330
  if (id && type) {
@@ -7317,7 +7337,7 @@ function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEn
7317
7337
  editor.triggerEvent('entityOperation', entityOperationEventData);
7318
7338
  formattableRoots.forEach(function (root) {
7319
7339
  if (entity.wrapper.contains(root.element)) {
7320
- var editorContext = createEditorContextForEntity(editor, entity);
7340
+ var editorContext = (0, createEditorContextForEntity_1.createEditorContextForEntity)(editor, entity);
7321
7341
  var context = (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, root.domToModelOptions);
7322
7342
  // Treat everything as selected since the parent entity is selected
7323
7343
  context.isInSelection = true;
@@ -7334,7 +7354,7 @@ function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEn
7334
7354
  function writeBackEntities(editor, modelsFromEntities) {
7335
7355
  modelsFromEntities.forEach(function (_a) {
7336
7356
  var _b = (0, tslib_1.__read)(_a, 3), entity = _b[0], root = _b[1], model = _b[2];
7337
- var editorContext = createEditorContextForEntity(editor, entity);
7357
+ var editorContext = (0, createEditorContextForEntity_1.createEditorContextForEntity)(editor, entity);
7338
7358
  var modelToDomContext = (0, roosterjs_content_model_dom_1.createModelToDomContext)(editorContext, root.modelToDomOptions);
7339
7359
  (0, roosterjs_content_model_dom_1.contentModelToDom)(editor.getDocument(), root.element, model, modelToDomContext);
7340
7360
  });
@@ -8020,6 +8040,64 @@ function exportContent(editor, mode, optionsOrCallbacks) {
8020
8040
  exports.exportContent = exportContent;
8021
8041
 
8022
8042
 
8043
+ /***/ }),
8044
+
8045
+ /***/ "./packages/roosterjs-content-model-core/lib/command/paste/cleanHtmlComments.ts":
8046
+ /*!**************************************************************************************!*\
8047
+ !*** ./packages/roosterjs-content-model-core/lib/command/paste/cleanHtmlComments.ts ***!
8048
+ \**************************************************************************************/
8049
+ /***/ ((__unused_webpack_module, exports) => {
8050
+
8051
+ "use strict";
8052
+
8053
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
8054
+ exports.cleanHtmlComments = void 0;
8055
+ var HtmlCommentStart = '\x3C!--';
8056
+ var HtmlCommentStart2 = '<!--';
8057
+ var HtmlCommentEnd = '-->';
8058
+ var styleTag = '<style';
8059
+ var styleClosingTag = '</style>';
8060
+ var nonWordCharacterRegex = /\W/;
8061
+ /**
8062
+ * @internal
8063
+ * Exported only for unit test
8064
+ */
8065
+ function cleanHtmlComments(html) {
8066
+ var _a;
8067
+ var _b = extractHtmlIndexes(html), styleIndex = _b.styleIndex, styleEndIndex = _b.styleEndIndex;
8068
+ while (styleIndex > -1) {
8069
+ html = removeCommentsFromHtml(html, HtmlCommentStart, styleEndIndex, styleIndex);
8070
+ html = removeCommentsFromHtml(html, HtmlCommentStart2, styleEndIndex, styleIndex);
8071
+ html = removeCommentsFromHtml(html, HtmlCommentEnd, styleEndIndex, styleIndex);
8072
+ (_a = extractHtmlIndexes(html, styleEndIndex + 1), styleIndex = _a.styleIndex, styleEndIndex = _a.styleEndIndex);
8073
+ }
8074
+ return html;
8075
+ }
8076
+ exports.cleanHtmlComments = cleanHtmlComments;
8077
+ function extractHtmlIndexes(html, startIndex) {
8078
+ if (startIndex === void 0) { startIndex = 0; }
8079
+ var htmlLowercase = html.toLowerCase();
8080
+ var styleIndex = htmlLowercase.indexOf(styleTag, startIndex);
8081
+ var currentIndex = styleIndex + styleTag.length;
8082
+ var nextChar = html.substring(currentIndex, currentIndex + 1);
8083
+ while (!nonWordCharacterRegex.test(nextChar) && styleIndex > -1) {
8084
+ styleIndex = htmlLowercase.indexOf(styleTag, styleIndex + 1);
8085
+ currentIndex = styleIndex + styleTag.length;
8086
+ nextChar = html.substring(currentIndex, currentIndex + 1);
8087
+ }
8088
+ var styleEndIndex = htmlLowercase.indexOf(styleClosingTag, startIndex);
8089
+ return { styleIndex: styleIndex, styleEndIndex: styleEndIndex };
8090
+ }
8091
+ function removeCommentsFromHtml(html, marker, endId, startId) {
8092
+ var id = html.indexOf(marker, startId);
8093
+ while (id > -1 && id < endId) {
8094
+ html = html.substring(0, id) + html.substring(id + marker.length);
8095
+ id = html.indexOf(marker, id + 1);
8096
+ }
8097
+ return html;
8098
+ }
8099
+
8100
+
8023
8101
  /***/ }),
8024
8102
 
8025
8103
  /***/ "./packages/roosterjs-content-model-core/lib/command/paste/createPasteFragment.ts":
@@ -8259,6 +8337,7 @@ function getLastSegmentFormat(pasteModel) {
8259
8337
 
8260
8338
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8261
8339
  exports.paste = void 0;
8340
+ var cleanHtmlComments_1 = __webpack_require__(/*! ./cleanHtmlComments */ "./packages/roosterjs-content-model-core/lib/command/paste/cleanHtmlComments.ts");
8262
8341
  var mergePasteContent_1 = __webpack_require__(/*! ./mergePasteContent */ "./packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts");
8263
8342
  var convertInlineCss_1 = __webpack_require__(/*! ../createModelFromHtml/convertInlineCss */ "./packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts");
8264
8343
  var createPasteFragment_1 = __webpack_require__(/*! ./createPasteFragment */ "./packages/roosterjs-content-model-core/lib/command/paste/createPasteFragment.ts");
@@ -8283,7 +8362,11 @@ function paste(editor, clipboardData, pasteTypeOrGetter) {
8283
8362
  });
8284
8363
  }
8285
8364
  // 1. Prepare variables
8286
- var doc = createDOMFromHtml(clipboardData.rawHtml, editor.getDOMCreator());
8365
+ var domCreator = editor.getDOMCreator();
8366
+ if (!domCreator.isBypassed && clipboardData.rawHtml) {
8367
+ clipboardData.rawHtml = (0, cleanHtmlComments_1.cleanHtmlComments)(clipboardData.rawHtml);
8368
+ }
8369
+ var doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);
8287
8370
  var pasteType = typeof pasteTypeOrGetter == 'function'
8288
8371
  ? pasteTypeOrGetter(doc, clipboardData)
8289
8372
  : pasteTypeOrGetter;
@@ -8292,7 +8375,7 @@ function paste(editor, clipboardData, pasteTypeOrGetter) {
8292
8375
  // 3. Create target fragment
8293
8376
  var sourceFragment = (0, createPasteFragment_1.createPasteFragment)(editor.getDocument(), clipboardData, pasteType, (_a = (clipboardData.rawHtml == clipboardData.html
8294
8377
  ? doc
8295
- : createDOMFromHtml(clipboardData.html, editor.getDOMCreator()))) === null || _a === void 0 ? void 0 : _a.body);
8378
+ : createDOMFromHtml(clipboardData.html, domCreator))) === null || _a === void 0 ? void 0 : _a.body);
8296
8379
  // 4. Trigger BeforePaste event to allow plugins modify the fragment
8297
8380
  var eventResult = (0, generatePasteOptionFromPlugins_1.generatePasteOptionFromPlugins)(editor, clipboardData, sourceFragment, htmlFromClipboard, pasteType);
8298
8381
  // 5. Convert global CSS to inline CSS
@@ -9405,7 +9488,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
9405
9488
  * @internal
9406
9489
  */
9407
9490
  function restoreSnapshotHTML(core, snapshot) {
9408
- var _a;
9491
+ var _a, _b;
9409
9492
  var physicalRoot = core.physicalRoot, entityMap = core.entity.entityMap;
9410
9493
  var refNode = physicalRoot.firstChild;
9411
9494
  var body = core.domCreator.htmlToDOM(snapshot.html).body;
@@ -9413,6 +9496,14 @@ function restoreSnapshotHTML(core, snapshot) {
9413
9496
  var next = currentNode.nextSibling;
9414
9497
  var originalEntityElement = tryGetEntityElement(entityMap, currentNode);
9415
9498
  if (originalEntityElement) {
9499
+ // After restoring the snapshot, we need to clear the delimiter indexes since cached model will be cleared
9500
+ if ((0, roosterjs_content_model_dom_1.isBlockEntityContainer)(originalEntityElement)) {
9501
+ for (var node = originalEntityElement.firstChild; node; node = node.nextSibling) {
9502
+ if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(node)) {
9503
+ (_a = core.cache.domIndexer) === null || _a === void 0 ? void 0 : _a.clearIndex(node);
9504
+ }
9505
+ }
9506
+ }
9416
9507
  refNode = (0, roosterjs_content_model_dom_1.reuseCachedElement)(physicalRoot, originalEntityElement, refNode);
9417
9508
  }
9418
9509
  else {
@@ -9440,7 +9531,7 @@ function restoreSnapshotHTML(core, snapshot) {
9440
9531
  }
9441
9532
  while (refNode) {
9442
9533
  var next = refNode.nextSibling;
9443
- (_a = refNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(refNode);
9534
+ (_b = refNode.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(refNode);
9444
9535
  refNode = next;
9445
9536
  }
9446
9537
  }
@@ -10740,14 +10831,20 @@ var DomIndexerImpl = /** @class */ (function () {
10740
10831
  unindex(targetText);
10741
10832
  }
10742
10833
  };
10834
+ DomIndexerImpl.prototype.clearIndex = function (container) {
10835
+ internalClearIndex(container);
10836
+ };
10743
10837
  DomIndexerImpl.prototype.reconcileSelection = function (model, newSelection, oldSelection) {
10744
10838
  var _a, _b;
10745
10839
  if (oldSelection) {
10840
+ var startNode = void 0;
10746
10841
  if (oldSelection.type == 'range' &&
10747
10842
  this.isCollapsed(oldSelection) &&
10748
- (0, roosterjs_content_model_dom_1.isNodeOfType)(oldSelection.start.node, 'TEXT_NODE') &&
10749
- isIndexedSegment(oldSelection.start.node)) {
10750
- this.reconcileTextSelection(oldSelection.start.node);
10843
+ (startNode = oldSelection.start.node) &&
10844
+ (0, roosterjs_content_model_dom_1.isNodeOfType)(startNode, 'TEXT_NODE') &&
10845
+ isIndexedSegment(startNode) &&
10846
+ startNode.__roosterjsContentModel.segments.length > 0) {
10847
+ this.reconcileTextSelection(startNode);
10751
10848
  }
10752
10849
  else {
10753
10850
  (0, roosterjs_content_model_dom_1.setSelection)(model);
@@ -11100,6 +11197,12 @@ function getFirstLeaf(node) {
11100
11197
  }
11101
11198
  return node;
11102
11199
  }
11200
+ function internalClearIndex(container) {
11201
+ unindex(container);
11202
+ for (var node = container.firstChild; node; node = node.nextSibling) {
11203
+ internalClearIndex(node);
11204
+ }
11205
+ }
11103
11206
 
11104
11207
 
11105
11208
  /***/ }),
@@ -11409,6 +11512,7 @@ var adjustImageSelectionOnSafari_1 = __webpack_require__(/*! ./utils/adjustImage
11409
11512
  var deleteEmptyList_1 = __webpack_require__(/*! ./utils/deleteEmptyList */ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts");
11410
11513
  var pasteCopyBlockEntityParser_1 = __webpack_require__(/*! ../../override/pasteCopyBlockEntityParser */ "./packages/roosterjs-content-model-core/lib/override/pasteCopyBlockEntityParser.ts");
11411
11514
  var paste_1 = __webpack_require__(/*! ../../command/paste/paste */ "./packages/roosterjs-content-model-core/lib/command/paste/paste.ts");
11515
+ var pruneUnselectedModel_1 = __webpack_require__(/*! ./utils/pruneUnselectedModel */ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/pruneUnselectedModel.ts");
11412
11516
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
11413
11517
  var TEMP_DIV_ID = 'roosterJS_copyCutTempDiv';
11414
11518
  /**
@@ -11423,6 +11527,7 @@ var CopyPastePlugin = /** @class */ (function () {
11423
11527
  var _this = this;
11424
11528
  this.editor = null;
11425
11529
  this.disposer = null;
11530
+ this.customCopyCutEnabled = false;
11426
11531
  this.onPaste = function (event) {
11427
11532
  if (_this.editor && isClipboardEvent(event)) {
11428
11533
  var editor_1 = _this.editor;
@@ -11467,6 +11572,7 @@ var CopyPastePlugin = /** @class */ (function () {
11467
11572
  beforeDispatch: function (e) { return _this.onCutCopy(e, true /*isCut*/); },
11468
11573
  },
11469
11574
  });
11575
+ this.customCopyCutEnabled = editor.isExperimentalFeatureEnabled('CustomCopyCut');
11470
11576
  };
11471
11577
  /**
11472
11578
  * Dispose this plugin
@@ -11491,7 +11597,7 @@ var CopyPastePlugin = /** @class */ (function () {
11491
11597
  };
11492
11598
  CopyPastePlugin.prototype.onCutCopy = function (event, isCut) {
11493
11599
  var _this = this;
11494
- var _a;
11600
+ var _a, _b, _c;
11495
11601
  if (!this.editor) {
11496
11602
  return;
11497
11603
  }
@@ -11500,6 +11606,7 @@ var CopyPastePlugin = /** @class */ (function () {
11500
11606
  (0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(this.editor, selection);
11501
11607
  if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
11502
11608
  var pasteModel = this.editor.getContentModelCopy('disconnected');
11609
+ (0, pruneUnselectedModel_1.pruneUnselectedModel)(pasteModel);
11503
11610
  if (selection.type === 'table') {
11504
11611
  (0, roosterjs_content_model_dom_1.iterateSelections)(pasteModel, function (_, tableContext) {
11505
11612
  if (tableContext === null || tableContext === void 0 ? void 0 : tableContext.table) {
@@ -11526,10 +11633,16 @@ var CopyPastePlugin = /** @class */ (function () {
11526
11633
  rawEvent: event,
11527
11634
  isCut: isCut,
11528
11635
  }).range;
11529
- if (newRange) {
11636
+ if (this.customCopyCutEnabled && isClipboardEvent(event)) {
11637
+ event.preventDefault();
11638
+ var text = (0, roosterjs_content_model_dom_1.contentModelToText)(pasteModel);
11639
+ (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.setData('text/html', tempDiv_1.innerHTML);
11640
+ (_b = event.clipboardData) === null || _b === void 0 ? void 0 : _b.setData('text/plain', text);
11641
+ }
11642
+ else if (newRange) {
11530
11643
  (0, addRangeToSelection_1.addRangeToSelection)(doc, newRange);
11531
11644
  }
11532
- (_a = doc.defaultView) === null || _a === void 0 ? void 0 : _a.requestAnimationFrame(function () {
11645
+ (_c = doc.defaultView) === null || _c === void 0 ? void 0 : _c.requestAnimationFrame(function () {
11533
11646
  if (!_this.editor) {
11534
11647
  return;
11535
11648
  }
@@ -11566,7 +11679,9 @@ var CopyPastePlugin = /** @class */ (function () {
11566
11679
  tempDiv.style.left = '0';
11567
11680
  tempDiv.style.userSelect = 'text';
11568
11681
  tempDiv.contentEditable = 'true';
11569
- doc.body.appendChild(tempDiv);
11682
+ if (!this.customCopyCutEnabled) {
11683
+ doc.body.appendChild(tempDiv);
11684
+ }
11570
11685
  this.state.tempDiv = tempDiv;
11571
11686
  }
11572
11687
  var div = this.state.tempDiv;
@@ -11778,6 +11893,151 @@ var deleteEmptyList = function (context) {
11778
11893
  exports.deleteEmptyList = deleteEmptyList;
11779
11894
 
11780
11895
 
11896
+ /***/ }),
11897
+
11898
+ /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/pruneUnselectedModel.ts":
11899
+ /*!******************************************************************************************************!*\
11900
+ !*** ./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/pruneUnselectedModel.ts ***!
11901
+ \******************************************************************************************************/
11902
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11903
+
11904
+ "use strict";
11905
+
11906
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
11907
+ exports.pruneUnselectedModel = void 0;
11908
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
11909
+ /**
11910
+ * @internal
11911
+ */
11912
+ function pruneUnselectedModel(model) {
11913
+ pruneUnselectedModelInternal(model, false /* isSelectionAfterElement */);
11914
+ unwrap(model);
11915
+ }
11916
+ exports.pruneUnselectedModel = pruneUnselectedModel;
11917
+ function pruneUnselectedModelInternal(model, isSelectionAfterElement) {
11918
+ var e_1, _a, _b;
11919
+ for (var index = model.blocks.length - 1; index >= 0; index--) {
11920
+ var block = model.blocks[index];
11921
+ switch (block.blockType) {
11922
+ case 'BlockGroup':
11923
+ pruneUnselectedModelInternal(block, isSelectionAfterElement);
11924
+ if (block.blockGroupType == 'General'
11925
+ ? block.blocks.length == 0 && !block.isSelected
11926
+ : block.blocks.length == 0) {
11927
+ model.blocks.splice(index, 1);
11928
+ }
11929
+ break;
11930
+ case 'Divider':
11931
+ case 'Entity':
11932
+ if (!block.isSelected) {
11933
+ model.blocks.splice(index, 1);
11934
+ }
11935
+ else {
11936
+ isSelectionAfterElement = true;
11937
+ }
11938
+ break;
11939
+ case 'Paragraph':
11940
+ var newSegments = [];
11941
+ try {
11942
+ for (var _c = (e_1 = void 0, (0, tslib_1.__values)(block.segments)), _d = _c.next(); !_d.done; _d = _c.next()) {
11943
+ var segment = _d.value;
11944
+ if (segment.segmentType == 'General') {
11945
+ pruneUnselectedModel(segment);
11946
+ if (segment.blocks.length > 0 || segment.isSelected) {
11947
+ newSegments.push(segment);
11948
+ }
11949
+ }
11950
+ else if (segment.isSelected && segment.segmentType != 'SelectionMarker') {
11951
+ newSegments.push(segment);
11952
+ }
11953
+ }
11954
+ }
11955
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
11956
+ finally {
11957
+ try {
11958
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
11959
+ }
11960
+ finally { if (e_1) throw e_1.error; }
11961
+ }
11962
+ block.segments = newSegments;
11963
+ if (block.segments.length == 0) {
11964
+ model.blocks.splice(index, 1);
11965
+ }
11966
+ else {
11967
+ isSelectionAfterElement = true;
11968
+ }
11969
+ break;
11970
+ case 'Table':
11971
+ var filteredRows = [];
11972
+ for (var i = 0; i < block.rows.length; i++) {
11973
+ var row = block.rows[i];
11974
+ for (var j = 0; j < row.cells.length; j++) {
11975
+ var cell = row.cells[j];
11976
+ if (!cell.isSelected) {
11977
+ pruneUnselectedModelInternal(cell, isSelectionAfterElement);
11978
+ }
11979
+ else {
11980
+ isSelectionAfterElement = true;
11981
+ }
11982
+ }
11983
+ var newCells = [];
11984
+ for (var k = 0; k < row.cells.length; k++) {
11985
+ var cell = row.cells[k];
11986
+ if (cell.isSelected || cell.blocks.length > 0) {
11987
+ newCells.push(cell);
11988
+ }
11989
+ }
11990
+ row.cells = newCells;
11991
+ if (row.cells.length > 0) {
11992
+ filteredRows.push(row);
11993
+ }
11994
+ }
11995
+ if (!isSelectionAfterElement &&
11996
+ filteredRows.length == 1 &&
11997
+ filteredRows[0].cells.length == 1 &&
11998
+ !filteredRows[0].cells[0].isSelected) {
11999
+ var cell = filteredRows[0].cells[0];
12000
+ (_b = model.blocks).splice.apply(_b, (0, tslib_1.__spreadArray)([index, 1], (0, tslib_1.__read)(cell.blocks), false));
12001
+ }
12002
+ else if (filteredRows.length == 0) {
12003
+ model.blocks.splice(index, 1);
12004
+ }
12005
+ else {
12006
+ block.rows = filteredRows;
12007
+ }
12008
+ break;
12009
+ }
12010
+ }
12011
+ return isSelectionAfterElement;
12012
+ }
12013
+ function unwrap(model) {
12014
+ var block = model.blocks[0];
12015
+ if (model.blocks.length == 1) {
12016
+ while (block.blockType == 'BlockGroup') {
12017
+ model.blocks = block.blocks;
12018
+ block = model.blocks[0];
12019
+ if (model.blocks.length > 1) {
12020
+ return;
12021
+ }
12022
+ }
12023
+ if (block.blockType == 'Paragraph') {
12024
+ block.isImplicit = true;
12025
+ block.format = {};
12026
+ inheritSegmentFormatToChildren(block);
12027
+ }
12028
+ }
12029
+ }
12030
+ function inheritSegmentFormatToChildren(parent) {
12031
+ var value = parent.segmentFormat;
12032
+ if (value !== undefined) {
12033
+ for (var index = 0; index < parent.segments.length; index++) {
12034
+ var segment = parent.segments[index];
12035
+ segment.format = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, parent.segmentFormat), segment.format);
12036
+ }
12037
+ }
12038
+ }
12039
+
12040
+
11781
12041
  /***/ }),
11782
12042
 
11783
12043
  /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/createEditorCorePlugins.ts":
@@ -12546,17 +12806,10 @@ function handleDelimiterKeyDownEvent(editor, event) {
12546
12806
  var key = rawEvent.key;
12547
12807
  switch (key) {
12548
12808
  case 'Enter':
12549
- if (range.collapsed) {
12550
- handleInputOnDelimiter(editor, range, getFocusedElement(selection), rawEvent);
12551
- }
12552
- else {
12553
- var helper = editor.getDOMHelper();
12554
- var entity = (0, roosterjs_content_model_dom_1.findClosestEntityWrapper)(range.startContainer, helper);
12555
- if (entity &&
12556
- (0, roosterjs_content_model_dom_1.isNodeOfType)(entity, 'ELEMENT_NODE') &&
12557
- helper.isNodeInEditor(entity)) {
12558
- triggerEntityEventOnEnter(editor, entity, rawEvent);
12559
- }
12809
+ var helper = editor.getDOMHelper();
12810
+ var entity = (0, roosterjs_content_model_dom_1.findClosestEntityWrapper)(range.startContainer, helper);
12811
+ if (entity && (0, roosterjs_content_model_dom_1.isNodeOfType)(entity, 'ELEMENT_NODE') && helper.isNodeInEditor(entity)) {
12812
+ triggerEntityEventOnEnter(editor, entity, rawEvent);
12560
12813
  }
12561
12814
  break;
12562
12815
  case 'ArrowLeft':
@@ -12795,6 +13048,10 @@ var FormatPlugin = /** @class */ (function () {
12795
13048
  defaultFormat: (0, tslib_1.__assign)({}, option.defaultSegmentFormat),
12796
13049
  pendingFormat: null,
12797
13050
  };
13051
+ var defaultFormat = this.state.defaultFormat;
13052
+ if (defaultFormat.fontFamily) {
13053
+ defaultFormat.fontFamily = (0, roosterjs_content_model_dom_1.normalizeFontFamily)(defaultFormat.fontFamily);
13054
+ }
12798
13055
  this.defaultFormatKeys = new Set();
12799
13056
  (0, roosterjs_content_model_dom_1.getObjectKeys)(DefaultStyleKeyMap).forEach(function (key) {
12800
13057
  if (_this.state.defaultFormat[key]) {
@@ -12816,6 +13073,7 @@ var FormatPlugin = /** @class */ (function () {
12816
13073
  */
12817
13074
  FormatPlugin.prototype.initialize = function (editor) {
12818
13075
  this.editor = editor;
13076
+ this.state.defaultFormat = (0, roosterjs_content_model_dom_1.normalizeSegmentFormat)(this.state.defaultFormat, editor.getEnvironment());
12819
13077
  };
12820
13078
  /**
12821
13079
  * The last method that editor will call to a plugin before it is disposed.
@@ -13492,7 +13750,7 @@ var SelectionPlugin = /** @class */ (function () {
13492
13750
  }
13493
13751
  };
13494
13752
  SelectionPlugin.prototype.onMouseDown = function (editor, rawEvent) {
13495
- var _a;
13753
+ var _a, _b, _c;
13496
13754
  var selection = editor.getDOMSelection();
13497
13755
  var image;
13498
13756
  // Image selection
@@ -13531,6 +13789,7 @@ var SelectionPlugin = /** @class */ (function () {
13531
13789
  rawEvent.preventDefault();
13532
13790
  }
13533
13791
  }
13792
+ (_c = (_b = this.state).mouseDisposer) === null || _c === void 0 ? void 0 : _c.call(_b);
13534
13793
  this.state.mouseDisposer = editor.attachDomEvent({
13535
13794
  mousemove: {
13536
13795
  beforeDispatch: this.onMouseMove,
@@ -13543,7 +13802,7 @@ var SelectionPlugin = /** @class */ (function () {
13543
13802
  };
13544
13803
  SelectionPlugin.prototype.onKeyDown = function (editor, rawEvent) {
13545
13804
  var _this = this;
13546
- var _a;
13805
+ var _a, _b;
13547
13806
  var key = rawEvent.key;
13548
13807
  var selection = editor.getDOMSelection();
13549
13808
  var win = editor.getDocument().defaultView;
@@ -13586,7 +13845,25 @@ var SelectionPlugin = /** @class */ (function () {
13586
13845
  }
13587
13846
  break;
13588
13847
  case 'table':
13589
- if ((_a = this.state.tableSelection) === null || _a === void 0 ? void 0 : _a.lastCo) {
13848
+ // After a content change event is handled tableSelection state is reset to null
13849
+ // Since we have table selection from DOMSelection, we can use it to re-create the tableSelection state
13850
+ if (this.state.tableSelection == null) {
13851
+ var table = selection.table, firstRow = selection.firstRow, firstColumn = selection.firstColumn, lastRow = selection.lastRow, lastColumn = selection.lastColumn;
13852
+ var parsedTable = (0, roosterjs_content_model_dom_1.parseTableCells)(table);
13853
+ if (parsedTable) {
13854
+ var firstCo = { row: firstRow, col: firstColumn };
13855
+ var lastCo = { row: lastRow, col: lastColumn };
13856
+ // Create the tableSelection with current table info
13857
+ this.state.tableSelection = {
13858
+ table: table,
13859
+ parsedTable: parsedTable,
13860
+ firstCo: firstCo,
13861
+ lastCo: lastCo,
13862
+ startNode: ((_a = (0, findTableCellElement_1.findTableCellElement)(parsedTable, firstCo)) === null || _a === void 0 ? void 0 : _a.cell) || table,
13863
+ };
13864
+ }
13865
+ }
13866
+ if ((_b = this.state.tableSelection) === null || _b === void 0 ? void 0 : _b.lastCo) {
13590
13867
  var shiftKey = rawEvent.shiftKey, key_1 = rawEvent.key;
13591
13868
  if (shiftKey && (key_1 == Left || key_1 == Right)) {
13592
13869
  var isRtl = (win === null || win === void 0 ? void 0 : win.getComputedStyle(this.state.tableSelection.table).direction) ==
@@ -14379,7 +14656,7 @@ var Editor = /** @class */ (function () {
14379
14656
  return result;
14380
14657
  };
14381
14658
  this.core = (0, createEditorCore_1.createEditorCore)(contentDiv, options);
14382
- var initialModel = (_a = options.initialModel) !== null && _a !== void 0 ? _a : (0, roosterjs_content_model_dom_1.createEmptyModel)(options.defaultSegmentFormat);
14659
+ var initialModel = (_a = options.initialModel) !== null && _a !== void 0 ? _a : (0, roosterjs_content_model_dom_1.createEmptyModel)(this.core.format.defaultFormat);
14383
14660
  this.core.api.setContentModel(this.core, initialModel, { ignoreSelection: true }, undefined /*onNodeCreated*/, true /*isInitializing*/);
14384
14661
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
14385
14662
  }
@@ -15437,6 +15714,7 @@ function trustedHTMLHandlerToDOMCreator(trustedHTMLHandler) {
15437
15714
  var handler = trustedHTMLHandler || exports.defaultTrustHtmlHandler;
15438
15715
  return {
15439
15716
  htmlToDOM: function (html) { return new DOMParser().parseFromString(handler(html), 'text/html'); },
15717
+ isBypassed: !trustedHTMLHandler,
15440
15718
  };
15441
15719
  }
15442
15720
 
@@ -15705,10 +15983,22 @@ exports.BulletListType = {
15705
15983
  * Bullet type circle
15706
15984
  */
15707
15985
  Circle: 9,
15986
+ /**
15987
+ * Box Shadow bullet type
15988
+ */
15989
+ BoxShadow: 10,
15990
+ /**
15991
+ * Rhombus with a cross inside
15992
+ */
15993
+ Xrhombus: 11,
15994
+ /**
15995
+ * Check mark bullet type
15996
+ */
15997
+ CheckMark: 12,
15708
15998
  /**
15709
15999
  * Maximum value of the enum
15710
16000
  */
15711
- Max: 9,
16001
+ Max: 12,
15712
16002
  };
15713
16003
 
15714
16004
 
@@ -16081,7 +16371,7 @@ var BulletListType_1 = __webpack_require__(/*! ./BulletListType */ "./packages/r
16081
16371
  */
16082
16372
  exports.UnorderedListStyleMap = (_a = {},
16083
16373
  _a[BulletListType_1.BulletListType.Disc] = 'disc',
16084
- _a[BulletListType_1.BulletListType.Square] = '"∎ "',
16374
+ _a[BulletListType_1.BulletListType.Square] = 'square',
16085
16375
  _a[BulletListType_1.BulletListType.Circle] = 'circle',
16086
16376
  _a[BulletListType_1.BulletListType.Dash] = '"- "',
16087
16377
  _a[BulletListType_1.BulletListType.LongArrow] = '"➔ "',
@@ -16089,6 +16379,9 @@ exports.UnorderedListStyleMap = (_a = {},
16089
16379
  _a[BulletListType_1.BulletListType.ShortArrow] = '"➢ "',
16090
16380
  _a[BulletListType_1.BulletListType.UnfilledArrow] = '"➪ "',
16091
16381
  _a[BulletListType_1.BulletListType.Hyphen] = '"— "',
16382
+ _a[BulletListType_1.BulletListType.CheckMark] = '"✔ "',
16383
+ _a[BulletListType_1.BulletListType.Xrhombus] = '"❖ "',
16384
+ _a[BulletListType_1.BulletListType.BoxShadow] = '"❑ "',
16092
16385
  _a);
16093
16386
 
16094
16387
 
@@ -16977,6 +17270,7 @@ var createParagraph_1 = __webpack_require__(/*! ../../modelApi/creators/createPa
16977
17270
  var formatContainerProcessor_1 = __webpack_require__(/*! ./formatContainerProcessor */ "./packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts");
16978
17271
  var getDefaultStyle_1 = __webpack_require__(/*! ../utils/getDefaultStyle */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/getDefaultStyle.ts");
16979
17272
  var isBlockElement_1 = __webpack_require__(/*! ../utils/isBlockElement */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/isBlockElement.ts");
17273
+ var entityUtils_1 = __webpack_require__(/*! ../../domUtils/entityUtils */ "./packages/roosterjs-content-model-dom/lib/domUtils/entityUtils.ts");
16980
17274
  var parseFormat_1 = __webpack_require__(/*! ../utils/parseFormat */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/parseFormat.ts");
16981
17275
  var stackFormat_1 = __webpack_require__(/*! ../utils/stackFormat */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/stackFormat.ts");
16982
17276
  var FormatContainerTriggerStyles = [
@@ -16997,6 +17291,7 @@ var FormatContainerTriggerStyles = [
16997
17291
  'minWidth',
16998
17292
  'minHeight',
16999
17293
  ];
17294
+ var FormatContainerTriggerAttributes = ['id'];
17000
17295
  var ByPassFormatContainerTags = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P', 'A'];
17001
17296
  var SegmentDecoratorTags = ['A', 'CODE'];
17002
17297
  /**
@@ -17008,6 +17303,9 @@ var knownElementProcessor = function (group, element, context) {
17008
17303
  shouldUseFormatContainer(element, context)) {
17009
17304
  (0, formatContainerProcessor_1.formatContainerProcessor)(group, element, context);
17010
17305
  }
17306
+ else if ((0, entityUtils_1.isBlockEntityContainer)(element)) {
17307
+ context.elementProcessors.child(group, element, context);
17308
+ }
17011
17309
  else if (isBlock) {
17012
17310
  var decorator = context.blockDecorator.tagName ? context.blockDecorator : undefined;
17013
17311
  var isSegmentDecorator = SegmentDecoratorTags.indexOf(element.tagName) >= 0;
@@ -17050,7 +17348,8 @@ function shouldUseFormatContainer(element, context) {
17050
17348
  }
17051
17349
  // For block element with positive value of border width or top/bottom margin/padding,
17052
17350
  // we need to use format container
17053
- if (FormatContainerTriggerStyles.some(function (key) { return parseInt(style[key] || defaultStyle[key] || '') > 0; })) {
17351
+ if (FormatContainerTriggerStyles.some(function (key) { return parseInt(style[key] || defaultStyle[key] || '') > 0; }) ||
17352
+ FormatContainerTriggerAttributes.some(function (attr) { return element.hasAttribute(attr); })) {
17054
17353
  return true;
17055
17354
  }
17056
17355
  // For margin left/right with value "auto", we need to use format container
@@ -17336,6 +17635,7 @@ var tableProcessor = function (group, tableElement, context) {
17336
17635
  }
17337
17636
  (0, parseFormat_1.parseFormat)(tr, context.formatParsers.block, context.blockFormat, context);
17338
17637
  (0, parseFormat_1.parseFormat)(tr, context.formatParsers.segmentOnBlock, context.segmentFormat, context);
17638
+ tableRow.height = parseInt(tr.style.height) || 0;
17339
17639
  var _loop_2 = function (sourceCol, targetCol) {
17340
17640
  for (; tableRow.cells[targetCol]; targetCol++) { }
17341
17641
  var td = tr.cells[sourceCol];
@@ -18407,6 +18707,35 @@ function setHiddenProperty(node, key, value) {
18407
18707
  exports.setHiddenProperty = setHiddenProperty;
18408
18708
 
18409
18709
 
18710
+ /***/ }),
18711
+
18712
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/imageState.ts":
18713
+ /*!******************************************************************************************!*\
18714
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/imageState.ts ***!
18715
+ \******************************************************************************************/
18716
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18717
+
18718
+ "use strict";
18719
+
18720
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
18721
+ exports.setImageState = exports.getImageState = void 0;
18722
+ var hiddenProperty_1 = __webpack_require__(/*! ./hiddenProperty */ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/hiddenProperty.ts");
18723
+ /**
18724
+ * Get image state from element. This is used to store a image state.
18725
+ */
18726
+ function getImageState(element) {
18727
+ return (0, hiddenProperty_1.getHiddenProperty)(element, 'imageState');
18728
+ }
18729
+ exports.getImageState = getImageState;
18730
+ /**
18731
+ * Set image state to element. This is used to store a image state.
18732
+ */
18733
+ function setImageState(element, marker) {
18734
+ (0, hiddenProperty_1.setHiddenProperty)(element, 'imageState', marker);
18735
+ }
18736
+ exports.setImageState = setImageState;
18737
+
18738
+
18410
18739
  /***/ }),
18411
18740
 
18412
18741
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/paragraphMarker.ts":
@@ -18929,6 +19258,56 @@ function isBold(boldStyle) {
18929
19258
  exports.isBold = isBold;
18930
19259
 
18931
19260
 
19261
+ /***/ }),
19262
+
19263
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/normalizeFontFamily.ts":
19264
+ /*!****************************************************************************************!*\
19265
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/style/normalizeFontFamily.ts ***!
19266
+ \****************************************************************************************/
19267
+ /***/ ((__unused_webpack_module, exports) => {
19268
+
19269
+ "use strict";
19270
+
19271
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
19272
+ exports.normalizeFontFamily = void 0;
19273
+ /**
19274
+ * Normalize font family string to a standard format
19275
+ * Add quotes around font family names that contain non-alphanumeric/dash characters
19276
+ * @param fontFamily The font family string to normalize
19277
+ * @returns The normalized font family string
19278
+ */
19279
+ function normalizeFontFamily(fontFamily) {
19280
+ var existingQuotedFontsRegex = /".*?"/g;
19281
+ var match = existingQuotedFontsRegex.exec(fontFamily);
19282
+ var start = 0;
19283
+ var result = [];
19284
+ while (match) {
19285
+ process(fontFamily, result, start, match.index);
19286
+ start = match.index + match[0].length;
19287
+ result.push(match[0]);
19288
+ match = existingQuotedFontsRegex.exec(fontFamily);
19289
+ }
19290
+ process(fontFamily, result, start, fontFamily.length);
19291
+ return result.join(', ');
19292
+ }
19293
+ exports.normalizeFontFamily = normalizeFontFamily;
19294
+ function process(fontFamily, result, start, end) {
19295
+ var families = fontFamily.substring(start, end).split(',');
19296
+ families.forEach(function (family) {
19297
+ family = family.trim();
19298
+ if (family) {
19299
+ // Check if the family name contains non-alphanumeric characters
19300
+ if (/[^a-zA-Z0-9\-]/.test(family)) {
19301
+ result.push("\"" + family + "\"");
19302
+ }
19303
+ else {
19304
+ result.push(family);
19305
+ }
19306
+ }
19307
+ });
19308
+ }
19309
+
19310
+
18932
19311
  /***/ }),
18933
19312
 
18934
19313
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/style/transformColor.ts":
@@ -19949,6 +20328,7 @@ var fontSizeFormatHandler_1 = __webpack_require__(/*! ./segment/fontSizeFormatHa
19949
20328
  var getObjectKeys_1 = __webpack_require__(/*! ../domUtils/getObjectKeys */ "./packages/roosterjs-content-model-dom/lib/domUtils/getObjectKeys.ts");
19950
20329
  var htmlAlignFormatHandler_1 = __webpack_require__(/*! ./block/htmlAlignFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/block/htmlAlignFormatHandler.ts");
19951
20330
  var idFormatHandler_1 = __webpack_require__(/*! ./common/idFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/common/idFormatHandler.ts");
20331
+ var imageStateFormatHandler_1 = __webpack_require__(/*! ./segment/imageStateFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/imageStateFormatHandler.ts");
19952
20332
  var italicFormatHandler_1 = __webpack_require__(/*! ./segment/italicFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/italicFormatHandler.ts");
19953
20333
  var letterSpacingFormatHandler_1 = __webpack_require__(/*! ./segment/letterSpacingFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/letterSpacingFormatHandler.ts");
19954
20334
  var lineHeightFormatHandler_1 = __webpack_require__(/*! ./block/lineHeightFormatHandler */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/block/lineHeightFormatHandler.ts");
@@ -19988,6 +20368,7 @@ var defaultFormatHandlerMap = {
19988
20368
  entity: entityFormatHandler_1.entityFormatHandler,
19989
20369
  htmlAlign: htmlAlignFormatHandler_1.htmlAlignFormatHandler,
19990
20370
  id: idFormatHandler_1.idFormatHandler,
20371
+ imageState: imageStateFormatHandler_1.imageStateFormatHandler,
19991
20372
  italic: italicFormatHandler_1.italicFormatHandler,
19992
20373
  letterSpacing: letterSpacingFormatHandler_1.letterSpacingFormatHandler,
19993
20374
  lineHeight: lineHeightFormatHandler_1.lineHeightFormatHandler,
@@ -20100,6 +20481,7 @@ exports.defaultFormatKeysPerCategory = {
20100
20481
  'display',
20101
20482
  'float',
20102
20483
  'verticalAlign',
20484
+ 'imageState',
20103
20485
  ],
20104
20486
  link: [
20105
20487
  'link',
@@ -20118,7 +20500,7 @@ exports.defaultFormatKeysPerCategory = {
20118
20500
  code: ['fontFamily', 'display'],
20119
20501
  dataset: ['dataset'],
20120
20502
  divider: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedBlockFormats), false), (0, tslib_1.__read)(sharedContainerFormats), false), ['display', 'size', 'htmlAlign'], false),
20121
- container: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedContainerFormats), false), ['htmlAlign', 'size', 'display'], false),
20503
+ container: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(sharedContainerFormats), false), ['htmlAlign', 'size', 'display', 'id'], false),
20122
20504
  entity: ['entity'],
20123
20505
  general: ['textColor', 'backgroundColor'], // General model still need to do color transformation in dark mode
20124
20506
  };
@@ -20477,6 +20859,37 @@ function normalizeFontSize(fontSize, contextFont, context) {
20477
20859
  }
20478
20860
 
20479
20861
 
20862
+ /***/ }),
20863
+
20864
+ /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/imageStateFormatHandler.ts":
20865
+ /*!****************************************************************************************************!*\
20866
+ !*** ./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/imageStateFormatHandler.ts ***!
20867
+ \****************************************************************************************************/
20868
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20869
+
20870
+ "use strict";
20871
+
20872
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20873
+ exports.imageStateFormatHandler = void 0;
20874
+ var imageState_1 = __webpack_require__(/*! ../../domUtils/hiddenProperties/imageState */ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/imageState.ts");
20875
+ /**
20876
+ * @internal
20877
+ */
20878
+ exports.imageStateFormatHandler = {
20879
+ parse: function (format, element) {
20880
+ var marker = (0, imageState_1.getImageState)(element);
20881
+ if (marker) {
20882
+ format.imageState = marker;
20883
+ }
20884
+ },
20885
+ apply: function (format, element) {
20886
+ if (format.imageState) {
20887
+ (0, imageState_1.setImageState)(element, format.imageState);
20888
+ }
20889
+ },
20890
+ };
20891
+
20892
+
20480
20893
  /***/ }),
20481
20894
 
20482
20895
  /***/ "./packages/roosterjs-content-model-dom/lib/formatHandlers/segment/italicFormatHandler.ts":
@@ -21267,9 +21680,9 @@ exports.shouldSetValue = shouldSetValue;
21267
21680
 
21268
21681
  Object.defineProperty(exports, "__esModule", ({ value: true }));
21269
21682
  exports.createParagraphDecorator = exports.createContentModelDocument = exports.createImage = exports.createText = exports.createTableCell = exports.createTable = exports.createSelectionMarker = exports.createParagraph = exports.createFormatContainer = exports.createListItem = exports.createBr = exports.isLinkUndeletable = exports.setLinkUndeletable = exports.normalizeRect = exports.isWhiteSpacePreserved = exports.reuseCachedElement = exports.findClosestBlockEntityContainer = exports.isBlockEntityContainer = exports.isEntityDelimiter = exports.addDelimiters = exports.generateEntityClassNames = exports.parseEntityFormat = exports.getAllEntityWrappers = exports.findClosestEntityWrapper = exports.isEntityElement = exports.unwrap = exports.wrap = exports.wrapAllChildNodes = exports.moveChildNodes = exports.toArray = exports.getSafeIdSelector = exports.getObjectKeys = exports.isElementOfType = exports.isNodeOfType = exports.hasMetadata = exports.getMetadata = exports.updateMetadata = exports.buildSelectionMarker = exports.isBlockElement = exports.areSameFormats = exports.parseFormat = exports.getRegularSelectionOffsets = exports.tableProcessor = exports.entityProcessor = exports.processChildNode = exports.handleRegularSelection = exports.childProcessor = exports.contentModelToText = exports.contentModelToDom = exports.domToContentModel = void 0;
21270
- exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.isCursorMovingKey = exports.isModifierKey = exports.isCharacterValue = exports.getDOMInsertPointRect = exports.getSelectionRootNode = exports.isBold = exports.createModelToDomConfig = exports.createModelToDomContextWithConfig = exports.createModelToDomContext = exports.createDomToModelConfig = exports.createDomToModelContextWithConfig = exports.createDomToModelContext = exports.defaultGenerateColorKey = exports.parseColor = exports.setColor = exports.getColor = exports.DeprecatedColors = exports.BorderKeys = exports.parseValueWithUnit = exports.getAutoListStyleType = exports.getOrderedListNumberStr = exports.setParagraphNotImplicit = 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 = void 0;
21271
- 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 = 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.getParagraphMarker = exports.setParagraphMarker = exports.cacheGetEventData = exports.extractClipboardItems = exports.transformColor = exports.readFile = void 0;
21272
- exports.EmptySegmentFormat = void 0;
21683
+ exports.isCursorMovingKey = exports.isModifierKey = exports.isCharacterValue = exports.getDOMInsertPointRect = exports.getSelectionRootNode = exports.isBold = exports.createModelToDomConfig = exports.createModelToDomContextWithConfig = exports.createModelToDomContext = exports.createDomToModelConfig = exports.createDomToModelContextWithConfig = exports.createDomToModelContext = exports.defaultGenerateColorKey = exports.parseColor = exports.setColor = exports.getColor = exports.DeprecatedColors = exports.BorderKeys = exports.parseValueWithUnit = exports.getAutoListStyleType = exports.getOrderedListNumberStr = exports.ParagraphFormats = exports.ListFormatsToMove = exports.ListFormatsToKeep = exports.ListFormats = exports.copyFormat = exports.setParagraphNotImplicit = exports.normalizeSegmentFormat = exports.mergeTextSegments = exports.normalizeSingleSegment = exports.isEmpty = exports.addSegment = exports.unwrapBlock = exports.isGeneralSegment = exports.normalizeContentModel = exports.normalizeParagraph = exports.addTextSegment = exports.addLink = exports.addCode = exports.addBlock = exports.mutateSegment = exports.mutateSegments = exports.mutateBlock = exports.createTableRow = exports.createEmptyModel = exports.createListLevel = exports.createDivider = exports.createEntity = exports.createGeneralBlock = exports.createGeneralSegment = void 0;
21684
+ exports.getTableMetadata = exports.updateTableMetadata = exports.getTableCellMetadata = exports.updateTableCellMetadata = exports.getImageMetadata = exports.updateImageMetadata = exports.runEditSteps = exports.getClosestAncestorBlockGroupIndex = exports.getSegmentTextFormat = exports.getListStyleTypeFromString = exports.retrieveModelFormatState = exports.setTableCellBackgroundColor = exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = exports.MIN_ALLOWED_TABLE_CELL_WIDTH = exports.normalizeTable = exports.setFirstColumnFormatBorders = exports.applyTableFormat = exports.deleteBlock = exports.deleteSegment = exports.deleteSelection = exports.mergeModel = exports.cloneModel = exports.setSelection = exports.hasSelectionInBlockGroup = exports.hasSelectionInSegment = exports.hasSelectionInBlock = exports.getSelectedCells = exports.getSelectedSegmentsAndParagraphs = exports.getSelectedSegments = exports.getSelectedParagraphs = exports.getOperationalBlocks = exports.getFirstSelectedTable = exports.getFirstSelectedListItem = exports.iterateSelections = exports.isBlockGroupOfType = exports.getImageState = exports.setImageState = exports.getParagraphMarker = exports.setParagraphMarker = exports.cacheGetEventData = exports.extractClipboardItems = exports.normalizeFontFamily = exports.transformColor = exports.readFile = exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = void 0;
21685
+ exports.EmptySegmentFormat = exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = void 0;
21273
21686
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
21274
21687
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
21275
21688
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -21398,8 +21811,16 @@ var normalizeSegment_1 = __webpack_require__(/*! ./modelApi/common/normalizeSegm
21398
21811
  Object.defineProperty(exports, "normalizeSingleSegment", ({ enumerable: true, get: function () { return normalizeSegment_1.normalizeSingleSegment; } }));
21399
21812
  var mergeTextSegments_1 = __webpack_require__(/*! ./modelApi/common/mergeTextSegments */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mergeTextSegments.ts");
21400
21813
  Object.defineProperty(exports, "mergeTextSegments", ({ enumerable: true, get: function () { return mergeTextSegments_1.mergeTextSegments; } }));
21814
+ var normalizeSegmentFormat_1 = __webpack_require__(/*! ./modelApi/common/normalizeSegmentFormat */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeSegmentFormat.ts");
21815
+ Object.defineProperty(exports, "normalizeSegmentFormat", ({ enumerable: true, get: function () { return normalizeSegmentFormat_1.normalizeSegmentFormat; } }));
21401
21816
  var setParagraphNotImplicit_1 = __webpack_require__(/*! ./modelApi/block/setParagraphNotImplicit */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/setParagraphNotImplicit.ts");
21402
21817
  Object.defineProperty(exports, "setParagraphNotImplicit", ({ enumerable: true, get: function () { return setParagraphNotImplicit_1.setParagraphNotImplicit; } }));
21818
+ var copyFormat_1 = __webpack_require__(/*! ./modelApi/block/copyFormat */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/copyFormat.ts");
21819
+ Object.defineProperty(exports, "copyFormat", ({ enumerable: true, get: function () { return copyFormat_1.copyFormat; } }));
21820
+ Object.defineProperty(exports, "ListFormats", ({ enumerable: true, get: function () { return copyFormat_1.ListFormats; } }));
21821
+ Object.defineProperty(exports, "ListFormatsToKeep", ({ enumerable: true, get: function () { return copyFormat_1.ListFormatsToKeep; } }));
21822
+ Object.defineProperty(exports, "ListFormatsToMove", ({ enumerable: true, get: function () { return copyFormat_1.ListFormatsToMove; } }));
21823
+ Object.defineProperty(exports, "ParagraphFormats", ({ enumerable: true, get: function () { return copyFormat_1.ParagraphFormats; } }));
21403
21824
  var getOrderedListNumberStr_1 = __webpack_require__(/*! ./modelApi/list/getOrderedListNumberStr */ "./packages/roosterjs-content-model-dom/lib/modelApi/list/getOrderedListNumberStr.ts");
21404
21825
  Object.defineProperty(exports, "getOrderedListNumberStr", ({ enumerable: true, get: function () { return getOrderedListNumberStr_1.getOrderedListNumberStr; } }));
21405
21826
  var getAutoListStyleType_1 = __webpack_require__(/*! ./modelApi/list/getAutoListStyleType */ "./packages/roosterjs-content-model-dom/lib/modelApi/list/getAutoListStyleType.ts");
@@ -21445,6 +21866,8 @@ var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roos
21445
21866
  Object.defineProperty(exports, "readFile", ({ enumerable: true, get: function () { return readFile_1.readFile; } }));
21446
21867
  var transformColor_1 = __webpack_require__(/*! ./domUtils/style/transformColor */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/transformColor.ts");
21447
21868
  Object.defineProperty(exports, "transformColor", ({ enumerable: true, get: function () { return transformColor_1.transformColor; } }));
21869
+ var normalizeFontFamily_1 = __webpack_require__(/*! ./domUtils/style/normalizeFontFamily */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/normalizeFontFamily.ts");
21870
+ Object.defineProperty(exports, "normalizeFontFamily", ({ enumerable: true, get: function () { return normalizeFontFamily_1.normalizeFontFamily; } }));
21448
21871
  var extractClipboardItems_1 = __webpack_require__(/*! ./domUtils/event/extractClipboardItems */ "./packages/roosterjs-content-model-dom/lib/domUtils/event/extractClipboardItems.ts");
21449
21872
  Object.defineProperty(exports, "extractClipboardItems", ({ enumerable: true, get: function () { return extractClipboardItems_1.extractClipboardItems; } }));
21450
21873
  var cacheGetEventData_1 = __webpack_require__(/*! ./domUtils/event/cacheGetEventData */ "./packages/roosterjs-content-model-dom/lib/domUtils/event/cacheGetEventData.ts");
@@ -21452,6 +21875,9 @@ Object.defineProperty(exports, "cacheGetEventData", ({ enumerable: true, get: fu
21452
21875
  var paragraphMarker_1 = __webpack_require__(/*! ./domUtils/hiddenProperties/paragraphMarker */ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/paragraphMarker.ts");
21453
21876
  Object.defineProperty(exports, "setParagraphMarker", ({ enumerable: true, get: function () { return paragraphMarker_1.setParagraphMarker; } }));
21454
21877
  Object.defineProperty(exports, "getParagraphMarker", ({ enumerable: true, get: function () { return paragraphMarker_1.getParagraphMarker; } }));
21878
+ var imageState_1 = __webpack_require__(/*! ./domUtils/hiddenProperties/imageState */ "./packages/roosterjs-content-model-dom/lib/domUtils/hiddenProperties/imageState.ts");
21879
+ Object.defineProperty(exports, "setImageState", ({ enumerable: true, get: function () { return imageState_1.setImageState; } }));
21880
+ Object.defineProperty(exports, "getImageState", ({ enumerable: true, get: function () { return imageState_1.getImageState; } }));
21455
21881
  var isBlockGroupOfType_1 = __webpack_require__(/*! ./modelApi/typeCheck/isBlockGroupOfType */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isBlockGroupOfType.ts");
21456
21882
  Object.defineProperty(exports, "isBlockGroupOfType", ({ enumerable: true, get: function () { return isBlockGroupOfType_1.isBlockGroupOfType; } }));
21457
21883
  var iterateSelections_1 = __webpack_require__(/*! ./modelApi/selection/iterateSelections */ "./packages/roosterjs-content-model-dom/lib/modelApi/selection/iterateSelections.ts");
@@ -21531,6 +21957,92 @@ var EmptySegmentFormat_1 = __webpack_require__(/*! ./constants/EmptySegmentForma
21531
21957
  Object.defineProperty(exports, "EmptySegmentFormat", ({ enumerable: true, get: function () { return EmptySegmentFormat_1.EmptySegmentFormat; } }));
21532
21958
 
21533
21959
 
21960
+ /***/ }),
21961
+
21962
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/block/copyFormat.ts":
21963
+ /*!*******************************************************************************!*\
21964
+ !*** ./packages/roosterjs-content-model-dom/lib/modelApi/block/copyFormat.ts ***!
21965
+ \*******************************************************************************/
21966
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
21967
+
21968
+ "use strict";
21969
+
21970
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
21971
+ exports.copyFormat = exports.ParagraphFormats = exports.ListFormats = exports.ListFormatsToKeep = exports.ListFormatsToMove = void 0;
21972
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
21973
+ /**
21974
+ * When copy format between list and paragraph, these are the formats that we can copy and remove from the source
21975
+ */
21976
+ exports.ListFormatsToMove = [
21977
+ 'marginRight',
21978
+ 'marginLeft',
21979
+ 'paddingRight',
21980
+ 'paddingLeft',
21981
+ ];
21982
+ /**
21983
+ * When copy format between list and paragraph, these are the formats that we can copy and keep in the source
21984
+ */
21985
+ exports.ListFormatsToKeep = [
21986
+ 'direction',
21987
+ 'textAlign',
21988
+ 'htmlAlign',
21989
+ ];
21990
+ /**
21991
+ * When copy format from one block to another, these are all the formats that we can copy
21992
+ */
21993
+ exports.ListFormats = exports.ListFormatsToMove.concat(exports.ListFormatsToKeep);
21994
+ /**
21995
+ * When copy format between paragraphs, these are the formats that we can copy
21996
+ */
21997
+ exports.ParagraphFormats = [
21998
+ 'backgroundColor',
21999
+ 'direction',
22000
+ 'textAlign',
22001
+ 'htmlAlign',
22002
+ 'lineHeight',
22003
+ 'textIndent',
22004
+ 'marginTop',
22005
+ 'marginRight',
22006
+ 'marginBottom',
22007
+ 'marginLeft',
22008
+ 'paddingTop',
22009
+ 'paddingRight',
22010
+ 'paddingBottom',
22011
+ 'paddingLeft',
22012
+ ];
22013
+ /**
22014
+ * Copy formats from source to target with only specified keys
22015
+ * @param targetFormat The format object to copy format to
22016
+ * @param sourceFormat The format object to copy format from
22017
+ * @param formatKeys The format keys to copy
22018
+ * @param deleteOriginalFormat True to delete the original format from sourceFormat, false to keep it. @default false
22019
+ */
22020
+ function copyFormat(targetFormat, sourceFormat, formatKeys, deleteOriginalFormat) {
22021
+ var e_1, _a, _b;
22022
+ try {
22023
+ for (var formatKeys_1 = (0, tslib_1.__values)(formatKeys), formatKeys_1_1 = formatKeys_1.next(); !formatKeys_1_1.done; formatKeys_1_1 = formatKeys_1.next()) {
22024
+ var key = formatKeys_1_1.value;
22025
+ if (sourceFormat[key] !== undefined) {
22026
+ Object.assign(targetFormat, (_b = {},
22027
+ _b[key] = sourceFormat[key],
22028
+ _b));
22029
+ if (deleteOriginalFormat) {
22030
+ delete sourceFormat[key];
22031
+ }
22032
+ }
22033
+ }
22034
+ }
22035
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
22036
+ finally {
22037
+ try {
22038
+ if (formatKeys_1_1 && !formatKeys_1_1.done && (_a = formatKeys_1.return)) _a.call(formatKeys_1);
22039
+ }
22040
+ finally { if (e_1) throw e_1.error; }
22041
+ }
22042
+ }
22043
+ exports.copyFormat = copyFormat;
22044
+
22045
+
21534
22046
  /***/ }),
21535
22047
 
21536
22048
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/block/setParagraphNotImplicit.ts":
@@ -22010,6 +22522,7 @@ function isListItem(obj) {
22010
22522
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22011
22523
  exports.normalizeContentModel = void 0;
22012
22524
  var isEmpty_1 = __webpack_require__(/*! ./isEmpty */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/isEmpty.ts");
22525
+ var copyFormat_1 = __webpack_require__(/*! ../block/copyFormat */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/copyFormat.ts");
22013
22526
  var mutate_1 = __webpack_require__(/*! ./mutate */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts");
22014
22527
  var normalizeParagraph_1 = __webpack_require__(/*! ./normalizeParagraph */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeParagraph.ts");
22015
22528
  var unwrapBlock_1 = __webpack_require__(/*! ./unwrapBlock */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts");
@@ -22029,7 +22542,7 @@ function normalizeContentModel(group) {
22029
22542
  case 'BlockGroup':
22030
22543
  if (block.blockGroupType == 'ListItem' && block.levels.length == 0) {
22031
22544
  i += block.blocks.length;
22032
- (0, unwrapBlock_1.unwrapBlock)(group, block);
22545
+ (0, unwrapBlock_1.unwrapBlock)(group, block, copyFormat_1.ListFormats);
22033
22546
  }
22034
22547
  else {
22035
22548
  normalizeContentModel(block);
@@ -22301,6 +22814,44 @@ function normalizeLastTextSegment(paragraph, segment, lastInlineSegment) {
22301
22814
  }
22302
22815
 
22303
22816
 
22817
+ /***/ }),
22818
+
22819
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeSegmentFormat.ts":
22820
+ /*!********************************************************************************************!*\
22821
+ !*** ./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeSegmentFormat.ts ***!
22822
+ \********************************************************************************************/
22823
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
22824
+
22825
+ "use strict";
22826
+
22827
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
22828
+ exports.normalizeSegmentFormat = void 0;
22829
+ var createContentModelDocument_1 = __webpack_require__(/*! ../creators/createContentModelDocument */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createContentModelDocument.ts");
22830
+ var createText_1 = __webpack_require__(/*! ../creators/createText */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createText.ts");
22831
+ var ensureParagraph_1 = __webpack_require__(/*! ./ensureParagraph */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/ensureParagraph.ts");
22832
+ var createModelToDomContext_1 = __webpack_require__(/*! ../../modelToDom/context/createModelToDomContext */ "./packages/roosterjs-content-model-dom/lib/modelToDom/context/createModelToDomContext.ts");
22833
+ var createDomToModelContext_1 = __webpack_require__(/*! ../../domToModel/context/createDomToModelContext */ "./packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts");
22834
+ /**
22835
+ * Some format values can be changed when apply to DOM, such as font family.
22836
+ * This function will normalize the format and return the same string after DOM modification.
22837
+ * @param format The format to be normalized
22838
+ * @return Normalized format
22839
+ */
22840
+ function normalizeSegmentFormat(format, environment) {
22841
+ var _a, _b;
22842
+ var span = document.createElement('span');
22843
+ var segment = (0, createText_1.createText)('text', format);
22844
+ var domToModelContext = (0, createDomToModelContext_1.createDomToModelContextWithConfig)(environment.domToModelSettings.calculated);
22845
+ var modelToDomContext = (0, createModelToDomContext_1.createModelToDomContextWithConfig)(environment.modelToDomSettings.calculated);
22846
+ var model = (0, createContentModelDocument_1.createContentModelDocument)();
22847
+ modelToDomContext.modelHandlers.segment(span.ownerDocument, span, segment, modelToDomContext, []);
22848
+ domToModelContext.elementProcessors.element(model, span, domToModelContext);
22849
+ var paragraph = (0, ensureParagraph_1.ensureParagraph)(model);
22850
+ return (_b = (_a = paragraph.segments[0]) === null || _a === void 0 ? void 0 : _a.format) !== null && _b !== void 0 ? _b : format;
22851
+ }
22852
+ exports.normalizeSegmentFormat = normalizeSegmentFormat;
22853
+
22854
+
22304
22855
  /***/ }),
22305
22856
 
22306
22857
  /***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts":
@@ -22314,6 +22865,7 @@ function normalizeLastTextSegment(paragraph, segment, lastInlineSegment) {
22314
22865
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22315
22866
  exports.unwrapBlock = void 0;
22316
22867
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
22868
+ var copyFormat_1 = __webpack_require__(/*! ../../modelApi/block/copyFormat */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/copyFormat.ts");
22317
22869
  var mutate_1 = __webpack_require__(/*! ./mutate */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts");
22318
22870
  var setParagraphNotImplicit_1 = __webpack_require__(/*! ../block/setParagraphNotImplicit */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/setParagraphNotImplicit.ts");
22319
22871
  /**
@@ -22321,14 +22873,21 @@ var setParagraphNotImplicit_1 = __webpack_require__(/*! ../block/setParagraphNot
22321
22873
  * @param parent Parent block group of the unwrapping group
22322
22874
  * @param groupToUnwrap The block group to unwrap
22323
22875
  */
22324
- function unwrapBlock(parent, groupToUnwrap) {
22876
+ function unwrapBlock(parent, groupToUnwrap, formatsToKeep) {
22325
22877
  var _a;
22326
22878
  var _b, _c;
22327
22879
  var index = (_b = parent === null || parent === void 0 ? void 0 : parent.blocks.indexOf(groupToUnwrap)) !== null && _b !== void 0 ? _b : -1;
22328
22880
  if (index >= 0) {
22329
22881
  groupToUnwrap.blocks.forEach(setParagraphNotImplicit_1.setParagraphNotImplicit);
22330
22882
  if (parent) {
22331
- (_c = (0, mutate_1.mutateBlock)(parent)) === null || _c === void 0 ? void 0 : (_a = _c.blocks).splice.apply(_a, (0, tslib_1.__spreadArray)([index, 1], (0, tslib_1.__read)(groupToUnwrap.blocks.map(mutate_1.mutateBlock)), false));
22883
+ (_c = (0, mutate_1.mutateBlock)(parent)) === null || _c === void 0 ? void 0 : (_a = _c.blocks).splice.apply(_a, (0, tslib_1.__spreadArray)([index,
22884
+ 1], (0, tslib_1.__read)(groupToUnwrap.blocks.map(function (x) {
22885
+ var mutableBlock = (0, mutate_1.mutateBlock)(x);
22886
+ if (formatsToKeep) {
22887
+ (0, copyFormat_1.copyFormat)(mutableBlock.format, groupToUnwrap.format, formatsToKeep);
22888
+ }
22889
+ return mutableBlock;
22890
+ })), false));
22332
22891
  }
22333
22892
  }
22334
22893
  }
@@ -24454,6 +25013,7 @@ exports.retrieveModelFormatState = void 0;
24454
25013
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
24455
25014
  var borderValues_1 = __webpack_require__(/*! ../../domUtils/style/borderValues */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts");
24456
25015
  var getClosestAncestorBlockGroupIndex_1 = __webpack_require__(/*! ./getClosestAncestorBlockGroupIndex */ "./packages/roosterjs-content-model-dom/lib/modelApi/editing/getClosestAncestorBlockGroupIndex.ts");
25016
+ var updateImageMetadata_1 = __webpack_require__(/*! ../metadata/updateImageMetadata */ "./packages/roosterjs-content-model-dom/lib/modelApi/metadata/updateImageMetadata.ts");
24457
25017
  var updateTableMetadata_1 = __webpack_require__(/*! ../metadata/updateTableMetadata */ "./packages/roosterjs-content-model-dom/lib/modelApi/metadata/updateTableMetadata.ts");
24458
25018
  var isBold_1 = __webpack_require__(/*! ../../domUtils/style/isBold */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/isBold.ts");
24459
25019
  var iterateSelections_1 = __webpack_require__(/*! ../selection/iterateSelections */ "./packages/roosterjs-content-model-dom/lib/modelApi/selection/iterateSelections.ts");
@@ -24526,6 +25086,7 @@ function retrieveModelFormatState(model, pendingFormat, formatState, conflictSol
24526
25086
  }
24527
25087
  else {
24528
25088
  formatState.imageFormat = undefined;
25089
+ formatState.imageEditingMetadata = undefined;
24529
25090
  }
24530
25091
  }
24531
25092
  });
@@ -24622,6 +25183,7 @@ function retrieveImageFormat(image, result) {
24622
25183
  boxShadow: format.boxShadow,
24623
25184
  borderRadius: format.borderRadius,
24624
25185
  };
25186
+ result.imageEditingMetadata = (0, updateImageMetadata_1.getImageMetadata)(image);
24625
25187
  }
24626
25188
  function mergeValue(format, key, newValue, isFirst, conflictSolution, parseFn) {
24627
25189
  if (conflictSolution === void 0) { conflictSolution = 'remove'; }
@@ -28957,52 +29519,71 @@ var AutoFormatPlugin = /** @class */ (function () {
28957
29519
  if (options === void 0) { options = DefaultOptions; }
28958
29520
  this.options = options;
28959
29521
  this.editor = null;
28960
- this.features = [
29522
+ this.autoLink = {
29523
+ enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),
29524
+ transformFunction: function (_model, previousSegment, paragraph, context) {
29525
+ var _a;
29526
+ var _b = _this.options, autoLink = _b.autoLink, autoTel = _b.autoTel, autoMailto = _b.autoMailto;
29527
+ var linkSegment = (0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
29528
+ autoLink: autoLink,
29529
+ autoTel: autoTel,
29530
+ autoMailto: autoMailto,
29531
+ });
29532
+ if (linkSegment) {
29533
+ return createAnchor(((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
29534
+ }
29535
+ return false;
29536
+ },
29537
+ apiName: 'autoLink',
29538
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoLink,
29539
+ };
29540
+ this.tabFeatures = [
28961
29541
  {
28962
- autoFormat: 'list',
28963
29542
  enabled: !!(this.options.autoBullet || this.options.autoNumbering),
28964
29543
  transformFunction: function (model, _previousSegment, paragraph, context) {
28965
29544
  return (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, _this.options.autoBullet, _this.options.autoNumbering, _this.options.removeListMargins);
28966
29545
  },
29546
+ apiName: 'autoToggleList',
29547
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
28967
29548
  },
29549
+ this.autoLink,
29550
+ ];
29551
+ this.features = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(this.tabFeatures), false), [
28968
29552
  {
28969
- autoFormat: 'link',
28970
- enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),
28971
- transformFunction: function (_model, previousSegment, paragraph, context) {
28972
- var _a;
28973
- var _b = _this.options, autoLink = _b.autoLink, autoTel = _b.autoTel, autoMailto = _b.autoMailto;
28974
- var linkSegment = (0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
28975
- autoLink: autoLink,
28976
- autoTel: autoTel,
28977
- autoMailto: autoMailto,
28978
- });
28979
- if (linkSegment) {
28980
- return createAnchor(((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
28981
- }
28982
- return false;
28983
- },
28984
- },
28985
- {
28986
- autoFormat: 'hyphen',
28987
29553
  enabled: !!this.options.autoHyphen,
29554
+ apiName: 'autoHyphen',
29555
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Format,
28988
29556
  transformFunction: function (_model, previousSegment, paragraph, context) {
28989
29557
  return (0, transformHyphen_1.transformHyphen)(previousSegment, paragraph, context);
28990
29558
  },
28991
29559
  },
28992
29560
  {
28993
- autoFormat: 'fraction',
28994
29561
  enabled: !!this.options.autoFraction,
29562
+ apiName: 'autoFraction',
29563
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Format,
28995
29564
  transformFunction: function (_model, previousSegment, paragraph, context) {
28996
29565
  return (0, transformFraction_1.transformFraction)(previousSegment, paragraph, context);
28997
29566
  },
28998
29567
  },
28999
29568
  {
29000
- autoFormat: 'ordinal',
29001
29569
  enabled: !!this.options.autoOrdinals,
29570
+ apiName: 'autoOrdinal',
29571
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Format,
29002
29572
  transformFunction: function (_model, previousSegment, paragraph, context) {
29003
29573
  return (0, transformOrdinals_1.transformOrdinals)(previousSegment, paragraph, context);
29004
29574
  },
29005
29575
  },
29576
+ ], false);
29577
+ this.enterFeatures = [
29578
+ {
29579
+ enabled: !!this.options.autoHorizontalLine,
29580
+ transformFunction: function (model, _previousSegment, paragraph, context) {
29581
+ return (0, checkAndInsertHorizontalLine_1.checkAndInsertHorizontalLine)(model, paragraph, context);
29582
+ },
29583
+ apiName: 'autoHorizontalLine',
29584
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
29585
+ },
29586
+ this.autoLink,
29006
29587
  ];
29007
29588
  }
29008
29589
  /**
@@ -29049,8 +29630,51 @@ var AutoFormatPlugin = /** @class */ (function () {
29049
29630
  }
29050
29631
  }
29051
29632
  };
29633
+ AutoFormatPlugin.prototype.handleKeyboardEvents = function (editor, features) {
29634
+ var formatOptions = {
29635
+ changeSource: '',
29636
+ apiName: '',
29637
+ getChangeData: undefined,
29638
+ };
29639
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph, _markerFormat, context) {
29640
+ var e_1, _a;
29641
+ var featureApplied = undefined;
29642
+ var _loop_1 = function (feature) {
29643
+ if (feature.enabled) {
29644
+ var result_1 = feature.transformFunction(model, previousSegment, paragraph, context);
29645
+ if (result_1) {
29646
+ if (typeof result_1 !== 'boolean') {
29647
+ formatOptions.getChangeData = function () { return result_1; };
29648
+ }
29649
+ featureApplied = feature;
29650
+ return "break";
29651
+ }
29652
+ }
29653
+ };
29654
+ try {
29655
+ for (var features_1 = (0, tslib_1.__values)(features), features_1_1 = features_1.next(); !features_1_1.done; features_1_1 = features_1.next()) {
29656
+ var feature = features_1_1.value;
29657
+ var state_1 = _loop_1(feature);
29658
+ if (state_1 === "break")
29659
+ break;
29660
+ }
29661
+ }
29662
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
29663
+ finally {
29664
+ try {
29665
+ if (features_1_1 && !features_1_1.done && (_a = features_1.return)) _a.call(features_1);
29666
+ }
29667
+ finally { if (e_1) throw e_1.error; }
29668
+ }
29669
+ if (featureApplied) {
29670
+ formatOptions.changeSource = featureApplied.changeSource;
29671
+ formatOptions.apiName = featureApplied.apiName;
29672
+ }
29673
+ return !!featureApplied;
29674
+ }, formatOptions);
29675
+ return formatOptions;
29676
+ };
29052
29677
  AutoFormatPlugin.prototype.handleEditorInputEvent = function (editor, event) {
29053
- var _this = this;
29054
29678
  var rawEvent = event.rawEvent;
29055
29679
  var selection = editor.getDOMSelection();
29056
29680
  if (rawEvent.inputType === 'insertText' &&
@@ -29059,53 +29683,12 @@ var AutoFormatPlugin = /** @class */ (function () {
29059
29683
  selection.range.collapsed) {
29060
29684
  switch (rawEvent.data) {
29061
29685
  case ' ':
29062
- var formatOptions_1 = {
29063
- changeSource: '',
29064
- apiName: '',
29065
- getChangeData: undefined,
29066
- };
29067
- (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph, _markerFormat, context) {
29068
- var e_1, _a;
29069
- var formatApplied = undefined;
29070
- var _loop_1 = function (feature) {
29071
- if (feature.enabled) {
29072
- var result_1 = feature.transformFunction(model, previousSegment, paragraph, context);
29073
- if (result_1) {
29074
- if (typeof result_1 !== 'boolean') {
29075
- formatOptions_1.getChangeData = function () { return result_1; };
29076
- }
29077
- formatApplied = feature.autoFormat;
29078
- return "break";
29079
- }
29080
- }
29081
- };
29082
- try {
29083
- for (var _b = (0, tslib_1.__values)(_this.features), _c = _b.next(); !_c.done; _c = _b.next()) {
29084
- var feature = _c.value;
29085
- var state_1 = _loop_1(feature);
29086
- if (state_1 === "break")
29087
- break;
29088
- }
29089
- }
29090
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
29091
- finally {
29092
- try {
29093
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
29094
- }
29095
- finally { if (e_1) throw e_1.error; }
29096
- }
29097
- if (formatApplied) {
29098
- formatOptions_1.changeSource = getChangeSource(formatApplied);
29099
- formatOptions_1.apiName = getApiName(formatApplied);
29100
- }
29101
- return !!formatApplied;
29102
- }, formatOptions_1);
29686
+ this.handleKeyboardEvents(editor, this.features);
29103
29687
  break;
29104
29688
  }
29105
29689
  }
29106
29690
  };
29107
29691
  AutoFormatPlugin.prototype.handleKeyDownEvent = function (editor, event) {
29108
- var _this = this;
29109
29692
  var rawEvent = event.rawEvent;
29110
29693
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
29111
29694
  switch (rawEvent.key) {
@@ -29116,34 +29699,21 @@ var AutoFormatPlugin = /** @class */ (function () {
29116
29699
  break;
29117
29700
  case 'Tab':
29118
29701
  if (!rawEvent.shiftKey) {
29119
- (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _previousSegment, paragraph, _markerFormat, context) {
29120
- var _a = _this.options, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering, removeListMargins = _a.removeListMargins;
29121
- var shouldList = false;
29122
- if (autoBullet || autoNumbering) {
29123
- shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering, removeListMargins);
29124
- context.canUndoByBackspace = shouldList;
29125
- }
29126
- if (shouldList) {
29127
- event.rawEvent.preventDefault();
29128
- }
29129
- return shouldList;
29130
- }, {
29131
- changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
29132
- apiName: 'autoToggleList',
29133
- });
29702
+ var eventHandled_1 = this.handleKeyboardEvents(editor, this.tabFeatures);
29703
+ if (eventHandled_1.apiName == 'autoToggleList') {
29704
+ event.rawEvent.preventDefault();
29705
+ }
29134
29706
  }
29135
29707
  break;
29136
29708
  case 'Enter':
29137
- this.handleEnterKey(editor, event);
29709
+ var eventHandled = this.handleKeyboardEvents(editor, this.enterFeatures);
29710
+ if (eventHandled.apiName == 'autoHorizontalLine') {
29711
+ event.rawEvent.preventDefault();
29712
+ }
29138
29713
  break;
29139
29714
  }
29140
29715
  }
29141
29716
  };
29142
- AutoFormatPlugin.prototype.handleEnterKey = function (editor, event) {
29143
- if (this.options.autoHorizontalLine) {
29144
- (0, checkAndInsertHorizontalLine_1.checkAndInsertHorizontalLine)(editor, event);
29145
- }
29146
- };
29147
29717
  AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
29148
29718
  var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
29149
29719
  if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
@@ -29157,16 +29727,6 @@ var AutoFormatPlugin = /** @class */ (function () {
29157
29727
  return AutoFormatPlugin;
29158
29728
  }());
29159
29729
  exports.AutoFormatPlugin = AutoFormatPlugin;
29160
- var getApiName = function (autoFormat) {
29161
- return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';
29162
- };
29163
- var getChangeSource = function (autoFormat) {
29164
- return autoFormat == 'list' || autoFormat == 'hyphen'
29165
- ? roosterjs_content_model_dom_1.ChangeSource.AutoFormat
29166
- : autoFormat == 'link'
29167
- ? roosterjs_content_model_dom_1.ChangeSource.AutoLink
29168
- : '';
29169
- };
29170
29730
  var createAnchor = function (url, text) {
29171
29731
  var anchor = document.createElement('a');
29172
29732
  anchor.href = url;
@@ -29188,7 +29748,6 @@ var createAnchor = function (url, text) {
29188
29748
  Object.defineProperty(exports, "__esModule", ({ value: true }));
29189
29749
  exports.checkAndInsertHorizontalLine = exports.insertHorizontalLineIntoModel = void 0;
29190
29750
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
29191
- var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
29192
29751
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
29193
29752
  var HorizontalLineTriggerCharacters = [
29194
29753
  '-',
@@ -29252,28 +29811,22 @@ exports.insertHorizontalLineIntoModel = insertHorizontalLineIntoModel;
29252
29811
  * @param event The keydown event
29253
29812
  * @returns True if horizontal line is inserted, otherwise false
29254
29813
  */
29255
- function checkAndInsertHorizontalLine(editor, event) {
29256
- return (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _, para, __, context) {
29257
- var allText = para.segments.reduce(function (acc, segment) { return (segment.segmentType === 'Text' ? acc + segment.text : acc); }, '');
29258
- // At least 3 characters are needed to trigger horizontal line
29259
- if (allText.length < 3) {
29260
- return false;
29814
+ var checkAndInsertHorizontalLine = function (model, paragraph, context) {
29815
+ var allText = paragraph.segments.reduce(function (acc, segment) { return (segment.segmentType === 'Text' ? acc + segment.text : acc); }, '');
29816
+ // At least 3 characters are needed to trigger horizontal line
29817
+ if (allText.length < 3) {
29818
+ return false;
29819
+ }
29820
+ return HorizontalLineTriggerCharacters.some(function (triggerCharacter) {
29821
+ var shouldFormat = allText.split('').every(function (char) { return char === triggerCharacter; });
29822
+ if (shouldFormat) {
29823
+ paragraph.segments = paragraph.segments.filter(function (s) { return s.segmentType != 'Text'; });
29824
+ insertHorizontalLineIntoModel(model, context, triggerCharacter);
29825
+ context.canUndoByBackspace = true;
29261
29826
  }
29262
- return HorizontalLineTriggerCharacters.some(function (triggerCharacter) {
29263
- var shouldFormat = allText.split('').every(function (char) { return char === triggerCharacter; });
29264
- if (shouldFormat) {
29265
- para.segments = para.segments.filter(function (s) { return s.segmentType != 'Text'; });
29266
- insertHorizontalLineIntoModel(model, context, triggerCharacter);
29267
- event.rawEvent.preventDefault();
29268
- context.canUndoByBackspace = true;
29269
- }
29270
- return shouldFormat;
29271
- });
29272
- }, {
29273
- changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
29274
- apiName: 'autoHorizontalLine',
29827
+ return shouldFormat;
29275
29828
  });
29276
- }
29829
+ };
29277
29830
  exports.checkAndInsertHorizontalLine = checkAndInsertHorizontalLine;
29278
29831
 
29279
29832
 
@@ -30101,6 +30654,7 @@ exports.CustomReplacePlugin = CustomReplacePlugin;
30101
30654
 
30102
30655
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30103
30656
  exports.EditPlugin = void 0;
30657
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
30104
30658
  var keyboardDelete_1 = __webpack_require__(/*! ./keyboardDelete */ "./packages/roosterjs-content-model-plugins/lib/edit/keyboardDelete.ts");
30105
30659
  var keyboardEnter_1 = __webpack_require__(/*! ./keyboardEnter */ "./packages/roosterjs-content-model-plugins/lib/edit/keyboardEnter.ts");
30106
30660
  var keyboardInput_1 = __webpack_require__(/*! ./keyboardInput */ "./packages/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts");
@@ -30138,8 +30692,25 @@ var EditPlugin = /** @class */ (function () {
30138
30692
  this.disposer = null;
30139
30693
  this.shouldHandleNextInputEvent = false;
30140
30694
  this.selectionAfterDelete = null;
30141
- this.handleNormalEnter = false;
30695
+ this.handleNormalEnter = function (editor) { return false; };
30696
+ this.options = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultOptions), options);
30142
30697
  }
30698
+ EditPlugin.prototype.createNormalEnterChecker = function (result) {
30699
+ return result ? function () { return true; } : function () { return false; };
30700
+ };
30701
+ EditPlugin.prototype.getHandleNormalEnter = function (editor) {
30702
+ switch (typeof this.options.shouldHandleEnterKey) {
30703
+ case 'function':
30704
+ return this.options.shouldHandleEnterKey;
30705
+ break;
30706
+ case 'boolean':
30707
+ return this.createNormalEnterChecker(this.options.shouldHandleEnterKey);
30708
+ break;
30709
+ default:
30710
+ return this.createNormalEnterChecker(editor.isExperimentalFeatureEnabled('HandleEnterKey'));
30711
+ break;
30712
+ }
30713
+ };
30143
30714
  /**
30144
30715
  * Get name of this plugin
30145
30716
  */
@@ -30155,7 +30726,7 @@ var EditPlugin = /** @class */ (function () {
30155
30726
  EditPlugin.prototype.initialize = function (editor) {
30156
30727
  var _this = this;
30157
30728
  this.editor = editor;
30158
- this.handleNormalEnter = this.editor.isExperimentalFeatureEnabled('HandleEnterKey');
30729
+ this.handleNormalEnter = this.getHandleNormalEnter(editor);
30159
30730
  if (editor.getEnvironment().isAndroid) {
30160
30731
  this.disposer = this.editor.attachDomEvent({
30161
30732
  beforeinput: {
@@ -30262,7 +30833,7 @@ var EditPlugin = /** @class */ (function () {
30262
30833
  if (!hasCtrlOrMetaKey &&
30263
30834
  !event.rawEvent.isComposing &&
30264
30835
  event.rawEvent.keyCode !== DEAD_KEY) {
30265
- (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter);
30836
+ (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter(editor));
30266
30837
  }
30267
30838
  break;
30268
30839
  default:
@@ -30942,6 +31513,7 @@ var createNewListItem = function (context, listItem, listParent) {
30942
31513
  var levels = createNewListLevel(listItem);
30943
31514
  var newListItem = (0, roosterjs_content_model_dom_1.createListItem)(levels, listItem.formatHolder.format);
30944
31515
  newListItem.blocks.push(newParagraph);
31516
+ (0, roosterjs_content_model_dom_1.copyFormat)(newListItem.format, listItem.format, roosterjs_content_model_dom_1.ListFormats);
30945
31517
  var remainingBlockCount = listItem.blocks.length - paraIndex - 1;
30946
31518
  if (paraIndex >= 0 && remainingBlockCount > 0) {
30947
31519
  (_a = newListItem.blocks).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, roosterjs_content_model_dom_1.mutateBlock)(listItem).blocks.splice(paraIndex + 1, remainingBlockCount)), false));
@@ -31155,7 +31727,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
31155
31727
  function keyboardEnter(editor, rawEvent, handleNormalEnter) {
31156
31728
  var selection = editor.getDOMSelection();
31157
31729
  editor.formatContentModel(function (model, context) {
31158
- var _a;
31730
+ var _a, _b;
31159
31731
  // 1. delete the expanded selection if any, then merge paragraph
31160
31732
  var result = (0, roosterjs_content_model_dom_1.deleteSelection)(model, [], context);
31161
31733
  // 2. Add line break
@@ -31166,14 +31738,14 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
31166
31738
  var steps = rawEvent.shiftKey
31167
31739
  ? []
31168
31740
  : [handleAutoLink_1.handleAutoLink, handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
31169
- if (handleNormalEnter) {
31741
+ if (handleNormalEnter || hasEnterForEntity((_a = result.insertPoint) === null || _a === void 0 ? void 0 : _a.paragraph)) {
31170
31742
  steps.push(handleEnterOnParagraph_1.handleEnterOnParagraph);
31171
31743
  }
31172
31744
  (0, roosterjs_content_model_dom_1.runEditSteps)(steps, result);
31173
31745
  }
31174
31746
  if (result.deleteResult == 'range') {
31175
31747
  // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here
31176
- context.newPendingFormat = (_a = result.insertPoint) === null || _a === void 0 ? void 0 : _a.marker.format;
31748
+ context.newPendingFormat = (_b = result.insertPoint) === null || _b === void 0 ? void 0 : _b.marker.format;
31177
31749
  (0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
31178
31750
  rawEvent.preventDefault();
31179
31751
  return true;
@@ -31190,6 +31762,10 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
31190
31762
  });
31191
31763
  }
31192
31764
  exports.keyboardEnter = keyboardEnter;
31765
+ function hasEnterForEntity(paragraph) {
31766
+ return (paragraph &&
31767
+ (paragraph.isImplicit || paragraph.segments.some(function (x) { return x.segmentType == 'SelectionMarker'; })));
31768
+ }
31193
31769
 
31194
31770
 
31195
31771
  /***/ }),
@@ -31404,7 +31980,7 @@ var space = ' ';
31404
31980
  * @internal
31405
31981
  The handleTabOnParagraph function will handle the tab key in following scenarios:
31406
31982
  * 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.
31407
- * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to indent the whole paragraph
31983
+ * 2. When the selection is collapsed and the cursor is at the start of a paragraph, add 4 spaces.
31408
31984
  * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.
31409
31985
  * 4. When the selection is not collapsed, replace the selected range with a single space.
31410
31986
  * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph
@@ -31418,8 +31994,10 @@ var space = ' ';
31418
31994
  function handleTabOnParagraph(model, paragraph, rawEvent, context) {
31419
31995
  var selectedSegments = paragraph.segments.filter(function (segment) { return segment.isSelected; });
31420
31996
  var isCollapsed = selectedSegments.length === 1 && selectedSegments[0].segmentType === 'SelectionMarker';
31421
- var isAllSelected = paragraph.segments.every(function (segment) { return segment.isSelected; });
31422
- if ((paragraph.segments[0].segmentType === 'SelectionMarker' && isCollapsed) || isAllSelected) {
31997
+ var isAllSelected = paragraph.segments.every(function (segment) {
31998
+ return segment.isSelected || (segment.segmentType == 'Text' && segment.text.trim().length == 0);
31999
+ });
32000
+ if (isAllSelected) {
31423
32001
  var _a = paragraph.format, marginLeft = _a.marginLeft, marginRight = _a.marginRight, direction = _a.direction;
31424
32002
  var isRtl = direction === 'rtl';
31425
32003
  if (rawEvent.shiftKey &&
@@ -31459,6 +32037,9 @@ function handleTabOnParagraph(model, paragraph, rawEvent, context) {
31459
32037
  (0, roosterjs_content_model_dom_1.mutateBlock)(paragraph).segments.splice(markerIndex, 0, tabText);
31460
32038
  }
31461
32039
  else {
32040
+ if (markerIndex <= 0) {
32041
+ return false;
32042
+ }
31462
32043
  var tabText = paragraph.segments[markerIndex - 1];
31463
32044
  var tabSpacesLength = tabSpaces.length;
31464
32045
  if (tabText.segmentType == 'Text') {
@@ -31676,19 +32257,23 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
31676
32257
  * Split the given paragraph from insert point into two paragraphs,
31677
32258
  * and move the selection marker to the beginning of the second paragraph
31678
32259
  * @param insertPoint The input insert point which includes the paragraph and selection marker
32260
+ * @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied
31679
32261
  * @returns The new paragraph it created
31680
32262
  */
31681
32263
  function splitParagraph(insertPoint) {
31682
32264
  var _a;
31683
32265
  var paragraph = insertPoint.paragraph, marker = insertPoint.marker;
31684
- var newParagraph = (0, roosterjs_content_model_dom_1.createParagraph)(false /*isImplicit*/, paragraph.format, paragraph.segmentFormat);
32266
+ var newParagraph = (0, roosterjs_content_model_dom_1.createParagraph)(false /*isImplicit*/, {}, paragraph.segmentFormat);
32267
+ (0, roosterjs_content_model_dom_1.copyFormat)(newParagraph.format, paragraph.format, roosterjs_content_model_dom_1.ParagraphFormats);
31685
32268
  var markerIndex = paragraph.segments.indexOf(marker);
31686
32269
  var segments = paragraph.segments.splice(markerIndex, paragraph.segments.length - markerIndex);
31687
- if (paragraph.segments.length == 0) {
32270
+ (_a = newParagraph.segments).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(segments), false));
32271
+ if (paragraph.segments.length == 0 && !paragraph.isImplicit) {
31688
32272
  paragraph.segments.push((0, roosterjs_content_model_dom_1.createBr)(marker.format));
31689
32273
  }
31690
- (_a = newParagraph.segments).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(segments), false));
31691
- (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(paragraph);
32274
+ else if (paragraph.segments.length > 0) {
32275
+ (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(paragraph);
32276
+ }
31692
32277
  insertPoint.paragraph = newParagraph;
31693
32278
  (0, roosterjs_content_model_dom_1.normalizeParagraph)(paragraph);
31694
32279
  return newParagraph;
@@ -32302,9 +32887,6 @@ var ImageEditPlugin = /** @class */ (function () {
32302
32887
  ImageEditPlugin.prototype.removeImageEditing = function (clonedRoot) {
32303
32888
  var images = clonedRoot.querySelectorAll('img');
32304
32889
  images.forEach(function (image) {
32305
- if (image.dataset.isEditing) {
32306
- delete image.dataset.isEditing;
32307
- }
32308
32890
  if (image.dataset.editingInfo) {
32309
32891
  delete image.dataset.editingInfo;
32310
32892
  }
@@ -32375,8 +32957,11 @@ var ImageEditPlugin = /** @class */ (function () {
32375
32957
  };
32376
32958
  ImageEditPlugin.prototype.setContentHandler = function (editor) {
32377
32959
  var selection = editor.getDOMSelection();
32378
- if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image' && selection.image.dataset.isEditing && !this.isEditing) {
32379
- delete selection.image.dataset.isEditing;
32960
+ if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
32961
+ this.cleanInfo();
32962
+ (0, roosterjs_content_model_dom_1.setImageState)(selection.image, '');
32963
+ this.isEditing = false;
32964
+ this.isCropMode = false;
32380
32965
  }
32381
32966
  };
32382
32967
  ImageEditPlugin.prototype.formatEventHandler = function (event) {
@@ -32414,7 +32999,7 @@ var ImageEditPlugin = /** @class */ (function () {
32414
32999
  var result = false;
32415
33000
  if (shouldSelectImage ||
32416
33001
  (previousSelectedImage === null || previousSelectedImage === void 0 ? void 0 : previousSelectedImage.image) != (editingImage === null || editingImage === void 0 ? void 0 : editingImage.image) ||
32417
- (previousSelectedImage === null || previousSelectedImage === void 0 ? void 0 : previousSelectedImage.image.dataset.isEditing) ||
33002
+ (previousSelectedImage === null || previousSelectedImage === void 0 ? void 0 : previousSelectedImage.image.format.imageState) == findEditingImage_1.EDITING_MARKER ||
32418
33003
  isApiOperation) {
32419
33004
  var _a = _this, lastSrc_1 = _a.lastSrc, selectedImage_1 = _a.selectedImage, imageEditInfo_1 = _a.imageEditInfo, clonedImage_1 = _a.clonedImage;
32420
33005
  if ((_this.isEditing || isApiOperation) &&
@@ -32427,7 +33012,7 @@ var ImageEditPlugin = /** @class */ (function () {
32427
33012
  (0, applyChange_1.applyChange)(editor, selectedImage_1, image, imageEditInfo_1, lastSrc_1, _this.wasImageResized || _this.isCropMode, clonedImage_1);
32428
33013
  image.isSelected = shouldSelectImage;
32429
33014
  image.isSelectedAsImageSelection = shouldSelectImage;
32430
- delete image.dataset.isEditing;
33015
+ image.format.imageState = undefined;
32431
33016
  if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'range' && !selection.range.collapsed) {
32432
33017
  var selectedParagraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true);
32433
33018
  var isImageInRange = selectedParagraphs.some(function (paragraph) {
@@ -32455,7 +33040,7 @@ var ImageEditPlugin = /** @class */ (function () {
32455
33040
  (0, roosterjs_content_model_dom_1.mutateSegment)(editingImage.paragraph, editingImage.image, function (image) {
32456
33041
  editingImageModel = image;
32457
33042
  _this.imageEditInfo = (0, updateImageEditInfo_1.updateImageEditInfo)(image, selection.image);
32458
- image.dataset.isEditing = 'true';
33043
+ image.format.imageState = 'isEditing';
32459
33044
  });
32460
33045
  result = true;
32461
33046
  }
@@ -32466,7 +33051,7 @@ var ImageEditPlugin = /** @class */ (function () {
32466
33051
  if (!isApiOperation &&
32467
33052
  editingImageModel &&
32468
33053
  editingImageModel == model &&
32469
- editingImageModel.dataset.isEditing &&
33054
+ editingImageModel.format.imageState == findEditingImage_1.EDITING_MARKER &&
32470
33055
  (0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') &&
32471
33056
  (0, roosterjs_content_model_dom_1.isElementOfType)(node, 'img')) {
32472
33057
  if (isCropMode) {
@@ -33557,9 +34142,13 @@ exports.doubleCheckResize = doubleCheckResize;
33557
34142
  "use strict";
33558
34143
 
33559
34144
  Object.defineProperty(exports, "__esModule", ({ value: true }));
33560
- exports.findEditingImage = void 0;
34145
+ exports.findEditingImage = exports.EDITING_MARKER = void 0;
33561
34146
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
33562
34147
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
34148
+ /**
34149
+ * @internal
34150
+ */
34151
+ exports.EDITING_MARKER = 'isEditing';
33563
34152
  /**
33564
34153
  * @internal
33565
34154
  */
@@ -33571,7 +34160,8 @@ function findEditingImage(group, imageId) {
33571
34160
  for (var _b = (0, tslib_1.__values)(paragraph.segments), _c = _b.next(); !_c.done; _c = _b.next()) {
33572
34161
  var segment = _c.value;
33573
34162
  if (segment.segmentType == 'Image' &&
33574
- ((imageId && segment.format.id == imageId) || segment.dataset.isEditing)) {
34163
+ ((imageId && segment.format.id == imageId) ||
34164
+ segment.format.imageState == exports.EDITING_MARKER)) {
33575
34165
  imageAndParagraph = { image: segment, paragraph: paragraph };
33576
34166
  return true;
33577
34167
  }
@@ -34689,15 +35279,17 @@ var addParser_1 = __webpack_require__(/*! ./utils/addParser */ "./packages/roost
34689
35279
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
34690
35280
  var chainSanitizerCallback_1 = __webpack_require__(/*! ./utils/chainSanitizerCallback */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/chainSanitizerCallback.ts");
34691
35281
  var DefaultSanitizers_1 = __webpack_require__(/*! ./DefaultSanitizers */ "./packages/roosterjs-content-model-plugins/lib/paste/DefaultSanitizers.ts");
34692
- var deprecatedColorParser_1 = __webpack_require__(/*! ./utils/deprecatedColorParser */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/deprecatedColorParser.ts");
35282
+ var deprecatedColorParser_1 = __webpack_require__(/*! ./parsers/deprecatedColorParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/deprecatedColorParser.ts");
34693
35283
  var getPasteSource_1 = __webpack_require__(/*! ./pasteSourceValidations/getPasteSource */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getPasteSource.ts");
34694
- var linkParser_1 = __webpack_require__(/*! ./utils/linkParser */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/linkParser.ts");
35284
+ var linkParser_1 = __webpack_require__(/*! ./parsers/linkParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/linkParser.ts");
35285
+ var pasteButtonProcessor_1 = __webpack_require__(/*! ./processors/pasteButtonProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/processors/pasteButtonProcessor.ts");
34695
35286
  var constants_1 = __webpack_require__(/*! ./pasteSourceValidations/constants */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/constants.ts");
34696
35287
  var processPastedContentFromExcel_1 = __webpack_require__(/*! ./Excel/processPastedContentFromExcel */ "./packages/roosterjs-content-model-plugins/lib/paste/Excel/processPastedContentFromExcel.ts");
34697
35288
  var processPastedContentFromOneNote_1 = __webpack_require__(/*! ./oneNote/processPastedContentFromOneNote */ "./packages/roosterjs-content-model-plugins/lib/paste/oneNote/processPastedContentFromOneNote.ts");
34698
35289
  var processPastedContentFromPowerPoint_1 = __webpack_require__(/*! ./PowerPoint/processPastedContentFromPowerPoint */ "./packages/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts");
34699
35290
  var processPastedContentFromWordDesktop_1 = __webpack_require__(/*! ./WordDesktop/processPastedContentFromWordDesktop */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts");
34700
35291
  var processPastedContentWacComponents_1 = __webpack_require__(/*! ./WacComponents/processPastedContentWacComponents */ "./packages/roosterjs-content-model-plugins/lib/paste/WacComponents/processPastedContentWacComponents.ts");
35292
+ var setProcessor_1 = __webpack_require__(/*! ./utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
34701
35293
  /**
34702
35294
  * Paste plugin, handles BeforePaste event and reformat some special content, including:
34703
35295
  * 1. Content copied from Word
@@ -34758,11 +35350,11 @@ var PastePlugin = /** @class */ (function () {
34758
35350
  if (!event.domToModelOption) {
34759
35351
  return;
34760
35352
  }
34761
- var pasteSource = (0, getPasteSource_1.getPasteSource)(event, false);
35353
+ var pasteSource = (0, getPasteSource_1.getPasteSource)(event, false /* shouldConvertSingleImage */, this.editor.getEnvironment());
34762
35354
  var pasteType = event.pasteType;
34763
35355
  switch (pasteSource) {
34764
35356
  case 'wordDesktop':
34765
- (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event, this.editor.getDOMCreator());
35357
+ (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event);
34766
35358
  break;
34767
35359
  case 'wacComponents':
34768
35360
  (0, processPastedContentWacComponents_1.processPastedContentWacComponents)(event);
@@ -34789,6 +35381,7 @@ var PastePlugin = /** @class */ (function () {
34789
35381
  (0, addParser_1.addParser)(event.domToModelOption, 'tableCell', deprecatedColorParser_1.deprecatedBorderColorParser);
34790
35382
  (0, addParser_1.addParser)(event.domToModelOption, 'tableCell', tableBorderParser);
34791
35383
  (0, addParser_1.addParser)(event.domToModelOption, 'table', deprecatedColorParser_1.deprecatedBorderColorParser);
35384
+ (0, setProcessor_1.setProcessor)(event.domToModelOption, 'button', pasteButtonProcessor_1.pasteButtonProcessor);
34792
35385
  if (pasteType === 'mergeFormat') {
34793
35386
  (0, addParser_1.addParser)(event.domToModelOption, 'block', blockElementParser);
34794
35387
  (0, addParser_1.addParser)(event.domToModelOption, 'listLevel', blockElementParser);
@@ -34854,22 +35447,153 @@ function tableBorderParser(format, element) {
34854
35447
 
34855
35448
  Object.defineProperty(exports, "__esModule", ({ value: true }));
34856
35449
  exports.processPastedContentFromPowerPoint = void 0;
35450
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
35451
+ var addParser_1 = __webpack_require__(/*! ../utils/addParser */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/addParser.ts");
35452
+ var customListUtils_1 = __webpack_require__(/*! ../utils/customListUtils */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/customListUtils.ts");
35453
+ var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ../parsers/removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts");
35454
+ var setProcessor_1 = __webpack_require__(/*! ../utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
34857
35455
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
35456
+ var BulletSelector = '* > span > span[style*=mso-special-format]';
35457
+ var MsOfficeSpecialFormat = 'mso-special-format';
35458
+ var CssStyleKey = 'style';
35459
+ var MsoSpecialFormatRegex = /mso-special-format:\s*([^;]*)/;
35460
+ var clearListItemStyles = function (format) {
35461
+ delete format.textAlign;
35462
+ delete format.marginLeft;
35463
+ delete format.paddingLeft;
35464
+ };
34858
35465
  /**
34859
35466
  * @internal
34860
35467
  * Convert pasted content from PowerPoint
34861
35468
  * @param event The BeforePaste event
34862
35469
  */
34863
35470
  function processPastedContentFromPowerPoint(event, domCreator) {
34864
- var fragment = event.fragment, clipboardData = event.clipboardData;
35471
+ var fragment = event.fragment, clipboardData = event.clipboardData, domToModelOption = event.domToModelOption;
34865
35472
  if (clipboardData.html && !clipboardData.text && clipboardData.image) {
34866
35473
  // It is possible that PowerPoint copied both image and HTML but not plain text.
34867
35474
  // We always prefer HTML if any.
34868
35475
  var doc = domCreator.htmlToDOM(clipboardData.html);
34869
35476
  (0, roosterjs_content_model_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
34870
35477
  }
35478
+ (0, addParser_1.addParser)(domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
35479
+ (0, setProcessor_1.setProcessor)(domToModelOption, 'element', function (group, element, context) {
35480
+ var _a, _b;
35481
+ var style = element.getAttribute(CssStyleKey) || '';
35482
+ // If the element is the bullet element, just ignore it, otherwise we will see an extra bullet in the list
35483
+ if (style.includes(MsOfficeSpecialFormat) && context.listFormat.levels.length > 0) {
35484
+ return;
35485
+ }
35486
+ var bulletElement = element.querySelector(BulletSelector);
35487
+ if (bulletElement) {
35488
+ var _c = extractPowerPointListInfo(element, bulletElement), depth = _c.depth, unorderedBulletType = _c.unorderedBulletType, orderedBulletType = _c.orderedBulletType, startNumberOverrideOrBullet_1 = _c.startNumberOverrideOrBullet, isOrderedList = _c.isOrderedList, isNewList_1 = _c.isNewList;
35489
+ // Setup the listformat with the metadata extracted from the bullet element
35490
+ (0, customListUtils_1.setupListFormat)(isOrderedList ? 'OL' : 'UL', element, context, depth, context.listFormat, group, [clearListItemStyles]);
35491
+ // Set the metadata for the list item, which will be used to set the correct bullet style type
35492
+ var listMetadata = {
35493
+ unorderedStyleType: !isOrderedList && unorderedBulletType
35494
+ ? roosterjs_content_model_dom_1.BulletListType[unorderedBulletType]
35495
+ : undefined,
35496
+ orderedStyleType: isOrderedList && orderedBulletType
35497
+ ? roosterjs_content_model_dom_1.NumberingListType[orderedBulletType]
35498
+ : undefined,
35499
+ };
35500
+ // Process the Div element as a list item.
35501
+ (0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, function (listItem) {
35502
+ var _a;
35503
+ var currentMarkerSize = listItem.formatHolder.format.fontSize;
35504
+ var bulletElementSize = (_a = bulletElement.parentElement) === null || _a === void 0 ? void 0 : _a.style.fontSize;
35505
+ listItem.formatHolder.format.fontSize = bulletElementSize || currentMarkerSize;
35506
+ if (isNewList_1) {
35507
+ listItem.levels[listItem.levels.length - 1].format.startNumberOverride = parseInt(startNumberOverrideOrBullet_1);
35508
+ }
35509
+ clearListItemStyles(listItem.levels[listItem.levels.length - 1].format);
35510
+ clearListItemStyles(listItem.format);
35511
+ });
35512
+ }
35513
+ else {
35514
+ (_b = (_a = context.defaultElementProcessors).element) === null || _b === void 0 ? void 0 : _b.call(_a, group, element, context);
35515
+ }
35516
+ });
34871
35517
  }
34872
35518
  exports.processPastedContentFromPowerPoint = processPastedContentFromPowerPoint;
35519
+ /**
35520
+ * Extract list information from PowerPoint pasted content
35521
+ *
35522
+ * The lists from PowerPoint are represent as:
35523
+ *
35524
+ * - The class 0# represents the depth of the list, if the list is in the first level, the class attribute wont be present.
35525
+ * - The mso-special-format style represents the type of bullet and the start of the list.
35526
+ * The first part of the mso-special-format is the type of bullet, and the second part is the start of the list.
35527
+ * - All the items that are in the same list have the same mso-special-format style. Which we are leveraging to identify when a list is new or part of the existing list thread.
35528
+ *
35529
+ * @example
35530
+ * ` <div class="O1" style="...">
35531
+ <span style="font-size: 5pt"
35532
+ ><span style="mso-special-format: 'numbullet6\,1'; font-family: +mj-lt"
35533
+ >i.</span
35534
+ ></span
35535
+ ><span style="...;">123</span>
35536
+ </div> `
35537
+ *
35538
+ * @param element The element to extract list information from
35539
+ * @param bulletElement The bullet element to extract list information from
35540
+ * @returns The extracted list information
35541
+ */
35542
+ function extractPowerPointListInfo(element, bulletElement) {
35543
+ var className = element.className.substring(1) || '0';
35544
+ var depth = parseInt(className) + 1;
35545
+ var style = bulletElement.getAttribute(CssStyleKey) || '';
35546
+ var msoSpecialFormat = style.match(MsoSpecialFormatRegex);
35547
+ var _a = (0, tslib_1.__read)((msoSpecialFormat === null || msoSpecialFormat === void 0 ? void 0 : msoSpecialFormat[1].replace('"', '').split('\\,')) || [], 2), bulletTypeHtml = _a[0], startNumberOverrideOrBullet = _a[1];
35548
+ var isOrderedList = OrderedListStyleMap.has(bulletTypeHtml);
35549
+ var unorderedBulletType = UnorderedBullets.get(bulletElement.innerText);
35550
+ var orderedBulletType = OrderedListStyleMap.get(bulletTypeHtml);
35551
+ return {
35552
+ depth: depth,
35553
+ unorderedBulletType: unorderedBulletType,
35554
+ orderedBulletType: orderedBulletType,
35555
+ startNumberOverrideOrBullet: startNumberOverrideOrBullet,
35556
+ isOrderedList: isOrderedList,
35557
+ isNewList: isOrderedList &&
35558
+ !!orderedBulletType &&
35559
+ bulletElement.innerText ===
35560
+ getPptListStart(orderedBulletType, startNumberOverrideOrBullet),
35561
+ };
35562
+ }
35563
+ var UnorderedBullets = new Map([
35564
+ ['•', 'Disc'],
35565
+ ['o', 'Circle'],
35566
+ ['§', 'Square'],
35567
+ ['q', 'BoxShadow'],
35568
+ ['v', 'Xrhombus'],
35569
+ ['Ø', 'ShortArrow'],
35570
+ ['ü', 'CheckMark'],
35571
+ ]);
35572
+ var OrderedListStyleMap = new Map([
35573
+ ['numbullet1', 'UpperAlpha'],
35574
+ ['numbullet2', 'DecimalParenthesis'],
35575
+ ['numbullet3', 'Decimal'],
35576
+ ['numbullet7', 'UpperRoman'],
35577
+ ['numbullet9', 'LowerAlphaParenthesis'],
35578
+ ['numbullet0', 'LowerAlpha'],
35579
+ ['numbullet6', 'LowerRoman'],
35580
+ ]);
35581
+ function getPptListStart(orderedBulletType, startNumberOverride) {
35582
+ var bullet = (0, roosterjs_content_model_dom_1.getOrderedListNumberStr)(roosterjs_content_model_dom_1.NumberingListType[orderedBulletType], parseInt(startNumberOverride));
35583
+ switch (orderedBulletType) {
35584
+ case 'Decimal':
35585
+ case 'UpperAlpha':
35586
+ case 'LowerAlpha':
35587
+ case 'UpperRoman':
35588
+ case 'LowerRoman':
35589
+ return bullet + '.';
35590
+ case 'DecimalParenthesis':
35591
+ case 'LowerAlphaParenthesis':
35592
+ return bullet + ')';
35593
+ default:
35594
+ return undefined;
35595
+ }
35596
+ }
34873
35597
 
34874
35598
 
34875
35599
  /***/ }),
@@ -35165,6 +35889,36 @@ exports.getStyleMetadata = void 0;
35165
35889
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
35166
35890
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
35167
35891
  var FORMATING_REGEX = /[\n\t'{}"]+/g;
35892
+ var STYLE_TAG = '<style';
35893
+ var STYLE_TAG_END = '</style>';
35894
+ var nonWordCharacterRegex = /\W/;
35895
+ function extractStyleTagsFromHtml(htmlContent) {
35896
+ var _a;
35897
+ var styles = [];
35898
+ var _b = extractHtmlIndexes(htmlContent), styleIndex = _b.styleIndex, styleEndIndex = _b.styleEndIndex;
35899
+ while (styleIndex >= 0 && styleEndIndex >= 0) {
35900
+ var styleContent = htmlContent
35901
+ .substring(styleIndex + STYLE_TAG.length, styleEndIndex)
35902
+ .trim();
35903
+ styles.push(styleContent);
35904
+ (_a = extractHtmlIndexes(htmlContent, styleEndIndex + 1), styleIndex = _a.styleIndex, styleEndIndex = _a.styleEndIndex);
35905
+ }
35906
+ return styles;
35907
+ }
35908
+ function extractHtmlIndexes(html, startIndex) {
35909
+ if (startIndex === void 0) { startIndex = 0; }
35910
+ var htmlLowercase = html.toLowerCase();
35911
+ var styleIndex = htmlLowercase.indexOf(STYLE_TAG, startIndex);
35912
+ var currentIndex = styleIndex + STYLE_TAG.length;
35913
+ var nextChar = html.substring(currentIndex, currentIndex + 1);
35914
+ while (!nonWordCharacterRegex.test(nextChar) && styleIndex > -1) {
35915
+ styleIndex = htmlLowercase.indexOf(STYLE_TAG, styleIndex + 1);
35916
+ currentIndex = styleIndex + STYLE_TAG.length;
35917
+ nextChar = html.substring(currentIndex, currentIndex + 1);
35918
+ }
35919
+ var styleEndIndex = htmlLowercase.indexOf(STYLE_TAG_END, startIndex);
35920
+ return { styleIndex: styleIndex, styleEndIndex: styleEndIndex };
35921
+ }
35168
35922
  /**
35169
35923
  * @internal
35170
35924
  * Word Desktop content has a style tag that contains data for the lists.
@@ -35185,12 +35939,10 @@ var FORMATING_REGEX = /[\n\t'{}"]+/g;
35185
35939
  * 5. Save data in record and only use the required information.
35186
35940
  *
35187
35941
  */
35188
- function getStyleMetadata(ev, domCreator) {
35942
+ function getStyleMetadata(ev) {
35189
35943
  var metadataMap = new Map();
35190
- var doc = domCreator.htmlToDOM(ev.htmlBefore);
35191
- var styles = doc.querySelectorAll('style');
35192
- styles.forEach(function (style) {
35193
- var text = (style === null || style === void 0 ? void 0 : style.innerHTML.trim()) || '';
35944
+ var headStyles = extractStyleTagsFromHtml(ev.htmlBefore || ev.clipboardData.rawHtml || '');
35945
+ headStyles.forEach(function (text) {
35194
35946
  var index = 0;
35195
35947
  var _loop_1 = function () {
35196
35948
  var indexAt = text.indexOf('@', index + 1);
@@ -35257,7 +36009,7 @@ var getStyleMetadata_1 = __webpack_require__(/*! ./getStyleMetadata */ "./packag
35257
36009
  var getStyles_1 = __webpack_require__(/*! ../utils/getStyles */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/getStyles.ts");
35258
36010
  var processWordComments_1 = __webpack_require__(/*! ./processWordComments */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordComments.ts");
35259
36011
  var processWordLists_1 = __webpack_require__(/*! ./processWordLists */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts");
35260
- var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ./removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeNegativeTextIndentParser.ts");
36012
+ var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ../parsers/removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts");
35261
36013
  var setProcessor_1 = __webpack_require__(/*! ../utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
35262
36014
  var PERCENTAGE_REGEX = /%/;
35263
36015
  // Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal
@@ -35267,8 +36019,8 @@ var DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;
35267
36019
  * Handles Pasted content when source is Word Desktop
35268
36020
  * @param ev BeforePasteEvent
35269
36021
  */
35270
- function processPastedContentFromWordDesktop(ev, domCreator) {
35271
- var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(ev, domCreator);
36022
+ function processPastedContentFromWordDesktop(ev) {
36023
+ var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(ev);
35272
36024
  (0, setProcessor_1.setProcessor)(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
35273
36025
  (0, addParser_1.addParser)(ev.domToModelOption, 'block', adjustPercentileLineHeight);
35274
36026
  (0, addParser_1.addParser)(ev.domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
@@ -35296,12 +36048,12 @@ function adjustPercentileLineHeight(format, element) {
35296
36048
  (parsedLineHeight / 100)).toString();
35297
36049
  }
35298
36050
  }
35299
- function listLevelParser(format, element, context, defaultStyle) {
36051
+ var listLevelParser = function (format, element, _context, defaultStyle) {
35300
36052
  if (element.style.marginLeft != '') {
35301
36053
  format.marginLeft = defaultStyle.marginLeft;
35302
36054
  }
35303
36055
  format.marginBottom = undefined;
35304
- }
36056
+ };
35305
36057
  var wordTableParser = function (format) {
35306
36058
  var _a;
35307
36059
  if ((_a = format.marginLeft) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
@@ -35355,7 +36107,7 @@ exports.processWordComments = processWordComments;
35355
36107
  Object.defineProperty(exports, "__esModule", ({ value: true }));
35356
36108
  exports.processWordList = void 0;
35357
36109
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
35358
- var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ./removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeNegativeTextIndentParser.ts");
36110
+ var customListUtils_1 = __webpack_require__(/*! ../utils/customListUtils */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/customListUtils.ts");
35359
36111
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
35360
36112
  /** Word list metadata style name */
35361
36113
  var MSO_LIST = 'mso-list';
@@ -35395,28 +36147,28 @@ function processWordList(styles, group, element, context, metadata) {
35395
36147
  if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {
35396
36148
  var wordLevel = listFormat.wordLevel, wordList = listFormat.wordList;
35397
36149
  // Retrieve the Fake bullet on the element and also the list type
35398
- var listMetadata = metadata.get(lNumber + ":" + level);
35399
- var listType = ((_a = listMetadata === null || listMetadata === void 0 ? void 0 : listMetadata['mso-level-number-format']) === null || _a === void 0 ? void 0 : _a.toLowerCase()) != BULLET_METADATA
36150
+ var listMetadata_1 = metadata.get(lNumber + ":" + level);
36151
+ var listType_1 = ((_a = listMetadata_1 === null || listMetadata_1 === void 0 ? void 0 : listMetadata_1['mso-level-number-format']) === null || _a === void 0 ? void 0 : _a.toLowerCase()) != BULLET_METADATA
35400
36152
  ? 'OL'
35401
36153
  : 'UL';
35402
36154
  // Create the new level of the list item and parse the format
35403
- var newLevel = (0, roosterjs_content_model_dom_1.createListLevel)(listType);
35404
- (0, roosterjs_content_model_dom_1.parseFormat)(element, (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(context.formatParsers.listLevel), false), [wordListPaddingParser], false), newLevel.format, context);
35405
- // If the list format is in a different level, update the array so we get the new item
35406
- // To be in the same level as the provided level metadata.
35407
- if (wordLevel > listFormat.levels.length) {
35408
- while (wordLevel != listFormat.levels.length) {
35409
- listFormat.levels.push(newLevel);
35410
- }
35411
- }
35412
- else {
35413
- listFormat.levels.splice(wordLevel, listFormat.levels.length - 1);
35414
- listFormat.levels[wordLevel - 1] = newLevel;
35415
- }
36155
+ (0, customListUtils_1.setupListFormat)(listType_1, element, context, wordLevel, listFormat, group, [
36156
+ wordListPaddingParser,
36157
+ ]);
35416
36158
  listFormat.levels[listFormat.levels.length - 1]
35417
36159
  .format.wordList = wordList;
35418
- listFormat.listParent = group;
35419
- processAsListItem(listFormat, context, element, group, listMetadata);
36160
+ var bullet = getBulletFromMetadata(listMetadata_1, listType_1);
36161
+ var listFormatMetadata = bullet
36162
+ ? {
36163
+ unorderedStyleType: listType_1 == 'UL' ? bullet : undefined,
36164
+ orderedStyleType: listType_1 == 'OL' ? bullet : undefined,
36165
+ }
36166
+ : undefined;
36167
+ (0, customListUtils_1.processAsListItem)(context, element, group, listFormatMetadata, function (listItem) {
36168
+ if (listType_1 == 'OL') {
36169
+ setStartNumber(listItem, context, listMetadata_1, element);
36170
+ }
36171
+ });
35420
36172
  if (listFormat.levels.length > 0 &&
35421
36173
  listFormat.wordKnownLevels.get(wordList) != listFormat.levels) {
35422
36174
  listFormat.wordKnownLevels.set(wordList, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(listFormat.levels), false));
@@ -35426,28 +36178,6 @@ function processWordList(styles, group, element, context, metadata) {
35426
36178
  return false;
35427
36179
  }
35428
36180
  exports.processWordList = processWordList;
35429
- function processAsListItem(listFormat, context, element, group, listMetadata) {
35430
- var listLevel = listFormat.levels[listFormat.levels.length - 1];
35431
- var listType = listLevel.listType;
35432
- var bullet = getBulletFromMetadata(listMetadata, listType);
35433
- if (bullet) {
35434
- (0, roosterjs_content_model_dom_1.updateListMetadata)(listFormat.levels[listFormat.levels.length - 1], function (metadata) {
35435
- return Object.assign({}, metadata, {
35436
- unorderedStyleType: listType == 'UL' ? bullet : undefined,
35437
- orderedStyleType: listType == 'OL' ? bullet : undefined,
35438
- });
35439
- });
35440
- }
35441
- var listItem = (0, roosterjs_content_model_dom_1.createListItem)(listFormat.levels, context.segmentFormat);
35442
- (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);
35443
- (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.listItemElement, listItem.format, context);
35444
- (0, roosterjs_content_model_dom_1.parseFormat)(element, [removeNegativeTextIndentParser_1.removeNegativeTextIndentParser, nonListElementParser], listItem.format, context);
35445
- if (listType == 'OL') {
35446
- setStartNumber(listItem, context, listMetadata);
35447
- }
35448
- context.elementProcessors.child(listItem, element, context);
35449
- (0, roosterjs_content_model_dom_1.addBlock)(group, listItem);
35450
- }
35451
36181
  function getBulletFromMetadata(listMetadata, listType) {
35452
36182
  var templateType = (listMetadata === null || listMetadata === void 0 ? void 0 : listMetadata['mso-level-number-format']) || 'decimal';
35453
36183
  var templateFinal;
@@ -35494,15 +36224,7 @@ function getBulletFromMetadata(listMetadata, listType) {
35494
36224
  }
35495
36225
  return (0, roosterjs_content_model_dom_1.getListStyleTypeFromString)(listType, templateFinal);
35496
36226
  }
35497
- function wordListPaddingParser(format, element) {
35498
- if (element.style.marginLeft && element.style.marginLeft != '0in') {
35499
- format.paddingLeft = '0px';
35500
- }
35501
- if (element.style.marginRight && element.style.marginRight != '0in') {
35502
- format.paddingRight = '0px';
35503
- }
35504
- }
35505
- function setStartNumber(listItem, context, listMetadata) {
36227
+ function setStartNumber(listItem, context, listMetadata, element) {
35506
36228
  var _a, _b;
35507
36229
  var _c = context.listFormat, listParent = _c.listParent, wordList = _c.wordList, wordKnownLevels = _c.wordKnownLevels, wordLevel = _c.wordLevel, levels = _c.levels;
35508
36230
  var block = getLastNotEmptyBlock(listParent);
@@ -35518,6 +36240,14 @@ function setStartNumber(listItem, context, listMetadata) {
35518
36240
  if (start != undefined && !isNaN(start) && knownLevel.length != levels.length) {
35519
36241
  listItem.levels[listItem.levels.length - 1].format.startNumberOverride = start;
35520
36242
  }
36243
+ else if ((0, roosterjs_content_model_dom_1.isElementOfType)(element, 'li') &&
36244
+ (0, roosterjs_content_model_dom_1.isNodeOfType)(element.parentElement, 'ELEMENT_NODE') &&
36245
+ (0, roosterjs_content_model_dom_1.isElementOfType)(element.parentElement, 'ol') &&
36246
+ element.parentElement.firstElementChild == element &&
36247
+ knownLevel.length != element.parentElement.start) {
36248
+ listItem.levels[listItem.levels.length - 1].format.startNumberOverride =
36249
+ element.parentElement.start;
36250
+ }
35521
36251
  }
35522
36252
  }
35523
36253
  function getLastNotEmptyBlock(listParent) {
@@ -35529,43 +36259,14 @@ function getLastNotEmptyBlock(listParent) {
35529
36259
  }
35530
36260
  return undefined;
35531
36261
  }
35532
- var nonListElementParser = function (format, element, _context, defaultStyle) {
35533
- if (!(0, roosterjs_content_model_dom_1.isElementOfType)(element, 'li')) {
35534
- Object.keys(defaultStyle).forEach(function (keyInput) {
35535
- var key = keyInput;
35536
- var formatKey = keyInput;
35537
- if (key != 'display' &&
35538
- format[formatKey] != undefined &&
35539
- format[formatKey] == defaultStyle[key]) {
35540
- delete format[formatKey];
35541
- }
35542
- });
36262
+ function wordListPaddingParser(format, element) {
36263
+ if (element.style.marginLeft && element.style.marginLeft != '0in') {
36264
+ format.paddingLeft = '0px';
35543
36265
  }
35544
- };
35545
-
35546
-
35547
- /***/ }),
35548
-
35549
- /***/ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeNegativeTextIndentParser.ts":
35550
- /*!**********************************************************************************************************!*\
35551
- !*** ./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeNegativeTextIndentParser.ts ***!
35552
- \**********************************************************************************************************/
35553
- /***/ ((__unused_webpack_module, exports) => {
35554
-
35555
- "use strict";
35556
-
35557
- Object.defineProperty(exports, "__esModule", ({ value: true }));
35558
- exports.removeNegativeTextIndentParser = void 0;
35559
- /**
35560
- * @internal
35561
- */
35562
- var removeNegativeTextIndentParser = function (format, element) {
35563
- var _a;
35564
- if ((_a = format.textIndent) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
35565
- delete format.textIndent;
36266
+ if (element.style.marginRight && element.style.marginRight != '0in') {
36267
+ format.paddingRight = '0px';
35566
36268
  }
35567
- };
35568
- exports.removeNegativeTextIndentParser = removeNegativeTextIndentParser;
36269
+ }
35569
36270
 
35570
36271
 
35571
36272
  /***/ }),
@@ -35692,6 +36393,98 @@ function ensureOneNoteListContext(cmContext) {
35692
36393
  }
35693
36394
 
35694
36395
 
36396
+ /***/ }),
36397
+
36398
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/deprecatedColorParser.ts":
36399
+ /*!*********************************************************************************************!*\
36400
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/deprecatedColorParser.ts ***!
36401
+ \*********************************************************************************************/
36402
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
36403
+
36404
+ "use strict";
36405
+
36406
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
36407
+ exports.deprecatedBorderColorParser = void 0;
36408
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
36409
+ /**
36410
+ * @internal
36411
+ */
36412
+ var deprecatedBorderColorParser = function (format) {
36413
+ roosterjs_content_model_dom_1.BorderKeys.forEach(function (key) {
36414
+ var value = format[key];
36415
+ var color = '';
36416
+ if (value &&
36417
+ roosterjs_content_model_dom_1.DeprecatedColors.some(function (dColor) { return value.indexOf(dColor) > -1 && (color = dColor); })) {
36418
+ var newValue = value.replace(color, '').trimRight();
36419
+ format[key] = newValue;
36420
+ }
36421
+ });
36422
+ };
36423
+ exports.deprecatedBorderColorParser = deprecatedBorderColorParser;
36424
+
36425
+
36426
+ /***/ }),
36427
+
36428
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/linkParser.ts":
36429
+ /*!**********************************************************************************!*\
36430
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/linkParser.ts ***!
36431
+ \**********************************************************************************/
36432
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
36433
+
36434
+ "use strict";
36435
+
36436
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
36437
+ exports.parseLink = void 0;
36438
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
36439
+ var SUPPORTED_PROTOCOLS = ['http:', 'https:', 'notes:', 'mailto:', 'onenote:'];
36440
+ var INVALID_LINKS_REGEX = /^file:\/\/\/[a-zA-Z\/]/i;
36441
+ /**
36442
+ * @internal
36443
+ */
36444
+ var parseLink = function (format, element) {
36445
+ if (!(0, roosterjs_content_model_dom_1.isElementOfType)(element, 'a')) {
36446
+ return;
36447
+ }
36448
+ var url;
36449
+ try {
36450
+ url = new URL(element.href);
36451
+ }
36452
+ catch (_a) {
36453
+ url = undefined;
36454
+ }
36455
+ if ((url && SUPPORTED_PROTOCOLS.indexOf(url.protocol) === -1) ||
36456
+ INVALID_LINKS_REGEX.test(element.href)) {
36457
+ element.removeAttribute('href');
36458
+ format.href = '';
36459
+ }
36460
+ };
36461
+ exports.parseLink = parseLink;
36462
+
36463
+
36464
+ /***/ }),
36465
+
36466
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts":
36467
+ /*!******************************************************************************************************!*\
36468
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts ***!
36469
+ \******************************************************************************************************/
36470
+ /***/ ((__unused_webpack_module, exports) => {
36471
+
36472
+ "use strict";
36473
+
36474
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
36475
+ exports.removeNegativeTextIndentParser = void 0;
36476
+ /**
36477
+ * @internal
36478
+ */
36479
+ var removeNegativeTextIndentParser = function (format) {
36480
+ var _a;
36481
+ if ((_a = format.textIndent) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
36482
+ delete format.textIndent;
36483
+ }
36484
+ };
36485
+ exports.removeNegativeTextIndentParser = removeNegativeTextIndentParser;
36486
+
36487
+
35695
36488
  /***/ }),
35696
36489
 
35697
36490
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/constants.ts":
@@ -35788,7 +36581,7 @@ var getSourceFunctions = new Map([
35788
36581
  * @param shouldConvertSingleImage Whether convert single image is enabled.
35789
36582
  * @returns The Type of pasted content, if no type found will return {KnownSourceType.Default}
35790
36583
  */
35791
- function getPasteSource(event, shouldConvertSingleImage) {
36584
+ function getPasteSource(event, shouldConvertSingleImage, environment) {
35792
36585
  var htmlAttributes = event.htmlAttributes, clipboardData = event.clipboardData, fragment = event.fragment;
35793
36586
  var result = null;
35794
36587
  var param = {
@@ -35796,6 +36589,7 @@ function getPasteSource(event, shouldConvertSingleImage) {
35796
36589
  fragment: fragment,
35797
36590
  shouldConvertSingleImage: shouldConvertSingleImage,
35798
36591
  clipboardData: clipboardData,
36592
+ environment: environment,
35799
36593
  };
35800
36594
  getSourceFunctions.forEach(function (func, key) {
35801
36595
  if (!result && func(param)) {
@@ -35996,9 +36790,14 @@ var WORD_PROG_ID = 'Word.Document';
35996
36790
  * @returns
35997
36791
  */
35998
36792
  var isWordDesktopDocument = function (props) {
35999
- var htmlAttributes = props.htmlAttributes;
36793
+ var _a;
36794
+ var htmlAttributes = props.htmlAttributes, clipboardData = props.clipboardData, environment = props.environment;
36000
36795
  return (htmlAttributes[WORD_ATTRIBUTE_NAME] == WORD_ATTRIBUTE_VALUE ||
36001
- htmlAttributes[constants_1.PastePropertyNames.PROG_ID_NAME] == WORD_PROG_ID);
36796
+ htmlAttributes[constants_1.PastePropertyNames.PROG_ID_NAME] == WORD_PROG_ID ||
36797
+ // Safari removes the metadata from the clipboard html, so we need to do this check.
36798
+ !!(environment.isSafari &&
36799
+ clipboardData.rawHtml &&
36800
+ ((_a = clipboardData.rawHtml) === null || _a === void 0 ? void 0 : _a.replace(/ /g, '').indexOf(WORD_ATTRIBUTE_NAME + "=\"" + WORD_ATTRIBUTE_VALUE)) > -1));
36002
36801
  };
36003
36802
  exports.isWordDesktopDocument = isWordDesktopDocument;
36004
36803
 
@@ -36032,6 +36831,52 @@ var shouldConvertToSingleImage = function (props) {
36032
36831
  exports.shouldConvertToSingleImage = shouldConvertToSingleImage;
36033
36832
 
36034
36833
 
36834
+ /***/ }),
36835
+
36836
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/processors/pasteButtonProcessor.ts":
36837
+ /*!***********************************************************************************************!*\
36838
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/processors/pasteButtonProcessor.ts ***!
36839
+ \***********************************************************************************************/
36840
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
36841
+
36842
+ "use strict";
36843
+
36844
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
36845
+ exports.pasteButtonProcessor = void 0;
36846
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
36847
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
36848
+ /**
36849
+ * @internal
36850
+ * This processor is used to process <button> elements in the DOM and convert them into Content Model.
36851
+ * It handles the button element by creating a text segment for each text node within the button.
36852
+ */
36853
+ var pasteButtonProcessor = function (group, element, context) {
36854
+ var format = {};
36855
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.segment, format, context);
36856
+ // Recursively process text nodes in the button
36857
+ processTextNodesRecursively(group, element, context, format);
36858
+ };
36859
+ exports.pasteButtonProcessor = pasteButtonProcessor;
36860
+ /**
36861
+ * Helper function to recursively iterate through nodes and process text nodes
36862
+ */
36863
+ function processTextNodesRecursively(group, node, context, format) {
36864
+ if (node.nodeType === Node.TEXT_NODE) {
36865
+ // Process text node directly
36866
+ var text = (0, roosterjs_content_model_dom_1.createText)(node.nodeValue || '', format);
36867
+ (0, roosterjs_content_model_dom_1.addSegment)(group, text);
36868
+ }
36869
+ else if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE')) {
36870
+ var newFormat = (0, tslib_1.__assign)({}, format);
36871
+ (0, roosterjs_content_model_dom_1.parseFormat)(node, context.formatParsers.segment, newFormat, context);
36872
+ // Recursively process all child nodes
36873
+ for (var i = 0; i < node.childNodes.length; i++) {
36874
+ processTextNodesRecursively(group, node.childNodes[i], context, newFormat);
36875
+ }
36876
+ }
36877
+ }
36878
+
36879
+
36035
36880
  /***/ }),
36036
36881
 
36037
36882
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/utils/addParser.ts":
@@ -36108,32 +36953,75 @@ exports.chainSanitizerCallback = chainSanitizerCallback;
36108
36953
 
36109
36954
  /***/ }),
36110
36955
 
36111
- /***/ "./packages/roosterjs-content-model-plugins/lib/paste/utils/deprecatedColorParser.ts":
36112
- /*!*******************************************************************************************!*\
36113
- !*** ./packages/roosterjs-content-model-plugins/lib/paste/utils/deprecatedColorParser.ts ***!
36114
- \*******************************************************************************************/
36956
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/utils/customListUtils.ts":
36957
+ /*!*************************************************************************************!*\
36958
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/utils/customListUtils.ts ***!
36959
+ \*************************************************************************************/
36115
36960
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
36116
36961
 
36117
36962
  "use strict";
36118
36963
 
36119
36964
  Object.defineProperty(exports, "__esModule", ({ value: true }));
36120
- exports.deprecatedBorderColorParser = void 0;
36965
+ exports.processAsListItem = exports.setupListFormat = void 0;
36966
+ var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ../parsers/removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts");
36121
36967
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
36968
+ var removeMargin = function (format) {
36969
+ delete format.marginLeft;
36970
+ };
36122
36971
  /**
36123
36972
  * @internal
36124
36973
  */
36125
- var deprecatedBorderColorParser = function (format) {
36126
- roosterjs_content_model_dom_1.BorderKeys.forEach(function (key) {
36127
- var value = format[key];
36128
- var color = '';
36129
- if (value &&
36130
- roosterjs_content_model_dom_1.DeprecatedColors.some(function (dColor) { return value.indexOf(dColor) > -1 && (color = dColor); })) {
36131
- var newValue = value.replace(color, '').trimRight();
36132
- format[key] = newValue;
36974
+ function setupListFormat(listType, element, context, listDepth, listFormat, group, additionalParsers) {
36975
+ if (additionalParsers === void 0) { additionalParsers = []; }
36976
+ var newLevel = (0, roosterjs_content_model_dom_1.createListLevel)(listType);
36977
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.listLevel, newLevel.format, context);
36978
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, additionalParsers.concat(removeMargin), newLevel.format, context);
36979
+ // If the list format is in a different level, update the array so we get the new item
36980
+ // To be in the same level as the provided level metadata.
36981
+ if (listDepth > listFormat.levels.length) {
36982
+ while (listDepth != listFormat.levels.length) {
36983
+ listFormat.levels.push(newLevel);
36133
36984
  }
36134
- });
36985
+ }
36986
+ else {
36987
+ listFormat.levels.splice(listDepth, listFormat.levels.length - 1);
36988
+ listFormat.levels[listDepth - 1] = newLevel;
36989
+ }
36990
+ listFormat.listParent = group;
36991
+ }
36992
+ exports.setupListFormat = setupListFormat;
36993
+ /**
36994
+ * @internal
36995
+ */
36996
+ function processAsListItem(context, element, group, listFormatMetadata, beforeProcessingChildren) {
36997
+ var listFormat = context.listFormat;
36998
+ if (listFormatMetadata) {
36999
+ (0, roosterjs_content_model_dom_1.updateListMetadata)(listFormat.levels[listFormat.levels.length - 1], function (metadata) {
37000
+ return Object.assign({}, metadata, listFormatMetadata);
37001
+ });
37002
+ }
37003
+ var listItem = (0, roosterjs_content_model_dom_1.createListItem)(listFormat.levels, context.segmentFormat);
37004
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);
37005
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.listItemElement, listItem.format, context);
37006
+ (0, roosterjs_content_model_dom_1.parseFormat)(element, [removeNegativeTextIndentParser_1.removeNegativeTextIndentParser, nonListElementParser], listItem.format, context);
37007
+ beforeProcessingChildren === null || beforeProcessingChildren === void 0 ? void 0 : beforeProcessingChildren(listItem);
37008
+ context.elementProcessors.child(listItem, element, context);
37009
+ (0, roosterjs_content_model_dom_1.addBlock)(group, listItem);
37010
+ }
37011
+ exports.processAsListItem = processAsListItem;
37012
+ var nonListElementParser = function (format, element, _context, defaultStyle) {
37013
+ if (!(0, roosterjs_content_model_dom_1.isElementOfType)(element, 'li')) {
37014
+ Object.keys(defaultStyle).forEach(function (keyInput) {
37015
+ var key = keyInput;
37016
+ var formatKey = keyInput;
37017
+ if (key != 'display' &&
37018
+ format[formatKey] != undefined &&
37019
+ format[formatKey] == defaultStyle[key]) {
37020
+ delete format[formatKey];
37021
+ }
37022
+ });
37023
+ }
36135
37024
  };
36136
- exports.deprecatedBorderColorParser = deprecatedBorderColorParser;
36137
37025
 
36138
37026
 
36139
37027
  /***/ }),
@@ -36169,44 +37057,6 @@ function getStyles(element) {
36169
37057
  exports.getStyles = getStyles;
36170
37058
 
36171
37059
 
36172
- /***/ }),
36173
-
36174
- /***/ "./packages/roosterjs-content-model-plugins/lib/paste/utils/linkParser.ts":
36175
- /*!********************************************************************************!*\
36176
- !*** ./packages/roosterjs-content-model-plugins/lib/paste/utils/linkParser.ts ***!
36177
- \********************************************************************************/
36178
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
36179
-
36180
- "use strict";
36181
-
36182
- Object.defineProperty(exports, "__esModule", ({ value: true }));
36183
- exports.parseLink = void 0;
36184
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
36185
- var SUPPORTED_PROTOCOLS = ['http:', 'https:', 'notes:', 'mailto:', 'onenote:'];
36186
- var INVALID_LINKS_REGEX = /^file:\/\/\/[a-zA-Z\/]/i;
36187
- /**
36188
- * @internal
36189
- */
36190
- var parseLink = function (format, element) {
36191
- if (!(0, roosterjs_content_model_dom_1.isElementOfType)(element, 'a')) {
36192
- return;
36193
- }
36194
- var url;
36195
- try {
36196
- url = new URL(element.href);
36197
- }
36198
- catch (_a) {
36199
- url = undefined;
36200
- }
36201
- if ((url && SUPPORTED_PROTOCOLS.indexOf(url.protocol) === -1) ||
36202
- INVALID_LINKS_REGEX.test(element.href)) {
36203
- element.removeAttribute('href');
36204
- format.href = '';
36205
- }
36206
- };
36207
- exports.parseLink = parseLink;
36208
-
36209
-
36210
37060
  /***/ }),
36211
37061
 
36212
37062
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts":
@@ -37234,6 +38084,7 @@ exports.setShortcutIndentationCommand = setShortcutIndentationCommand;
37234
38084
 
37235
38085
  Object.defineProperty(exports, "__esModule", ({ value: true }));
37236
38086
  exports.TableEditPlugin = void 0;
38087
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
37237
38088
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
37238
38089
  var TableEditor_1 = __webpack_require__(/*! ./editors/TableEditor */ "./packages/roosterjs-content-model-plugins/lib/tableEdit/editors/TableEditor.ts");
37239
38090
  var TABLE_RESIZER_LENGTH = 12;
@@ -37248,12 +38099,15 @@ var TableEditPlugin = /** @class */ (function () {
37248
38099
  * If not specified, the plugin will be inserted in document.body
37249
38100
  * @param onTableEditorCreated An optional callback to customize the Table Editors elements when created.
37250
38101
  * @param disableFeatures An optional array of TableEditFeatures to disable
38102
+ * @param tableSelector A function to select the tables to be edited. By default, it selects all contentEditable tables.
37251
38103
  */
37252
- function TableEditPlugin(anchorContainerSelector, onTableEditorCreated, disableFeatures) {
38104
+ function TableEditPlugin(anchorContainerSelector, onTableEditorCreated, disableFeatures, tableSelector) {
37253
38105
  var _this = this;
38106
+ if (tableSelector === void 0) { tableSelector = defaultTableSelector; }
37254
38107
  this.anchorContainerSelector = anchorContainerSelector;
37255
38108
  this.onTableEditorCreated = onTableEditorCreated;
37256
38109
  this.disableFeatures = disableFeatures;
38110
+ this.tableSelector = tableSelector;
37257
38111
  this.editor = null;
37258
38112
  this.onMouseMoveDisposer = null;
37259
38113
  this.tableRectMap = null;
@@ -37284,12 +38138,13 @@ var TableEditPlugin = /** @class */ (function () {
37284
38138
  //Find table in range of mouse
37285
38139
  if (_this.tableRectMap) {
37286
38140
  for (var i = _this.tableRectMap.length - 1; i >= 0; i--) {
37287
- var _b = _this.tableRectMap[i], table = _b.table, rect = _b.rect;
38141
+ var entry = _this.tableRectMap[i];
38142
+ var rect = entry.rect;
37288
38143
  if (x >= rect.left - TABLE_RESIZER_LENGTH &&
37289
38144
  x <= rect.right + TABLE_RESIZER_LENGTH &&
37290
38145
  y >= rect.top - TABLE_RESIZER_LENGTH &&
37291
38146
  y <= rect.bottom + TABLE_RESIZER_LENGTH) {
37292
- currentTable = table;
38147
+ currentTable = entry;
37293
38148
  break;
37294
38149
  }
37295
38150
  }
@@ -37350,19 +38205,21 @@ var TableEditPlugin = /** @class */ (function () {
37350
38205
  };
37351
38206
  /**
37352
38207
  * @internal Public only for unit test
37353
- * @param table Table to use when setting the Editors
38208
+ * @param entry Table to use when setting the Editors
37354
38209
  * @param event (Optional) Mouse event
37355
38210
  */
37356
- TableEditPlugin.prototype.setTableEditor = function (table, event) {
37357
- if (this.tableEditor && !this.tableEditor.isEditing() && table != this.tableEditor.table) {
38211
+ TableEditPlugin.prototype.setTableEditor = function (entry, event) {
38212
+ if (this.tableEditor &&
38213
+ !this.tableEditor.isEditing() &&
38214
+ (entry === null || entry === void 0 ? void 0 : entry.table) != this.tableEditor.table) {
37358
38215
  this.disposeTableEditor();
37359
38216
  }
37360
- if (!this.tableEditor && table && this.editor && table.rows.length > 0) {
38217
+ if (!this.tableEditor && entry && this.editor && entry.table.rows.length > 0) {
37361
38218
  // anchorContainerSelector is used to specify the container to host the plugin, which can be outside of the editor's div
37362
38219
  var container = this.anchorContainerSelector
37363
38220
  ? this.editor.getDocument().querySelector(this.anchorContainerSelector)
37364
38221
  : undefined;
37365
- this.tableEditor = new TableEditor_1.TableEditor(this.editor, table, this.invalidateTableRects, (0, roosterjs_content_model_dom_1.isNodeOfType)(container, 'ELEMENT_NODE') ? container : undefined, event === null || event === void 0 ? void 0 : event.currentTarget, this.onTableEditorCreated, this.disableFeatures);
38222
+ this.tableEditor = new TableEditor_1.TableEditor(this.editor, entry.table, entry.logicalRoot, this.invalidateTableRects, (0, roosterjs_content_model_dom_1.isNodeOfType)(container, 'ELEMENT_NODE') ? container : undefined, event === null || event === void 0 ? void 0 : event.currentTarget, this.onTableEditorCreated, this.disableFeatures);
37366
38223
  }
37367
38224
  };
37368
38225
  TableEditPlugin.prototype.disposeTableEditor = function () {
@@ -37374,16 +38231,11 @@ var TableEditPlugin = /** @class */ (function () {
37374
38231
  var _this = this;
37375
38232
  if (!this.tableRectMap && this.editor) {
37376
38233
  this.tableRectMap = [];
37377
- var tables = this.editor.getDOMHelper().queryElements('table');
38234
+ var tables = this.tableSelector(this.editor.getDOMHelper());
37378
38235
  tables.forEach(function (table) {
37379
- if (table.isContentEditable) {
37380
- var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(table.getBoundingClientRect());
37381
- if (rect && _this.tableRectMap) {
37382
- _this.tableRectMap.push({
37383
- table: table,
37384
- rect: rect,
37385
- });
37386
- }
38236
+ var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(table.table.getBoundingClientRect());
38237
+ if (rect && _this.tableRectMap) {
38238
+ _this.tableRectMap.push((0, tslib_1.__assign)((0, tslib_1.__assign)({}, table), { rect: rect }));
37387
38239
  }
37388
38240
  });
37389
38241
  }
@@ -37391,6 +38243,15 @@ var TableEditPlugin = /** @class */ (function () {
37391
38243
  return TableEditPlugin;
37392
38244
  }());
37393
38245
  exports.TableEditPlugin = TableEditPlugin;
38246
+ function defaultTableSelector(domHelper) {
38247
+ return domHelper
38248
+ .queryElements('table')
38249
+ .filter(function (table) { return table.isContentEditable; })
38250
+ .map(function (table) { return ({
38251
+ table: table,
38252
+ logicalRoot: null,
38253
+ }); });
38254
+ }
37394
38255
 
37395
38256
 
37396
38257
  /***/ }),
@@ -37447,11 +38308,12 @@ var TOP_OR_SIDE;
37447
38308
  * When set a different current table or change current TD, we need to update these areas
37448
38309
  */
37449
38310
  var TableEditor = /** @class */ (function () {
37450
- function TableEditor(editor, table, onChanged, anchorContainer, contentDiv, onTableEditorCreated, disableFeatures) {
38311
+ function TableEditor(editor, table, logicalRoot, onChanged, anchorContainer, contentDiv, onTableEditorCreated, disableFeatures) {
37451
38312
  var _this = this;
37452
38313
  var _a;
37453
38314
  this.editor = editor;
37454
38315
  this.table = table;
38316
+ this.logicalRoot = logicalRoot;
37455
38317
  this.onChanged = onChanged;
37456
38318
  this.anchorContainer = anchorContainer;
37457
38319
  this.contentDiv = contentDiv;
@@ -37503,6 +38365,7 @@ var TableEditor = /** @class */ (function () {
37503
38365
  _this.onStartResize();
37504
38366
  };
37505
38367
  this.onStartTableMove = function () {
38368
+ _this.onBeforeEditTable();
37506
38369
  _this.isCurrentlyEditing = true;
37507
38370
  _this.disposeTableResizer();
37508
38371
  _this.disposeTableInserter();
@@ -37514,7 +38377,10 @@ var TableEditor = /** @class */ (function () {
37514
38377
  }
37515
38378
  return _this.onFinishEditing();
37516
38379
  };
37517
- this.onInserted = function () {
38380
+ this.onBeforeEditTable = function () {
38381
+ _this.editor.setLogicalRoot(_this.logicalRoot);
38382
+ };
38383
+ this.onAfterInsert = function () {
37518
38384
  _this.disposeTableResizer();
37519
38385
  _this.onFinishEditing();
37520
38386
  };
@@ -37681,7 +38547,7 @@ var TableEditor = /** @class */ (function () {
37681
38547
  this.disposeTableInserter();
37682
38548
  }
37683
38549
  if (!this.horizontalInserter && !this.verticalInserter && td) {
37684
- var newInserter = (0, TableInserter_1.createTableInserter)(this.editor, td, this.table, this.isRTL, !!isHorizontal, this.onInserted, this.anchorContainer, this.onEditorCreated);
38550
+ var newInserter = (0, TableInserter_1.createTableInserter)(this.editor, td, this.table, this.isRTL, !!isHorizontal, this.onBeforeEditTable, this.onAfterInsert, this.anchorContainer, this.onEditorCreated);
37685
38551
  if (isHorizontal) {
37686
38552
  this.horizontalInserter = newInserter;
37687
38553
  }
@@ -37723,6 +38589,7 @@ var TableEditor = /** @class */ (function () {
37723
38589
  }
37724
38590
  };
37725
38591
  TableEditor.prototype.onStartResize = function () {
38592
+ this.onBeforeEditTable();
37726
38593
  this.isCurrentlyEditing = true;
37727
38594
  var range = this.editor.getDOMSelection();
37728
38595
  if (range && range.type == 'range') {
@@ -38003,7 +38870,7 @@ exports.VERTICAL_INSERTER_ID = 'verticalInserter';
38003
38870
  /**
38004
38871
  * @internal
38005
38872
  */
38006
- function createTableInserter(editor, td, table, isRTL, isHorizontal, onInsert, anchorContainer, onTableEditorCreated) {
38873
+ function createTableInserter(editor, td, table, isRTL, isHorizontal, onBeforeInsert, onAfterInserted, anchorContainer, onTableEditorCreated) {
38007
38874
  var tdRect = (0, roosterjs_content_model_dom_1.normalizeRect)(td.getBoundingClientRect());
38008
38875
  var viewPort = editor.getVisibleViewport();
38009
38876
  var tableRect = table && viewPort ? (0, getIntersectedRect_1.getIntersectedRect)([table], [viewPort]) : null;
@@ -38029,7 +38896,7 @@ function createTableInserter(editor, td, table, isRTL, isHorizontal, onInsert, a
38029
38896
  div.firstChild.style.height = tableRect.bottom - tableRect.top + "px";
38030
38897
  }
38031
38898
  (anchorContainer || document_1.body).appendChild(div);
38032
- var handler = new TableInsertHandler(div, td, table, isHorizontal, editor, onInsert, onTableEditorCreated);
38899
+ var handler = new TableInsertHandler(div, td, table, isHorizontal, editor, onBeforeInsert, onAfterInserted, onTableEditorCreated);
38033
38900
  return { div: div, featureHandler: handler, node: td };
38034
38901
  }
38035
38902
  return null;
@@ -38040,14 +38907,15 @@ exports.createTableInserter = createTableInserter;
38040
38907
  * Exported for test only
38041
38908
  */
38042
38909
  var TableInsertHandler = /** @class */ (function () {
38043
- function TableInsertHandler(div, td, table, isHorizontal, editor, onInsert, onTableEditorCreated) {
38910
+ function TableInsertHandler(div, td, table, isHorizontal, editor, onBeforeInsert, onAfterInsert, onTableEditorCreated) {
38044
38911
  var _this = this;
38045
38912
  this.div = div;
38046
38913
  this.td = td;
38047
38914
  this.table = table;
38048
38915
  this.isHorizontal = isHorizontal;
38049
38916
  this.editor = editor;
38050
- this.onInsert = onInsert;
38917
+ this.onBeforeInsert = onBeforeInsert;
38918
+ this.onAfterInsert = onAfterInsert;
38051
38919
  this.insertTd = function () {
38052
38920
  // Get cell coordinates
38053
38921
  var columnIndex = _this.td.cellIndex;
@@ -38058,6 +38926,7 @@ var TableInsertHandler = /** @class */ (function () {
38058
38926
  if ((row === null || row === void 0 ? void 0 : row.cells) == undefined || rowIndex == undefined) {
38059
38927
  return;
38060
38928
  }
38929
+ _this.onBeforeInsert();
38061
38930
  // Insert row or column
38062
38931
  (0, roosterjs_content_model_api_1.formatTableWithContentModel)(_this.editor, 'editTablePlugin', function (tableModel) {
38063
38932
  _this.isHorizontal
@@ -38072,7 +38941,7 @@ var TableInsertHandler = /** @class */ (function () {
38072
38941
  lastRow: rowIndex,
38073
38942
  table: _this.table,
38074
38943
  });
38075
- _this.onInsert();
38944
+ _this.onAfterInsert();
38076
38945
  };
38077
38946
  this.div.addEventListener('click', this.insertTd);
38078
38947
  this.disposer = onTableEditorCreated === null || onTableEditorCreated === void 0 ? void 0 : onTableEditorCreated(isHorizontal ? 'HorizontalTableInserter' : 'VerticalTableInserter', div);
@@ -38738,7 +39607,7 @@ var WatermarkPlugin = /** @class */ (function () {
38738
39607
  this.isShowing = true;
38739
39608
  };
38740
39609
  WatermarkPlugin.prototype.applyWatermarkStyle = function (editor) {
38741
- var rule = "position: absolute; pointer-events: none; content: \"" + this.watermark + "\";";
39610
+ var rule = "position: absolute; pointer-events: none; margin-inline-start: 1px; content: \"" + this.watermark + "\";";
38742
39611
  var format = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, this.format), { textColor: editor.isDarkMode() ? this.darkTextColor : this.format.textColor });
38743
39612
  (0, roosterjs_content_model_dom_1.getObjectKeys)(styleMap).forEach(function (x) {
38744
39613
  if (format[x]) {