roosterjs 9.5.0 → 9.6.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.5.0)
1
+ // Type definitions for roosterjs (Version 9.6.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -3068,6 +3068,16 @@ interface DomIndexer {
3068
3068
  * @returns True if reconcile successfully, otherwise false
3069
3069
  */
3070
3070
  reconcileSelection: (model: ContentModelDocument, newSelection: DOMSelection, oldSelection?: CacheSelection) => boolean;
3071
+ /**
3072
+ * When child list of editor content is changed, we can use this method to do sync the change from editor into content model.
3073
+ * This is mostly used when user start to type in an empty line. In that case browser will remove the existing BR node in the empty line if any,
3074
+ * and create a new TEXT node for the typed text. Here we use these information to remove original Br segment and create a new Text segment
3075
+ * in content model. But if we find anything that cannot be handled, return false so caller will invalidate the cached model
3076
+ * @param addedNodes Nodes added by browser during mutation
3077
+ * @param removedNodes Nodes removed by browser during mutation
3078
+ * @returns True if the changed nodes are successfully reconciled, otherwise false
3079
+ */
3080
+ reconcileChildList: (addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>) => boolean;
3071
3081
  }
3072
3082
 
3073
3083
  /**
@@ -3085,7 +3095,7 @@ interface TextMutationObserver {
3085
3095
  /**
3086
3096
  * Flush all pending mutations that have not be handled in order to ignore them
3087
3097
  */
3088
- flushMutations(): void;
3098
+ flushMutations(newModel?: ContentModelDocument): void;
3089
3099
  }
3090
3100
 
3091
3101
  /**
@@ -7493,6 +7503,11 @@ const OrderedListStyleMap: Record<number, string>;
7493
7503
  */
7494
7504
  const UnorderedListStyleMap: Record<number, string>;
7495
7505
 
7506
+ /**
7507
+ * Provide a default empty instance of segment format with all its properties
7508
+ */
7509
+ const EmptySegmentFormat: Readonly<Required<ContentModelSegmentFormat>>;
7510
+
7496
7511
  /**
7497
7512
  * The main editor class based on Content Model
7498
7513
  */
package/dist/rooster.js CHANGED
@@ -2953,7 +2953,24 @@ function insertEntityModel(model, entityModel, position, isBlock, focusAfterEnti
2953
2953
  exports.insertEntityModel = insertEntityModel;
2954
2954
  function getInsertPoint(model, insertPointOverride, context) {
2955
2955
  if (insertPointOverride) {
2956
- return insertPointOverride;
2956
+ var paragraph = insertPointOverride.paragraph, marker = insertPointOverride.marker, tableContext = insertPointOverride.tableContext, path = insertPointOverride.path;
2957
+ var index = paragraph.segments.indexOf(marker);
2958
+ var previousSegment = index > 0 ? paragraph.segments[index - 1] : null;
2959
+ // It is possible that the real selection is right before the override selection marker.
2960
+ // This happens when:
2961
+ // [Override marker][Entity node to wrap][Real marker]
2962
+ // Then we will move the entity node into entity wrapper, causes the override marker and real marker are at the same place
2963
+ // And recreating content model causes real marker to appear before override marker.
2964
+ // Once that happens, we need to use the real marker instead so that after insert entity, real marker can be placed
2965
+ // after new entity (if insertPointOverride==true)
2966
+ return (previousSegment === null || previousSegment === void 0 ? void 0 : previousSegment.segmentType) == 'SelectionMarker' && previousSegment.isSelected
2967
+ ? {
2968
+ marker: previousSegment,
2969
+ paragraph: paragraph,
2970
+ tableContext: tableContext,
2971
+ path: path,
2972
+ }
2973
+ : insertPointOverride;
2957
2974
  }
2958
2975
  else {
2959
2976
  var deleteResult = (0, roosterjs_content_model_dom_1.deleteSelection)(model, [], context);
@@ -6858,8 +6875,8 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
6858
6875
  function formatSegmentWithContentModel(editor, apiName, toggleStyleCallback, segmentHasStyleCallback, includingFormatHolder, afterFormatCallback) {
6859
6876
  editor.formatContentModel(function (model, context) {
6860
6877
  var segmentAndParagraphs = (0, roosterjs_content_model_dom_1.getSelectedSegmentsAndParagraphs)(model, !!includingFormatHolder, false /*includingEntity*/, true /*mutate*/);
6861
- var isCollapsedSelection = segmentAndParagraphs.length == 1 &&
6862
- segmentAndParagraphs[0][0].segmentType == 'SelectionMarker';
6878
+ var isCollapsedSelection = segmentAndParagraphs.length >= 1 &&
6879
+ segmentAndParagraphs.every(function (x) { return x[0].segmentType == 'SelectionMarker'; });
6863
6880
  if (isCollapsedSelection) {
6864
6881
  var para_1 = segmentAndParagraphs[0][1];
6865
6882
  var path_1 = segmentAndParagraphs[0][2];
@@ -7711,19 +7728,6 @@ exports.mergePasteContent = exports.cloneModelForPaste = void 0;
7711
7728
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
7712
7729
  var createDomToModelContextForSanitizing_1 = __webpack_require__(/*! ../createModelFromHtml/createDomToModelContextForSanitizing */ "./packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts");
7713
7730
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
7714
- var EmptySegmentFormat = {
7715
- backgroundColor: '',
7716
- fontFamily: '',
7717
- fontSize: '',
7718
- fontWeight: '',
7719
- italic: false,
7720
- letterSpacing: '',
7721
- lineHeight: '',
7722
- strikethrough: false,
7723
- superOrSubScriptSequence: '',
7724
- textColor: '',
7725
- underline: false,
7726
- };
7727
7731
  var CloneOption = {
7728
7732
  includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
7729
7733
  };
@@ -7758,7 +7762,7 @@ function mergePasteContent(editor, eventResult, clipboardData) {
7758
7762
  ? customizedMerge(model, pasteModel)
7759
7763
  : (0, roosterjs_content_model_dom_1.mergeModel)(model, pasteModel, context, mergeOption);
7760
7764
  if (insertPoint) {
7761
- context.newPendingFormat = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, EmptySegmentFormat), model.format), insertPoint.marker.format);
7765
+ context.newPendingFormat = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, roosterjs_content_model_dom_1.EmptySegmentFormat), model.format), insertPoint.marker.format);
7762
7766
  }
7763
7767
  return true;
7764
7768
  }, {
@@ -9188,8 +9192,7 @@ var setContentModel = function (core, model, option, onNodeCreated) {
9188
9192
  core.selection.selection = selection;
9189
9193
  }
9190
9194
  // Clear pending mutations since we will use our latest model object to replace existing cache
9191
- (_a = core.cache.textMutationObserver) === null || _a === void 0 ? void 0 : _a.flushMutations();
9192
- core.cache.cachedModel = model;
9195
+ (_a = core.cache.textMutationObserver) === null || _a === void 0 ? void 0 : _a.flushMutations(model);
9193
9196
  }
9194
9197
  return selection;
9195
9198
  };
@@ -9831,19 +9834,30 @@ var CachePlugin = /** @class */ (function () {
9831
9834
  }
9832
9835
  }
9833
9836
  };
9837
+ this.onSkipMutation = function (newModel) {
9838
+ var _a;
9839
+ if (!((_a = _this.editor) === null || _a === void 0 ? void 0 : _a.isInShadowEdit())) {
9840
+ _this.state.cachedModel = newModel;
9841
+ _this.state.cachedSelection = undefined;
9842
+ }
9843
+ };
9834
9844
  this.onNativeSelectionChange = function () {
9835
9845
  var _a;
9836
9846
  if ((_a = _this.editor) === null || _a === void 0 ? void 0 : _a.hasFocus()) {
9837
9847
  _this.updateCachedModel(_this.editor);
9838
9848
  }
9839
9849
  };
9840
- this.state = option.disableCache
9841
- ? {}
9842
- : {
9843
- domIndexer: new domIndexerImpl_1.DomIndexerImpl(option.experimentalFeatures &&
9844
- option.experimentalFeatures.indexOf('PersistCache') >= 0),
9845
- textMutationObserver: (0, textMutationObserver_1.createTextMutationObserver)(contentDiv, this.onMutation),
9850
+ if (option.disableCache) {
9851
+ this.state = {};
9852
+ }
9853
+ else {
9854
+ var domIndexer = new domIndexerImpl_1.DomIndexerImpl(option.experimentalFeatures &&
9855
+ option.experimentalFeatures.indexOf('PersistCache') >= 0);
9856
+ this.state = {
9857
+ domIndexer: domIndexer,
9858
+ textMutationObserver: (0, textMutationObserver_1.createTextMutationObserver)(contentDiv, domIndexer, this.onMutation, this.onSkipMutation),
9846
9859
  };
9860
+ }
9847
9861
  }
9848
9862
  /**
9849
9863
  * Get name of this plugin
@@ -10026,6 +10040,9 @@ function isIndexedSegment(node) {
10026
10040
  Array.isArray(paragraph.segments) &&
10027
10041
  Array.isArray(segments));
10028
10042
  }
10043
+ function getIndexedSegmentItem(node) {
10044
+ return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;
10045
+ }
10029
10046
  /**
10030
10047
  * @internal
10031
10048
  * Implementation of DomIndexer
@@ -10049,9 +10066,7 @@ var DomIndexerImpl = /** @class */ (function () {
10049
10066
  previousText = child;
10050
10067
  }
10051
10068
  else {
10052
- var item = isIndexedSegment(previousText)
10053
- ? previousText.__roosterjsContentModel
10054
- : undefined;
10069
+ var item = getIndexedSegmentItem(previousText);
10055
10070
  if (item && isIndexedSegment(child)) {
10056
10071
  item.segments = item.segments.concat(child.__roosterjsContentModel.segments);
10057
10072
  child.__roosterjsContentModel.segments = [];
@@ -10124,6 +10139,32 @@ var DomIndexerImpl = /** @class */ (function () {
10124
10139
  }
10125
10140
  return false;
10126
10141
  };
10142
+ DomIndexerImpl.prototype.reconcileChildList = function (addedNodes, removedNodes) {
10143
+ if (!this.persistCache) {
10144
+ return false;
10145
+ }
10146
+ var canHandle = true;
10147
+ var context = {
10148
+ segIndex: -1,
10149
+ };
10150
+ // First process added nodes
10151
+ var addedNode = addedNodes[0];
10152
+ if (addedNodes.length == 1 && (0, roosterjs_content_model_dom_1.isNodeOfType)(addedNode, 'TEXT_NODE')) {
10153
+ canHandle = this.reconcileAddedNode(addedNode, context);
10154
+ }
10155
+ else if (addedNodes.length > 0) {
10156
+ canHandle = false;
10157
+ }
10158
+ // Second, process removed nodes
10159
+ var removedNode = removedNodes[0];
10160
+ if (canHandle && removedNodes.length == 1) {
10161
+ canHandle = this.reconcileRemovedNode(removedNode, context);
10162
+ }
10163
+ else if (removedNodes.length > 0) {
10164
+ canHandle = false;
10165
+ }
10166
+ return canHandle && !context.pendingTextNode;
10167
+ };
10127
10168
  DomIndexerImpl.prototype.isCollapsed = function (selection) {
10128
10169
  var start = selection.start, end = selection.end;
10129
10170
  return start.node == end.node && start.offset == end.offset;
@@ -10141,8 +10182,9 @@ var DomIndexerImpl = /** @class */ (function () {
10141
10182
  };
10142
10183
  DomIndexerImpl.prototype.insertMarker = function (node, isAfter) {
10143
10184
  var marker;
10144
- if (node && isIndexedSegment(node)) {
10145
- var _a = node.__roosterjsContentModel, paragraph = _a.paragraph, segments = _a.segments;
10185
+ var segmentItem = node && getIndexedSegmentItem(node);
10186
+ if (segmentItem) {
10187
+ var paragraph = segmentItem.paragraph, segments = segmentItem.segments;
10146
10188
  var index = paragraph.segments.indexOf(segments[0]);
10147
10189
  if (index >= 0) {
10148
10190
  var formatSegment = (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];
@@ -10212,6 +10254,88 @@ var DomIndexerImpl = /** @class */ (function () {
10212
10254
  }
10213
10255
  return selectable;
10214
10256
  };
10257
+ DomIndexerImpl.prototype.reconcileAddedNode = function (node, context) {
10258
+ var segmentItem = null;
10259
+ var index = -1;
10260
+ var existingSegment;
10261
+ var previousSibling = node.previousSibling, nextSibling = node.nextSibling;
10262
+ if ((segmentItem = getIndexedSegmentItem(previousSibling)) &&
10263
+ (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&
10264
+ (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0) {
10265
+ // When we can find indexed segment before current one, use it as the insert index
10266
+ this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);
10267
+ }
10268
+ else if ((segmentItem = getIndexedSegmentItem(nextSibling)) &&
10269
+ (existingSegment = segmentItem.segments[0]) &&
10270
+ (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0) {
10271
+ // When we can find indexed segment after current one, use it as the insert index
10272
+ this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);
10273
+ }
10274
+ else if (context.paragraph && context.segIndex >= 0) {
10275
+ // When there is indexed paragraph from removed nodes, we can use it as the insert index
10276
+ this.indexNode(context.paragraph, context.segIndex, node, context.format);
10277
+ }
10278
+ else if (context.pendingTextNode === undefined) {
10279
+ // When we can't find the insert index, set current node as pending node
10280
+ // so later we can pick it up when we have enough info when processing removed node
10281
+ // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before
10282
+ // and in that case we should return false since we can't handle two pending text node
10283
+ context.pendingTextNode = node;
10284
+ }
10285
+ else {
10286
+ return false;
10287
+ }
10288
+ return true;
10289
+ };
10290
+ DomIndexerImpl.prototype.reconcileRemovedNode = function (node, context) {
10291
+ var segmentItem = null;
10292
+ var removingSegment;
10293
+ if (context.segIndex < 0 &&
10294
+ !context.paragraph && // No previous removed segment or related paragraph found, and
10295
+ (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and
10296
+ (removingSegment = segmentItem.segments[0]) // There is at least one related segment
10297
+ ) {
10298
+ // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it
10299
+ context.format = removingSegment.format;
10300
+ context.paragraph = segmentItem.paragraph;
10301
+ context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);
10302
+ if (context.segIndex < 0) {
10303
+ // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling
10304
+ return false;
10305
+ }
10306
+ for (var i = 0; i < segmentItem.segments.length; i++) {
10307
+ var index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);
10308
+ if (index >= 0) {
10309
+ segmentItem.paragraph.segments.splice(index, 1);
10310
+ }
10311
+ }
10312
+ if (context.pendingTextNode) {
10313
+ // If we have pending text node added but not indexed, do it now
10314
+ this.indexNode(context.paragraph, context.segIndex, context.pendingTextNode, segmentItem.segments[0].format);
10315
+ // Set to null since we have processed it.
10316
+ // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle
10317
+ context.pendingTextNode = null;
10318
+ }
10319
+ return true;
10320
+ }
10321
+ else {
10322
+ return false;
10323
+ }
10324
+ };
10325
+ DomIndexerImpl.prototype.indexNode = function (paragraph, index, textNode, format) {
10326
+ var _a;
10327
+ var copiedFormat = format ? (0, tslib_1.__assign)({}, format) : undefined;
10328
+ if (copiedFormat) {
10329
+ (0, roosterjs_content_model_dom_1.getObjectKeys)(copiedFormat).forEach(function (key) {
10330
+ if (roosterjs_content_model_dom_1.EmptySegmentFormat[key] === undefined) {
10331
+ delete copiedFormat[key];
10332
+ }
10333
+ });
10334
+ }
10335
+ var text = (0, roosterjs_content_model_dom_1.createText)((_a = textNode.textContent) !== null && _a !== void 0 ? _a : '', copiedFormat);
10336
+ paragraph.segments.splice(index, 0, text);
10337
+ this.onSegment(textNode, paragraph, [text]);
10338
+ };
10215
10339
  return DomIndexerImpl;
10216
10340
  }());
10217
10341
  exports.DomIndexerImpl = DomIndexerImpl;
@@ -10230,16 +10354,60 @@ exports.DomIndexerImpl = DomIndexerImpl;
10230
10354
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10231
10355
  exports.createTextMutationObserver = void 0;
10232
10356
  var TextMutationObserverImpl = /** @class */ (function () {
10233
- function TextMutationObserverImpl(contentDiv, onMutation) {
10357
+ function TextMutationObserverImpl(contentDiv, domIndexer, onMutation, onSkipMutation) {
10234
10358
  var _this = this;
10235
10359
  this.contentDiv = contentDiv;
10360
+ this.domIndexer = domIndexer;
10236
10361
  this.onMutation = onMutation;
10362
+ this.onSkipMutation = onSkipMutation;
10237
10363
  this.onMutationInternal = function (mutations) {
10238
- var _a;
10239
- var firstTarget = (_a = mutations[0]) === null || _a === void 0 ? void 0 : _a.target;
10240
- if (firstTarget) {
10241
- var isTextChangeOnly = mutations.every(function (mutation) { return mutation.type == 'characterData' && mutation.target == firstTarget; });
10242
- _this.onMutation(isTextChangeOnly);
10364
+ var canHandle = true;
10365
+ var firstTarget = null;
10366
+ var lastTextChangeNode = null;
10367
+ var addedNodes = [];
10368
+ var removedNodes = [];
10369
+ var reconcileText = false;
10370
+ for (var i = 0; i < mutations.length && canHandle; i++) {
10371
+ var mutation = mutations[i];
10372
+ switch (mutation.type) {
10373
+ case 'attributes':
10374
+ if (mutation.target != _this.contentDiv) {
10375
+ // We cannot handle attributes changes on editor content for now
10376
+ canHandle = false;
10377
+ }
10378
+ break;
10379
+ case 'characterData':
10380
+ if (lastTextChangeNode && lastTextChangeNode != mutation.target) {
10381
+ // Multiple text nodes got changed, we don't know how to handle it
10382
+ canHandle = false;
10383
+ }
10384
+ else {
10385
+ lastTextChangeNode = mutation.target;
10386
+ reconcileText = true;
10387
+ }
10388
+ break;
10389
+ case 'childList':
10390
+ if (!firstTarget) {
10391
+ firstTarget = mutation.target;
10392
+ }
10393
+ else if (firstTarget != mutation.target) {
10394
+ canHandle = false;
10395
+ }
10396
+ if (canHandle) {
10397
+ addedNodes = addedNodes.concat(Array.from(mutation.addedNodes));
10398
+ removedNodes = removedNodes.concat(Array.from(mutation.removedNodes));
10399
+ }
10400
+ break;
10401
+ }
10402
+ }
10403
+ if (canHandle && (addedNodes.length > 0 || removedNodes.length > 0)) {
10404
+ canHandle = _this.domIndexer.reconcileChildList(addedNodes, removedNodes);
10405
+ }
10406
+ if (canHandle && reconcileText) {
10407
+ _this.onMutation(true /*textOnly*/);
10408
+ }
10409
+ else if (!canHandle) {
10410
+ _this.onMutation(false /*textOnly*/);
10243
10411
  }
10244
10412
  };
10245
10413
  this.observer = new MutationObserver(this.onMutationInternal);
@@ -10255,17 +10423,22 @@ var TextMutationObserverImpl = /** @class */ (function () {
10255
10423
  TextMutationObserverImpl.prototype.stopObserving = function () {
10256
10424
  this.observer.disconnect();
10257
10425
  };
10258
- TextMutationObserverImpl.prototype.flushMutations = function () {
10426
+ TextMutationObserverImpl.prototype.flushMutations = function (model) {
10259
10427
  var mutations = this.observer.takeRecords();
10260
- this.onMutationInternal(mutations);
10428
+ if (model) {
10429
+ this.onSkipMutation(model);
10430
+ }
10431
+ else {
10432
+ this.onMutationInternal(mutations);
10433
+ }
10261
10434
  };
10262
10435
  return TextMutationObserverImpl;
10263
10436
  }());
10264
10437
  /**
10265
10438
  * @internal
10266
10439
  */
10267
- function createTextMutationObserver(contentDiv, onMutation) {
10268
- return new TextMutationObserverImpl(contentDiv, onMutation);
10440
+ function createTextMutationObserver(contentDiv, domIndexer, onMutation, onSkipMutation) {
10441
+ return new TextMutationObserverImpl(contentDiv, domIndexer, onMutation, onSkipMutation);
10269
10442
  }
10270
10443
  exports.createTextMutationObserver = createTextMutationObserver;
10271
10444
 
@@ -14614,6 +14787,36 @@ exports.ChangeSource = {
14614
14787
  };
14615
14788
 
14616
14789
 
14790
+ /***/ }),
14791
+
14792
+ /***/ "./packages/roosterjs-content-model-dom/lib/constants/EmptySegmentFormat.ts":
14793
+ /*!**********************************************************************************!*\
14794
+ !*** ./packages/roosterjs-content-model-dom/lib/constants/EmptySegmentFormat.ts ***!
14795
+ \**********************************************************************************/
14796
+ /***/ ((__unused_webpack_module, exports) => {
14797
+
14798
+ "use strict";
14799
+
14800
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
14801
+ exports.EmptySegmentFormat = void 0;
14802
+ /**
14803
+ * Provide a default empty instance of segment format with all its properties
14804
+ */
14805
+ exports.EmptySegmentFormat = {
14806
+ backgroundColor: '',
14807
+ fontFamily: '',
14808
+ fontSize: '',
14809
+ fontWeight: '',
14810
+ italic: false,
14811
+ letterSpacing: '',
14812
+ lineHeight: '',
14813
+ strikethrough: false,
14814
+ superOrSubScriptSequence: '',
14815
+ textColor: '',
14816
+ underline: false,
14817
+ };
14818
+
14819
+
14617
14820
  /***/ }),
14618
14821
 
14619
14822
  /***/ "./packages/roosterjs-content-model-dom/lib/constants/NumberingListType.ts":
@@ -19804,7 +20007,7 @@ exports.shouldSetValue = shouldSetValue;
19804
20007
  Object.defineProperty(exports, "__esModule", ({ value: true }));
19805
20008
  exports.createEntity = exports.createGeneralBlock = exports.createGeneralSegment = exports.createParagraphDecorator = exports.createContentModelDocument = exports.createImage = exports.createText = exports.createTableCell = exports.createTable = exports.createSelectionMarker = exports.createParagraph = exports.createFormatContainer = exports.createListItem = exports.createBr = 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.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;
19806
20009
  exports.cacheGetEventData = exports.extractClipboardItems = exports.transformColor = exports.readFile = exports.parseTableCells = exports.normalizeText = exports.isSpace = exports.isPunctuation = exports.extractBorderValues = exports.combineBorderValue = exports.isCursorMovingKey = exports.isModifierKey = exports.isCharacterValue = exports.getDOMInsertPointRect = exports.getSelectionRootNode = exports.isBold = exports.createModelToDomConfig = exports.createModelToDomContextWithConfig = exports.createModelToDomContext = exports.createDomToModelConfig = exports.createDomToModelContextWithConfig = exports.createDomToModelContext = exports.defaultGenerateColorKey = exports.parseColor = exports.setColor = exports.getColor = exports.DeprecatedColors = exports.BorderKeys = exports.parseValueWithUnit = exports.getAutoListStyleType = exports.getOrderedListNumberStr = exports.setParagraphNotImplicit = exports.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 = void 0;
19807
- exports.UnorderedListStyleMap = exports.OrderedListStyleMap = exports.TableBorderFormat = exports.NumberingListType = exports.BulletListType = exports.ChangeSource = exports.ListMetadataDefinition = exports.getListMetadata = exports.updateListMetadata = exports.getTableMetadata = exports.updateTableMetadata = exports.getTableCellMetadata = exports.updateTableCellMetadata = exports.getImageMetadata = exports.updateImageMetadata = exports.runEditSteps = exports.getClosestAncestorBlockGroupIndex = exports.getSegmentTextFormat = exports.getListStyleTypeFromString = exports.retrieveModelFormatState = exports.setTableCellBackgroundColor = exports.MIN_ALLOWED_TABLE_CELL_HEIGHT = exports.MIN_ALLOWED_TABLE_CELL_WIDTH = exports.normalizeTable = exports.setFirstColumnFormatBorders = exports.applyTableFormat = exports.deleteBlock = exports.deleteSegment = exports.deleteSelection = exports.mergeModel = exports.cloneModel = exports.setSelection = exports.hasSelectionInBlockGroup = exports.hasSelectionInSegment = exports.hasSelectionInBlock = exports.getSelectedCells = exports.getSelectedSegmentsAndParagraphs = exports.getSelectedSegments = exports.getSelectedParagraphs = exports.getOperationalBlocks = exports.getFirstSelectedTable = exports.getFirstSelectedListItem = exports.iterateSelections = exports.isBlockGroupOfType = void 0;
20010
+ 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 = 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 = void 0;
19808
20011
  var domToContentModel_1 = __webpack_require__(/*! ./domToModel/domToContentModel */ "./packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts");
19809
20012
  Object.defineProperty(exports, "domToContentModel", ({ enumerable: true, get: function () { return domToContentModel_1.domToContentModel; } }));
19810
20013
  var contentModelToDom_1 = __webpack_require__(/*! ./modelToDom/contentModelToDom */ "./packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts");
@@ -20052,6 +20255,8 @@ var OrderedListStyleMap_1 = __webpack_require__(/*! ./constants/OrderedListStyle
20052
20255
  Object.defineProperty(exports, "OrderedListStyleMap", ({ enumerable: true, get: function () { return OrderedListStyleMap_1.OrderedListStyleMap; } }));
20053
20256
  var UnorderedListStyleMap_1 = __webpack_require__(/*! ./constants/UnorderedListStyleMap */ "./packages/roosterjs-content-model-dom/lib/constants/UnorderedListStyleMap.ts");
20054
20257
  Object.defineProperty(exports, "UnorderedListStyleMap", ({ enumerable: true, get: function () { return UnorderedListStyleMap_1.UnorderedListStyleMap; } }));
20258
+ var EmptySegmentFormat_1 = __webpack_require__(/*! ./constants/EmptySegmentFormat */ "./packages/roosterjs-content-model-dom/lib/constants/EmptySegmentFormat.ts");
20259
+ Object.defineProperty(exports, "EmptySegmentFormat", ({ enumerable: true, get: function () { return EmptySegmentFormat_1.EmptySegmentFormat; } }));
20055
20260
 
20056
20261
 
20057
20262
  /***/ }),
@@ -22375,27 +22580,14 @@ var createParagraph_1 = __webpack_require__(/*! ../creators/createParagraph */ "
22375
22580
  var createSelectionMarker_1 = __webpack_require__(/*! ../creators/createSelectionMarker */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createSelectionMarker.ts");
22376
22581
  var createTableCell_1 = __webpack_require__(/*! ../creators/createTableCell */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createTableCell.ts");
22377
22582
  var deleteSelection_1 = __webpack_require__(/*! ./deleteSelection */ "./packages/roosterjs-content-model-dom/lib/modelApi/editing/deleteSelection.ts");
22583
+ var EmptySegmentFormat_1 = __webpack_require__(/*! ../../constants/EmptySegmentFormat */ "./packages/roosterjs-content-model-dom/lib/constants/EmptySegmentFormat.ts");
22378
22584
  var getClosestAncestorBlockGroupIndex_1 = __webpack_require__(/*! ./getClosestAncestorBlockGroupIndex */ "./packages/roosterjs-content-model-dom/lib/modelApi/editing/getClosestAncestorBlockGroupIndex.ts");
22379
22585
  var getObjectKeys_1 = __webpack_require__(/*! ../..//domUtils/getObjectKeys */ "./packages/roosterjs-content-model-dom/lib/domUtils/getObjectKeys.ts");
22380
22586
  var mutate_1 = __webpack_require__(/*! ../common/mutate */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts");
22381
22587
  var normalizeContentModel_1 = __webpack_require__(/*! ../common/normalizeContentModel */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeContentModel.ts");
22382
22588
  var normalizeTable_1 = __webpack_require__(/*! ./normalizeTable */ "./packages/roosterjs-content-model-dom/lib/modelApi/editing/normalizeTable.ts");
22383
22589
  var HeadingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
22384
- // An object to provide keys of required properties of segment format, do NOT use any of its values
22385
- var RequiredEmptySegmentFormat = {
22386
- backgroundColor: null,
22387
- fontFamily: null,
22388
- fontSize: null,
22389
- fontWeight: null,
22390
- italic: null,
22391
- letterSpacing: null,
22392
- lineHeight: null,
22393
- strikethrough: null,
22394
- superOrSubScriptSequence: null,
22395
- textColor: null,
22396
- underline: null,
22397
- };
22398
- var KeysOfSegmentFormat = (0, getObjectKeys_1.getObjectKeys)(RequiredEmptySegmentFormat);
22590
+ var KeysOfSegmentFormat = (0, getObjectKeys_1.getObjectKeys)(EmptySegmentFormat_1.EmptySegmentFormat);
22399
22591
  /**
22400
22592
  * Merge source model into target mode
22401
22593
  * @param target Target Content Model that will merge content into
@@ -22628,7 +22820,7 @@ function applyDefaultFormat(group, format, applyDefaultFormatOption) {
22628
22820
  }
22629
22821
  segment.format = mergeSegmentFormat(applyDefaultFormatOption, format, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, paragraphFormat_1), segment.format));
22630
22822
  if (segment.link) {
22631
- segment.link.format = mergeSegmentFormat(applyDefaultFormatOption, getSegmentFormatInLinkFormat(format), segment.link.format);
22823
+ segment.link.format = mergeLinkFormat(applyDefaultFormatOption, format, segment.link.format);
22632
22824
  }
22633
22825
  });
22634
22826
  if (applyDefaultFormatOption === 'keepSourceEmphasisFormat') {
@@ -22644,14 +22836,11 @@ function mergeBlockFormat(applyDefaultFormatOption, block) {
22644
22836
  }
22645
22837
  }
22646
22838
  /**
22647
- * Hyperlink format type definition only contains textColor, backgroundColor and underline.
22839
+ * Hyperlink format type definition only contains backgroundColor and underline.
22648
22840
  * So create a minimum object with the styles supported in Hyperlink to be used in merge.
22649
22841
  */
22650
22842
  function getSegmentFormatInLinkFormat(targetFormat) {
22651
22843
  var result = {};
22652
- if (targetFormat.textColor) {
22653
- result.textColor = targetFormat.textColor;
22654
- }
22655
22844
  if (targetFormat.backgroundColor) {
22656
22845
  result.backgroundColor = targetFormat.backgroundColor;
22657
22846
  }
@@ -22660,6 +22849,10 @@ function getSegmentFormatInLinkFormat(targetFormat) {
22660
22849
  }
22661
22850
  return result;
22662
22851
  }
22852
+ function mergeLinkFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
22853
+ return applyDefaultFormatOption == 'mergeAll'
22854
+ ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getSegmentFormatInLinkFormat(targetFormat)), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), getSegmentFormatInLinkFormat(targetFormat)), getSemanticFormat(sourceFormat)), getHyperlinkTextColor(sourceFormat));
22855
+ }
22663
22856
  function mergeSegmentFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
22664
22857
  return applyDefaultFormatOption == 'mergeAll'
22665
22858
  ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, targetFormat), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), targetFormat), getSemanticFormat(sourceFormat));
@@ -22687,6 +22880,13 @@ function getFormatWithoutSegmentFormat(sourceFormat) {
22687
22880
  KeysOfSegmentFormat.forEach(function (key) { return delete resultFormat[key]; });
22688
22881
  return resultFormat;
22689
22882
  }
22883
+ function getHyperlinkTextColor(sourceFormat) {
22884
+ var result = {};
22885
+ if (sourceFormat.textColor) {
22886
+ result.textColor = sourceFormat.textColor;
22887
+ }
22888
+ return result;
22889
+ }
22690
22890
 
22691
22891
 
22692
22892
  /***/ }),
@@ -26351,7 +26551,7 @@ function getListTypeStyle(model, shouldSearchForBullet, shouldSearchForNumbering
26351
26551
  listMarkerSegment &&
26352
26552
  listMarkerSegment.segmentType == 'Text') {
26353
26553
  var listMarker = listMarkerSegment.text.trim();
26354
- var bulletType = bulletListType[listMarker];
26554
+ var bulletType = bulletListType.get(listMarker);
26355
26555
  if (bulletType && shouldSearchForBullet) {
26356
26556
  return { listType: 'UL', styleType: bulletType };
26357
26557
  }
@@ -26402,16 +26602,16 @@ var getPreviousListStyle = function (list) {
26402
26602
  return (_a = (0, roosterjs_content_model_dom_1.updateListMetadata)(list.levels[0])) === null || _a === void 0 ? void 0 : _a.orderedStyleType;
26403
26603
  }
26404
26604
  };
26405
- var bulletListType = {
26406
- '*': roosterjs_content_model_dom_1.BulletListType.Disc,
26407
- '-': roosterjs_content_model_dom_1.BulletListType.Dash,
26408
- '--': roosterjs_content_model_dom_1.BulletListType.Square,
26409
- '->': roosterjs_content_model_dom_1.BulletListType.LongArrow,
26410
- '-->': roosterjs_content_model_dom_1.BulletListType.DoubleLongArrow,
26411
- '=>': roosterjs_content_model_dom_1.BulletListType.UnfilledArrow,
26412
- '>': roosterjs_content_model_dom_1.BulletListType.ShortArrow,
26413
- '—': roosterjs_content_model_dom_1.BulletListType.Hyphen,
26414
- };
26605
+ var bulletListType = new Map([
26606
+ ['*', roosterjs_content_model_dom_1.BulletListType.Disc],
26607
+ ['-', roosterjs_content_model_dom_1.BulletListType.Dash],
26608
+ ['--', roosterjs_content_model_dom_1.BulletListType.Square],
26609
+ ['->', roosterjs_content_model_dom_1.BulletListType.LongArrow],
26610
+ ['-->', roosterjs_content_model_dom_1.BulletListType.DoubleLongArrow],
26611
+ ['=>', roosterjs_content_model_dom_1.BulletListType.UnfilledArrow],
26612
+ ['>', roosterjs_content_model_dom_1.BulletListType.ShortArrow],
26613
+ ['—', roosterjs_content_model_dom_1.BulletListType.Hyphen],
26614
+ ]);
26415
26615
  var isNewList = function (listMarker) {
26416
26616
  var marker = listMarker.replace(/[^\w\s]/g, '');
26417
26617
  var pattern = /^[1aAiI]$/;
@@ -26643,22 +26843,23 @@ var triggerList = function (model, listType, styleType, index) {
26643
26843
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26644
26844
  exports.transformFraction = void 0;
26645
26845
  var splitTextSegment_1 = __webpack_require__(/*! ../../pluginUtils/splitTextSegment */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/splitTextSegment.ts");
26646
- var FRACTIONS = {
26647
- '1/2': '½',
26648
- '1/4': '¼',
26649
- '3/4': '¾',
26650
- };
26846
+ var FRACTIONS = new Map([
26847
+ ['1/2', '½'],
26848
+ ['1/4', '¼'],
26849
+ ['3/4', '¾'],
26850
+ ]);
26651
26851
  /**
26652
26852
  * @internal
26653
26853
  */
26654
26854
  function transformFraction(previousSegment, paragraph, context) {
26655
26855
  var _a;
26656
26856
  var fraction = (_a = previousSegment.text.split(' ').pop()) === null || _a === void 0 ? void 0 : _a.trim();
26657
- if (fraction && FRACTIONS[fraction]) {
26857
+ var text = fraction ? FRACTIONS.get(fraction) : undefined;
26858
+ if (fraction && text) {
26658
26859
  var textLength = previousSegment.text.length - 1;
26659
26860
  var textIndex = textLength - fraction.length;
26660
26861
  var textSegment = (0, splitTextSegment_1.splitTextSegment)(previousSegment, paragraph, textIndex, textLength);
26661
- textSegment.text = FRACTIONS[fraction];
26862
+ textSegment.text = text;
26662
26863
  context.canUndoByBackspace = true;
26663
26864
  return true;
26664
26865
  }