roosterjs 9.50.1 → 9.52.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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Type definitions for roosterjs (Version 9.50.1)
1
+ // Type definitions for roosterjs (Version 9.52.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -2976,6 +2976,7 @@ interface EditorContext {
2976
2976
  */
2977
2977
  allowCacheElement?: boolean;
2978
2978
  /**
2979
+ * @deprecated This is now always be treated as true
2979
2980
  * Whether to allow caching list item elements separately.
2980
2981
  */
2981
2982
  allowCacheListItem?: boolean;
@@ -3058,6 +3059,11 @@ interface DomToModelListFormat {
3058
3059
  * Current list type stack
3059
3060
  */
3060
3061
  levels: ContentModelListLevel[];
3062
+ /**
3063
+ * This is used for handling an abnormal case where list items are not inside a ul or ol tag
3064
+ * It is not common and against the HTML specification, but we need to handle it for robustness
3065
+ */
3066
+ potentialListType?: 'OL' | 'UL';
3061
3067
  }
3062
3068
 
3063
3069
  /**
@@ -3812,11 +3818,6 @@ interface IEditor {
3812
3818
  * when create editor
3813
3819
  */
3814
3820
  type ExperimentalFeature = GraduatedExperimentalFeature
3815
- /**
3816
- * @deprecated Please use the shouldHandleEnterKey option of the EditPlugin Options
3817
- * Use Content Model handle ENTER key
3818
- */
3819
- | 'HandleEnterKey'
3820
3821
  /**
3821
3822
  * For CJK keyboard input on mobile, if the user toggles bold/italic/underline on an empty div,
3822
3823
  * the pending format will be applied on the selection marker. When typing text, the selection moves to the text node and the
@@ -3824,19 +3825,6 @@ type ExperimentalFeature = GraduatedExperimentalFeature
3824
3825
  * the original formatting of the selection marker is kept to match the pending format.
3825
3826
  */
3826
3827
  | 'KeepSelectionMarkerWhenEnteringTextNode'
3827
- /**
3828
- * Export editor content as HTML using HTMLFast option
3829
- */
3830
- | 'ExportHTMLFast'
3831
- /**
3832
- * Get cloned root element from an independent HTML document instead of current document.
3833
- * So any operation to the cloned root won't trigger network request for resources like images
3834
- */
3835
- | 'CloneIndependentRoot'
3836
- /**
3837
- * Allow caching list item elements.
3838
- */
3839
- | 'CacheList'
3840
3828
  /**
3841
3829
  * Transform the table border colors when switching from light to dark mode
3842
3830
  */
@@ -3860,7 +3848,28 @@ type GraduatedExperimentalFeature = /**
3860
3848
  * Prevent default browser behavior for copy/cut event,
3861
3849
  * and set the clipboard data with custom implementation.
3862
3850
  */
3863
- | 'CustomCopyCut';
3851
+ | 'CustomCopyCut'
3852
+ /**
3853
+ * @deprecated
3854
+ * Export editor content as HTML using HTMLFast option
3855
+ */
3856
+ | 'ExportHTMLFast'
3857
+ /**
3858
+ * @deprecated Please use the shouldHandleEnterKey option of the EditPlugin Options
3859
+ * Use Content Model handle ENTER key
3860
+ */
3861
+ | 'HandleEnterKey'
3862
+ /**
3863
+ * @deprecated
3864
+ * Get cloned root element from an independent HTML document instead of current document.
3865
+ * So any operation to the cloned root won't trigger network request for resources like images
3866
+ */
3867
+ | 'CloneIndependentRoot'
3868
+ /**
3869
+ * @deprecated
3870
+ * Allow caching list item elements.
3871
+ */
3872
+ | 'CacheList';
3864
3873
 
3865
3874
  /**
3866
3875
  * Options for editor
@@ -6314,6 +6323,18 @@ interface BeforePasteEvent extends BasePluginEvent<'beforePaste'> {
6314
6323
  * Whether the current clipboard contains at least a block element.
6315
6324
  */
6316
6325
  readonly containsBlockElements?: boolean;
6326
+ /**
6327
+ * Global CSS rules extracted from the pasted document's style sheets
6328
+ */
6329
+ readonly globalCssRules?: CssRule[];
6330
+ }
6331
+
6332
+ /**
6333
+ * Represents a single CSS rule parsed from a pasted document's style sheets
6334
+ */
6335
+ interface CssRule {
6336
+ selectors: string[];
6337
+ text: string;
6317
6338
  }
6318
6339
 
6319
6340
  /**
@@ -8745,7 +8766,7 @@ function createModelFromHtml(html: string, options?: Partial<DomToModelOptionFor
8745
8766
  /**
8746
8767
  * Export HTML content. If there are entities, this will cause EntityOperation event with option = 'replaceTemporaryContent' to get a dehydrated entity
8747
8768
  * @param editor The editor to get content from
8748
- * @param mode Specify HTML to get HTML. This is the default option
8769
+ * @param mode Specify HTML to get HTML.
8749
8770
  * @param options @optional Options for Model to DOM conversion
8750
8771
  */
8751
8772
  function exportContent(editor: IEditor, mode?: 'HTML', options?: ModelToDomOption): string;
@@ -8754,9 +8775,9 @@ function exportContent(editor: IEditor, mode?: 'HTML', options?: ModelToDomOptio
8754
8775
  * Export HTML content. If there are entities, this will cause EntityOperation event with option = 'replaceTemporaryContent' to get a dehydrated entity.
8755
8776
  * This is a fast version, it retrieve HTML content directly from editor without going through content model conversion.
8756
8777
  * @param editor The editor to get content from
8757
- * @param mode Specify HTMLFast to get HTML result.
8778
+ * @param mode Specify HTMLFast to get HTML result. This is the default option
8758
8779
  */
8759
- function exportContent(editor: IEditor, mode: 'HTMLFast'): string;
8780
+ function exportContent(editor: IEditor, mode?: 'HTMLFast'): string;
8760
8781
 
8761
8782
  /**
8762
8783
  * Export plain text content
@@ -9473,15 +9494,12 @@ class EditPlugin implements EditorPlugin {
9473
9494
  private disposer;
9474
9495
  private shouldHandleNextInputEvent;
9475
9496
  private selectionAfterDelete;
9476
- private handleNormalEnter;
9477
9497
  private options;
9478
9498
  /**
9479
9499
  * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:
9480
9500
  * 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.
9481
9501
  */
9482
9502
  constructor(options?: EditOptions);
9483
- private createNormalEnterChecker;
9484
- private getHandleNormalEnter;
9485
9503
  /**
9486
9504
  * Get name of this plugin
9487
9505
  */
package/dist/rooster.js CHANGED
@@ -9102,7 +9102,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
9102
9102
  // Here I didn't add 'HTMLFast' to ExportContentMode type because it will make this a breaking change and EditorAdapter will see build time error without bumping version
9103
9103
  // Once we are confident that 'HTMLFast' is stable, we can fully switch 'HTML' to use the 'HTMLFast' approach
9104
9104
  function exportContent(editor, mode, optionsOrCallbacks) {
9105
- if (mode === void 0) { mode = 'HTML'; }
9105
+ if (mode === void 0) { mode = 'HTMLFast'; }
9106
9106
  var model;
9107
9107
  switch (mode) {
9108
9108
  case 'PlainTextFast':
@@ -9111,6 +9111,7 @@ function exportContent(editor, mode, optionsOrCallbacks) {
9111
9111
  model = editor.getContentModelCopy('clean');
9112
9112
  return (0, roosterjs_content_model_dom_1.contentModelToText)(model, undefined /*separator*/, optionsOrCallbacks);
9113
9113
  case 'HTMLFast':
9114
+ default:
9114
9115
  var clonedRoot = editor.getDOMHelper().getClonedRoot();
9115
9116
  if (editor.isDarkMode()) {
9116
9117
  (0, roosterjs_content_model_dom_1.transformColor)(clonedRoot, false /*includeSelf*/, 'darkToLight', editor.getColorManager(), {
@@ -9119,7 +9120,6 @@ function exportContent(editor, mode, optionsOrCallbacks) {
9119
9120
  }
9120
9121
  return getHTMLFromDOM(editor, clonedRoot);
9121
9122
  case 'HTML':
9122
- default:
9123
9123
  model = editor.getContentModelCopy('clean');
9124
9124
  var doc = editor.getDocument();
9125
9125
  var div = doc.createElement('div');
@@ -9319,6 +9319,7 @@ function generatePasteOptionFromPlugins(editor, clipboardData, fragment, htmlFro
9319
9319
  pasteType: pasteType,
9320
9320
  domToModelOption: domToModelOption,
9321
9321
  containsBlockElements: !!htmlFromClipboard.containsBlockElements,
9322
+ globalCssRules: htmlFromClipboard.globalCssRules,
9322
9323
  };
9323
9324
  return editor.triggerEvent('beforePaste', event, true /* broadcast */);
9324
9325
  }
@@ -10130,10 +10131,10 @@ var getRootComputedStyleForContext_1 = __webpack_require__(/*! ./getRootComputed
10130
10131
  * Create a EditorContext object used by ContentModel API
10131
10132
  */
10132
10133
  var createEditorContext = function (core, saveIndex) {
10133
- var _a, _b, _c;
10134
+ var _a, _b;
10134
10135
  var lifecycle = core.lifecycle, format = core.format, darkColorHandler = core.darkColorHandler, logicalRoot = core.logicalRoot, cache = core.cache, domHelper = core.domHelper;
10135
10136
  saveIndex = saveIndex && !core.lifecycle.shadowEditFragment;
10136
- 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));
10137
+ 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, editorViewWidth: domHelper.getClientWidth() }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(logicalRoot.ownerDocument));
10137
10138
  if (core.domHelper.isRightToLeft()) {
10138
10139
  context.isRootRtl = true;
10139
10140
  }
@@ -15954,7 +15955,6 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
15954
15955
  var DOMHelperImpl = /** @class */ (function () {
15955
15956
  function DOMHelperImpl(contentDiv, options) {
15956
15957
  this.contentDiv = contentDiv;
15957
- this.options = options;
15958
15958
  }
15959
15959
  DOMHelperImpl.prototype.queryElements = function (selector) {
15960
15960
  return (0, roosterjs_content_model_dom_1.toArray)(this.contentDiv.querySelectorAll(selector));
@@ -16043,14 +16043,9 @@ var DOMHelperImpl = /** @class */ (function () {
16043
16043
  * Get a deep cloned root element
16044
16044
  */
16045
16045
  DOMHelperImpl.prototype.getClonedRoot = function () {
16046
- if (this.options.cloneIndependentRoot) {
16047
- var doc = this.contentDiv.ownerDocument.implementation.createHTMLDocument();
16048
- var clone = doc.importNode(this.contentDiv, true /*deep*/);
16049
- return clone;
16050
- }
16051
- else {
16052
- return this.contentDiv.cloneNode(true /*deep*/);
16053
- }
16046
+ var doc = this.contentDiv.ownerDocument.implementation.createHTMLDocument();
16047
+ var clone = doc.importNode(this.contentDiv, true /*deep*/);
16048
+ return clone;
16054
16049
  };
16055
16050
  /**
16056
16051
  * Get format of the container element
@@ -16188,7 +16183,7 @@ var createEditorCorePlugins_1 = __webpack_require__(/*! ../../corePlugin/createE
16188
16183
  * @param options Editor options
16189
16184
  */
16190
16185
  function createEditorCore(contentDiv, options) {
16191
- var _a, _b, _c;
16186
+ var _a, _b;
16192
16187
  var corePlugins = (0, createEditorCorePlugins_1.createEditorCorePlugins)(options, contentDiv);
16193
16188
  var domCreator = (0, domCreator_1.createDOMCreator)(options.trustedHTMLHandler);
16194
16189
  return (0, tslib_1.__assign)((0, tslib_1.__assign)({ physicalRoot: contentDiv, logicalRoot: contentDiv, api: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, coreApiMap_1.coreApiMap), options.coreApiOverride), originalApi: (0, tslib_1.__assign)({}, coreApiMap_1.coreApiMap), plugins: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([
@@ -16204,9 +16199,7 @@ function createEditorCore(contentDiv, options) {
16204
16199
  corePlugins.lifecycle,
16205
16200
  ], false), environment: createEditorEnvironment(contentDiv, options), darkColorHandler: (0, DarkColorHandlerImpl_1.createDarkColorHandler)(contentDiv, (_b = options.getDarkColor) !== null && _b !== void 0 ? _b : getDarkColorFallback, options.knownColors, options.generateColorKey), trustedHTMLHandler: options.trustedHTMLHandler && !(0, domCreator_1.isDOMCreator)(options.trustedHTMLHandler)
16206
16201
  ? options.trustedHTMLHandler
16207
- : (0, domCreator_1.createTrustedHTMLHandler)(domCreator), domCreator: domCreator, domHelper: (0, DOMHelperImpl_1.createDOMHelper)(contentDiv, {
16208
- cloneIndependentRoot: (_c = options.experimentalFeatures) === null || _c === void 0 ? void 0 : _c.includes('CloneIndependentRoot'),
16209
- }) }, getPluginState(corePlugins)), { disposeErrorHandler: options.disposeErrorHandler, onFixUpModel: options.onFixUpModel, experimentalFeatures: options.experimentalFeatures ? (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(options.experimentalFeatures), false) : [] });
16202
+ : (0, domCreator_1.createTrustedHTMLHandler)(domCreator), domCreator: domCreator, domHelper: (0, DOMHelperImpl_1.createDOMHelper)(contentDiv) }, getPluginState(corePlugins)), { disposeErrorHandler: options.disposeErrorHandler, onFixUpModel: options.onFixUpModel, experimentalFeatures: options.experimentalFeatures ? (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(options.experimentalFeatures), false) : [] });
16210
16203
  }
16211
16204
  exports.createEditorCore = createEditorCore;
16212
16205
  function createEditorEnvironment(contentDiv, options) {
@@ -18493,6 +18486,7 @@ exports.linkProcessor = linkProcessor;
18493
18486
  Object.defineProperty(exports, "__esModule", ({ value: true }));
18494
18487
  exports.listItemProcessor = void 0;
18495
18488
  var createListItem_1 = __webpack_require__(/*! ../../modelApi/creators/createListItem */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createListItem.ts");
18489
+ var createListLevel_1 = __webpack_require__(/*! ../../modelApi/creators/createListLevel */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createListLevel.ts");
18496
18490
  var parseFormat_1 = __webpack_require__(/*! ../utils/parseFormat */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/parseFormat.ts");
18497
18491
  var stackFormat_1 = __webpack_require__(/*! ../utils/stackFormat */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/stackFormat.ts");
18498
18492
  /**
@@ -18501,14 +18495,22 @@ var stackFormat_1 = __webpack_require__(/*! ../utils/stackFormat */ "./packages/
18501
18495
  var listItemProcessor = function (group, element, context) {
18502
18496
  var _a;
18503
18497
  var listFormat = context.listFormat;
18504
- if (listFormat.listParent && listFormat.levels.length > 0) {
18498
+ var originalListParent = listFormat.listParent;
18499
+ var shouldPopListLevel = false;
18500
+ try {
18501
+ listFormat.listParent = (_a = listFormat.listParent) !== null && _a !== void 0 ? _a : group;
18502
+ var listParent_1 = listFormat.listParent;
18503
+ if (listFormat.levels.length == 0) {
18504
+ listFormat.levels.push((0, createListLevel_1.createListLevel)(listFormat.potentialListType || 'UL', context.blockFormat));
18505
+ shouldPopListLevel = true;
18506
+ }
18505
18507
  (0, stackFormat_1.stackFormat)(context, {
18506
18508
  segment: 'shallowCloneForBlock',
18507
18509
  }, function () {
18508
18510
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);
18509
18511
  var listItem = (0, createListItem_1.createListItem)(listFormat.levels, context.segmentFormat);
18510
18512
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.listItemElement, listItem.format, context);
18511
- listFormat.listParent.blocks.push(listItem);
18513
+ listParent_1.blocks.push(listItem);
18512
18514
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.listItemThread, listItem.levels[listItem.levels.length - 1].format, context);
18513
18515
  context.elementProcessors.child(listItem, element, context);
18514
18516
  var firstChild = listItem.blocks[0];
@@ -18520,10 +18522,11 @@ var listItemProcessor = function (group, element, context) {
18520
18522
  }
18521
18523
  });
18522
18524
  }
18523
- else {
18524
- var currentBlocks = (_a = listFormat.listParent) === null || _a === void 0 ? void 0 : _a.blocks;
18525
- var lastItem = currentBlocks === null || currentBlocks === void 0 ? void 0 : currentBlocks[(currentBlocks === null || currentBlocks === void 0 ? void 0 : currentBlocks.length) - 1];
18526
- context.elementProcessors['*']((lastItem === null || lastItem === void 0 ? void 0 : lastItem.blockType) == 'BlockGroup' ? lastItem : group, element, context);
18525
+ finally {
18526
+ if (shouldPopListLevel) {
18527
+ listFormat.levels.pop();
18528
+ }
18529
+ listFormat.listParent = originalListParent;
18527
18530
  }
18528
18531
  };
18529
18532
  exports.listItemProcessor = listItemProcessor;
@@ -18552,13 +18555,15 @@ var listProcessor = function (group, element, context) {
18552
18555
  segment: 'shallowCloneForBlock',
18553
18556
  paragraph: 'shallowCloneForGroup',
18554
18557
  }, function () {
18555
- var level = (0, createListLevel_1.createListLevel)(element.tagName, context.blockFormat);
18558
+ var tagName = element.tagName;
18559
+ var level = (0, createListLevel_1.createListLevel)(tagName, context.blockFormat);
18556
18560
  var listFormat = context.listFormat;
18557
18561
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.dataset, level.dataset, context);
18558
18562
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.listLevelThread, level.format, context);
18559
18563
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.listLevel, level.format, context);
18560
18564
  (0, parseFormat_1.parseFormat)(element, context.formatParsers.segment, context.segmentFormat, context);
18561
18565
  var originalListParent = listFormat.listParent;
18566
+ listFormat.potentialListType = tagName;
18562
18567
  listFormat.listParent = listFormat.listParent || group;
18563
18568
  listFormat.levels.push(level);
18564
18569
  try {
@@ -29127,7 +29132,7 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
29127
29132
  exports.handleBlockGroupChildren = handleBlockGroupChildren;
29128
29133
  function cleanUpNodeStack(nodeStack, context) {
29129
29134
  var _a, _b;
29130
- if (context.allowCacheListItem && nodeStack.length > 0) {
29135
+ if (nodeStack.length > 0) {
29131
29136
  // Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
29132
29137
  for (var i = nodeStack.length - 1; i > 0; i--) {
29133
29138
  var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
@@ -29502,20 +29507,16 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29502
29507
  // Apply metadata to list level to make sure list style is correct after rendering
29503
29508
  (0, applyMetadata_1.applyMetadata)(itemLevel, context.metadataAppliers.listLevel, itemLevel.format, context);
29504
29509
  }
29505
- if (context.allowCacheListItem &&
29506
- parentLevel.refNode &&
29507
- itemLevel.cachedElement == parentLevel.refNode) {
29510
+ if (parentLevel.refNode && itemLevel.cachedElement == parentLevel.refNode) {
29508
29511
  // Move refNode to next node since we are reusing this cached element
29509
29512
  parentLevel.refNode = parentLevel.refNode.nextSibling;
29510
29513
  }
29511
29514
  }
29512
29515
  // Cut off remained list levels that we can't reuse
29513
- if (context.allowCacheListItem) {
29514
- // Clean up all rest nodes in the reused list levels
29515
- for (var i = layer + 1; i < nodeStack.length; i++) {
29516
- var stackLevel = nodeStack[i];
29517
- (0, cleanUpRestNodes_1.cleanUpRestNodes)(stackLevel.refNode, context.rewriteFromModel);
29518
- }
29516
+ // Clean up all rest nodes in the reused list levels
29517
+ for (var i = layer + 1; i < nodeStack.length; i++) {
29518
+ var stackLevel = nodeStack[i];
29519
+ (0, cleanUpRestNodes_1.cleanUpRestNodes)(stackLevel.refNode, context.rewriteFromModel);
29519
29520
  }
29520
29521
  nodeStack.splice(layer + 1);
29521
29522
  // Create new list levels that are after reused ones
@@ -29526,7 +29527,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29526
29527
  var isNewlyCreated = false;
29527
29528
  var levelRefNode = (_c = nodeStack[layer].refNode) !== null && _c !== void 0 ? _c : null;
29528
29529
  context.listFormat.currentLevel = layer;
29529
- if (context.allowCacheListItem && level.cachedElement) {
29530
+ if (level.cachedElement) {
29530
29531
  newList = level.cachedElement;
29531
29532
  nodeStack[layer].refNode = (0, reuseCachedElement_1.reuseCachedElement)(lastParent, level.cachedElement, levelRefNode, context.rewriteFromModel);
29532
29533
  nodeStack.push({
@@ -29548,9 +29549,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
29548
29549
  format: (0, tslib_1.__assign)({}, level.format),
29549
29550
  dataset: (0, tslib_1.__assign)({}, level.dataset),
29550
29551
  });
29551
- if (context.allowCacheListItem) {
29552
- level.cachedElement = newList;
29553
- }
29552
+ level.cachedElement = newList;
29554
29553
  }
29555
29554
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.listLevelThread, level.format, context);
29556
29555
  // Need to apply metadata after applying list level format since the list numbers value relies on the result of list thread handling
@@ -29601,7 +29600,7 @@ var handleListItem = function (doc, parent, listItem, context, refNode) {
29601
29600
  var level = listItem.levels[listItem.levels.length - 1];
29602
29601
  var li;
29603
29602
  var isNewlyCreated = false;
29604
- if (context.allowCacheListItem && listItem.cachedElement) {
29603
+ if (listItem.cachedElement) {
29605
29604
  li = listItem.cachedElement;
29606
29605
  // Check if the cached LI is used as refNode under another list level,
29607
29606
  // since we know we are going to move it under the current listParent,
@@ -29620,9 +29619,7 @@ var handleListItem = function (doc, parent, listItem, context, refNode) {
29620
29619
  // This happens when outdent a list item to cause it has no list level
29621
29620
  listParent.insertBefore(li, (itemRefNode === null || itemRefNode === void 0 ? void 0 : itemRefNode.parentNode) == listParent ? itemRefNode : null);
29622
29621
  context.rewriteFromModel.addedBlockElements.push(li);
29623
- if (context.allowCacheListItem) {
29624
- listItem.cachedElement = li;
29625
- }
29622
+ listItem.cachedElement = li;
29626
29623
  }
29627
29624
  if (level) {
29628
29625
  (0, applyFormat_1.applyFormat)(li, context.formatAppliers.segment, listItem.formatHolder.format, context);
@@ -33512,7 +33509,6 @@ var EditPlugin = /** @class */ (function () {
33512
33509
  this.disposer = null;
33513
33510
  this.shouldHandleNextInputEvent = false;
33514
33511
  this.selectionAfterDelete = null;
33515
- this.handleNormalEnter = function () { return false; };
33516
33512
  var tabOptions = options.handleTabKey === false
33517
33513
  ? DisabledHandleTabOptions
33518
33514
  : options.handleTabKey === true || !options.handleTabKey
@@ -33520,19 +33516,6 @@ var EditPlugin = /** @class */ (function () {
33520
33516
  : (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultHandleTabOptions), options.handleTabKey);
33521
33517
  this.options = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultOptions), options), { handleTabKey: tabOptions });
33522
33518
  }
33523
- EditPlugin.prototype.createNormalEnterChecker = function (result) {
33524
- return result ? function () { return true; } : function () { return false; };
33525
- };
33526
- EditPlugin.prototype.getHandleNormalEnter = function (editor) {
33527
- switch (typeof this.options.shouldHandleEnterKey) {
33528
- case 'function':
33529
- return this.options.shouldHandleEnterKey;
33530
- case 'boolean':
33531
- return this.createNormalEnterChecker(this.options.shouldHandleEnterKey);
33532
- default:
33533
- return this.createNormalEnterChecker(editor.isExperimentalFeatureEnabled('HandleEnterKey'));
33534
- }
33535
- };
33536
33519
  /**
33537
33520
  * Get name of this plugin
33538
33521
  */
@@ -33548,7 +33531,6 @@ var EditPlugin = /** @class */ (function () {
33548
33531
  EditPlugin.prototype.initialize = function (editor) {
33549
33532
  var _this = this;
33550
33533
  this.editor = editor;
33551
- this.handleNormalEnter = this.getHandleNormalEnter(editor);
33552
33534
  if (editor.getEnvironment().isAndroid) {
33553
33535
  this.disposer = this.editor.attachDomEvent({
33554
33536
  beforeinput: {
@@ -33652,7 +33634,11 @@ var EditPlugin = /** @class */ (function () {
33652
33634
  if (!hasCtrlOrMetaKey &&
33653
33635
  !event.rawEvent.isComposing &&
33654
33636
  event.rawEvent.keyCode !== DEAD_KEY) {
33655
- (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter(editor), this.options.formatsToPreserveOnMerge);
33637
+ var shouldHandleEnterKey = this.options.shouldHandleEnterKey;
33638
+ var handleNormalEnter = typeof shouldHandleEnterKey === 'function'
33639
+ ? shouldHandleEnterKey(editor)
33640
+ : shouldHandleEnterKey !== false;
33641
+ (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, handleNormalEnter, this.options.formatsToPreserveOnMerge);
33656
33642
  }
33657
33643
  break;
33658
33644
  default:
@@ -39070,7 +39056,7 @@ var PastePlugin = /** @class */ (function () {
39070
39056
  var pasteType = event.pasteType;
39071
39057
  switch (pasteSource) {
39072
39058
  case 'wordDesktop':
39073
- (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event.domToModelOption, event.htmlBefore || event.clipboardData.rawHtml || '');
39059
+ (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(event.domToModelOption, event.htmlBefore || event.clipboardData.rawHtml || '', event.globalCssRules);
39074
39060
  break;
39075
39061
  case 'wacComponents':
39076
39062
  (0, processPastedContentWacComponents_1.processPastedContentWacComponents)(event);
@@ -39707,13 +39693,17 @@ var removeNegativeTextIndentParser_1 = __webpack_require__(/*! ../parsers/remove
39707
39693
  var setProcessor_1 = __webpack_require__(/*! ../utils/setProcessor */ "./packages/roosterjs-content-model-plugins/lib/paste/utils/setProcessor.ts");
39708
39694
  var wordContainerParser_1 = __webpack_require__(/*! ../parsers/wordContainerParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordContainerParser.ts");
39709
39695
  var wordTableParser_1 = __webpack_require__(/*! ../parsers/wordTableParser */ "./packages/roosterjs-content-model-plugins/lib/paste/parsers/wordTableParser.ts");
39696
+ var removeListParagraphMargins_1 = __webpack_require__(/*! ./removeListParagraphMargins */ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeListParagraphMargins.ts");
39710
39697
  /**
39711
39698
  * @internal
39712
39699
  * Handles pasted content when the source is Word Desktop.
39713
39700
  * @param domToModelOption Options for DOM to Content Model conversion
39714
39701
  * @param htmlString The HTML string to process
39702
+ * @param globalCssRules Global CSS rules extracted from the pasted document
39715
39703
  */
39716
- function processPastedContentFromWordDesktop(domToModelOption, htmlString) {
39704
+ function processPastedContentFromWordDesktop(domToModelOption, htmlString, globalCssRules) {
39705
+ if (globalCssRules === void 0) { globalCssRules = []; }
39706
+ (0, removeListParagraphMargins_1.removeListParagraphMargins)(globalCssRules);
39717
39707
  var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(htmlString);
39718
39708
  (0, setProcessor_1.setProcessor)(domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
39719
39709
  (0, addParser_1.addParser)(domToModelOption, 'block', adjustPercentileLineHeightParser_1.adjustPercentileLineHeight);
@@ -39984,6 +39974,96 @@ function getBulletElement(element) {
39984
39974
  }
39985
39975
 
39986
39976
 
39977
+ /***/ },
39978
+
39979
+ /***/ "./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeListParagraphMargins.ts"
39980
+ /*!******************************************************************************************************!*\
39981
+ !*** ./packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/removeListParagraphMargins.ts ***!
39982
+ \******************************************************************************************************/
39983
+ (__unused_webpack_module, exports) {
39984
+
39985
+ "use strict";
39986
+
39987
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
39988
+ exports.removeListParagraphMargins = void 0;
39989
+ /**
39990
+ * CSS class selectors used by Word Desktop to mark list paragraph elements.
39991
+ * Word emits global CSS rules that apply margins to these classes, which we want
39992
+ * to suppress so that RoosterJS list indentation logic is used instead.
39993
+ */
39994
+ var WORD_LIST_PARAGRAPH_SELECTORS = new Set([
39995
+ 'p.MsoListParagraph',
39996
+ 'p.MsoListParagraphCxSpFirst',
39997
+ 'p.MsoListParagraphCxSpMiddle',
39998
+ 'p.MsoListParagraphCxSpLast',
39999
+ 'div.MsoListParagraph',
40000
+ 'div.MsoListParagraphCxSpFirst',
40001
+ 'div.MsoListParagraphCxSpMiddle',
40002
+ 'div.MsoListParagraphCxSpLast',
40003
+ ]);
40004
+ /**
40005
+ * @internal
40006
+ * Strips all margin-* properties from a CSS property string.
40007
+ * Empty tokens produced by a trailing semicolon are preserved so that the
40008
+ * resulting string still ends with ";" and remains safe to concatenate.
40009
+ * For example, "margin-top: 0pt; color: red;" becomes " color: red;".
40010
+ */
40011
+ function removeMarginProperties(cssText) {
40012
+ return cssText
40013
+ .split(';')
40014
+ .filter(function (prop) {
40015
+ var name = prop.split(':')[0].trim().toLowerCase();
40016
+ // Keep empty tokens (the trailing ';' produces one) and any non-margin property.
40017
+ return !name || !/^margin/.test(name);
40018
+ })
40019
+ .join(';');
40020
+ }
40021
+ /**
40022
+ * @internal
40023
+ * Removes margin properties from global CSS rules that target Word list paragraph
40024
+ * classes (p.MsoListParagraph, p.MsoListParagraphCxSpFirst, etc.).
40025
+ *
40026
+ * Word Desktop pastes a global stylesheet that typically includes rules like:
40027
+ * p.MsoListParagraph { margin: 0in; margin-bottom: .0001pt; ... }
40028
+ * These margins conflict with RoosterJS's own list indentation, causing double
40029
+ * indentation when the CSS is converted to inline styles via convertInlineCss.
40030
+ *
40031
+ * When a rule's selectors are exclusively list paragraph classes the margins are
40032
+ * removed in place. When a rule groups list paragraph classes with other selectors
40033
+ * the rule is split: the non-list selectors keep the original text, and a new rule
40034
+ * is inserted for the list paragraph selectors with margins stripped.
40035
+ *
40036
+ * The array is mutated in place so the changes are reflected when convertInlineCss
40037
+ * subsequently processes the same array reference.
40038
+ */
40039
+ function removeListParagraphMargins(globalCssRules) {
40040
+ // Iterate in reverse so that splice insertions don't shift unvisited indices.
40041
+ for (var i = globalCssRules.length - 1; i >= 0; i--) {
40042
+ var rule = globalCssRules[i];
40043
+ var matchingSelectors = rule.selectors.filter(function (s) { return WORD_LIST_PARAGRAPH_SELECTORS.has(s); });
40044
+ if (matchingSelectors.length === 0) {
40045
+ continue;
40046
+ }
40047
+ var nonMatchingSelectors = rule.selectors.filter(function (s) { return !WORD_LIST_PARAGRAPH_SELECTORS.has(s); });
40048
+ if (nonMatchingSelectors.length === 0) {
40049
+ // All selectors target list paragraphs — strip margins directly.
40050
+ rule.text = removeMarginProperties(rule.text);
40051
+ }
40052
+ else {
40053
+ // Mixed rule: keep the non-list selectors on the original entry, then
40054
+ // insert a new entry immediately after for the list paragraph selectors
40055
+ // with margins removed.
40056
+ rule.selectors = nonMatchingSelectors;
40057
+ globalCssRules.splice(i + 1, 0, {
40058
+ selectors: matchingSelectors,
40059
+ text: removeMarginProperties(rule.text),
40060
+ });
40061
+ }
40062
+ }
40063
+ }
40064
+ exports.removeListParagraphMargins = removeListParagraphMargins;
40065
+
40066
+
39987
40067
  /***/ },
39988
40068
 
39989
40069
  /***/ "./packages/roosterjs-content-model-plugins/lib/paste/oneNote/processPastedContentFromOneNote.ts"