roosterjs 9.41.0 → 9.44.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.
@@ -2094,7 +2094,7 @@ exports["default"] = getDarkColor;
2094
2094
 
2095
2095
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2096
2096
  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;
2097
- exports.adjustWordSelection = 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;
2097
+ exports.adjustWordSelection = exports.queryContentModelBlocks = exports.getListAnnounceData = exports.getPromoteLink = exports.promoteLink = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = exports.formatSegmentWithContentModel = void 0;
2098
2098
  var insertTable_1 = __webpack_require__(/*! ./publicApi/table/insertTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts");
2099
2099
  Object.defineProperty(exports, "insertTable", ({ enumerable: true, get: function () { return insertTable_1.insertTable; } }));
2100
2100
  var formatTable_1 = __webpack_require__(/*! ./publicApi/table/formatTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/formatTable.ts");
@@ -2215,6 +2215,7 @@ var matchLink_1 = __webpack_require__(/*! ./modelApi/link/matchLink */ "./packag
2215
2215
  Object.defineProperty(exports, "matchLink", ({ enumerable: true, get: function () { return matchLink_1.matchLink; } }));
2216
2216
  var promoteLink_1 = __webpack_require__(/*! ./modelApi/link/promoteLink */ "./packages/roosterjs-content-model-api/lib/modelApi/link/promoteLink.ts");
2217
2217
  Object.defineProperty(exports, "promoteLink", ({ enumerable: true, get: function () { return promoteLink_1.promoteLink; } }));
2218
+ Object.defineProperty(exports, "getPromoteLink", ({ enumerable: true, get: function () { return promoteLink_1.getPromoteLink; } }));
2218
2219
  var getListAnnounceData_1 = __webpack_require__(/*! ./modelApi/list/getListAnnounceData */ "./packages/roosterjs-content-model-api/lib/modelApi/list/getListAnnounceData.ts");
2219
2220
  Object.defineProperty(exports, "getListAnnounceData", ({ enumerable: true, get: function () { return getListAnnounceData_1.getListAnnounceData; } }));
2220
2221
  var queryContentModelBlocks_1 = __webpack_require__(/*! ./modelApi/common/queryContentModelBlocks */ "./packages/roosterjs-content-model-api/lib/modelApi/common/queryContentModelBlocks.ts");
@@ -2533,7 +2534,13 @@ function setModelIndentation(model, indentation, length, context) {
2533
2534
  }
2534
2535
  }
2535
2536
  });
2536
- return paragraphOrListItem.length > 0;
2537
+ if (paragraphOrListItem.length > 0) {
2538
+ (0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
2539
+ return true;
2540
+ }
2541
+ else {
2542
+ return false;
2543
+ }
2537
2544
  }
2538
2545
  exports.setModelIndentation = setModelIndentation;
2539
2546
  function isSelected(listItem) {
@@ -3448,9 +3455,12 @@ var MAILTO_REGEX = "(M|m)ailto:" + COMMON_REGEX;
3448
3455
  function getLinkUrl(text, autoLinkOptions) {
3449
3456
  var _a;
3450
3457
  var _b = autoLinkOptions !== null && autoLinkOptions !== void 0 ? autoLinkOptions : {}, autoLink = _b.autoLink, autoMailto = _b.autoMailto, autoTel = _b.autoTel;
3458
+ var mailtoMatch = matchMailTo(text);
3459
+ if (mailtoMatch && !autoMailto) {
3460
+ return undefined;
3461
+ }
3451
3462
  var linkMatch = autoLink ? (_a = (0, matchLink_1.matchLink)(text)) === null || _a === void 0 ? void 0 : _a.normalizedUrl : undefined;
3452
3463
  var telMatch = autoTel ? matchTel(text) : undefined;
3453
- var mailtoMatch = autoMailto ? matchMailTo(text) : undefined;
3454
3464
  return linkMatch || telMatch || mailtoMatch;
3455
3465
  }
3456
3466
  exports.getLinkUrl = getLinkUrl;
@@ -3577,7 +3587,7 @@ exports.matchLink = matchLink;
3577
3587
  "use strict";
3578
3588
 
3579
3589
  Object.defineProperty(exports, "__esModule", ({ value: true }));
3580
- exports.promoteLink = void 0;
3590
+ exports.getPromoteLink = exports.promoteLink = void 0;
3581
3591
  var getLinkUrl_1 = __webpack_require__(/*! ./getLinkUrl */ "./packages/roosterjs-content-model-api/lib/modelApi/link/getLinkUrl.ts");
3582
3592
  var splitTextSegment_1 = __webpack_require__(/*! ../../publicApi/segment/splitTextSegment */ "./packages/roosterjs-content-model-api/lib/publicApi/segment/splitTextSegment.ts");
3583
3593
  /**
@@ -3595,14 +3605,12 @@ function promoteLink(segment, paragraph, autoLinkOptions) {
3595
3605
  if (segment.link) {
3596
3606
  return null;
3597
3607
  }
3598
- var link = segment.text.split(' ').pop();
3599
- var url = link === null || link === void 0 ? void 0 : link.trim();
3600
- var linkUrl = undefined;
3601
- if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
3602
- var linkSegment = (0, splitTextSegment_1.splitTextSegment)(segment, paragraph, segment.text.length - link.trimLeft().length, segment.text.trimRight().length);
3608
+ var promotedLink = getPromoteLink(segment, autoLinkOptions);
3609
+ if (promotedLink) {
3610
+ var linkSegment = (0, splitTextSegment_1.splitTextSegment)(segment, paragraph, segment.text.length - promotedLink.label.trimLeft().length, segment.text.trimRight().length);
3603
3611
  linkSegment.link = {
3604
3612
  format: {
3605
- href: linkUrl,
3613
+ href: promotedLink.href,
3606
3614
  underline: true,
3607
3615
  },
3608
3616
  dataset: {},
@@ -3612,6 +3620,25 @@ function promoteLink(segment, paragraph, autoLinkOptions) {
3612
3620
  return null;
3613
3621
  }
3614
3622
  exports.promoteLink = promoteLink;
3623
+ /**
3624
+ * Verify if the link can be promoted
3625
+ * @param segment The text segment to search link text from
3626
+ * @param options Options of auto link
3627
+ * @returns if a link can be promoted
3628
+ */
3629
+ function getPromoteLink(segment, autoLinkOptions) {
3630
+ var link = segment.text.split(' ').pop();
3631
+ var url = link === null || link === void 0 ? void 0 : link.trim();
3632
+ var linkUrl = undefined;
3633
+ if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
3634
+ return {
3635
+ label: link,
3636
+ href: linkUrl,
3637
+ };
3638
+ }
3639
+ return undefined;
3640
+ }
3641
+ exports.getPromoteLink = getPromoteLink;
3615
3642
 
3616
3643
 
3617
3644
  /***/ }),
@@ -3855,7 +3882,8 @@ function setListType(model, listType, removeMargins) {
3855
3882
  var _b, _c;
3856
3883
  var block = _a.block, parent = _a.parent;
3857
3884
  if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(block, 'ListItem')) {
3858
- var level = block.levels.pop();
3885
+ var mutableBlock = (0, roosterjs_content_model_dom_1.mutateBlock)(block);
3886
+ var level = mutableBlock.levels.pop();
3859
3887
  if (!alreadyInExpectedType && level) {
3860
3888
  level.listType = listType;
3861
3889
  (0, roosterjs_content_model_dom_1.updateListMetadata)(level, function (metadata) {
@@ -3863,7 +3891,7 @@ function setListType(model, listType, removeMargins) {
3863
3891
  applyListStyleFromLevel: true,
3864
3892
  });
3865
3893
  });
3866
- block.levels.push(level);
3894
+ mutableBlock.levels.push(level);
3867
3895
  }
3868
3896
  else if (block.blocks.length == 1) {
3869
3897
  (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(block.blocks[0]);
@@ -5146,7 +5174,6 @@ function getExistingHeadingTag(decorator) {
5146
5174
 
5147
5175
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5148
5176
  exports.setIndentation = void 0;
5149
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
5150
5177
  var setModelIndentation_1 = __webpack_require__(/*! ../../modelApi/block/setModelIndentation */ "./packages/roosterjs-content-model-api/lib/modelApi/block/setModelIndentation.ts");
5151
5178
  /**
5152
5179
  * Indent or outdent to selected paragraphs
@@ -5158,9 +5185,6 @@ function setIndentation(editor, indentation, length) {
5158
5185
  editor.focus();
5159
5186
  editor.formatContentModel(function (model, context) {
5160
5187
  var result = (0, setModelIndentation_1.setModelIndentation)(model, indentation, length);
5161
- if (result) {
5162
- (0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
5163
- }
5164
5188
  context.newPendingFormat = 'preserve';
5165
5189
  return result;
5166
5190
  }, {
@@ -7100,6 +7124,7 @@ exports.formatTable = formatTable;
7100
7124
 
7101
7125
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7102
7126
  exports.insertTable = void 0;
7127
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
7103
7128
  var adjustIndentation_1 = __webpack_require__(/*! ../../modelApi/common/adjustIndentation */ "./packages/roosterjs-content-model-api/lib/modelApi/common/adjustIndentation.ts");
7104
7129
  var createTableStructure_1 = __webpack_require__(/*! ../../modelApi/table/createTableStructure */ "./packages/roosterjs-content-model-api/lib/modelApi/table/createTableStructure.ts");
7105
7130
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
@@ -7109,10 +7134,10 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
7109
7134
  * @param columns Number of columns in table, it also controls the default table cell width:
7110
7135
  * if columns <= 4, width = 120px; if columns <= 6, width = 100px; else width = 70px
7111
7136
  * @param rows Number of rows in table
7112
- * @param format (Optional) The table format. If not passed, the default format will be applied:
7113
- * background color: #FFF; border color: #ABABAB
7137
+ * @param tableMetadataFormat (Optional) The table format that are stored as metadata. If not passed, the default format will be applied: background color: #FFF; border color: #ABABAB
7138
+ * @param format (Optional) The table format used for style attributes
7114
7139
  */
7115
- function insertTable(editor, columns, rows, format) {
7140
+ function insertTable(editor, columns, rows, tableMetadataFormat, format) {
7116
7141
  editor.focus();
7117
7142
  editor.formatContentModel(function (model, context) {
7118
7143
  var _a, _b, _c;
@@ -7120,11 +7145,14 @@ function insertTable(editor, columns, rows, format) {
7120
7145
  if (insertPosition) {
7121
7146
  var doc = (0, roosterjs_content_model_dom_1.createContentModelDocument)();
7122
7147
  var table = (0, createTableStructure_1.createTableStructure)(doc, columns, rows);
7148
+ if (format) {
7149
+ table.format = (0, tslib_1.__assign)({}, format);
7150
+ }
7123
7151
  (0, roosterjs_content_model_dom_1.normalizeTable)(table, editor.getPendingFormat() || insertPosition.marker.format);
7124
7152
  (0, adjustIndentation_1.adjustTableIndentation)(insertPosition, table);
7125
7153
  // Assign default vertical align
7126
- format = format || { verticalAlign: 'top' };
7127
- (0, roosterjs_content_model_dom_1.applyTableFormat)(table, format);
7154
+ tableMetadataFormat = tableMetadataFormat || { verticalAlign: 'top' };
7155
+ (0, roosterjs_content_model_dom_1.applyTableFormat)(table, tableMetadataFormat);
7128
7156
  (0, roosterjs_content_model_dom_1.mergeModel)(model, doc, context, {
7129
7157
  insertPosition: insertPosition,
7130
7158
  mergeFormat: 'mergeAll',
@@ -7478,7 +7506,7 @@ function formatSegmentWithContentModel(editor, apiName, toggleStyleCallback, seg
7478
7506
  var modelsFromEntities = [];
7479
7507
  segmentAndParagraphs.forEach(function (item) {
7480
7508
  if (item[0].segmentType == 'Entity') {
7481
- expandEntitySelections(editor, item[0], formatsAndSegments, modelsFromEntities);
7509
+ expandEntitySelections(editor, item[0], formatsAndSegments, modelsFromEntities, item[1]);
7482
7510
  }
7483
7511
  else {
7484
7512
  formatsAndSegments.push([item[0].format, item[0], item[1]]);
@@ -7523,7 +7551,7 @@ function formatSegmentWithContentModel(editor, apiName, toggleStyleCallback, seg
7523
7551
  });
7524
7552
  }
7525
7553
  exports.formatSegmentWithContentModel = formatSegmentWithContentModel;
7526
- function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEntities) {
7554
+ function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEntities, paragraph) {
7527
7555
  var _a = entity.entityFormat, id = _a.id, type = _a.entityType, isReadonly = _a.isReadonly;
7528
7556
  if (id && type) {
7529
7557
  var formattableRoots = [];
@@ -7547,6 +7575,9 @@ function expandEntitySelections(editor, entity, formatsAndSegments, modelsFromEn
7547
7575
  modelsFromEntities.push([entity, root, model]);
7548
7576
  }
7549
7577
  });
7578
+ if (formattableRoots.length > 0) {
7579
+ formatsAndSegments.push([entity.format, entity, paragraph]);
7580
+ }
7550
7581
  }
7551
7582
  }
7552
7583
  function writeBackEntities(editor, modelsFromEntities) {
@@ -7783,9 +7814,9 @@ var DefaultSanitizingOption = {
7783
7814
  /**
7784
7815
  * @internal
7785
7816
  */
7786
- function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption) {
7817
+ function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption, domHelper) {
7787
7818
  var sanitizingOption = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultSanitizingOption), additionalSanitizingOption);
7788
- return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [] }), defaultOption, {
7819
+ return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [], editorViewWidth: domHelper === null || domHelper === void 0 ? void 0 : domHelper.getClientWidth() }), defaultOption, {
7789
7820
  processorOverride: {
7790
7821
  '#text': pasteTextProcessor_1.pasteTextProcessor,
7791
7822
  entity: (0, pasteEntityProcessor_1.createPasteEntityProcessor)(sanitizingOption),
@@ -8824,7 +8855,7 @@ function mergePasteContent(editor, eventResult, isFirstPaste) {
8824
8855
  var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
8825
8856
  model.blocks = clonedModel.blocks;
8826
8857
  }
8827
- var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption);
8858
+ var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
8828
8859
  domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);
8829
8860
  var pasteModel = (0, roosterjs_content_model_dom_1.domToContentModel)(fragment, domToModelContext);
8830
8861
  var mergeOption = {
@@ -8964,8 +8995,8 @@ function createDOMFromHtml(html, domCreator) {
8964
8995
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8965
8996
  exports.retrieveHtmlInfo = void 0;
8966
8997
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
8967
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
8968
8998
  var convertInlineCss_1 = __webpack_require__(/*! ../createModelFromHtml/convertInlineCss */ "./packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts");
8999
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
8969
9000
  var START_FRAGMENT = '<!--StartFragment-->';
8970
9001
  var END_FRAGMENT = '<!--EndFragment-->';
8971
9002
  /**
@@ -8977,7 +9008,7 @@ function retrieveHtmlInfo(doc, clipboardData) {
8977
9008
  globalCssRules: [],
8978
9009
  };
8979
9010
  if (doc) {
8980
- result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata: retrieveMetadata(doc), containsBlockElements: checkBlockElements(doc) });
9011
+ result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata: (0, roosterjs_content_model_dom_1.retrieveDocumentMetadata)(doc), containsBlockElements: checkBlockElements(doc) });
8981
9012
  clipboardData.htmlFirstLevelChildTags = retrieveTopLevelTags(doc);
8982
9013
  }
8983
9014
  return result;
@@ -8999,18 +9030,6 @@ function retrieveTopLevelTags(doc) {
8999
9030
  }
9000
9031
  return topLevelTags;
9001
9032
  }
9002
- function retrieveMetadata(doc) {
9003
- var _a;
9004
- var result = {};
9005
- var attributes = (_a = doc.querySelector('html')) === null || _a === void 0 ? void 0 : _a.attributes;
9006
- (attributes ? (0, roosterjs_content_model_dom_1.toArray)(attributes) : []).forEach(function (attr) {
9007
- result[attr.name] = attr.value;
9008
- });
9009
- (0, roosterjs_content_model_dom_1.toArray)(doc.querySelectorAll('meta')).forEach(function (meta) {
9010
- result[meta.name] = meta.content;
9011
- });
9012
- return result;
9013
- }
9014
9033
  function retrieveHtmlStrings(clipboardData) {
9015
9034
  var _a;
9016
9035
  var rawHtml = (_a = clipboardData.rawHtml) !== null && _a !== void 0 ? _a : '';
@@ -9605,10 +9624,10 @@ var getRootComputedStyleForContext_1 = __webpack_require__(/*! ./getRootComputed
9605
9624
  * Create a EditorContext object used by ContentModel API
9606
9625
  */
9607
9626
  var createEditorContext = function (core, saveIndex) {
9608
- var _a, _b;
9627
+ var _a, _b, _c;
9609
9628
  var lifecycle = core.lifecycle, format = core.format, darkColorHandler = core.darkColorHandler, logicalRoot = core.logicalRoot, cache = core.cache, domHelper = core.domHelper;
9610
9629
  saveIndex = saveIndex && !core.lifecycle.shadowEditFragment;
9611
- var context = (0, tslib_1.__assign)({ isDarkMode: lifecycle.isDarkMode, defaultFormat: format.defaultFormat, pendingFormat: (_a = format.pendingFormat) !== null && _a !== void 0 ? _a : undefined, darkColorHandler: darkColorHandler, addDelimiterForEntity: true, allowCacheElement: true, domIndexer: saveIndex ? cache.domIndexer : undefined, zoomScale: domHelper.calculateZoomScale(), experimentalFeatures: (_b = core.experimentalFeatures) !== null && _b !== void 0 ? _b : [], paragraphMap: core.cache.paragraphMap }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(logicalRoot.ownerDocument));
9630
+ var context = (0, tslib_1.__assign)({ isDarkMode: lifecycle.isDarkMode, defaultFormat: format.defaultFormat, pendingFormat: (_a = format.pendingFormat) !== null && _a !== void 0 ? _a : undefined, darkColorHandler: darkColorHandler, addDelimiterForEntity: true, allowCacheElement: true, allowCacheListItem: !!((_b = core.experimentalFeatures) === null || _b === void 0 ? void 0 : _b.includes('CacheList')), domIndexer: saveIndex ? cache.domIndexer : undefined, zoomScale: domHelper.calculateZoomScale(), experimentalFeatures: (_c = core.experimentalFeatures) !== null && _c !== void 0 ? _c : [], paragraphMap: core.cache.paragraphMap, editorViewWidth: domHelper.getClientWidth() }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(logicalRoot.ownerDocument));
9612
9631
  if (core.domHelper.isRightToLeft()) {
9613
9632
  context.isRootRtl = true;
9614
9633
  }
@@ -11442,7 +11461,7 @@ var DomIndexerImpl = /** @class */ (function () {
11442
11461
  var startContainer = newRange.startContainer, startOffset = newRange.startOffset, endContainer = newRange.endContainer, endOffset = newRange.endOffset, collapsed = newRange.collapsed;
11443
11462
  delete model.hasRevertedRangeSelection;
11444
11463
  if (collapsed) {
11445
- return !!this.reconcileNodeSelection(startContainer, startOffset, model.format);
11464
+ return !!this.reconcileNodeSelection(startContainer, startOffset, model.format, selectionMarker);
11446
11465
  }
11447
11466
  else if (startContainer == endContainer &&
11448
11467
  (0, roosterjs_content_model_dom_1.isNodeOfType)(startContainer, 'TEXT_NODE')) {
@@ -11530,10 +11549,10 @@ var DomIndexerImpl = /** @class */ (function () {
11530
11549
  var start = selection.start, end = selection.end;
11531
11550
  return start.node == end.node && start.offset == end.offset;
11532
11551
  };
11533
- DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat) {
11552
+ DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker) {
11534
11553
  if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'TEXT_NODE')) {
11535
11554
  if (isIndexedSegment(node)) {
11536
- return this.reconcileTextSelection(node, offset);
11555
+ return this.reconcileTextSelection(node, offset, undefined, selectionMarker);
11537
11556
  }
11538
11557
  else if (isIndexedDelimiter(node)) {
11539
11558
  return this.reconcileDelimiterSelection(node, defaultFormat);
@@ -16987,10 +17006,6 @@ function domToContentModel(root, context) {
16987
17006
  if (((_a = context.selection) === null || _a === void 0 ? void 0 : _a.type) == 'range' && context.selection.isReverted) {
16988
17007
  model.hasRevertedRangeSelection = true;
16989
17008
  }
16990
- // When allowed, persist cached element and do not clear it if not changed
16991
- if (context.domIndexer && context.allowCacheElement) {
16992
- model.persistCache = true;
16993
- }
16994
17009
  context.elementProcessors.child(model, root, context);
16995
17010
  (0, normalizeContentModel_1.normalizeContentModel)(model);
16996
17011
  return model;
@@ -19548,6 +19563,39 @@ function readFile(file, callback) {
19548
19563
  exports.readFile = readFile;
19549
19564
 
19550
19565
 
19566
+ /***/ }),
19567
+
19568
+ /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/retrieveDocumentMetadata.ts":
19569
+ /*!***************************************************************************************!*\
19570
+ !*** ./packages/roosterjs-content-model-dom/lib/domUtils/retrieveDocumentMetadata.ts ***!
19571
+ \***************************************************************************************/
19572
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19573
+
19574
+ "use strict";
19575
+
19576
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
19577
+ exports.retrieveDocumentMetadata = void 0;
19578
+ var toArray_1 = __webpack_require__(/*! ./toArray */ "./packages/roosterjs-content-model-dom/lib/domUtils/toArray.ts");
19579
+ /**
19580
+ * Retrieves metadata from the given document, including HTML attributes and meta tags.
19581
+ * @param doc The document from which to retrieve metadata.
19582
+ * @returns A record containing metadata key-value pairs.
19583
+ */
19584
+ function retrieveDocumentMetadata(doc) {
19585
+ var _a;
19586
+ var result = {};
19587
+ var attributes = (_a = doc.querySelector('html')) === null || _a === void 0 ? void 0 : _a.attributes;
19588
+ (attributes ? (0, toArray_1.toArray)(attributes) : []).forEach(function (attr) {
19589
+ result[attr.name] = attr.value;
19590
+ });
19591
+ (0, toArray_1.toArray)(doc.querySelectorAll('meta')).forEach(function (meta) {
19592
+ result[meta.name] = meta.content;
19593
+ });
19594
+ return result;
19595
+ }
19596
+ exports.retrieveDocumentMetadata = retrieveDocumentMetadata;
19597
+
19598
+
19551
19599
  /***/ }),
19552
19600
 
19553
19601
  /***/ "./packages/roosterjs-content-model-dom/lib/domUtils/reuseCachedElement.ts":
@@ -21338,8 +21386,8 @@ exports.listLevelThreadFormatHandler = {
21338
21386
  var threadItemCounts = listFormat.threadItemCounts, levels = listFormat.levels;
21339
21387
  var depth = levels.length;
21340
21388
  if (element.start == 1 ||
21341
- (typeof threadItemCounts[depth] === 'number' &&
21342
- element.start != threadItemCounts[depth] + 1)) {
21389
+ typeof threadItemCounts[depth] !== 'number' ||
21390
+ element.start != threadItemCounts[depth] + 1) {
21343
21391
  format.startNumberOverride = element.start;
21344
21392
  }
21345
21393
  threadItemCounts[depth] = element.start - 1;
@@ -22385,8 +22433,8 @@ exports.shouldSetValue = shouldSetValue;
22385
22433
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22386
22434
  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.scrollRectIntoView = exports.normalizeRect = exports.isWhiteSpacePreserved = exports.reuseCachedElement = exports.findClosestBlockEntityContainer = exports.isBlockEntityContainer = exports.isEntityDelimiter = exports.addDelimiters = exports.generateEntityClassNames = exports.parseEntityFormat = exports.getAllEntityWrappers = exports.findClosestEntityWrapper = exports.isEntityElement = exports.unwrap = exports.wrap = exports.wrapAllChildNodes = exports.moveChildNodes = exports.toArray = exports.getSafeIdSelector = exports.getObjectKeys = exports.isElementOfType = exports.isNodeOfType = exports.hasMetadata = exports.getMetadata = exports.updateMetadata = exports.buildSelectionMarker = exports.isBlockElement = exports.areSameFormats = exports.parseFormat = exports.getRegularSelectionOffsets = exports.tableProcessor = exports.entityProcessor = exports.processChildNode = exports.handleRegularSelection = exports.childProcessor = exports.contentModelToText = exports.contentModelToDom = exports.domToContentModel = void 0;
22387
22435
  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 = exports.createParagraphDecorator = void 0;
22388
- 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.getRangesByText = 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 = exports.isCursorMovingKey = void 0;
22389
- exports.EmptySegmentFormat = exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = exports.getTableMetadata = exports.updateTableMetadata = void 0;
22436
+ 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.getRangesByText = exports.getImageState = exports.setImageState = exports.getParagraphMarker = exports.setParagraphMarker = exports.cacheGetEventData = exports.extractClipboardItems = exports.normalizeFontFamily = exports.transformColor = exports.retrieveDocumentMetadata = exports.readFile = exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.isCursorMovingKey = void 0;
22437
+ exports.EmptySegmentFormat = exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = exports.getTableMetadata = exports.updateTableMetadata = exports.getTableCellMetadata = void 0;
22390
22438
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
22391
22439
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
22392
22440
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -22570,6 +22618,8 @@ var parseTableCells_1 = __webpack_require__(/*! ./domUtils/table/parseTableCells
22570
22618
  Object.defineProperty(exports, "parseTableCells", ({ enumerable: true, get: function () { return parseTableCells_1.parseTableCells; } }));
22571
22619
  var readFile_1 = __webpack_require__(/*! ./domUtils/readFile */ "./packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts");
22572
22620
  Object.defineProperty(exports, "readFile", ({ enumerable: true, get: function () { return readFile_1.readFile; } }));
22621
+ var retrieveDocumentMetadata_1 = __webpack_require__(/*! ./domUtils/retrieveDocumentMetadata */ "./packages/roosterjs-content-model-dom/lib/domUtils/retrieveDocumentMetadata.ts");
22622
+ Object.defineProperty(exports, "retrieveDocumentMetadata", ({ enumerable: true, get: function () { return retrieveDocumentMetadata_1.retrieveDocumentMetadata; } }));
22573
22623
  var transformColor_1 = __webpack_require__(/*! ./domUtils/style/transformColor */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/transformColor.ts");
22574
22624
  Object.defineProperty(exports, "transformColor", ({ enumerable: true, get: function () { return transformColor_1.transformColor; } }));
22575
22625
  var normalizeFontFamily_1 = __webpack_require__(/*! ./domUtils/style/normalizeFontFamily */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/normalizeFontFamily.ts");
@@ -24386,32 +24436,47 @@ function formatCells(rows, format, metaOverrides) {
24386
24436
  * @param format The table metadata format
24387
24437
  */
24388
24438
  function setFirstColumnFormatBorders(rows, format) {
24389
- // Exit early hasFirstColumn is not set
24390
- if (!format.hasFirstColumn) {
24391
- return;
24392
- }
24393
24439
  rows.forEach(function (row, rowIndex) {
24394
24440
  row.cells.forEach(function (readonlyCell, cellIndex) {
24441
+ var e_1, _a, e_2, _b;
24395
24442
  var cell = (0, mutate_1.mutateBlock)(readonlyCell);
24396
24443
  if (cellIndex === 0) {
24397
- cell.isHeader = true;
24398
- switch (rowIndex) {
24399
- case 0:
24400
- cell.isHeader = !!format.hasHeaderRow;
24401
- if (cell.isHeader) {
24402
- cell.format.fontWeight = 'bold';
24444
+ if (rowIndex == 0) {
24445
+ cell.isHeader = !!format.hasHeaderRow;
24446
+ }
24447
+ try {
24448
+ for (var _c = (0, tslib_1.__values)(cell.blocks), _d = _c.next(); !_d.done; _d = _c.next()) {
24449
+ var block = _d.value;
24450
+ if (block.blockType == 'Paragraph') {
24451
+ try {
24452
+ for (var _e = (e_2 = void 0, (0, tslib_1.__values)(block.segments)), _f = _e.next(); !_f.done; _f = _e.next()) {
24453
+ var segment = _f.value;
24454
+ (0, mutate_1.mutateSegment)(block, segment, function (cellSegment) {
24455
+ if (format.hasFirstColumn) {
24456
+ cellSegment.format.fontWeight = 'bold';
24457
+ }
24458
+ else if (cellSegment.format.fontWeight == 'bold') {
24459
+ delete cellSegment.format.fontWeight;
24460
+ }
24461
+ });
24462
+ }
24463
+ }
24464
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
24465
+ finally {
24466
+ try {
24467
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
24468
+ }
24469
+ finally { if (e_2) throw e_2.error; }
24470
+ }
24403
24471
  }
24404
- break;
24405
- case rows.length - 1:
24406
- setBorderColor(cell.format, 'borderTop');
24407
- break;
24408
- case 1:
24409
- setBorderColor(cell.format, 'borderBottom');
24410
- break;
24411
- default:
24412
- setBorderColor(cell.format, 'borderTop');
24413
- setBorderColor(cell.format, 'borderBottom');
24414
- break;
24472
+ }
24473
+ }
24474
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
24475
+ finally {
24476
+ try {
24477
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
24478
+ }
24479
+ finally { if (e_1) throw e_1.error; }
24415
24480
  }
24416
24481
  }
24417
24482
  });
@@ -27036,19 +27101,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
27036
27101
  exports.iterateSelections = void 0;
27037
27102
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
27038
27103
  function iterateSelections(group, callback, option) {
27039
- var persistCache = group.blockGroupType == 'Document'
27040
- ? group.persistCache
27041
- : false;
27042
- var internalCallback = persistCache
27043
- ? callback
27044
- : function (path, tableContext, block, segments) {
27045
- var _a;
27046
- if (!!((_a = block) === null || _a === void 0 ? void 0 : _a.cachedElement)) {
27047
- delete block.cachedElement;
27048
- }
27049
- return callback(path, tableContext, block, segments);
27050
- };
27051
- internalIterateSelections([group], internalCallback, option);
27104
+ internalIterateSelections([group], callback, option);
27052
27105
  }
27053
27106
  exports.iterateSelections = iterateSelections;
27054
27107
  function internalIterateSelections(path, callback, option, table, treatAllAsSelect) {
@@ -27424,9 +27477,6 @@ function contentModelToDom(doc, root, model, context) {
27424
27477
  if (model.hasRevertedRangeSelection && (range === null || range === void 0 ? void 0 : range.type) == 'range') {
27425
27478
  range.isReverted = true;
27426
27479
  }
27427
- if (context.domIndexer && context.allowCacheElement) {
27428
- model.persistCache = true;
27429
- }
27430
27480
  root.normalize();
27431
27481
  return range;
27432
27482
  }
@@ -27725,12 +27775,11 @@ exports.handleBlock = handleBlock;
27725
27775
 
27726
27776
  Object.defineProperty(exports, "__esModule", ({ value: true }));
27727
27777
  exports.handleBlockGroupChildren = void 0;
27728
- var isNodeOfType_1 = __webpack_require__(/*! ../../domUtils/isNodeOfType */ "./packages/roosterjs-content-model-dom/lib/domUtils/isNodeOfType.ts");
27778
+ var cleanUpRestNodes_1 = __webpack_require__(/*! ../utils/cleanUpRestNodes */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/cleanUpRestNodes.ts");
27729
27779
  /**
27730
27780
  * @internal
27731
27781
  */
27732
27782
  var handleBlockGroupChildren = function (doc, parent, group, context) {
27733
- var _a;
27734
27783
  var listFormat = context.listFormat;
27735
27784
  var nodeStack = listFormat.nodeStack;
27736
27785
  var refNode = parent.firstChild;
@@ -27744,28 +27793,35 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
27744
27793
  if (index == 0 ||
27745
27794
  childBlock.blockType != 'BlockGroup' ||
27746
27795
  childBlock.blockGroupType != 'ListItem') {
27747
- listFormat.nodeStack = [];
27796
+ cleanUpNodeStack(listFormat.nodeStack, context);
27797
+ if (listFormat.nodeStack.length > 0) {
27798
+ listFormat.nodeStack = [];
27799
+ }
27748
27800
  }
27749
27801
  refNode = context.modelHandlers.block(doc, parent, childBlock, context, refNode);
27750
27802
  if (childBlock.blockType == 'Entity') {
27751
27803
  (_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onBlockEntity(childBlock, group);
27752
27804
  }
27753
27805
  });
27806
+ cleanUpNodeStack(listFormat.nodeStack, context);
27754
27807
  // Remove all rest node if any since they don't appear in content model
27755
- while (refNode) {
27756
- var next = refNode.nextSibling;
27757
- if ((0, isNodeOfType_1.isNodeOfType)(refNode, 'ELEMENT_NODE')) {
27758
- context.rewriteFromModel.removedBlockElements.push(refNode);
27759
- }
27760
- (_a = refNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(refNode);
27761
- refNode = next;
27762
- }
27808
+ (0, cleanUpRestNodes_1.cleanUpRestNodes)(refNode, context.rewriteFromModel);
27763
27809
  }
27764
27810
  finally {
27765
27811
  listFormat.nodeStack = nodeStack;
27766
27812
  }
27767
27813
  };
27768
27814
  exports.handleBlockGroupChildren = handleBlockGroupChildren;
27815
+ function cleanUpNodeStack(nodeStack, context) {
27816
+ var _a, _b;
27817
+ if (context.allowCacheListItem && nodeStack.length > 0) {
27818
+ // Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
27819
+ for (var i = nodeStack.length - 1; i > 0; i--) {
27820
+ var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
27821
+ (0, cleanUpRestNodes_1.cleanUpRestNodes)(node, context.rewriteFromModel);
27822
+ }
27823
+ }
27824
+ }
27769
27825
 
27770
27826
 
27771
27827
  /***/ }),
@@ -28100,20 +28156,24 @@ exports.handleList = void 0;
28100
28156
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
28101
28157
  var applyFormat_1 = __webpack_require__(/*! ../utils/applyFormat */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/applyFormat.ts");
28102
28158
  var applyMetadata_1 = __webpack_require__(/*! ../utils/applyMetadata */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/applyMetadata.ts");
28159
+ var cleanUpRestNodes_1 = __webpack_require__(/*! ../utils/cleanUpRestNodes */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/cleanUpRestNodes.ts");
28160
+ var reuseCachedElement_1 = __webpack_require__(/*! ../../domUtils/reuseCachedElement */ "./packages/roosterjs-content-model-dom/lib/domUtils/reuseCachedElement.ts");
28103
28161
  /**
28104
28162
  * @internal
28105
28163
  */
28106
28164
  var handleList = function (doc, parent, listItem, context, refNode) {
28107
- var _a, _b, _c;
28165
+ var _a, _b, _c, _d;
28108
28166
  var layer = 0;
28109
28167
  var nodeStack = context.listFormat.nodeStack;
28110
28168
  if (nodeStack.length == 0) {
28111
28169
  nodeStack.push({
28112
28170
  node: parent,
28171
+ refNode: refNode,
28113
28172
  });
28114
28173
  }
28115
28174
  // Skip existing list levels that has same properties so we can reuse them
28116
28175
  for (; layer < listItem.levels.length && layer + 1 < nodeStack.length; layer++) {
28176
+ var parentLevel = nodeStack[layer];
28117
28177
  var stackLevel = nodeStack[layer + 1];
28118
28178
  var itemLevel = listItem.levels[layer];
28119
28179
  if (stackLevel.listType != itemLevel.listType ||
@@ -28124,25 +28184,66 @@ var handleList = function (doc, parent, listItem, context, refNode) {
28124
28184
  itemLevel.format.listStyleType != ((_b = stackLevel.format) === null || _b === void 0 ? void 0 : _b.listStyleType))) {
28125
28185
  break;
28126
28186
  }
28187
+ if (context.allowCacheListItem &&
28188
+ parentLevel.refNode &&
28189
+ itemLevel.cachedElement == parentLevel.refNode) {
28190
+ // Move refNode to next node since we are reusing this cached element
28191
+ parentLevel.refNode = parentLevel.refNode.nextSibling;
28192
+ }
28127
28193
  }
28128
28194
  // Cut off remained list levels that we can't reuse
28195
+ if (context.allowCacheListItem) {
28196
+ // Clean up all rest nodes in the reused list levels
28197
+ for (var i = layer + 1; i < nodeStack.length; i++) {
28198
+ var stackLevel = nodeStack[i];
28199
+ (0, cleanUpRestNodes_1.cleanUpRestNodes)(stackLevel.refNode, context.rewriteFromModel);
28200
+ }
28201
+ }
28129
28202
  nodeStack.splice(layer + 1);
28130
28203
  // Create new list levels that are after reused ones
28131
28204
  for (; layer < listItem.levels.length; layer++) {
28132
28205
  var level = listItem.levels[layer];
28133
- var newList = doc.createElement(level.listType || 'UL');
28134
28206
  var lastParent = nodeStack[nodeStack.length - 1].node;
28135
- lastParent.insertBefore(newList, layer == 0 ? refNode : null);
28136
- nodeStack.push((0, tslib_1.__assign)({ node: newList }, level));
28207
+ var newList = void 0;
28208
+ var isNewlyCreated = false;
28209
+ var levelRefNode = (_c = nodeStack[layer].refNode) !== null && _c !== void 0 ? _c : null;
28210
+ if (context.allowCacheListItem && level.cachedElement) {
28211
+ newList = level.cachedElement;
28212
+ nodeStack[layer].refNode = (0, reuseCachedElement_1.reuseCachedElement)(lastParent, level.cachedElement, levelRefNode, context.rewriteFromModel);
28213
+ nodeStack.push({
28214
+ node: newList,
28215
+ refNode: newList.firstChild,
28216
+ listType: level.listType,
28217
+ format: (0, tslib_1.__assign)({}, level.format),
28218
+ dataset: (0, tslib_1.__assign)({}, level.dataset),
28219
+ });
28220
+ }
28221
+ else {
28222
+ newList = doc.createElement(level.listType == 'OL' ? 'ol' : 'ul');
28223
+ isNewlyCreated = true;
28224
+ lastParent.insertBefore(newList, levelRefNode);
28225
+ nodeStack.push({
28226
+ node: newList,
28227
+ refNode: null,
28228
+ listType: level.listType,
28229
+ format: (0, tslib_1.__assign)({}, level.format),
28230
+ dataset: (0, tslib_1.__assign)({}, level.dataset),
28231
+ });
28232
+ if (context.allowCacheListItem) {
28233
+ level.cachedElement = newList;
28234
+ }
28235
+ }
28137
28236
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.listLevelThread, level.format, context);
28138
28237
  // Need to apply metadata after applying list level format since the list numbers value relies on the result of list thread handling
28139
28238
  (0, applyMetadata_1.applyMetadata)(level, context.metadataAppliers.listLevel, level.format, context);
28140
28239
  // Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling
28141
28240
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.listLevel, level.format, context);
28142
28241
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.dataset, level.dataset, context);
28143
- (_c = context.onNodeCreated) === null || _c === void 0 ? void 0 : _c.call(context, level, newList);
28242
+ if (isNewlyCreated) {
28243
+ (_d = context.onNodeCreated) === null || _d === void 0 ? void 0 : _d.call(context, level, newList);
28244
+ }
28144
28245
  }
28145
- return refNode;
28246
+ return nodeStack[0].refNode;
28146
28247
  };
28147
28248
  exports.handleList = handleList;
28148
28249
 
@@ -28162,6 +28263,7 @@ exports.handleListItem = void 0;
28162
28263
  var applyFormat_1 = __webpack_require__(/*! ../utils/applyFormat */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/applyFormat.ts");
28163
28264
  var applyMetadata_1 = __webpack_require__(/*! ../utils/applyMetadata */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/applyMetadata.ts");
28164
28265
  var isGenericRoleElement_1 = __webpack_require__(/*! ../../domUtils/isGenericRoleElement */ "./packages/roosterjs-content-model-dom/lib/domUtils/isGenericRoleElement.ts");
28266
+ var reuseCachedElement_1 = __webpack_require__(/*! ../../domUtils/reuseCachedElement */ "./packages/roosterjs-content-model-dom/lib/domUtils/reuseCachedElement.ts");
28165
28267
  var setParagraphNotImplicit_1 = __webpack_require__(/*! ../../modelApi/block/setParagraphNotImplicit */ "./packages/roosterjs-content-model-dom/lib/modelApi/block/setParagraphNotImplicit.ts");
28166
28268
  var stackFormat_1 = __webpack_require__(/*! ../utils/stackFormat */ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/stackFormat.ts");
28167
28269
  var unwrap_1 = __webpack_require__(/*! ../../domUtils/unwrap */ "./packages/roosterjs-content-model-dom/lib/domUtils/unwrap.ts");
@@ -28174,13 +28276,35 @@ var handleListItem = function (doc, parent, listItem, context, refNode) {
28174
28276
  var _a, _b;
28175
28277
  refNode = context.modelHandlers.list(doc, parent, listItem, context, refNode);
28176
28278
  var nodeStack = context.listFormat.nodeStack;
28177
- var listParent = ((_a = nodeStack === null || nodeStack === void 0 ? void 0 : nodeStack[(nodeStack === null || nodeStack === void 0 ? void 0 : nodeStack.length) - 1]) === null || _a === void 0 ? void 0 : _a.node) || parent;
28178
- var li = doc.createElement('li');
28279
+ var leafLevel = (_a = nodeStack === null || nodeStack === void 0 ? void 0 : nodeStack[nodeStack.length - 1]) !== null && _a !== void 0 ? _a : {};
28280
+ var itemRefNode = leafLevel.refNode || null;
28281
+ var listParent = leafLevel.node || parent;
28179
28282
  var level = listItem.levels[listItem.levels.length - 1];
28180
- // It is possible listParent is the same with parent param.
28181
- // This happens when outdent a list item to cause it has no list level
28182
- listParent.insertBefore(li, (refNode === null || refNode === void 0 ? void 0 : refNode.parentNode) == listParent ? refNode : null);
28183
- context.rewriteFromModel.addedBlockElements.push(li);
28283
+ var li;
28284
+ var isNewlyCreated = false;
28285
+ if (context.allowCacheListItem && listItem.cachedElement) {
28286
+ li = listItem.cachedElement;
28287
+ // Check if the cached LI is used as refNode under another list level,
28288
+ // since we know we are going to move it under the current listParent,
28289
+ // we need to update the refNode of the previous list level to avoid removing it later
28290
+ for (var i = 0; i < nodeStack.length - 1; i++) {
28291
+ if (nodeStack[i].refNode === li) {
28292
+ nodeStack[i].refNode = li.nextSibling;
28293
+ }
28294
+ }
28295
+ leafLevel.refNode = (0, reuseCachedElement_1.reuseCachedElement)(listParent, li, itemRefNode, context.rewriteFromModel);
28296
+ }
28297
+ else {
28298
+ li = doc.createElement('li');
28299
+ isNewlyCreated = true;
28300
+ // It is possible listParent is the same with parent param.
28301
+ // This happens when outdent a list item to cause it has no list level
28302
+ listParent.insertBefore(li, (itemRefNode === null || itemRefNode === void 0 ? void 0 : itemRefNode.parentNode) == listParent ? itemRefNode : null);
28303
+ context.rewriteFromModel.addedBlockElements.push(li);
28304
+ if (context.allowCacheListItem) {
28305
+ listItem.cachedElement = li;
28306
+ }
28307
+ }
28184
28308
  if (level) {
28185
28309
  (0, applyFormat_1.applyFormat)(li, context.formatAppliers.segment, listItem.formatHolder.format, context);
28186
28310
  (0, applyFormat_1.applyFormat)(li, context.formatAppliers.listItemThread, level.format, context);
@@ -28208,7 +28332,9 @@ var handleListItem = function (doc, parent, listItem, context, refNode) {
28208
28332
  element.setAttribute(HtmlRoleAttribute, PresentationRoleValue);
28209
28333
  }
28210
28334
  }
28211
- (_b = context.onNodeCreated) === null || _b === void 0 ? void 0 : _b.call(context, listItem, li);
28335
+ if (isNewlyCreated) {
28336
+ (_b = context.onNodeCreated) === null || _b === void 0 ? void 0 : _b.call(context, listItem, li);
28337
+ }
28212
28338
  return refNode;
28213
28339
  };
28214
28340
  exports.handleListItem = handleListItem;
@@ -28788,6 +28914,40 @@ function applyMetadata(model, applier, format, context) {
28788
28914
  exports.applyMetadata = applyMetadata;
28789
28915
 
28790
28916
 
28917
+ /***/ }),
28918
+
28919
+ /***/ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/cleanUpRestNodes.ts":
28920
+ /*!***************************************************************************************!*\
28921
+ !*** ./packages/roosterjs-content-model-dom/lib/modelToDom/utils/cleanUpRestNodes.ts ***!
28922
+ \***************************************************************************************/
28923
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
28924
+
28925
+ "use strict";
28926
+
28927
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
28928
+ exports.cleanUpRestNodes = void 0;
28929
+ var isNodeOfType_1 = __webpack_require__(/*! ../../domUtils/isNodeOfType */ "./packages/roosterjs-content-model-dom/lib/domUtils/isNodeOfType.ts");
28930
+ /**
28931
+ * @internal
28932
+ * Cleans up all rest nodes starting from refNode
28933
+ * @param refNode The reference node to start cleaning up
28934
+ * @param rewriteContext The context for rewrite process
28935
+ */
28936
+ function cleanUpRestNodes(refNode, rewriteContext) {
28937
+ while (refNode) {
28938
+ var next = refNode.nextSibling;
28939
+ if (refNode.parentNode) {
28940
+ if ((0, isNodeOfType_1.isNodeOfType)(refNode, 'ELEMENT_NODE')) {
28941
+ rewriteContext.removedBlockElements.push(refNode);
28942
+ }
28943
+ refNode.parentNode.removeChild(refNode);
28944
+ }
28945
+ refNode = next;
28946
+ }
28947
+ }
28948
+ exports.cleanUpRestNodes = cleanUpRestNodes;
28949
+
28950
+
28791
28951
  /***/ }),
28792
28952
 
28793
28953
  /***/ "./packages/roosterjs-content-model-dom/lib/modelToDom/utils/handleSegmentCommon.ts":
@@ -28840,12 +29000,15 @@ function stackFormat(context, tagNameOrFormat, callback) {
28840
29000
  : tagNameOrFormat;
28841
29001
  if (newFormat) {
28842
29002
  var implicitFormat = context.implicitFormat;
29003
+ var nodeStack = context.listFormat.nodeStack;
28843
29004
  try {
28844
29005
  context.implicitFormat = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, implicitFormat), newFormat);
29006
+ context.listFormat.nodeStack = [];
28845
29007
  callback();
28846
29008
  }
28847
29009
  finally {
28848
29010
  context.implicitFormat = implicitFormat;
29011
+ context.listFormat.nodeStack = nodeStack;
28849
29012
  }
28850
29013
  }
28851
29014
  else {
@@ -30503,13 +30666,13 @@ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.m
30503
30666
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
30504
30667
  var checkAndInsertHorizontalLine_1 = __webpack_require__(/*! ./horizontalLine/checkAndInsertHorizontalLine */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.ts");
30505
30668
  var createLink_1 = __webpack_require__(/*! ./link/createLink */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLink.ts");
30506
- var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
30507
30669
  var getListTypeStyle_1 = __webpack_require__(/*! ./list/getListTypeStyle */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/list/getListTypeStyle.ts");
30508
30670
  var keyboardListTrigger_1 = __webpack_require__(/*! ./list/keyboardListTrigger */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/list/keyboardListTrigger.ts");
30509
30671
  var transformFraction_1 = __webpack_require__(/*! ./numbers/transformFraction */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformFraction.ts");
30510
30672
  var transformHyphen_1 = __webpack_require__(/*! ./hyphen/transformHyphen */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/hyphen/transformHyphen.ts");
30511
30673
  var transformOrdinals_1 = __webpack_require__(/*! ./numbers/transformOrdinals */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformOrdinals.ts");
30512
30674
  var unlink_1 = __webpack_require__(/*! ./link/unlink */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/unlink.ts");
30675
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
30513
30676
  /**
30514
30677
  * @internal
30515
30678
  */
@@ -30639,7 +30802,6 @@ var AutoFormatPlugin = /** @class */ (function () {
30639
30802
  this.editor = null;
30640
30803
  };
30641
30804
  AutoFormatPlugin.prototype.shouldHandleInputEventExclusively = function (editor, event) {
30642
- var _this = this;
30643
30805
  var rawEvent = event.rawEvent;
30644
30806
  var selection = editor.getDOMSelection();
30645
30807
  var shouldHandle = false;
@@ -30648,15 +30810,15 @@ var AutoFormatPlugin = /** @class */ (function () {
30648
30810
  selection.type === 'range' &&
30649
30811
  selection.range.collapsed &&
30650
30812
  rawEvent.data == ' ') {
30651
- (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph) {
30652
- var _a = _this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering;
30653
- var list = (0, getListTypeStyle_1.getListTypeStyle)(model, autoBullet, autoNumbering);
30654
- var link = (0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
30655
- autoLink: autoLink,
30656
- autoTel: autoTel,
30657
- autoMailto: autoMailto,
30813
+ var _a = this.options, autoLink_1 = _a.autoLink, autoTel_1 = _a.autoTel, autoMailto_1 = _a.autoMailto, autoBullet_1 = _a.autoBullet, autoNumbering_1 = _a.autoNumbering;
30814
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, _paragraph, _markerFormat) {
30815
+ var list = (0, getListTypeStyle_1.getListTypeStyle)(model, autoBullet_1, autoNumbering_1);
30816
+ var promotedLink = (0, roosterjs_content_model_api_1.getPromoteLink)(previousSegment, {
30817
+ autoLink: autoLink_1,
30818
+ autoTel: autoTel_1,
30819
+ autoMailto: autoMailto_1,
30658
30820
  });
30659
- shouldHandle = !!link || !!list;
30821
+ shouldHandle = !!promotedLink || !!list;
30660
30822
  return false;
30661
30823
  });
30662
30824
  }
@@ -31741,8 +31903,22 @@ var DELETE_KEY = 46;
31741
31903
  * Other cases: https://stackoverflow.com/questions/25043934/is-it-ok-to-ignore-keydown-events-with-keycode-229
31742
31904
  */
31743
31905
  var DEAD_KEY = 229;
31906
+ var DefaultHandleTabOptions = {
31907
+ indentMultipleBlocks: true,
31908
+ indentTable: true,
31909
+ appendTableRow: true,
31910
+ indentList: true,
31911
+ indentParagraph: true,
31912
+ };
31913
+ var DisabledHandleTabOptions = {
31914
+ indentMultipleBlocks: false,
31915
+ indentTable: false,
31916
+ appendTableRow: false,
31917
+ indentList: false,
31918
+ indentParagraph: false,
31919
+ };
31744
31920
  var DefaultOptions = {
31745
- handleTabKey: true,
31921
+ handleTabKey: DefaultHandleTabOptions,
31746
31922
  handleExpandedSelectionOnDelete: true,
31747
31923
  };
31748
31924
  /**
@@ -31755,17 +31931,21 @@ var DefaultOptions = {
31755
31931
  var EditPlugin = /** @class */ (function () {
31756
31932
  /**
31757
31933
  * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:
31758
- * handleTabKey: A boolean that enables or disables Tab key handling. Defaults to true.
31934
+ * handleTabKey: A boolean or HandleTabOptions object that controls Tab key handling. When a boolean, true enables all features and false disables all. When an object, individual features can be controlled. Defaults to all enabled.
31759
31935
  */
31760
31936
  function EditPlugin(options) {
31761
31937
  if (options === void 0) { options = DefaultOptions; }
31762
- this.options = options;
31763
31938
  this.editor = null;
31764
31939
  this.disposer = null;
31765
31940
  this.shouldHandleNextInputEvent = false;
31766
31941
  this.selectionAfterDelete = null;
31767
31942
  this.handleNormalEnter = function () { return false; };
31768
- this.options = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultOptions), options);
31943
+ var tabOptions = options.handleTabKey === false
31944
+ ? DisabledHandleTabOptions
31945
+ : options.handleTabKey === true || !options.handleTabKey
31946
+ ? DefaultHandleTabOptions
31947
+ : (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultHandleTabOptions), options.handleTabKey);
31948
+ this.options = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultOptions), options), { handleTabKey: tabOptions });
31769
31949
  }
31770
31950
  EditPlugin.prototype.createNormalEnterChecker = function (result) {
31771
31951
  return result ? function () { return true; } : function () { return false; };
@@ -31846,7 +32026,7 @@ var EditPlugin = /** @class */ (function () {
31846
32026
  */
31847
32027
  EditPlugin.prototype.willHandleEventExclusively = function (event) {
31848
32028
  if (this.editor &&
31849
- this.options.handleTabKey &&
32029
+ this.options.handleTabKey.appendTableRow &&
31850
32030
  event.eventType == 'keyDown' &&
31851
32031
  event.rawEvent.key == 'Tab' &&
31852
32032
  !event.rawEvent.shiftKey) {
@@ -31889,8 +32069,8 @@ var EditPlugin = /** @class */ (function () {
31889
32069
  }
31890
32070
  break;
31891
32071
  case 'Tab':
31892
- if (this.options.handleTabKey && !hasCtrlOrMetaKey) {
31893
- (0, keyboardTab_1.keyboardTab)(editor, rawEvent);
32072
+ if (!hasCtrlOrMetaKey) {
32073
+ (0, keyboardTab_1.keyboardTab)(editor, rawEvent, this.options.handleTabKey);
31894
32074
  }
31895
32075
  break;
31896
32076
  case 'Unidentified':
@@ -32620,24 +32800,6 @@ var handleEnterOnList = function (context) {
32620
32800
  ], (0, tslib_1.__read)(path.slice(index + 1)), false));
32621
32801
  }
32622
32802
  }
32623
- var listIndex = listParent.blocks.indexOf(listItem);
32624
- var nextBlock = listParent.blocks[listIndex + 1];
32625
- if (nextBlock) {
32626
- if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(nextBlock, 'ListItem') &&
32627
- nextBlock.levels[0]) {
32628
- nextBlock.levels.forEach(function (level) {
32629
- // Remove startNumberOverride so that next list item can join current list, unless it is 1.
32630
- // List start with 1 means it should be an explicit new list and should never join another list before it
32631
- if (level.format.startNumberOverride !== 1) {
32632
- level.format.startNumberOverride = undefined;
32633
- }
32634
- });
32635
- if (listItem.levels.length == 0) {
32636
- var nextBlockIndex = findIndex(listParent.blocks, nextBlock.levels.length);
32637
- nextBlock.levels[nextBlock.levels.length - 1].format.startNumberOverride = nextBlockIndex;
32638
- }
32639
- }
32640
- }
32641
32803
  context.deleteResult = 'range';
32642
32804
  }
32643
32805
  }
@@ -32679,21 +32841,6 @@ var createNewListLevel = function (listItem) {
32679
32841
  return (0, roosterjs_content_model_dom_1.createListLevel)(level.listType, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, level.format), { startNumberOverride: undefined, displayForDummyItem: undefined }), level.dataset);
32680
32842
  });
32681
32843
  };
32682
- var findIndex = function (blocks, levelLength) {
32683
- var counter = 1;
32684
- for (var i = 0; i < blocks.length; i++) {
32685
- var listItem = blocks[i];
32686
- if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(listItem, 'ListItem') &&
32687
- listItem.levels.length === levelLength) {
32688
- counter++;
32689
- }
32690
- else if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(listItem, 'ListItem') &&
32691
- listItem.levels.length == 0) {
32692
- return counter;
32693
- }
32694
- }
32695
- return counter;
32696
- };
32697
32844
 
32698
32845
 
32699
32846
  /***/ }),
@@ -33014,29 +33161,31 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
33014
33161
  /**
33015
33162
  * @internal
33016
33163
  */
33017
- function keyboardTab(editor, rawEvent) {
33164
+ function keyboardTab(editor, rawEvent, options) {
33018
33165
  var selection = editor.getDOMSelection();
33019
33166
  switch (selection === null || selection === void 0 ? void 0 : selection.type) {
33020
33167
  case 'range':
33021
33168
  editor.formatContentModel(function (model, context) {
33022
- return handleTab(model, rawEvent, context);
33169
+ return handleTab(model, rawEvent, context, options);
33023
33170
  }, {
33024
33171
  apiName: 'handleTabKey',
33025
33172
  rawEvent: rawEvent,
33026
33173
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
33027
33174
  getChangeData: function () { return rawEvent.which; },
33028
33175
  });
33029
- return true;
33176
+ break;
33030
33177
  case 'table':
33031
- editor.formatContentModel(function (model) {
33032
- return (0, handleTabOnTable_1.handleTabOnTable)(model, rawEvent);
33033
- }, {
33034
- apiName: 'handleTabKey',
33035
- rawEvent: rawEvent,
33036
- changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
33037
- getChangeData: function () { return rawEvent.which; },
33038
- });
33039
- return true;
33178
+ if (options.indentTable) {
33179
+ editor.formatContentModel(function (model) {
33180
+ return (0, handleTabOnTable_1.handleTabOnTable)(model, rawEvent);
33181
+ }, {
33182
+ apiName: 'handleTabKey',
33183
+ rawEvent: rawEvent,
33184
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
33185
+ getChangeData: function () { return rawEvent.which; },
33186
+ });
33187
+ }
33188
+ break;
33040
33189
  }
33041
33190
  }
33042
33191
  exports.keyboardTab = keyboardTab;
@@ -33047,22 +33196,30 @@ exports.keyboardTab = keyboardTab;
33047
33196
  * - If it is a paragraph, call handleTabOnParagraph to handle the tab key.
33048
33197
  * - If it is a list item, call handleTabOnList to handle the tab key.
33049
33198
  */
33050
- function handleTab(model, rawEvent, context) {
33199
+ function handleTab(model, rawEvent, context, options) {
33051
33200
  var blocks = (0, roosterjs_content_model_dom_1.getOperationalBlocks)(model, ['ListItem', 'TableCell'], []);
33052
33201
  var block = blocks.length > 0 ? blocks[0].block : undefined;
33053
33202
  if (blocks.length > 1) {
33054
- (0, roosterjs_content_model_api_1.setModelIndentation)(model, rawEvent.shiftKey ? 'outdent' : 'indent');
33055
- rawEvent.preventDefault();
33056
- return true;
33203
+ if (options.indentMultipleBlocks) {
33204
+ (0, roosterjs_content_model_api_1.setModelIndentation)(model, rawEvent.shiftKey ? 'outdent' : 'indent');
33205
+ rawEvent.preventDefault();
33206
+ return true;
33207
+ }
33057
33208
  }
33058
33209
  else if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(block, 'TableCell')) {
33059
- return (0, handleTabOnTableCell_1.handleTabOnTableCell)(model, block, rawEvent);
33210
+ if (options.appendTableRow) {
33211
+ return (0, handleTabOnTableCell_1.handleTabOnTableCell)(model, block, rawEvent);
33212
+ }
33060
33213
  }
33061
33214
  else if ((block === null || block === void 0 ? void 0 : block.blockType) === 'Paragraph') {
33062
- return (0, handleTabOnParagraph_1.handleTabOnParagraph)(model, block, rawEvent, context);
33215
+ if (options.indentParagraph) {
33216
+ return (0, handleTabOnParagraph_1.handleTabOnParagraph)(model, block, rawEvent, context);
33217
+ }
33063
33218
  }
33064
33219
  else if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(block, 'ListItem')) {
33065
- return (0, handleTabOnList_1.handleTabOnList)(model, block, rawEvent, context);
33220
+ if (options.indentList) {
33221
+ return (0, handleTabOnList_1.handleTabOnList)(model, block, rawEvent, context);
33222
+ }
33066
33223
  }
33067
33224
  return false;
33068
33225
  }
@@ -34750,11 +34907,10 @@ var ImageEditPlugin = /** @class */ (function () {
34750
34907
  }
34751
34908
  }
34752
34909
  };
34753
- ImageEditPlugin.prototype.setContentHandler = function (editor) {
34754
- var selection = editor.getDOMSelection();
34755
- if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
34910
+ ImageEditPlugin.prototype.setContentHandler = function () {
34911
+ if (this.selectedImage) {
34756
34912
  this.cleanInfo();
34757
- (0, roosterjs_content_model_dom_1.setImageState)(selection.image, '');
34913
+ (0, roosterjs_content_model_dom_1.setImageState)(this.selectedImage, '');
34758
34914
  this.isEditing = false;
34759
34915
  this.isCropMode = false;
34760
34916
  }
@@ -34769,7 +34925,7 @@ var ImageEditPlugin = /** @class */ (function () {
34769
34925
  ImageEditPlugin.prototype.contentChangedHandler = function (editor, event) {
34770
34926
  switch (event.source) {
34771
34927
  case roosterjs_content_model_dom_1.ChangeSource.SetContent:
34772
- this.setContentHandler(editor);
34928
+ this.setContentHandler();
34773
34929
  break;
34774
34930
  case roosterjs_content_model_dom_1.ChangeSource.Format:
34775
34931
  this.formatEventHandler(event);
@@ -36103,14 +36259,19 @@ function generateDataURL(image, editInfo) {
36103
36259
  canvas.width = targetWidth * devicePixelRatio;
36104
36260
  canvas.height = targetHeight * devicePixelRatio;
36105
36261
  var context = canvas.getContext('2d');
36106
- if (context) {
36107
- context.scale(devicePixelRatio, devicePixelRatio);
36108
- context.translate(targetWidth / 2, targetHeight / 2);
36109
- context.rotate(angle);
36110
- context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);
36111
- context.drawImage(image, nWidth * left, nHeight * top, imageWidth, imageHeight, -width / 2, -height / 2, width, height);
36262
+ try {
36263
+ if (context) {
36264
+ context.scale(devicePixelRatio, devicePixelRatio);
36265
+ context.translate(targetWidth / 2, targetHeight / 2);
36266
+ context.rotate(angle);
36267
+ context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);
36268
+ context.drawImage(image, nWidth * left, nHeight * top, imageWidth, imageHeight, -width / 2, -height / 2, width, height);
36269
+ }
36270
+ return canvas.toDataURL('image/png', 1.0);
36271
+ }
36272
+ catch (_a) {
36273
+ return image.src;
36112
36274
  }
36113
- return canvas.toDataURL('image/png', 1.0);
36114
36275
  }
36115
36276
  exports.generateDataURL = generateDataURL;
36116
36277
 
@@ -37178,11 +37339,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
37178
37339
  exports.PastePlugin = void 0;
37179
37340
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
37180
37341
  var addParser_1 = __webpack_require__(/*! ./utils/addParser */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/addParser.ts");
37181
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
37342
+ var blockElementParser_1 = __webpack_require__(/*! ./parsers/blockElementParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/blockElementParser.ts");
37182
37343
  var chainSanitizerCallback_1 = __webpack_require__(/*! ./utils/chainSanitizerCallback */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/chainSanitizerCallback.ts");
37183
37344
  var DefaultSanitizers_1 = __webpack_require__(/*! ./DefaultSanitizers */ "./packages/roosterjs-content-model-plugins/lib/paste/DefaultSanitizers.ts");
37184
37345
  var deprecatedColorParser_1 = __webpack_require__(/*! ./parsers/deprecatedColorParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/deprecatedColorParser.ts");
37185
- var getPasteSource_1 = __webpack_require__(/*! ./pasteSourceValidations/getPasteSource */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getPasteSource.ts");
37346
+ var getDocumentSource_1 = __webpack_require__(/*! ./pasteSourceValidations/getDocumentSource */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getDocumentSource.ts");
37347
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
37348
+ var imageSizeParser_1 = __webpack_require__(/*! ./parsers/imageSizeParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/imageSizeParser.ts");
37186
37349
  var linkParser_1 = __webpack_require__(/*! ./parsers/linkParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/linkParser.ts");
37187
37350
  var pasteButtonProcessor_1 = __webpack_require__(/*! ./processors/pasteButtonProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/processors/pasteButtonProcessor.ts");
37188
37351
  var constants_1 = __webpack_require__(/*! ./pasteSourceValidations/constants */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/constants.ts");
@@ -37192,6 +37355,7 @@ var processPastedContentFromPowerPoint_1 = __webpack_require__(/*! ./PowerPoint/
37192
37355
  var processPastedContentFromWordDesktop_1 = __webpack_require__(/*! ./WordDesktop/processPastedContentFromWordDesktop */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts");
37193
37356
  var processPastedContentWacComponents_1 = __webpack_require__(/*! ./WacComponents/processPastedContentWacComponents */ "./packages/roosterjs-content-model-plugins/lib/paste/WacComponents/processPastedContentWacComponents.ts");
37194
37357
  var setProcessor_1 = __webpack_require__(/*! ./utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
37358
+ var tableBorderParser_1 = __webpack_require__(/*! ./parsers/tableBorderParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/tableBorderParser.ts");
37195
37359
  /**
37196
37360
  * Paste plugin, handles BeforePaste event and reformat some special content, including:
37197
37361
  * 1. Content copied from Word
@@ -37252,11 +37416,19 @@ var PastePlugin = /** @class */ (function () {
37252
37416
  if (!event.domToModelOption) {
37253
37417
  return;
37254
37418
  }
37255
- var pasteSource = (0, getPasteSource_1.getPasteSource)(event, false /* shouldConvertSingleImage */, this.editor.getEnvironment());
37419
+ var htmlAttributes = event.htmlAttributes, clipboardData = event.clipboardData, fragment = event.fragment;
37420
+ var pasteSource = (0, getDocumentSource_1.getDocumentSource)({
37421
+ htmlAttributes: htmlAttributes,
37422
+ fragment: fragment,
37423
+ clipboardItemTypes: clipboardData.types,
37424
+ htmlFirstLevelChildTags: clipboardData.htmlFirstLevelChildTags,
37425
+ environment: this.editor.getEnvironment(),
37426
+ rawHtml: clipboardData.rawHtml,
37427
+ });
37256
37428
  var pasteType = event.pasteType;
37257
37429
  switch (pasteSource) {
37258
37430
  case 'wordDesktop':
37259
- (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event);
37431
+ (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event.domToModelOption, event.htmlBefore || event.clipboardData.rawHtml || '');
37260
37432
  break;
37261
37433
  case 'wacComponents':
37262
37434
  (0, processPastedContentWacComponents_1.processPastedContentWacComponents)(event);
@@ -37281,12 +37453,13 @@ var PastePlugin = /** @class */ (function () {
37281
37453
  }
37282
37454
  (0, addParser_1.addParser)(event.domToModelOption, 'link', linkParser_1.parseLink);
37283
37455
  (0, addParser_1.addParser)(event.domToModelOption, 'tableCell', deprecatedColorParser_1.deprecatedBorderColorParser);
37284
- (0, addParser_1.addParser)(event.domToModelOption, 'tableCell', tableBorderParser);
37456
+ (0, addParser_1.addParser)(event.domToModelOption, 'tableCell', tableBorderParser_1.tableBorderParser);
37285
37457
  (0, addParser_1.addParser)(event.domToModelOption, 'table', deprecatedColorParser_1.deprecatedBorderColorParser);
37458
+ (0, addParser_1.addParser)(event.domToModelOption, 'image', imageSizeParser_1.imageSizeParser);
37286
37459
  (0, setProcessor_1.setProcessor)(event.domToModelOption, 'button', pasteButtonProcessor_1.pasteButtonProcessor);
37287
37460
  if (pasteType === 'mergeFormat') {
37288
- (0, addParser_1.addParser)(event.domToModelOption, 'block', blockElementParser);
37289
- (0, addParser_1.addParser)(event.domToModelOption, 'listLevel', blockElementParser);
37461
+ (0, addParser_1.addParser)(event.domToModelOption, 'block', blockElementParser_1.blockElementParser);
37462
+ (0, addParser_1.addParser)(event.domToModelOption, 'listLevel', blockElementParser_1.blockElementParser);
37290
37463
  }
37291
37464
  this.setEventSanitizers(event);
37292
37465
  };
@@ -37307,34 +37480,6 @@ var PastePlugin = /** @class */ (function () {
37307
37480
  return PastePlugin;
37308
37481
  }());
37309
37482
  exports.PastePlugin = PastePlugin;
37310
- /**
37311
- * For block elements that have background color style, remove the background color when user selects the merge current format
37312
- * paste option
37313
- */
37314
- var blockElementParser = function (format, element) {
37315
- if (element.style.backgroundColor) {
37316
- delete format.backgroundColor;
37317
- }
37318
- };
37319
- var ElementBorderKeys = new Map([
37320
- ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],
37321
- ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],
37322
- ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],
37323
- ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],
37324
- ]);
37325
- function tableBorderParser(format, element) {
37326
- roosterjs_content_model_dom_1.BorderKeys.forEach(function (key) {
37327
- if (!format[key]) {
37328
- var styleSet = ElementBorderKeys.get(key);
37329
- if (styleSet &&
37330
- element.style[styleSet.w] &&
37331
- element.style[styleSet.s] &&
37332
- !element.style[styleSet.c]) {
37333
- format[key] = element.style[styleSet.w] + " " + element.style[styleSet.s];
37334
- }
37335
- }
37336
- });
37337
- }
37338
37483
 
37339
37484
 
37340
37485
  /***/ }),
@@ -37837,9 +37982,12 @@ function extractHtmlIndexes(html, startIndex) {
37837
37982
  * 5. Save data in record and only use the required information.
37838
37983
  *
37839
37984
  */
37840
- function getStyleMetadata(ev) {
37985
+ function getStyleMetadata(htmlString) {
37841
37986
  var metadataMap = new Map();
37842
- var headStyles = extractStyleTagsFromHtml(ev.htmlBefore || ev.clipboardData.rawHtml || '');
37987
+ if (!htmlString) {
37988
+ return metadataMap;
37989
+ }
37990
+ var headStyles = extractStyleTagsFromHtml(htmlString);
37843
37991
  headStyles.forEach(function (text) {
37844
37992
  var index = 0;
37845
37993
  var _loop_1 = function () {
@@ -37903,28 +38051,31 @@ exports.getStyleMetadata = getStyleMetadata;
37903
38051
  Object.defineProperty(exports, "__esModule", ({ value: true }));
37904
38052
  exports.processPastedContentFromWordDesktop = void 0;
37905
38053
  var addParser_1 = __webpack_require__(/*! ../utils/addParser */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/addParser.ts");
38054
+ var adjustPercentileLineHeightParser_1 = __webpack_require__(/*! ../parsers/adjustPercentileLineHeightParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/adjustPercentileLineHeightParser.ts");
37906
38055
  var getStyleMetadata_1 = __webpack_require__(/*! ./getStyleMetadata */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/getStyleMetadata.ts");
37907
38056
  var getStyles_1 = __webpack_require__(/*! ../utils/getStyles */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/getStyles.ts");
38057
+ var listLevelParser_1 = __webpack_require__(/*! ../parsers/listLevelParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/listLevelParser.ts");
37908
38058
  var processWordComments_1 = __webpack_require__(/*! ./processWordComments */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordComments.ts");
37909
38059
  var processWordLists_1 = __webpack_require__(/*! ./processWordLists */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts");
37910
38060
  var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ../parsers/removeNegativeTextIndentParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts");
37911
38061
  var setProcessor_1 = __webpack_require__(/*! ../utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
37912
- var PERCENTAGE_REGEX = /%/;
37913
- // Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal
37914
- var DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;
38062
+ var wordContainerParser_1 = __webpack_require__(/*! ../parsers/wordContainerParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordContainerParser.ts");
38063
+ var wordTableParser_1 = __webpack_require__(/*! ../parsers/wordTableParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordTableParser.ts");
37915
38064
  /**
37916
38065
  * @internal
37917
- * Handles Pasted content when source is Word Desktop
37918
- * @param ev BeforePasteEvent
38066
+ * Handles pasted content when the source is Word Desktop.
38067
+ * @param domToModelOption Options for DOM to Content Model conversion
38068
+ * @param htmlString The HTML string to process
37919
38069
  */
37920
- function processPastedContentFromWordDesktop(ev) {
37921
- var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(ev);
37922
- (0, setProcessor_1.setProcessor)(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
37923
- (0, addParser_1.addParser)(ev.domToModelOption, 'block', adjustPercentileLineHeight);
37924
- (0, addParser_1.addParser)(ev.domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
37925
- (0, addParser_1.addParser)(ev.domToModelOption, 'listLevel', listLevelParser);
37926
- (0, addParser_1.addParser)(ev.domToModelOption, 'container', wordTableParser);
37927
- (0, addParser_1.addParser)(ev.domToModelOption, 'table', wordTableParser);
38070
+ function processPastedContentFromWordDesktop(domToModelOption, htmlString) {
38071
+ var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(htmlString);
38072
+ (0, setProcessor_1.setProcessor)(domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
38073
+ (0, addParser_1.addParser)(domToModelOption, 'block', adjustPercentileLineHeightParser_1.adjustPercentileLineHeight);
38074
+ (0, addParser_1.addParser)(domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
38075
+ (0, addParser_1.addParser)(domToModelOption, 'listItemElement', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
38076
+ (0, addParser_1.addParser)(domToModelOption, 'listLevel', listLevelParser_1.listLevelParser);
38077
+ (0, addParser_1.addParser)(domToModelOption, 'container', wordContainerParser_1.wordContainerParser);
38078
+ (0, addParser_1.addParser)(domToModelOption, 'table', wordTableParser_1.wordTableParser);
37928
38079
  }
37929
38080
  exports.processPastedContentFromWordDesktop = processPastedContentFromWordDesktop;
37930
38081
  var wordDesktopElementProcessor = function (metadataKey) {
@@ -37937,30 +38088,6 @@ var wordDesktopElementProcessor = function (metadataKey) {
37937
38088
  }
37938
38089
  };
37939
38090
  };
37940
- function adjustPercentileLineHeight(format, element) {
37941
- //If the line height is less than the browser default line height, line between the text is going to be too narrow
37942
- var parsedLineHeight;
37943
- if (PERCENTAGE_REGEX.test(element.style.lineHeight) &&
37944
- !isNaN((parsedLineHeight = parseInt(element.style.lineHeight)))) {
37945
- format.lineHeight = (DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE *
37946
- (parsedLineHeight / 100)).toString();
37947
- }
37948
- }
37949
- var listLevelParser = function (format, element, _context, defaultStyle) {
37950
- if (element.style.marginLeft != '') {
37951
- format.marginLeft = defaultStyle.marginLeft;
37952
- }
37953
- format.marginBottom = undefined;
37954
- };
37955
- var wordTableParser = function (format, element) {
37956
- var _a;
37957
- if ((_a = format.marginLeft) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
37958
- delete format.marginLeft;
37959
- }
37960
- if (format.htmlAlign) {
37961
- delete format.htmlAlign;
37962
- }
37963
- };
37964
38091
 
37965
38092
 
37966
38093
  /***/ }),
@@ -38334,6 +38461,67 @@ function ensureOneNoteListContext(cmContext) {
38334
38461
  }
38335
38462
 
38336
38463
 
38464
+ /***/ }),
38465
+
38466
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/adjustPercentileLineHeightParser.ts":
38467
+ /*!********************************************************************************************************!*\
38468
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/adjustPercentileLineHeightParser.ts ***!
38469
+ \********************************************************************************************************/
38470
+ /***/ ((__unused_webpack_module, exports) => {
38471
+
38472
+ "use strict";
38473
+
38474
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38475
+ exports.adjustPercentileLineHeight = void 0;
38476
+ var PERCENTAGE_REGEX = /%/;
38477
+ // Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal
38478
+ var DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;
38479
+ /**
38480
+ * @internal
38481
+ * Parser for adjusting percentage-based line heights and converting 'normal' to a specific percentage
38482
+ * @param format The block format to modify
38483
+ * @param element The HTML element being processed
38484
+ */
38485
+ function adjustPercentileLineHeight(format, element) {
38486
+ // If the line height is less than the browser default line height, line between the text is going to be too narrow
38487
+ var parsedLineHeight;
38488
+ if (PERCENTAGE_REGEX.test(element.style.lineHeight) &&
38489
+ !isNaN((parsedLineHeight = parseInt(element.style.lineHeight)))) {
38490
+ format.lineHeight = (DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE *
38491
+ (parsedLineHeight / 100)).toString();
38492
+ }
38493
+ else if (element.style.lineHeight.toLowerCase() === 'normal') {
38494
+ format.lineHeight = '120%';
38495
+ }
38496
+ }
38497
+ exports.adjustPercentileLineHeight = adjustPercentileLineHeight;
38498
+
38499
+
38500
+ /***/ }),
38501
+
38502
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/blockElementParser.ts":
38503
+ /*!******************************************************************************************!*\
38504
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/blockElementParser.ts ***!
38505
+ \******************************************************************************************/
38506
+ /***/ ((__unused_webpack_module, exports) => {
38507
+
38508
+ "use strict";
38509
+
38510
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38511
+ exports.blockElementParser = void 0;
38512
+ /**
38513
+ * @internal
38514
+ * For block elements that have background color style, remove the background color when user selects the merge current format
38515
+ * paste option
38516
+ */
38517
+ var blockElementParser = function (format, element) {
38518
+ if (element.style.backgroundColor) {
38519
+ delete format.backgroundColor;
38520
+ }
38521
+ };
38522
+ exports.blockElementParser = blockElementParser;
38523
+
38524
+
38337
38525
  /***/ }),
38338
38526
 
38339
38527
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/deprecatedColorParser.ts":
@@ -38364,6 +38552,40 @@ var deprecatedBorderColorParser = function (format) {
38364
38552
  exports.deprecatedBorderColorParser = deprecatedBorderColorParser;
38365
38553
 
38366
38554
 
38555
+ /***/ }),
38556
+
38557
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/imageSizeParser.ts":
38558
+ /*!***************************************************************************************!*\
38559
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/imageSizeParser.ts ***!
38560
+ \***************************************************************************************/
38561
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
38562
+
38563
+ "use strict";
38564
+
38565
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38566
+ exports.imageSizeParser = void 0;
38567
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
38568
+ // Only process absolute units (px, pt, in, cm, mm)
38569
+ var AbsoluteUnitRegex = /^\s*\d+(\.\d+)?\s*(px|pt|in|cm|mm)\s*$/i;
38570
+ /**
38571
+ * @internal
38572
+ * Remove image size if it is larger than editor view width to let it auto size
38573
+ */
38574
+ var imageSizeParser = function (format, element, context) {
38575
+ var maxImageSize = context.editorViewWidth;
38576
+ var width = format.width;
38577
+ if (width && maxImageSize && AbsoluteUnitRegex.test(width)) {
38578
+ var widthValue = (0, roosterjs_content_model_dom_1.parseValueWithUnit)(width, element);
38579
+ // If the given width is larger than editor view width, we clear both width and height to let it auto size
38580
+ if (widthValue > maxImageSize) {
38581
+ delete format.width;
38582
+ delete format.height;
38583
+ }
38584
+ }
38585
+ };
38586
+ exports.imageSizeParser = imageSizeParser;
38587
+
38588
+
38367
38589
  /***/ }),
38368
38590
 
38369
38591
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/linkParser.ts":
@@ -38402,6 +38624,35 @@ var parseLink = function (format, element) {
38402
38624
  exports.parseLink = parseLink;
38403
38625
 
38404
38626
 
38627
+ /***/ }),
38628
+
38629
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/listLevelParser.ts":
38630
+ /*!***************************************************************************************!*\
38631
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/listLevelParser.ts ***!
38632
+ \***************************************************************************************/
38633
+ /***/ ((__unused_webpack_module, exports) => {
38634
+
38635
+ "use strict";
38636
+
38637
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38638
+ exports.listLevelParser = void 0;
38639
+ /**
38640
+ * @internal
38641
+ * Parser for processing list level formatting specific to Word Desktop
38642
+ * @param format The list item level format to modify
38643
+ * @param element The HTML element being processed
38644
+ * @param _context The DOM to model context
38645
+ * @param defaultStyle The default style properties
38646
+ */
38647
+ var listLevelParser = function (format, element, _context, defaultStyle) {
38648
+ if (element.style.marginLeft !== '') {
38649
+ format.marginLeft = defaultStyle.marginLeft;
38650
+ }
38651
+ format.marginBottom = undefined;
38652
+ };
38653
+ exports.listLevelParser = listLevelParser;
38654
+
38655
+
38405
38656
  /***/ }),
38406
38657
 
38407
38658
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/removeNegativeTextIndentParser.ts":
@@ -38417,7 +38668,7 @@ exports.removeNegativeTextIndentParser = void 0;
38417
38668
  /**
38418
38669
  * @internal
38419
38670
  */
38420
- var removeNegativeTextIndentParser = function (format) {
38671
+ var removeNegativeTextIndentParser = function (format, element) {
38421
38672
  var _a;
38422
38673
  if ((_a = format.textIndent) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
38423
38674
  delete format.textIndent;
@@ -38426,6 +38677,101 @@ var removeNegativeTextIndentParser = function (format) {
38426
38677
  exports.removeNegativeTextIndentParser = removeNegativeTextIndentParser;
38427
38678
 
38428
38679
 
38680
+ /***/ }),
38681
+
38682
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/tableBorderParser.ts":
38683
+ /*!*****************************************************************************************!*\
38684
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/tableBorderParser.ts ***!
38685
+ \*****************************************************************************************/
38686
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
38687
+
38688
+ "use strict";
38689
+
38690
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38691
+ exports.tableBorderParser = void 0;
38692
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
38693
+ var ElementBorderKeys = new Map([
38694
+ ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],
38695
+ ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],
38696
+ ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],
38697
+ ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],
38698
+ ]);
38699
+ /**
38700
+ * @internal
38701
+ */
38702
+ var tableBorderParser = function (format, element) {
38703
+ roosterjs_content_model_dom_1.BorderKeys.forEach(function (key) {
38704
+ if (!format[key]) {
38705
+ var styleSet = ElementBorderKeys.get(key);
38706
+ if (styleSet &&
38707
+ element.style[styleSet.w] &&
38708
+ element.style[styleSet.s] &&
38709
+ !element.style[styleSet.c]) {
38710
+ format[key] = element.style[styleSet.w] + " " + element.style[styleSet.s];
38711
+ }
38712
+ }
38713
+ });
38714
+ };
38715
+ exports.tableBorderParser = tableBorderParser;
38716
+
38717
+
38718
+ /***/ }),
38719
+
38720
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordContainerParser.ts":
38721
+ /*!*******************************************************************************************!*\
38722
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordContainerParser.ts ***!
38723
+ \*******************************************************************************************/
38724
+ /***/ ((__unused_webpack_module, exports) => {
38725
+
38726
+ "use strict";
38727
+
38728
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38729
+ exports.wordContainerParser = void 0;
38730
+ /**
38731
+ * @internal
38732
+ * Parser for processing container formatting specific to Word Desktop
38733
+ * Removes negative margin-left values which are commonly used in Word lists
38734
+ * @param format The container format to modify
38735
+ */
38736
+ var wordContainerParser = function (format) {
38737
+ var _a;
38738
+ if ((_a = format.marginLeft) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
38739
+ delete format.marginLeft;
38740
+ }
38741
+ };
38742
+ exports.wordContainerParser = wordContainerParser;
38743
+
38744
+
38745
+ /***/ }),
38746
+
38747
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordTableParser.ts":
38748
+ /*!***************************************************************************************!*\
38749
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordTableParser.ts ***!
38750
+ \***************************************************************************************/
38751
+ /***/ ((__unused_webpack_module, exports) => {
38752
+
38753
+ "use strict";
38754
+
38755
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
38756
+ exports.wordTableParser = void 0;
38757
+ /**
38758
+ * @internal
38759
+ * Parser for processing table formatting specific to Word Desktop
38760
+ * @param format The table format to modify
38761
+ * @param element The HTML element being processed
38762
+ */
38763
+ var wordTableParser = function (format, element) {
38764
+ var _a;
38765
+ if ((_a = format.marginLeft) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
38766
+ delete format.marginLeft;
38767
+ }
38768
+ if (format.htmlAlign) {
38769
+ delete format.htmlAlign;
38770
+ }
38771
+ };
38772
+ exports.wordTableParser = wordTableParser;
38773
+
38774
+
38429
38775
  /***/ }),
38430
38776
 
38431
38777
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/constants.ts":
@@ -38485,16 +38831,16 @@ exports.documentContainWacElements = documentContainWacElements;
38485
38831
 
38486
38832
  /***/ }),
38487
38833
 
38488
- /***/ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getPasteSource.ts":
38489
- /*!*****************************************************************************************************!*\
38490
- !*** ./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getPasteSource.ts ***!
38491
- \*****************************************************************************************************/
38834
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getDocumentSource.ts":
38835
+ /*!********************************************************************************************************!*\
38836
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/getDocumentSource.ts ***!
38837
+ \********************************************************************************************************/
38492
38838
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
38493
38839
 
38494
38840
  "use strict";
38495
38841
 
38496
38842
  Object.defineProperty(exports, "__esModule", ({ value: true }));
38497
- exports.getPasteSource = void 0;
38843
+ exports.getDocumentSource = void 0;
38498
38844
  var documentContainWacElements_1 = __webpack_require__(/*! ./documentContainWacElements */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/documentContainWacElements.ts");
38499
38845
  var isExcelDesktopDocument_1 = __webpack_require__(/*! ./isExcelDesktopDocument */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/isExcelDesktopDocument.ts");
38500
38846
  var isExcelNonNativeEvent_1 = __webpack_require__(/*! ./isExcelNonNativeEvent */ "./packages/roosterjs-content-model-plugins/lib/paste/pasteSourceValidations/isExcelNonNativeEvent.ts");
@@ -38522,16 +38868,8 @@ var getSourceFunctions = new Map([
38522
38868
  * @param shouldConvertSingleImage Whether convert single image is enabled.
38523
38869
  * @returns The Type of pasted content, if no type found will return {KnownSourceType.Default}
38524
38870
  */
38525
- function getPasteSource(event, shouldConvertSingleImage, environment) {
38526
- var htmlAttributes = event.htmlAttributes, clipboardData = event.clipboardData, fragment = event.fragment;
38871
+ function getDocumentSource(param) {
38527
38872
  var result = null;
38528
- var param = {
38529
- htmlAttributes: htmlAttributes,
38530
- fragment: fragment,
38531
- shouldConvertSingleImage: shouldConvertSingleImage,
38532
- clipboardData: clipboardData,
38533
- environment: environment,
38534
- };
38535
38873
  getSourceFunctions.forEach(function (func, key) {
38536
38874
  if (!result && func(param)) {
38537
38875
  result = key;
@@ -38539,7 +38877,7 @@ function getPasteSource(event, shouldConvertSingleImage, environment) {
38539
38877
  });
38540
38878
  return result !== null && result !== void 0 ? result : 'default';
38541
38879
  }
38542
- exports.getPasteSource = getPasteSource;
38880
+ exports.getDocumentSource = getDocumentSource;
38543
38881
 
38544
38882
 
38545
38883
  /***/ }),
@@ -38589,11 +38927,11 @@ var ShadowWorkbookClipboardType = 'web data/shadow-workbook';
38589
38927
  * attributes we use to determine if the content is from Excel. This function is used to handle that case.
38590
38928
  */
38591
38929
  var isExcelNotNativeEvent = function (props) {
38592
- var _a;
38593
- var clipboardData = props.clipboardData;
38594
- return (clipboardData.types.includes(ShadowWorkbookClipboardType) &&
38595
- ((_a = clipboardData.htmlFirstLevelChildTags) === null || _a === void 0 ? void 0 : _a.length) == 1 &&
38596
- clipboardData.htmlFirstLevelChildTags[0] == 'TABLE');
38930
+ var clipboardItemTypes = props.clipboardItemTypes, htmlFirstLevelChildTags = props.htmlFirstLevelChildTags;
38931
+ return !!(clipboardItemTypes &&
38932
+ clipboardItemTypes.includes(ShadowWorkbookClipboardType) &&
38933
+ (htmlFirstLevelChildTags === null || htmlFirstLevelChildTags === void 0 ? void 0 : htmlFirstLevelChildTags.length) == 1 &&
38934
+ htmlFirstLevelChildTags[0] == 'TABLE');
38597
38935
  };
38598
38936
  exports.isExcelNotNativeEvent = isExcelNotNativeEvent;
38599
38937
 
@@ -38731,14 +39069,14 @@ var WORD_PROG_ID = 'Word.Document';
38731
39069
  * @returns
38732
39070
  */
38733
39071
  var isWordDesktopDocument = function (props) {
38734
- var _a;
38735
- var htmlAttributes = props.htmlAttributes, clipboardData = props.clipboardData, environment = props.environment;
39072
+ var htmlAttributes = props.htmlAttributes, rawHtml = props.rawHtml, environment = props.environment;
38736
39073
  return (htmlAttributes[WORD_ATTRIBUTE_NAME] == WORD_ATTRIBUTE_VALUE ||
38737
39074
  htmlAttributes[constants_1.PastePropertyNames.PROG_ID_NAME] == WORD_PROG_ID ||
38738
39075
  // Safari removes the metadata from the clipboard html, so we need to do this check.
38739
39076
  !!(environment.isSafari &&
38740
- clipboardData.rawHtml &&
38741
- ((_a = clipboardData.rawHtml) === null || _a === void 0 ? void 0 : _a.replace(/ /g, '').indexOf(WORD_ATTRIBUTE_NAME + "=\"" + WORD_ATTRIBUTE_VALUE)) > -1));
39077
+ rawHtml &&
39078
+ (rawHtml === null || rawHtml === void 0 ? void 0 : rawHtml.replace(/ /g, '').indexOf(WORD_ATTRIBUTE_NAME + "=\"" + WORD_ATTRIBUTE_VALUE)) >
39079
+ -1));
38742
39080
  };
38743
39081
  exports.isWordDesktopDocument = isWordDesktopDocument;
38744
39082
 
@@ -38763,11 +39101,10 @@ exports.shouldConvertToSingleImage = void 0;
38763
39101
  * @returns
38764
39102
  */
38765
39103
  var shouldConvertToSingleImage = function (props) {
38766
- var _a;
38767
- var shouldConvertSingleImage = props.shouldConvertSingleImage, clipboardData = props.clipboardData;
38768
- return (shouldConvertSingleImage &&
38769
- ((_a = clipboardData.htmlFirstLevelChildTags) === null || _a === void 0 ? void 0 : _a.length) == 1 &&
38770
- clipboardData.htmlFirstLevelChildTags[0] == 'IMG');
39104
+ var shouldConvertSingleImage = props.shouldConvertSingleImage, htmlFirstLevelChildTags = props.htmlFirstLevelChildTags;
39105
+ return !!(shouldConvertSingleImage &&
39106
+ (htmlFirstLevelChildTags === null || htmlFirstLevelChildTags === void 0 ? void 0 : htmlFirstLevelChildTags.length) == 1 &&
39107
+ htmlFirstLevelChildTags[0] == 'IMG');
38771
39108
  };
38772
39109
  exports.shouldConvertToSingleImage = shouldConvertToSingleImage;
38773
39110