roosterjs 8.28.0-git → 8.29.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 8.28.0git)
1
+ // Type definitions for roosterjs (Version 8.29.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -2778,6 +2778,11 @@ interface PendingFormatStatePluginState {
2778
2778
  * The position of last pendable format state changing
2779
2779
  */
2780
2780
  pendableFormatPosition: NodePosition;
2781
+ /**
2782
+ * A temporary SPAN element to hold pending format change. it will be inserted into content when user type something,
2783
+ * or discard if focus position is moved
2784
+ */
2785
+ pendableFormatSpan: HTMLElement;
2781
2786
  }
2782
2787
 
2783
2788
  /**
@@ -3495,7 +3500,13 @@ const enum ExperimentalFeatures {
3495
3500
  * @deprecated this feature is always disabled
3496
3501
  * Automatically transform -- into hyphen, if typed between two words.
3497
3502
  */
3498
- AutoHyphen = "AutoHyphen"
3503
+ AutoHyphen = "AutoHyphen",
3504
+ /**
3505
+ * Use pending format strategy to do style based format, e.g. Font size, Color.
3506
+ * With this feature enabled, we don't need to insert temp ZeroWidthSpace character to hold pending format
3507
+ * when selection is collapsed. Instead, we will hold the pending format in memory and only apply it when type something
3508
+ */
3509
+ PendingStyleBasedFormat = "PendingStyleBasedFormat"
3499
3510
  }
3500
3511
 
3501
3512
  /**
@@ -3932,7 +3943,11 @@ const enum TableBorderFormat {
3932
3943
  * |
3933
3944
  * |
3934
3945
  */
3935
- ESPECIAL_TYPE_3 = 7
3946
+ ESPECIAL_TYPE_3 = 7,
3947
+ /**
3948
+ * No border
3949
+ */
3950
+ CLEAR = 8
3936
3951
  }
3937
3952
 
3938
3953
  /**
@@ -4497,14 +4512,28 @@ interface CompatibleExtractContentWithDomEvent extends ExtractContentWithDomEven
4497
4512
  * An event fired when pending format state (bold, italic, underline, ... with collapsed selection) is changed
4498
4513
  */
4499
4514
  interface PendingFormatStateChangedEvent extends BasePluginEvent<PluginEventType.PendingFormatStateChanged> {
4515
+ /**
4516
+ * The new format state to apply. If null is passed, clear existing pending format state if any
4517
+ */
4500
4518
  formatState: PendableFormatState;
4519
+ /**
4520
+ * A callback to do format change to a temp element. This is used for style-based format such as font and color
4521
+ */
4522
+ formatCallback?: (element: HTMLElement, isInnerNode?: boolean) => any;
4501
4523
  }
4502
4524
 
4503
4525
  /**
4504
4526
  * An event fired when pending format state (bold, italic, underline, ... with collapsed selection) is changed
4505
4527
  */
4506
4528
  interface CompatiblePendingFormatStateChangedEvent extends BasePluginEvent<CompatiblePluginEventType.PendingFormatStateChanged> {
4529
+ /**
4530
+ * The new format state to apply. If null is passed, clear existing pending format state if any
4531
+ */
4507
4532
  formatState: PendableFormatState;
4533
+ /**
4534
+ * A callback to do format change to a temp element. This is used for style-based format such as font and color
4535
+ */
4536
+ formatCallback?: (element: HTMLElement, isInnerNode?: boolean) => any;
4508
4537
  }
4509
4538
 
4510
4539
  /**
@@ -5038,6 +5067,10 @@ interface ElementBasedFormatState {
5038
5067
  * Whether unlink command can be called to the text
5039
5068
  */
5040
5069
  canUnlink?: boolean;
5070
+ /**
5071
+ * Whether the selected text is multiline
5072
+ */
5073
+ isMultilineSelection?: boolean;
5041
5074
  /**
5042
5075
  * Whether add image alt text command can be called to the text
5043
5076
  */
@@ -7722,7 +7755,13 @@ enum CompatibleExperimentalFeatures {
7722
7755
  * @deprecated this feature is always disabled
7723
7756
  * Automatically transform -- into hyphen, if typed between two words.
7724
7757
  */
7725
- AutoHyphen = "AutoHyphen"
7758
+ AutoHyphen = "AutoHyphen",
7759
+ /**
7760
+ * Use pending format strategy to do style based format, e.g. Font size, Color.
7761
+ * With this feature enabled, we don't need to insert temp ZeroWidthSpace character to hold pending format
7762
+ * when selection is collapsed. Instead, we will hold the pending format in memory and only apply it when type something
7763
+ */
7764
+ PendingStyleBasedFormat = "PendingStyleBasedFormat"
7726
7765
  }
7727
7766
 
7728
7767
  /**
@@ -8040,7 +8079,11 @@ enum CompatibleTableBorderFormat {
8040
8079
  * |
8041
8080
  * |
8042
8081
  */
8043
- ESPECIAL_TYPE_3 = 7
8082
+ ESPECIAL_TYPE_3 = 7,
8083
+ /**
8084
+ * No border
8085
+ */
8086
+ CLEAR = 8
8044
8087
  }
8045
8088
 
8046
8089
  /**
package/dist/rooster.js CHANGED
@@ -2312,7 +2312,7 @@ function changeFontSize(editor, change, fontSizes) {
2312
2312
  if (fontSizes === void 0) { fontSizes = exports.FONT_SIZES; }
2313
2313
  var changeBase = change == 0 /* Increase */ ? 1 : -1;
2314
2314
  (0, applyInlineStyle_1.default)(editor, function (element) {
2315
- var pt = parseFloat((0, roosterjs_editor_dom_1.getComputedStyle)(element, 'font-size'));
2315
+ var pt = parseFloat((0, roosterjs_editor_dom_1.getComputedStyle)(element, 'font-size') || element.style.fontSize);
2316
2316
  element.style.fontSize = getNewFontSize(pt, changeBase, fontSizes) + 'pt';
2317
2317
  var lineHeight = (0, roosterjs_editor_dom_1.getComputedStyle)(element, 'line-height');
2318
2318
  if (lineHeight != 'normal') {
@@ -2809,10 +2809,19 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
2809
2809
  */
2810
2810
  function getElementBasedFormatState(editor, event) {
2811
2811
  var listTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('OL,UL', null /*startFrom*/, event));
2812
+ // Check if selection is multiline, spans more than one block
2813
+ var range = editor.getSelectionRange();
2814
+ var multiline = false;
2815
+ if (range && !range.collapsed) {
2816
+ var startingBlock = editor.getBlockElementAtNode(range.startContainer);
2817
+ var endingBlock = editor.getBlockElementAtNode(range.endContainer);
2818
+ multiline = !endingBlock.equals(startingBlock);
2819
+ }
2812
2820
  var headerTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('H1,H2,H3,H4,H5,H6', null /*startFrom*/, event));
2813
2821
  return {
2814
2822
  isBullet: listTag == 'UL',
2815
2823
  isNumbering: listTag == 'OL',
2824
+ isMultilineSelection: multiline,
2816
2825
  headerLevel: (headerTag && parseInt(headerTag[1])) || 0,
2817
2826
  canUnlink: !!editor.queryElements('a[href]', 1 /* OnSelection */)[0],
2818
2827
  canAddImageAltText: !!editor.queryElements('img', 1 /* OnSelection */)[0],
@@ -4106,6 +4115,7 @@ exports.default = formatTable;
4106
4115
 
4107
4116
  Object.defineProperty(exports, "__esModule", { value: true });
4108
4117
  var formatUndoSnapshot_1 = __webpack_require__(/*! ../utils/formatUndoSnapshot */ "./packages/roosterjs-editor-api/lib/utils/formatUndoSnapshot.ts");
4118
+ var setBackgroundColor_1 = __webpack_require__(/*! ../format/setBackgroundColor */ "./packages/roosterjs-editor-api/lib/format/setBackgroundColor.ts");
4109
4119
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
4110
4120
  /**
4111
4121
  * Insert table into editor at current selection
@@ -4135,6 +4145,10 @@ function insertTable(editor, columns, rows, format) {
4135
4145
  }
4136
4146
  editor.focus();
4137
4147
  (0, formatUndoSnapshot_1.default)(editor, function () {
4148
+ var element = editor.getElementAtCursor();
4149
+ if (element.style.backgroundColor) {
4150
+ (0, setBackgroundColor_1.default)(editor, 'transparent');
4151
+ }
4138
4152
  var vtable = new roosterjs_editor_dom_1.VTable(table);
4139
4153
  vtable.applyFormat(format);
4140
4154
  vtable.writeBack();
@@ -4182,6 +4196,9 @@ var ZERO_WIDTH_SPACE = '\u200B';
4182
4196
  function applyInlineStyle(editor, callback, apiName) {
4183
4197
  editor.focus();
4184
4198
  var selection = editor.getSelectionRangeEx();
4199
+ var safeCallback = function (element, isInnerNode) {
4200
+ return element.isContentEditable && callback(element, isInnerNode);
4201
+ };
4185
4202
  if (selection && selection.areAllCollapsed) {
4186
4203
  var range = selection.ranges[0];
4187
4204
  var node = range.startContainer;
@@ -4190,7 +4207,14 @@ function applyInlineStyle(editor, callback, apiName) {
4190
4207
  ((0, roosterjs_editor_dom_1.getTagOfNode)(node.firstChild) == 'BR' && !node.firstChild.nextSibling));
4191
4208
  if (isEmptySpan) {
4192
4209
  editor.addUndoSnapshot();
4193
- callback(node);
4210
+ safeCallback(node);
4211
+ }
4212
+ else if (editor.isFeatureEnabled("PendingStyleBasedFormat" /* PendingStyleBasedFormat */)) {
4213
+ editor.triggerPluginEvent(13 /* PendingFormatStateChanged */, {
4214
+ formatState: {},
4215
+ formatCallback: safeCallback,
4216
+ });
4217
+ editor.triggerContentChangedEvent("Format" /* Format */);
4194
4218
  }
4195
4219
  else {
4196
4220
  var isZWSNode = node &&
@@ -4205,7 +4229,7 @@ function applyInlineStyle(editor, callback, apiName) {
4205
4229
  node = editor.getDocument().createTextNode(ZERO_WIDTH_SPACE);
4206
4230
  range.insertNode(node);
4207
4231
  }
4208
- (0, roosterjs_editor_dom_1.applyTextStyle)(node, callback);
4232
+ (0, roosterjs_editor_dom_1.applyTextStyle)(node, safeCallback);
4209
4233
  editor.select(node, -1 /* End */);
4210
4234
  }
4211
4235
  }
@@ -4221,7 +4245,7 @@ function applyInlineStyle(editor, callback, apiName) {
4221
4245
  while (inlineElement) {
4222
4246
  var nextInlineElement = contentTraverser.getNextInlineElement();
4223
4247
  inlineElement.applyStyle(function (element, isInnerNode) {
4224
- callback(element, isInnerNode);
4248
+ safeCallback(element, isInnerNode);
4225
4249
  firstNode = firstNode || element;
4226
4250
  lastNode = element;
4227
4251
  });
@@ -5405,19 +5429,35 @@ var getStyleBasedFormatState = function (core, node) {
5405
5429
  if (!node) {
5406
5430
  return {};
5407
5431
  }
5432
+ var override = [];
5433
+ var pendableFormatSpan = core.pendingFormatState.pendableFormatSpan;
5434
+ if (pendableFormatSpan) {
5435
+ override = [
5436
+ pendableFormatSpan.style.fontFamily,
5437
+ pendableFormatSpan.style.fontSize,
5438
+ pendableFormatSpan.style.color,
5439
+ pendableFormatSpan.style.backgroundColor,
5440
+ ];
5441
+ }
5408
5442
  var styles = node ? (0, roosterjs_editor_dom_1.getComputedStyles)(node) : [];
5409
5443
  var isDarkMode = core.lifecycle.isDarkMode;
5410
5444
  var root = core.contentDiv;
5411
- var ogTextColorNode = isDarkMode && (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, root, ORIGINAL_STYLE_COLOR_SELECTOR);
5412
- var ogBackgroundColorNode = isDarkMode && (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, root, ORIGINAL_STYLE_BACK_COLOR_SELECTOR);
5445
+ var ogTextColorNode = isDarkMode &&
5446
+ (override[2]
5447
+ ? pendableFormatSpan
5448
+ : (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, root, ORIGINAL_STYLE_COLOR_SELECTOR));
5449
+ var ogBackgroundColorNode = isDarkMode &&
5450
+ (override[3]
5451
+ ? pendableFormatSpan
5452
+ : (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, root, ORIGINAL_STYLE_BACK_COLOR_SELECTOR));
5413
5453
  return {
5414
- fontName: styles[0],
5415
- fontSize: styles[1],
5416
- textColor: styles[2],
5417
- backgroundColor: styles[3],
5454
+ fontName: override[0] || styles[0],
5455
+ fontSize: override[1] || styles[1],
5456
+ textColor: override[2] || styles[2],
5457
+ backgroundColor: override[3] || styles[3],
5418
5458
  textColors: ogTextColorNode
5419
5459
  ? {
5420
- darkModeColor: styles[2],
5460
+ darkModeColor: override[2] || styles[2],
5421
5461
  lightModeColor: ogTextColorNode.dataset["ogsc" /* OriginalStyleColor */] ||
5422
5462
  ogTextColorNode.dataset["ogac" /* OriginalAttributeColor */] ||
5423
5463
  styles[2],
@@ -5425,7 +5465,7 @@ var getStyleBasedFormatState = function (core, node) {
5425
5465
  : undefined,
5426
5466
  backgroundColors: ogBackgroundColorNode
5427
5467
  ? {
5428
- darkModeColor: styles[3],
5468
+ darkModeColor: override[3] || styles[3],
5429
5469
  lightModeColor: ogBackgroundColorNode.dataset["ogsb" /* OriginalStyleBackgroundColor */] ||
5430
5470
  ogBackgroundColorNode.dataset["ogab" /* OriginalAttributeBackgroundColor */] ||
5431
5471
  styles[3],
@@ -7516,6 +7556,7 @@ function normalizeTables(tables) {
7516
7556
 
7517
7557
  Object.defineProperty(exports, "__esModule", { value: true });
7518
7558
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7559
+ var ZERO_WIDTH_SPACE = '\u200B';
7519
7560
  /**
7520
7561
  * @internal
7521
7562
  * PendingFormatStatePlugin handles pending format state management
@@ -7530,6 +7571,7 @@ var PendingFormatStatePlugin = /** @class */ (function () {
7530
7571
  this.state = {
7531
7572
  pendableFormatPosition: null,
7532
7573
  pendableFormatState: null,
7574
+ pendableFormatSpan: null,
7533
7575
  };
7534
7576
  }
7535
7577
  /**
@@ -7565,18 +7607,37 @@ var PendingFormatStatePlugin = /** @class */ (function () {
7565
7607
  PendingFormatStatePlugin.prototype.onPluginEvent = function (event) {
7566
7608
  switch (event.eventType) {
7567
7609
  case 13 /* PendingFormatStateChanged */:
7568
- // Got PendingFormatStateChanged event, cache current position and pending format
7569
- this.state.pendableFormatPosition = this.getCurrentPosition();
7570
- this.state.pendableFormatState = event.formatState;
7610
+ // Got PendingFormatStateChanged event, cache current position and pending format if a format is passed in
7611
+ // otherwise clear existing pending format.
7612
+ if (event.formatState) {
7613
+ this.state.pendableFormatPosition = this.getCurrentPosition();
7614
+ this.state.pendableFormatState = event.formatState;
7615
+ this.state.pendableFormatSpan = event.formatCallback
7616
+ ? this.createPendingFormatSpan(event.formatCallback)
7617
+ : null;
7618
+ }
7619
+ else {
7620
+ this.clear();
7621
+ }
7571
7622
  break;
7572
7623
  case 0 /* KeyDown */:
7573
7624
  case 5 /* MouseDown */:
7574
7625
  case 7 /* ContentChanged */:
7575
- // If content or position is changed (by keyboard, mouse, or code),
7576
- // check if current position is still the same with the cached one (if exist),
7577
- // and clear cached format if position is changed since it is out-of-date now
7578
- if (this.state.pendableFormatPosition &&
7579
- !this.state.pendableFormatPosition.equalTo(this.getCurrentPosition())) {
7626
+ if (event.eventType == 0 /* KeyDown */ &&
7627
+ (0, roosterjs_editor_dom_1.isCharacterValue)(event.rawEvent) &&
7628
+ this.state.pendableFormatSpan) {
7629
+ this.editor.insertNode(this.state.pendableFormatSpan);
7630
+ this.editor.select(this.state.pendableFormatSpan, -2 /* Before */, this.state.pendableFormatSpan, -1 /* End */);
7631
+ this.clear();
7632
+ }
7633
+ else if ((event.eventType == 0 /* KeyDown */ &&
7634
+ event.rawEvent.which >= 33 /* PAGEUP */ &&
7635
+ event.rawEvent.which <= 40 /* DOWN */) ||
7636
+ (this.state.pendableFormatPosition &&
7637
+ !this.state.pendableFormatPosition.equalTo(this.getCurrentPosition()))) {
7638
+ // If content or position is changed (by keyboard, mouse, or code),
7639
+ // check if current position is still the same with the cached one (if exist),
7640
+ // and clear cached format if position is changed since it is out-of-date now
7580
7641
  this.clear();
7581
7642
  }
7582
7643
  break;
@@ -7585,11 +7646,29 @@ var PendingFormatStatePlugin = /** @class */ (function () {
7585
7646
  PendingFormatStatePlugin.prototype.clear = function () {
7586
7647
  this.state.pendableFormatPosition = null;
7587
7648
  this.state.pendableFormatState = null;
7649
+ this.state.pendableFormatSpan = null;
7588
7650
  };
7589
7651
  PendingFormatStatePlugin.prototype.getCurrentPosition = function () {
7590
7652
  var range = this.editor.getSelectionRange();
7591
7653
  return range && roosterjs_editor_dom_1.Position.getStart(range).normalize();
7592
7654
  };
7655
+ PendingFormatStatePlugin.prototype.createPendingFormatSpan = function (callback) {
7656
+ var span = this.state.pendableFormatSpan;
7657
+ if (!span) {
7658
+ var currentStyle = this.editor.getStyleBasedFormatState();
7659
+ var doc = this.editor.getDocument();
7660
+ var isDarkMode = this.editor.isDarkMode();
7661
+ span = doc.createElement('span');
7662
+ span.contentEditable = 'true';
7663
+ span.appendChild(doc.createTextNode(ZERO_WIDTH_SPACE));
7664
+ span.style.fontFamily = currentStyle.fontName;
7665
+ span.style.fontSize = currentStyle.fontSize;
7666
+ (0, roosterjs_editor_dom_1.setColor)(span, currentStyle.textColors || currentStyle.textColor, false /*isBackground*/, isDarkMode);
7667
+ (0, roosterjs_editor_dom_1.setColor)(span, currentStyle.backgroundColors || currentStyle.backgroundColor, true /*isBackground*/, isDarkMode);
7668
+ }
7669
+ callback(span);
7670
+ return span;
7671
+ };
7593
7672
  return PendingFormatStatePlugin;
7594
7673
  }());
7595
7674
  exports.default = PendingFormatStatePlugin;
@@ -10047,6 +10126,7 @@ exports.default = SelectionScoper;
10047
10126
  Object.defineProperty(exports, "__esModule", { value: true });
10048
10127
  var changeElementTag_1 = __webpack_require__(/*! ../utils/changeElementTag */ "./packages/roosterjs-editor-dom/lib/utils/changeElementTag.ts");
10049
10128
  var contains_1 = __webpack_require__(/*! ../utils/contains */ "./packages/roosterjs-editor-dom/lib/utils/contains.ts");
10129
+ var ContentTraverser_1 = __webpack_require__(/*! ../contentTraverser/ContentTraverser */ "./packages/roosterjs-editor-dom/lib/contentTraverser/ContentTraverser.ts");
10050
10130
  var createRange_1 = __webpack_require__(/*! ../selection/createRange */ "./packages/roosterjs-editor-dom/lib/selection/createRange.ts");
10051
10131
  var findClosestElementAncestor_1 = __webpack_require__(/*! ../utils/findClosestElementAncestor */ "./packages/roosterjs-editor-dom/lib/utils/findClosestElementAncestor.ts");
10052
10132
  var getBlockElementAtNode_1 = __webpack_require__(/*! ../blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
@@ -10072,6 +10152,7 @@ var adjustSteps = [
10072
10152
  adjustInsertPositionForVoidElement,
10073
10153
  adjustInsertPositionForMoveCursorOutOfALink,
10074
10154
  adjustInsertPositionForNotEditableNode,
10155
+ adjustInsertPositionForTable,
10075
10156
  ];
10076
10157
  /**
10077
10158
  * Adjust position for A tag don't be nested inside another A tag.
@@ -10232,6 +10313,37 @@ function adjustInsertPositionForNotEditableNode(root, nodeToInsert, position, ra
10232
10313
  }
10233
10314
  return position;
10234
10315
  }
10316
+ /**
10317
+ * Adjust the position of a table to be one line after another table.
10318
+ */
10319
+ function adjustInsertPositionForTable(root, nodeToInsert, position, range) {
10320
+ if ((nodeToInsert.childNodes.length == 1 &&
10321
+ (0, getTagOfNode_1.default)(nodeToInsert.childNodes[0]) == 'TABLE') ||
10322
+ (0, getTagOfNode_1.default)(nodeToInsert) == 'TABLE') {
10323
+ var element = position.element;
10324
+ var posBefore = new Position_1.default(element, -2 /* Before */);
10325
+ var rangeToTraverse = (0, createRange_1.default)(posBefore, position);
10326
+ var contentTraverser = ContentTraverser_1.default.createSelectionTraverser(root, rangeToTraverse);
10327
+ var blockElement = contentTraverser && contentTraverser.currentBlockElement;
10328
+ var nextBlockElement = blockElement;
10329
+ while (!nextBlockElement) {
10330
+ nextBlockElement = contentTraverser.getNextBlockElement();
10331
+ if (nextBlockElement) {
10332
+ blockElement = nextBlockElement;
10333
+ }
10334
+ }
10335
+ var prevElement = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode();
10336
+ if (prevElement && (0, findClosestElementAncestor_1.default)(prevElement, root, 'TABLE')) {
10337
+ var tempRange = (0, createRange_1.default)(position);
10338
+ tempRange.collapse(false /* toStart */);
10339
+ var br = root.ownerDocument.createElement('br');
10340
+ tempRange.insertNode(br);
10341
+ tempRange = (0, createRange_1.default)(br);
10342
+ position = Position_1.default.getEnd(tempRange);
10343
+ }
10344
+ }
10345
+ return position;
10346
+ }
10235
10347
  /**
10236
10348
  *
10237
10349
  * @param root the contentDiv of the ditor
@@ -10294,7 +10406,12 @@ function deleteSelectedContent(root, range) {
10294
10406
  if (!regionRange) {
10295
10407
  return null;
10296
10408
  }
10297
- var startContainer = regionRange.startContainer, endContainer = regionRange.endContainer, startOffset = regionRange.startOffset, endOffset = regionRange.endOffset;
10409
+ var startContainer = regionRange.startContainer, endContainer = regionRange.endContainer, startOffset = regionRange.startOffset, endOffset = regionRange.endOffset, commonAncestorContainer = regionRange.commonAncestorContainer;
10410
+ // Disallow merging of readonly elements
10411
+ if ((0, safeInstanceOf_1.default)(commonAncestorContainer, 'HTMLElement') &&
10412
+ !commonAncestorContainer.isContentEditable) {
10413
+ return null;
10414
+ }
10298
10415
  // Make sure there are node before and after the merging point.
10299
10416
  // This is required by mergeBlocksInRegion API.
10300
10417
  // This may create some empty text node as anchor
@@ -10307,8 +10424,8 @@ function deleteSelectedContent(root, range) {
10307
10424
  return { region: region, beforeStart: beforeStart, afterEnd: afterEnd };
10308
10425
  })
10309
10426
  .filter(function (x) { return !!x; });
10310
- // 3. Delete all nodes that we found
10311
- nodesToDelete.forEach(function (node) { var _a; return (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node); });
10427
+ // 3. Delete all nodes that we found, whose parent is editable
10428
+ nodesToDelete.forEach(function (node) { var _a; return ((_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.isContentEditable) && node.parentElement.removeChild(node); });
10312
10429
  // 4. Merge lines for each region, so that after we don't see extra line breaks
10313
10430
  nodesPairToMerge.forEach(function (nodes) {
10314
10431
  if (nodes) {
@@ -17805,6 +17922,7 @@ var TRANSPARENT = 'transparent';
17805
17922
  var DARK_COLORS_LIGHTNESS = 20;
17806
17923
  //If the value of the lightness is more than 80, the color is bright
17807
17924
  var BRIGHT_COLORS_LIGHTNESS = 80;
17925
+ var TRANSPARENT_COLOR = 'transparent';
17808
17926
  /**
17809
17927
  * Set text color or background color to the given element
17810
17928
  * @param element The element to set color to
@@ -17825,7 +17943,7 @@ function setColor(element, color, isBackgroundColor, isDarkMode, shouldAdaptTheF
17825
17943
  var dataSetName = isBackgroundColor
17826
17944
  ? "ogsb" /* OriginalStyleBackgroundColor */
17827
17945
  : "ogsc" /* OriginalStyleColor */;
17828
- if (!isDarkMode) {
17946
+ if (!isDarkMode || color == TRANSPARENT_COLOR) {
17829
17947
  delete element.dataset[dataSetName];
17830
17948
  }
17831
17949
  else if (modeIndependentColor) {
@@ -19382,16 +19500,17 @@ var AutoNumberingList = {
19382
19500
  var searcher = editor.getContentSearcherOfCursor();
19383
19501
  var textBeforeCursor = searcher.getSubStringBefore(5);
19384
19502
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
19385
- var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
19386
19503
  if (!textRange) {
19387
19504
  // no op if the range can't be found
19388
19505
  }
19389
19506
  else if ((regions = editor.getSelectedRegions()) && regions.length == 1) {
19390
19507
  var num = parseInt(textBeforeCursor);
19508
+ var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor, num);
19391
19509
  prepareAutoBullet(editor, textRange);
19392
19510
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, num, listStyle, 'autoToggleList' /** apiNameOverride */);
19393
19511
  }
19394
19512
  else {
19513
+ var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
19395
19514
  prepareAutoBullet(editor, textRange);
19396
19515
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, undefined /* startNumber*/, listStyle, 'autoToggleList' /** apiNameOverride */);
19397
19516
  }
@@ -20312,13 +20431,13 @@ var characters = {
20312
20431
  '.': 1 /* Dot */,
20313
20432
  '-': 2 /* Dash */,
20314
20433
  ')': 3 /* Parenthesis */,
20315
- '(': 4 /* DoubleParenthesis */,
20316
20434
  };
20317
- var identifyCharacter = function (text, secondSeparator) {
20318
- var charType = characters[text];
20319
- return charType === 4 /* DoubleParenthesis */ && secondSeparator !== ')'
20320
- ? undefined
20321
- : charType;
20435
+ var numberingTriggers = {
20436
+ '1': 1 /* Decimal */,
20437
+ i: 4 /* LowerRoman */,
20438
+ I: 5 /* UpperRoman */,
20439
+ a: 2 /* LowerAlpha */,
20440
+ A: 3 /* UpperAlpha */,
20322
20441
  };
20323
20442
  var identifyNumberingType = function (text) {
20324
20443
  if (!isNaN(parseInt(text))) {
@@ -20378,28 +20497,34 @@ var DecimalsTypes = (_f = {},
20378
20497
  _f[3 /* Parenthesis */] = 3 /* DecimalParenthesis */,
20379
20498
  _f[4 /* DoubleParenthesis */] = 4 /* DecimalDoubleParenthesis */,
20380
20499
  _f);
20381
- var identifyNumberingListType = function (numbering) {
20382
- // If the marker length is 3, the marker style is double parenthis such as (1), (A). Then the number is second character of the string and the separator is first character and last character.
20383
- var separator = numbering.length === 3 ? numbering[0] : numbering[1];
20384
- var secondSeparator = numbering.length === 3 ? numbering[2] : undefined;
20385
- var char = identifyCharacter(separator, secondSeparator);
20500
+ var identifyNumberingListType = function (numbering, isDoubleParenthesis, startNumber) {
20501
+ var separatorCharacter = isDoubleParenthesis
20502
+ ? 4 /* DoubleParenthesis */
20503
+ : characters[numbering[1]];
20386
20504
  // if separator is not valid, no need to check if the number is valid.
20387
- if (char) {
20505
+ if (separatorCharacter) {
20388
20506
  var number = numbering.length === 3 ? numbering[1] : numbering[0];
20389
- var numberingType = identifyNumberingType(number);
20390
- return numberingType ? numberingListTypes[numberingType](char) : null;
20507
+ var numberingType = startNumber
20508
+ ? identifyNumberingType(number)
20509
+ : numberingTriggers[number];
20510
+ return numberingType ? numberingListTypes[numberingType](separatorCharacter) : null;
20391
20511
  }
20392
20512
  return null;
20393
20513
  };
20394
20514
  /**
20395
20515
  * @internal
20396
20516
  * @param textBeforeCursor The trigger character
20517
+ * @param startNumber (Optional) Start number of the list
20397
20518
  * @returns The style of a numbering list triggered by a string
20398
20519
  */
20399
- function getAutoNumberingListStyle(textBeforeCursor) {
20520
+ function getAutoNumberingListStyle(textBeforeCursor, startNumber) {
20400
20521
  var trigger = textBeforeCursor.trim();
20401
20522
  // the marker must be a combination of 2 or 3 characters, so if the length is less than 2, no need to check
20402
- var numberingType = trigger.length > 1 ? identifyNumberingListType(trigger) : null;
20523
+ // If the marker length is 3, the marker style is double parenthesis such as (1), (A).
20524
+ var isDoubleParenthesis = trigger.length === 3 && trigger[0] === '(' && trigger[2] === ')';
20525
+ var numberingType = trigger.length === 2 || isDoubleParenthesis
20526
+ ? identifyNumberingListType(trigger, isDoubleParenthesis, startNumber)
20527
+ : null;
20403
20528
  return numberingType;
20404
20529
  }
20405
20530
  exports.default = getAutoNumberingListStyle;
@@ -22168,13 +22293,21 @@ exports.Resizer = {
22168
22293
  ? base.heightPx
22169
22294
  : Math.max(base.heightPx + deltaY * (y == 'n' ? -1 : 1), options.minHeight);
22170
22295
  if (shouldPreserveRatio && ratio > 0) {
22171
- newHeight = Math.min(newHeight, newWidth / ratio);
22172
- newWidth = Math.min(newWidth, newHeight * ratio);
22173
- if (newWidth < newHeight * ratio) {
22296
+ if (ratio > 1) {
22297
+ // first sure newHeight is right,calculate newWidth
22174
22298
  newWidth = newHeight * ratio;
22299
+ if (newWidth < options.minWidth) {
22300
+ newWidth = options.minWidth;
22301
+ newHeight = newWidth / ratio;
22302
+ }
22175
22303
  }
22176
22304
  else {
22305
+ // first sure newWidth is right,calculate newHeight
22177
22306
  newHeight = newWidth / ratio;
22307
+ if (newHeight < options.minHeight) {
22308
+ newHeight = options.minHeight;
22309
+ newWidth = newHeight * ratio;
22310
+ }
22178
22311
  }
22179
22312
  }
22180
22313
  editInfo.widthPx = newWidth;
@@ -27424,6 +27557,12 @@ var CompatibleExperimentalFeatures;
27424
27557
  * Automatically transform -- into hyphen, if typed between two words.
27425
27558
  */
27426
27559
  CompatibleExperimentalFeatures["AutoHyphen"] = "AutoHyphen";
27560
+ /**
27561
+ * Use pending format strategy to do style based format, e.g. Font size, Color.
27562
+ * With this feature enabled, we don't need to insert temp ZeroWidthSpace character to hold pending format
27563
+ * when selection is collapsed. Instead, we will hold the pending format in memory and only apply it when type something
27564
+ */
27565
+ CompatibleExperimentalFeatures["PendingStyleBasedFormat"] = "PendingStyleBasedFormat";
27427
27566
  })(CompatibleExperimentalFeatures = exports.CompatibleExperimentalFeatures || (exports.CompatibleExperimentalFeatures = {}));
27428
27567
 
27429
27568
 
@@ -28242,6 +28381,10 @@ var CompatibleTableBorderFormat;
28242
28381
  * |
28243
28382
  */
28244
28383
  CompatibleTableBorderFormat[CompatibleTableBorderFormat["ESPECIAL_TYPE_3"] = 7] = "ESPECIAL_TYPE_3";
28384
+ /**
28385
+ * No border
28386
+ */
28387
+ CompatibleTableBorderFormat[CompatibleTableBorderFormat["CLEAR"] = 8] = "CLEAR";
28245
28388
  })(CompatibleTableBorderFormat = exports.CompatibleTableBorderFormat || (exports.CompatibleTableBorderFormat = {}));
28246
28389
 
28247
28390