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