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