roosterjs 8.43.0 → 8.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2843,6 +2843,7 @@ function getElementBasedFormatState(editor, event) {
2843
2843
  canUnlink: !!editor.queryElements('a[href]', 1 /* OnSelection */)[0],
2844
2844
  canAddImageAltText: !!editor.queryElements('img', 1 /* OnSelection */)[0],
2845
2845
  isBlockQuote: !!editor.queryElements('blockquote', 1 /* OnSelection */)[0],
2846
+ isCodeInline: !!editor.queryElements('code', 1 /* OnSelection */)[0],
2846
2847
  isCodeBlock: !!editor.queryElements('pre>code', 1 /* OnSelection */)[0],
2847
2848
  isInTable: !!table,
2848
2849
  tableFormat: tableFormat,
@@ -2975,6 +2976,9 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2975
2976
  isReadonly &&
2976
2977
  editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
2977
2978
  (0, roosterjs_editor_dom_1.addDelimiters)(entity.wrapper);
2979
+ if (entity.wrapper.nextElementSibling) {
2980
+ editor.select(new roosterjs_editor_dom_1.Position(entity.wrapper.nextElementSibling, -3 /* After */));
2981
+ }
2978
2982
  }
2979
2983
  editor.triggerContentChangedEvent("InsertEntity" /* InsertEntity */, entity);
2980
2984
  return entity;
@@ -4381,9 +4385,11 @@ function blockFormat(editor, callback, beforeRunCallback, apiName) {
4381
4385
  (0, formatUndoSnapshot_1.default)(editor, function (start, end) {
4382
4386
  if (!beforeRunCallback || beforeRunCallback()) {
4383
4387
  var regions = editor.getSelectedRegions();
4384
- var chains_1 = roosterjs_editor_dom_1.VListChain.createListChains(regions, start === null || start === void 0 ? void 0 : start.node);
4385
- regions.forEach(function (region) { return callback(region, start, end, chains_1); });
4386
- (0, commitListChains_1.default)(editor, chains_1);
4388
+ if (regions.length > 0) {
4389
+ var chains_1 = roosterjs_editor_dom_1.VListChain.createListChains(regions, start === null || start === void 0 ? void 0 : start.node);
4390
+ regions.forEach(function (region) { return callback(region, start, end, chains_1); });
4391
+ (0, commitListChains_1.default)(editor, chains_1);
4392
+ }
4387
4393
  }
4388
4394
  if (selection.type == 0 /* Normal */) {
4389
4395
  editor.select(start, end);
@@ -5318,7 +5324,7 @@ var getContent = function (core, mode) {
5318
5324
  : null;
5319
5325
  var range = path && (0, roosterjs_editor_dom_1.createRange)(clonedRoot, path.start, path.end);
5320
5326
  if (core.lifecycle.isDarkMode || core.darkColorHandler) {
5321
- core.api.transformColor(core, clonedRoot, false /*includeSelf*/, null /*callback*/, 1 /* DarkToLight */, !!core.darkColorHandler);
5327
+ core.api.transformColor(core, clonedRoot, false /*includeSelf*/, null /*callback*/, 1 /* DarkToLight */, !!core.darkColorHandler, core.lifecycle.isDarkMode);
5322
5328
  }
5323
5329
  if (triggerExtractContentEvent) {
5324
5330
  core.api.triggerEvent(core, {
@@ -6303,7 +6309,7 @@ var setContent = function (core, content, triggerContentChangedEvent, metadata)
6303
6309
  }
6304
6310
  var isDarkMode = core.lifecycle.isDarkMode;
6305
6311
  if ((!metadata && isDarkMode) || (metadata && !!metadata.isDarkMode != !!isDarkMode)) {
6306
- core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, isDarkMode ? 0 /* LightToDark */ : 1 /* DarkToLight */, true /*forceTransform*/);
6312
+ core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, isDarkMode ? 0 /* LightToDark */ : 1 /* DarkToLight */, true /*forceTransform*/, metadata === null || metadata === void 0 ? void 0 : metadata.isDarkMode);
6307
6313
  contentChanged = true;
6308
6314
  }
6309
6315
  if (triggerContentChangedEvent && contentChanged) {
@@ -6471,14 +6477,14 @@ var ColorAttributeName = [
6471
6477
  * @param forceTransform By default this function will only work when editor core is in dark mode.
6472
6478
  * Pass true to this value to force do color transformation even editor core is in light mode
6473
6479
  */
6474
- var transformColor = function (core, rootNode, includeSelf, callback, direction, forceTransform) {
6480
+ var transformColor = function (core, rootNode, includeSelf, callback, direction, forceTransform, fromDarkMode) {
6475
6481
  var darkColorHandler = core.darkColorHandler;
6476
6482
  var elements = rootNode && (forceTransform || core.lifecycle.isDarkMode)
6477
6483
  ? getAll(rootNode, includeSelf)
6478
6484
  : [];
6479
6485
  callback === null || callback === void 0 ? void 0 : callback();
6480
6486
  if (darkColorHandler) {
6481
- transformV2(elements, darkColorHandler, direction == 0 /* LightToDark */);
6487
+ transformV2(elements, darkColorHandler, !!fromDarkMode, direction == 0 /* LightToDark */);
6482
6488
  }
6483
6489
  else {
6484
6490
  if (direction == 1 /* DarkToLight */) {
@@ -6493,12 +6499,13 @@ var transformColor = function (core, rootNode, includeSelf, callback, direction,
6493
6499
  }
6494
6500
  };
6495
6501
  exports.transformColor = transformColor;
6496
- function transformV2(elements, darkColorHandler, toDark) {
6502
+ function transformV2(elements, darkColorHandler, fromDark, toDark) {
6497
6503
  elements.forEach(function (element) {
6498
6504
  ColorAttributeName.forEach(function (names, i) {
6499
- var color = tryFetchAndClearFontColor(element, toDark, darkColorHandler, names) ||
6500
- darkColorHandler.parseColorValue(element.style.getPropertyValue(names[0 /* CssColor */]) ||
6501
- element.getAttribute(names[1 /* HtmlColor */])).lightModeColor;
6505
+ var color = darkColorHandler.parseColorValue(element.style.getPropertyValue(names[0 /* CssColor */]) ||
6506
+ element.getAttribute(names[1 /* HtmlColor */]), fromDark).lightModeColor;
6507
+ element.style.setProperty(names[0 /* CssColor */], null);
6508
+ element.removeAttribute(names[1 /* HtmlColor */]);
6502
6509
  if (color && color != 'inherit') {
6503
6510
  (0, roosterjs_editor_dom_1.setColor)(element, color, i != 0, toDark, false /*shouldAdaptFontColor*/, darkColorHandler);
6504
6511
  }
@@ -6587,27 +6594,6 @@ function isHTMLElement(element) {
6587
6594
  var htmlElement = element;
6588
6595
  return !!htmlElement.style && !!htmlElement.dataset;
6589
6596
  }
6590
- /**
6591
- * There is a known issue that when input with IME in Chrome, it is possible Chrome insert a new FONT tag with colors.
6592
- * If editor is in dark mode, this color will cause the FONT tag doesn't have light mode color info so that after convert
6593
- * to light mode the color will be wrong.
6594
- * To workaround it, we check if this is a known color (for light mode with VariableBasedDarkColor enabled, all used colors
6595
- * are stored in darkColorHandler), then use the related light mode color instead.
6596
- */
6597
- function tryFetchAndClearFontColor(element, toDark, darkColorHandler, names) {
6598
- var darkColor;
6599
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(element) == 'FONT' &&
6600
- !element.style.getPropertyValue(names[0 /* CssColor */]) &&
6601
- !toDark &&
6602
- (darkColor = element.getAttribute(names[1 /* HtmlColor */]))) {
6603
- var lightColor = darkColorHandler.findLightColorFromDarkColor(darkColor);
6604
- if (lightColor) {
6605
- element.removeAttribute(names[1 /* HtmlColor */]);
6606
- return lightColor;
6607
- }
6608
- }
6609
- return null;
6610
- }
6611
6597
 
6612
6598
 
6613
6599
  /***/ }),
@@ -7266,7 +7252,7 @@ exports.default = EditPlugin;
7266
7252
  "use strict";
7267
7253
 
7268
7254
  Object.defineProperty(exports, "__esModule", { value: true });
7269
- var inlineEntityOnPluginEvent_1 = __webpack_require__(/*! ./utils/InlineEntityHandlers/inlineEntityOnPluginEvent */ "./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts");
7255
+ var inlineEntityOnPluginEvent_1 = __webpack_require__(/*! ./utils/inlineEntityOnPluginEvent */ "./packages/roosterjs-editor-core/lib/corePlugins/utils/inlineEntityOnPluginEvent.ts");
7270
7256
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7271
7257
  var ENTITY_ID_REGEX = /_(\d{1,8})$/;
7272
7258
  var ENTITY_CSS_REGEX = '^' + "_Entity" /* ENTITY_INFO_NAME */ + '$';
@@ -7389,7 +7375,7 @@ var EntityPlugin = /** @class */ (function () {
7389
7375
  break;
7390
7376
  }
7391
7377
  if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
7392
- (0, inlineEntityOnPluginEvent_1.inlineEntityOnPluginEvent)(event);
7378
+ (0, inlineEntityOnPluginEvent_1.inlineEntityOnPluginEvent)(event, this.editor);
7393
7379
  }
7394
7380
  };
7395
7381
  EntityPlugin.prototype.handleContextMenuEvent = function (event) {
@@ -7440,6 +7426,8 @@ var EntityPlugin = /** @class */ (function () {
7440
7426
  };
7441
7427
  EntityPlugin.prototype.handleContentChangedEvent = function (event) {
7442
7428
  var _this = this;
7429
+ var _a;
7430
+ var shouldNormalizeDelimiters = false;
7443
7431
  // 1. find removed entities
7444
7432
  for (var i = this.state.knownEntityElements.length - 1; i >= 0; i--) {
7445
7433
  var element = this.state.knownEntityElements[i];
@@ -7448,6 +7436,11 @@ var EntityPlugin = /** @class */ (function () {
7448
7436
  if (element.shadowRoot) {
7449
7437
  this.triggerEvent(element, 10 /* RemoveShadowRoot */);
7450
7438
  }
7439
+ if (!shouldNormalizeDelimiters &&
7440
+ !element.isContentEditable &&
7441
+ !(0, roosterjs_editor_dom_1.isBlockElement)(element)) {
7442
+ shouldNormalizeDelimiters = true;
7443
+ }
7451
7444
  }
7452
7445
  }
7453
7446
  // 2. collect all new entities
@@ -7471,6 +7464,10 @@ var EntityPlugin = /** @class */ (function () {
7471
7464
  _this.triggerEvent(_this.state.shadowEntityCache[id], 6 /* Overwrite */);
7472
7465
  delete _this.state.shadowEntityCache[id];
7473
7466
  });
7467
+ if (shouldNormalizeDelimiters &&
7468
+ ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */))) {
7469
+ (0, inlineEntityOnPluginEvent_1.normalizeDelimitersInEditor)(this.editor);
7470
+ }
7474
7471
  };
7475
7472
  EntityPlugin.prototype.handleEntityOperationEvent = function (event) {
7476
7473
  var _this = this;
@@ -7647,6 +7644,7 @@ var workaroundSelectionIssueForIE = roosterjs_editor_dom_1.Browser.isIE
7647
7644
  Object.defineProperty(exports, "__esModule", { value: true });
7648
7645
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
7649
7646
  var Escape = 'Escape';
7647
+ var Delete = 'Delete';
7650
7648
  var mouseRightButton = 2;
7651
7649
  var mouseLeftButton = 0;
7652
7650
  /**
@@ -7718,6 +7716,10 @@ var ImageSelection = /** @class */ (function () {
7718
7716
  (_a = this.editor.getSelectionRange()) === null || _a === void 0 ? void 0 : _a.collapse();
7719
7717
  event.rawEvent.stopPropagation();
7720
7718
  }
7719
+ else if (key === Delete) {
7720
+ this.editor.deleteNode(keyDownSelection.image);
7721
+ event.rawEvent.preventDefault();
7722
+ }
7721
7723
  else {
7722
7724
  this.editor.select(keyDownSelection.ranges[0]);
7723
7725
  }
@@ -8752,68 +8754,6 @@ function getPluginState(corePlugins) {
8752
8754
  exports.getPluginState = getPluginState;
8753
8755
 
8754
8756
 
8755
- /***/ }),
8756
-
8757
- /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts":
8758
- /*!****************************************************************************************************************!*\
8759
- !*** ./packages/roosterjs-editor-core/lib/corePlugins/utils/InlineEntityHandlers/inlineEntityOnPluginEvent.ts ***!
8760
- \****************************************************************************************************************/
8761
- /*! no static exports found */
8762
- /***/ (function(module, exports, __webpack_require__) {
8763
-
8764
- "use strict";
8765
-
8766
- Object.defineProperty(exports, "__esModule", { value: true });
8767
- exports.inlineEntityOnPluginEvent = void 0;
8768
- var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
8769
- var DELIMITER_SELECTOR = '.' + "entityDelimiterAfter" /* DELIMITER_AFTER */ + ',.' + "entityDelimiterBefore" /* DELIMITER_BEFORE */;
8770
- function inlineEntityOnPluginEvent(event) {
8771
- switch (event.eventType) {
8772
- case 8 /* ExtractContentWithDom */:
8773
- case 9 /* BeforeCutCopy */:
8774
- event.clonedRoot.querySelectorAll(DELIMITER_SELECTOR).forEach(function (node) {
8775
- var _a;
8776
- (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(node);
8777
- });
8778
- break;
8779
- case 15 /* EntityOperation */:
8780
- var wrapper = event.entity.wrapper;
8781
- switch (event.operation) {
8782
- case 4 /* RemoveFromStart */:
8783
- case 5 /* RemoveFromEnd */:
8784
- case 6 /* Overwrite */:
8785
- var entity = event.entity;
8786
- // If the entity removed is a readonly entity, try to remove delimiters around it.
8787
- if (isReadOnly(entity)) {
8788
- removeDelimiters(wrapper);
8789
- }
8790
- break;
8791
- }
8792
- break;
8793
- }
8794
- }
8795
- exports.inlineEntityOnPluginEvent = inlineEntityOnPluginEvent;
8796
- function getDelimiter(entityWrapper, after) {
8797
- var el = after ? entityWrapper.nextElementSibling : entityWrapper.previousElementSibling;
8798
- return el && (0, roosterjs_editor_dom_1.safeInstanceOf)(el, 'HTMLElement') && (0, roosterjs_editor_dom_1.getDelimiterFromElement)(el) ? el : undefined;
8799
- }
8800
- function removeDelimiters(entityWrapper) {
8801
- var _a, _b;
8802
- var el = undefined;
8803
- if ((el = getDelimiter(entityWrapper, true))) {
8804
- (_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(el);
8805
- }
8806
- if ((el = getDelimiter(entityWrapper, false))) {
8807
- (_b = el.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(el);
8808
- }
8809
- }
8810
- function isReadOnly(entity) {
8811
- return (entity.isReadonly &&
8812
- !(0, roosterjs_editor_dom_1.isBlockElement)(entity.wrapper) &&
8813
- (0, roosterjs_editor_dom_1.safeInstanceOf)(entity.wrapper, 'HTMLElement'));
8814
- }
8815
-
8816
-
8817
8757
  /***/ }),
8818
8758
 
8819
8759
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/forEachSelectedCell.ts":
@@ -8849,6 +8789,222 @@ var forEachSelectedCell = function (vTable, callback) {
8849
8789
  exports.forEachSelectedCell = forEachSelectedCell;
8850
8790
 
8851
8791
 
8792
+ /***/ }),
8793
+
8794
+ /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/inlineEntityOnPluginEvent.ts":
8795
+ /*!*******************************************************************************************!*\
8796
+ !*** ./packages/roosterjs-editor-core/lib/corePlugins/utils/inlineEntityOnPluginEvent.ts ***!
8797
+ \*******************************************************************************************/
8798
+ /*! no static exports found */
8799
+ /***/ (function(module, exports, __webpack_require__) {
8800
+
8801
+ "use strict";
8802
+
8803
+ Object.defineProperty(exports, "__esModule", { value: true });
8804
+ exports.normalizeDelimitersInEditor = exports.inlineEntityOnPluginEvent = void 0;
8805
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
8806
+ var DELIMITER_SELECTOR = '.' + "entityDelimiterAfter" /* DELIMITER_AFTER */ + ',.' + "entityDelimiterBefore" /* DELIMITER_BEFORE */;
8807
+ var ZERO_WIDTH_SPACE = '\u200B';
8808
+ var INLINE_ENTITY_SELECTOR = 'span' + (0, roosterjs_editor_dom_1.getEntitySelector)();
8809
+ var NBSP = '\u00A0';
8810
+ function inlineEntityOnPluginEvent(event, editor) {
8811
+ switch (event.eventType) {
8812
+ case 7 /* ContentChanged */:
8813
+ if (event.source === "SetContent" /* SetContent */) {
8814
+ normalizeDelimitersInEditor(editor);
8815
+ }
8816
+ break;
8817
+ case 11 /* EditorReady */:
8818
+ normalizeDelimitersInEditor(editor);
8819
+ break;
8820
+ case 10 /* BeforePaste */:
8821
+ addDelimitersIfNeeded(event.fragment.querySelectorAll(INLINE_ENTITY_SELECTOR));
8822
+ break;
8823
+ case 8 /* ExtractContentWithDom */:
8824
+ case 9 /* BeforeCutCopy */:
8825
+ event.clonedRoot.querySelectorAll(DELIMITER_SELECTOR).forEach(removeNode);
8826
+ break;
8827
+ case 0 /* KeyDown */:
8828
+ handleKeyDownEvent(editor, event);
8829
+ break;
8830
+ }
8831
+ }
8832
+ exports.inlineEntityOnPluginEvent = inlineEntityOnPluginEvent;
8833
+ function preventTypeInDelimiter(delimiter) {
8834
+ var _a, _b, _c, _d;
8835
+ delimiter.normalize();
8836
+ var textNode = delimiter.firstChild;
8837
+ var index = (_b = (_a = textNode.nodeValue) === null || _a === void 0 ? void 0 : _a.indexOf(ZERO_WIDTH_SPACE)) !== null && _b !== void 0 ? _b : -1;
8838
+ if (index >= 0) {
8839
+ (0, roosterjs_editor_dom_1.splitTextNode)(textNode, index == 0 ? 1 : index, false /* returnFirstPart */);
8840
+ var nodeToMove_1;
8841
+ delimiter.childNodes.forEach(function (node) {
8842
+ if (node.nodeValue !== ZERO_WIDTH_SPACE) {
8843
+ nodeToMove_1 = node;
8844
+ }
8845
+ });
8846
+ if (nodeToMove_1) {
8847
+ (_c = delimiter.parentElement) === null || _c === void 0 ? void 0 : _c.insertBefore(nodeToMove_1, delimiter.className == "entityDelimiterBefore" /* DELIMITER_BEFORE */
8848
+ ? delimiter
8849
+ : delimiter.nextSibling);
8850
+ var selection = (_d = nodeToMove_1.ownerDocument) === null || _d === void 0 ? void 0 : _d.getSelection();
8851
+ if (selection) {
8852
+ selection.setPosition(nodeToMove_1, new roosterjs_editor_dom_1.Position(nodeToMove_1, -1 /* End */).offset);
8853
+ }
8854
+ }
8855
+ }
8856
+ }
8857
+ /**
8858
+ * @internal
8859
+ */
8860
+ function normalizeDelimitersInEditor(editor) {
8861
+ removeInvalidDelimiters(editor.queryElements(DELIMITER_SELECTOR));
8862
+ addDelimitersIfNeeded(editor.queryElements(INLINE_ENTITY_SELECTOR));
8863
+ }
8864
+ exports.normalizeDelimitersInEditor = normalizeDelimitersInEditor;
8865
+ function addDelimitersIfNeeded(nodes) {
8866
+ nodes.forEach(function (node) {
8867
+ if (tryGetEntityFromNode(node)) {
8868
+ (0, roosterjs_editor_dom_1.addDelimiters)(node);
8869
+ }
8870
+ });
8871
+ }
8872
+ function tryGetEntityFromNode(node) {
8873
+ return !!(node &&
8874
+ (0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLElement') &&
8875
+ isReadOnly((0, roosterjs_editor_dom_1.getEntityFromElement)(node)));
8876
+ }
8877
+ function removeNode(el) {
8878
+ var _a;
8879
+ (_a = el === null || el === void 0 ? void 0 : el.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(el);
8880
+ }
8881
+ function isReadOnly(entity) {
8882
+ return ((entity === null || entity === void 0 ? void 0 : entity.isReadonly) &&
8883
+ !(0, roosterjs_editor_dom_1.isBlockElement)(entity.wrapper) &&
8884
+ (0, roosterjs_editor_dom_1.safeInstanceOf)(entity.wrapper, 'HTMLElement'));
8885
+ }
8886
+ function removeInvalidDelimiters(nodes) {
8887
+ nodes.forEach(function (node) {
8888
+ if ((0, roosterjs_editor_dom_1.getDelimiterFromElement)(node)) {
8889
+ var sibling = node.classList.contains("entityDelimiterBefore" /* DELIMITER_BEFORE */)
8890
+ ? node.nextElementSibling
8891
+ : node.previousElementSibling;
8892
+ if (!((0, roosterjs_editor_dom_1.safeInstanceOf)(sibling, 'HTMLElement') && (0, roosterjs_editor_dom_1.getEntityFromElement)(sibling))) {
8893
+ removeNode(node);
8894
+ }
8895
+ }
8896
+ else {
8897
+ removeDelimiterAttr(node);
8898
+ }
8899
+ });
8900
+ }
8901
+ function removeDelimiterAttr(node) {
8902
+ if (!node) {
8903
+ return;
8904
+ }
8905
+ var isAfter = node.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */);
8906
+ var entitySibling = isAfter ? node.previousElementSibling : node.nextElementSibling;
8907
+ if (entitySibling && tryGetEntityFromNode(entitySibling)) {
8908
+ return;
8909
+ }
8910
+ node.classList.remove("entityDelimiterAfter" /* DELIMITER_AFTER */, "entityDelimiterBefore" /* DELIMITER_BEFORE */);
8911
+ node.normalize();
8912
+ node.childNodes.forEach(function (cn) {
8913
+ var _a, _b, _c;
8914
+ var index = (_b = (_a = cn.textContent) === null || _a === void 0 ? void 0 : _a.indexOf(ZERO_WIDTH_SPACE)) !== null && _b !== void 0 ? _b : -1;
8915
+ if (index >= 0) {
8916
+ (_c = (0, roosterjs_editor_dom_1.createRange)(cn, index, cn, index + 1)) === null || _c === void 0 ? void 0 : _c.deleteContents();
8917
+ }
8918
+ });
8919
+ }
8920
+ function handleCollapsedEnter(editor, delimiter) {
8921
+ var isAfter = delimiter.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */);
8922
+ var sibling = isAfter ? delimiter.nextSibling : delimiter.previousSibling;
8923
+ var positionToUse;
8924
+ var element;
8925
+ if (sibling) {
8926
+ positionToUse = new roosterjs_editor_dom_1.Position(sibling, isAfter ? 0 /* Begin */ : -1 /* End */);
8927
+ }
8928
+ else {
8929
+ element = delimiter.insertAdjacentElement(isAfter ? 'afterend' : 'beforebegin', (0, roosterjs_editor_dom_1.createElement)({
8930
+ tag: 'span',
8931
+ children: [NBSP],
8932
+ }, editor.getDocument()));
8933
+ if (!element) {
8934
+ return;
8935
+ }
8936
+ positionToUse = new roosterjs_editor_dom_1.Position(element, 0 /* Begin */);
8937
+ }
8938
+ if (positionToUse) {
8939
+ editor.select(positionToUse);
8940
+ editor.runAsync(function (aEditor) {
8941
+ var elAfter = aEditor.getElementAtCursor();
8942
+ removeDelimiterAttr(elAfter);
8943
+ removeNode(element);
8944
+ });
8945
+ }
8946
+ }
8947
+ var getPosition = function (container) {
8948
+ if (container && (0, roosterjs_editor_dom_1.getDelimiterFromElement)(container)) {
8949
+ var isAfter = container.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */);
8950
+ return new roosterjs_editor_dom_1.Position(container, isAfter ? -3 /* After */ : -2 /* Before */);
8951
+ }
8952
+ return undefined;
8953
+ };
8954
+ function handleSelectionNotCollapsed(editor, range, event) {
8955
+ var startContainer = range.startContainer, endContainer = range.endContainer, startOffset = range.startOffset, endOffset = range.endOffset;
8956
+ var startElement = editor.getElementAtCursor(DELIMITER_SELECTOR, startContainer);
8957
+ var endElement = editor.getElementAtCursor(DELIMITER_SELECTOR, endContainer);
8958
+ var startUpdate = getPosition(startElement);
8959
+ var endUpdate = getPosition(endElement);
8960
+ if (startUpdate || endUpdate) {
8961
+ editor.select(startUpdate !== null && startUpdate !== void 0 ? startUpdate : new roosterjs_editor_dom_1.Position(startContainer, startOffset), endUpdate !== null && endUpdate !== void 0 ? endUpdate : new roosterjs_editor_dom_1.Position(endContainer, endOffset));
8962
+ }
8963
+ editor.runAsync(function (aEditor) {
8964
+ var delimiter = aEditor.getElementAtCursor(DELIMITER_SELECTOR);
8965
+ if (delimiter) {
8966
+ preventTypeInDelimiter(delimiter);
8967
+ if (event.which === 13 /* ENTER */) {
8968
+ removeDelimiterAttr(delimiter);
8969
+ }
8970
+ }
8971
+ });
8972
+ }
8973
+ function handleKeyDownEvent(editor, event) {
8974
+ var _a, _b;
8975
+ var range = editor.getSelectionRangeEx();
8976
+ var rawEvent = event.rawEvent;
8977
+ if (range.type != 0 /* Normal */) {
8978
+ return;
8979
+ }
8980
+ if (range.areAllCollapsed && ((0, roosterjs_editor_dom_1.isCharacterValue)(rawEvent) || rawEvent.which === 13 /* ENTER */)) {
8981
+ var position = (_a = editor.getFocusedPosition()) === null || _a === void 0 ? void 0 : _a.normalize();
8982
+ if (!position) {
8983
+ return;
8984
+ }
8985
+ var element = position.element, node = position.node;
8986
+ var refNode = element == node ? element.childNodes.item(position.offset) : element;
8987
+ var delimiter_1 = editor.getElementAtCursor(DELIMITER_SELECTOR, refNode);
8988
+ if (!delimiter_1) {
8989
+ return;
8990
+ }
8991
+ if (rawEvent.which === 13 /* ENTER */) {
8992
+ handleCollapsedEnter(editor, delimiter_1);
8993
+ }
8994
+ else if (((_b = delimiter_1.firstChild) === null || _b === void 0 ? void 0 : _b.nodeType) == 3 /* Text */) {
8995
+ editor.runAsync(function () { return preventTypeInDelimiter(delimiter_1); });
8996
+ }
8997
+ }
8998
+ else if (!range.areAllCollapsed && !rawEvent.shiftKey && rawEvent.which != 16 /* SHIFT */) {
8999
+ var currentRange = range.ranges[0];
9000
+ if (!currentRange) {
9001
+ return;
9002
+ }
9003
+ handleSelectionNotCollapsed(editor, currentRange, rawEvent);
9004
+ }
9005
+ }
9006
+
9007
+
8852
9008
  /***/ }),
8853
9009
 
8854
9010
  /***/ "./packages/roosterjs-editor-core/lib/corePlugins/utils/removeCellsOutsideSelection.ts":
@@ -8968,11 +9124,13 @@ var DarkColorHandlerImpl = /** @class */ (function () {
8968
9124
  * Parse an existing color value, if it is in variable-based color format, extract color key,
8969
9125
  * light color and query related dark color if any
8970
9126
  * @param color The color string to parse
9127
+ * @param isInDarkMode Whether current content is in dark mode. When set to true, if the color value is not in dark var format,
9128
+ * we will treat is as a dark mode color and try to find a matched dark mode color.
8971
9129
  */
8972
- DarkColorHandlerImpl.prototype.parseColorValue = function (color) {
9130
+ DarkColorHandlerImpl.prototype.parseColorValue = function (color, isInDarkMode) {
8973
9131
  var _a;
8974
9132
  var key;
8975
- var lightModeColor = color || '';
9133
+ var lightModeColor = '';
8976
9134
  var darkModeColor;
8977
9135
  if (color) {
8978
9136
  var match = color.startsWith(VARIABLE_PREFIX) ? VARIABLE_REGEX.exec(color) : null;
@@ -8986,6 +9144,18 @@ var DarkColorHandlerImpl = /** @class */ (function () {
8986
9144
  lightModeColor = '';
8987
9145
  }
8988
9146
  }
9147
+ else if (isInDarkMode) {
9148
+ // If editor is in dark mode but the color is not in dark color format, it is possible the color was inserted from external code
9149
+ // without any light color info. So we first try to see if there is a known dark color can match this color, and use its related
9150
+ // light color as light mode color. Otherwise we need to drop this color to avoid show "white on white" content.
9151
+ lightModeColor = this.findLightColorFromDarkColor(color) || '';
9152
+ if (lightModeColor) {
9153
+ darkModeColor = color;
9154
+ }
9155
+ }
9156
+ else {
9157
+ lightModeColor = color;
9158
+ }
8989
9159
  }
8990
9160
  return { key: key, lightModeColor: lightModeColor, darkModeColor: darkModeColor };
8991
9161
  };
@@ -9786,13 +9956,14 @@ var Editor = /** @class */ (function () {
9786
9956
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
9787
9957
  */
9788
9958
  Editor.prototype.setDarkModeState = function (nextDarkMode) {
9789
- if (this.isDarkMode() == !!nextDarkMode) {
9959
+ var isDarkMode = this.isDarkMode();
9960
+ if (isDarkMode == !!nextDarkMode) {
9790
9961
  return;
9791
9962
  }
9792
9963
  var core = this.getCore();
9793
9964
  core.api.transformColor(core, core.contentDiv, false /*includeSelf*/, null /*callback*/, nextDarkMode
9794
9965
  ? 0 /* LightToDark */
9795
- : 1 /* DarkToLight */, true /*forceTransform*/);
9966
+ : 1 /* DarkToLight */, true /*forceTransform*/, isDarkMode);
9796
9967
  this.triggerContentChangedEvent(nextDarkMode ? "SwitchToDarkMode" /* SwitchToDarkMode */ : "SwitchToLightMode" /* SwitchToLightMode */);
9797
9968
  };
9798
9969
  /**
@@ -11278,28 +11449,62 @@ exports.default = SelectionScoper;
11278
11449
  "use strict";
11279
11450
 
11280
11451
  Object.defineProperty(exports, "__esModule", { value: true });
11452
+ exports.addDelimiterBefore = exports.addDelimiterAfter = void 0;
11281
11453
  var createElement_1 = __webpack_require__(/*! ../utils/createElement */ "./packages/roosterjs-editor-dom/lib/utils/createElement.ts");
11454
+ var getDelimiterFromElement_1 = __webpack_require__(/*! ./getDelimiterFromElement */ "./packages/roosterjs-editor-dom/lib/delimiter/getDelimiterFromElement.ts");
11282
11455
  var ZERO_WIDTH_SPACE = '\u200B';
11283
11456
  /**
11284
- * Adds delimiters to the element provided.
11285
- * @param element element to be between delimiters
11457
+ * Adds delimiters to the element provided. If the delimiters already exists, will not be added
11458
+ * @param node the node to add the delimiters
11286
11459
  */
11287
- function addDelimiters(element) {
11288
- function insertDelimiter(delimiterClass) {
11289
- var span = (0, createElement_1.default)({
11290
- tag: 'span',
11291
- className: delimiterClass,
11292
- children: [ZERO_WIDTH_SPACE],
11293
- }, element.ownerDocument);
11294
- if (span) {
11295
- var insertPosition = delimiterClass == "entityDelimiterAfter" /* DELIMITER_AFTER */ ? 'afterend' : 'beforebegin';
11296
- element.insertAdjacentElement(insertPosition, span);
11297
- }
11460
+ function addDelimiters(node) {
11461
+ var _a = getDelimiters(node), delimiterAfter = _a[0], delimiterBefore = _a[1];
11462
+ if (!delimiterAfter) {
11463
+ delimiterAfter = addDelimiterAfter(node);
11464
+ }
11465
+ if (!delimiterBefore) {
11466
+ delimiterBefore = addDelimiterBefore(node);
11298
11467
  }
11299
- insertDelimiter("entityDelimiterAfter" /* DELIMITER_AFTER */);
11300
- insertDelimiter("entityDelimiterBefore" /* DELIMITER_BEFORE */);
11468
+ return [delimiterAfter, delimiterBefore];
11301
11469
  }
11302
11470
  exports.default = addDelimiters;
11471
+ /**
11472
+ * Adds delimiter after the element provided.
11473
+ * @param element element to use
11474
+ */
11475
+ function addDelimiterAfter(element) {
11476
+ return insertDelimiter(element, "entityDelimiterAfter" /* DELIMITER_AFTER */);
11477
+ }
11478
+ exports.addDelimiterAfter = addDelimiterAfter;
11479
+ /**
11480
+ * Adds delimiter before the element provided.
11481
+ * @param element element to use
11482
+ */
11483
+ function addDelimiterBefore(element) {
11484
+ return insertDelimiter(element, "entityDelimiterBefore" /* DELIMITER_BEFORE */);
11485
+ }
11486
+ exports.addDelimiterBefore = addDelimiterBefore;
11487
+ function getDelimiters(entityWrapper) {
11488
+ var result = [];
11489
+ var nextElementSibling = entityWrapper.nextElementSibling, previousElementSibling = entityWrapper.previousElementSibling;
11490
+ result.push(isDelimiter(nextElementSibling, "entityDelimiterAfter" /* DELIMITER_AFTER */), isDelimiter(previousElementSibling, "entityDelimiterBefore" /* DELIMITER_BEFORE */));
11491
+ return result;
11492
+ }
11493
+ function isDelimiter(el, className) {
11494
+ return el && (0, getDelimiterFromElement_1.default)(el) && el.classList.contains(className) ? el : undefined;
11495
+ }
11496
+ function insertDelimiter(element, delimiterClass) {
11497
+ var span = (0, createElement_1.default)({
11498
+ tag: 'span',
11499
+ className: delimiterClass,
11500
+ children: [ZERO_WIDTH_SPACE],
11501
+ }, element.ownerDocument);
11502
+ if (span) {
11503
+ var insertPosition = delimiterClass == "entityDelimiterAfter" /* DELIMITER_AFTER */ ? 'afterend' : 'beforebegin';
11504
+ element.insertAdjacentElement(insertPosition, span);
11505
+ }
11506
+ return element;
11507
+ }
11303
11508
 
11304
11509
 
11305
11510
  /***/ }),
@@ -11314,7 +11519,7 @@ exports.default = addDelimiters;
11314
11519
  "use strict";
11315
11520
 
11316
11521
  Object.defineProperty(exports, "__esModule", { value: true });
11317
- var getTagOfNode_1 = __webpack_require__(/*! ../utils/getTagOfNode */ "./packages/roosterjs-editor-dom/lib/utils/getTagOfNode.ts");
11522
+ var safeInstanceOf_1 = __webpack_require__(/*! ../utils/safeInstanceOf */ "./packages/roosterjs-editor-dom/lib/utils/safeInstanceOf.ts");
11318
11523
  var ZERO_WIDTH_SPACE = '\u200B';
11319
11524
  /**
11320
11525
  * Retrieves Delimiter information from a provided element.
@@ -11325,7 +11530,7 @@ function getDelimiterFromElement(element) {
11325
11530
  if (!element) {
11326
11531
  return null;
11327
11532
  }
11328
- if ((0, getTagOfNode_1.default)(element) == 'SPAN' &&
11533
+ if ((0, safeInstanceOf_1.default)(element, 'HTMLSpanElement') &&
11329
11534
  (element.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */) ||
11330
11535
  element.classList.contains("entityDelimiterBefore" /* DELIMITER_BEFORE */)) &&
11331
11536
  element.textContent === ZERO_WIDTH_SPACE) {
@@ -12946,9 +13151,9 @@ exports.isCssVariable = isCssVariable;
12946
13151
  "use strict";
12947
13152
 
12948
13153
  Object.defineProperty(exports, "__esModule", { value: true });
12949
- exports.KnownCreateElementData = exports.createElement = exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.getDelimiterFromElement = exports.addDelimiters = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
12950
- exports.isModifierKey = exports.clearEventDataCache = exports.cacheGetEventData = exports.restoreContentWithEntityPlaceholder = exports.moveContentWithEntityPlaceholders = exports.createEntityPlaceholder = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.saveTableCellMetadata = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.parseColor = exports.isNodeAfter = exports.getIntersectedRect = exports.moveChildNodes = void 0;
12951
- exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = exports.createNumberDefinition = exports.validate = exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.removeGlobalCssStyle = exports.setGlobalCssStyles = exports.removeImportantStyleRule = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = void 0;
13154
+ exports.matchesSelector = exports.setColor = exports.getInnerHTML = exports.readFile = exports.safeInstanceOf = exports.normalizeRect = exports.splitTextNode = exports.getLastLeafNode = exports.getFirstLeafNode = exports.getPreviousLeafSibling = exports.getNextLeafSibling = exports.wrap = exports.unwrap = exports.splitBalancedNodeRange = exports.splitParentNode = exports.queryElements = exports.matchLink = exports.isVoidHtmlElement = exports.isNodeEmpty = exports.isBlockElement = exports.getTagOfNode = exports.PendableFormatCommandMap = exports.getPendableFormatState = exports.getComputedStyle = exports.getComputedStyles = exports.fromHtml = exports.findClosestElementAncestor = exports.contains = exports.collapseNodes = exports.changeElementTag = exports.applyFormat = exports.getBrowserInfo = exports.Browser = exports.extractClipboardItemsForIE = exports.extractClipboardItems = exports.extractClipboardEvent = exports.applyTextStyle = exports.PartialInlineElement = exports.NodeInlineElement = exports.LinkInlineElement = exports.ImageInlineElement = exports.getInlineElementAtNode = exports.getDelimiterFromElement = exports.addDelimiterBefore = exports.addDelimiterAfter = exports.addDelimiters = exports.PositionContentSearcher = exports.ContentTraverser = exports.getFirstLastBlockElement = exports.getBlockElementAtNode = void 0;
13155
+ exports.cacheGetEventData = exports.restoreContentWithEntityPlaceholder = exports.moveContentWithEntityPlaceholders = exports.createEntityPlaceholder = exports.getEntitySelector = exports.getEntityFromElement = exports.commitEntity = exports.chainSanitizerCallback = exports.createDefaultHtmlSanitizerOptions = exports.getInheritableStyles = exports.HtmlSanitizer = exports.canUndoAutoComplete = exports.createSnapshots = exports.moveCurrentSnapsnot = exports.moveCurrentSnapshot = exports.clearProceedingSnapshotsV2 = exports.clearProceedingSnapshots = exports.canMoveCurrentSnapshot = exports.addSnapshotV2 = exports.addSnapshot = exports.addRangeToSelection = exports.setHtmlWithMetadata = exports.setHtmlWithSelectionPath = exports.getHtmlWithSelectionPath = exports.getSelectionPath = exports.isPositionAtBeginningOf = exports.getPositionRect = exports.createRange = exports.Position = exports.mergeBlocksInRegion = exports.getSelectionRangeInRegion = exports.isNodeInRegion = exports.collapseNodesInRegion = exports.getSelectedBlockElementsInRegion = exports.getRegionsFromRange = exports.saveTableCellMetadata = exports.getTableFormatInfo = exports.setListItemStyle = exports.VListChain = exports.createVListFromRegion = exports.VListItem = exports.VList = exports.isWholeTableSelected = exports.VTable = exports.parseColor = exports.isNodeAfter = exports.getIntersectedRect = exports.moveChildNodes = exports.KnownCreateElementData = exports.createElement = void 0;
13156
+ exports.toArray = exports.getObjectKeys = exports.arrayPush = exports.removeMetadata = exports.setMetadata = exports.getMetadata = exports.createObjectDefinition = exports.createArrayDefinition = exports.createStringDefinition = exports.createBooleanDefinition = exports.createNumberDefinition = exports.validate = exports.getTextContent = exports.deleteSelectedContent = exports.adjustInsertPosition = exports.removeGlobalCssStyle = exports.setGlobalCssStyles = exports.removeImportantStyleRule = exports.setStyles = exports.getStyles = exports.isCtrlOrMetaPressed = exports.isCharacterValue = exports.isModifierKey = exports.clearEventDataCache = void 0;
12952
13157
  var getBlockElementAtNode_1 = __webpack_require__(/*! ./blockElements/getBlockElementAtNode */ "./packages/roosterjs-editor-dom/lib/blockElements/getBlockElementAtNode.ts");
12953
13158
  Object.defineProperty(exports, "getBlockElementAtNode", { enumerable: true, get: function () { return getBlockElementAtNode_1.default; } });
12954
13159
  var getFirstLastBlockElement_1 = __webpack_require__(/*! ./blockElements/getFirstLastBlockElement */ "./packages/roosterjs-editor-dom/lib/blockElements/getFirstLastBlockElement.ts");
@@ -12959,6 +13164,8 @@ var PositionContentSearcher_1 = __webpack_require__(/*! ./contentTraverser/Posit
12959
13164
  Object.defineProperty(exports, "PositionContentSearcher", { enumerable: true, get: function () { return PositionContentSearcher_1.default; } });
12960
13165
  var addDelimiters_1 = __webpack_require__(/*! ./delimiter/addDelimiters */ "./packages/roosterjs-editor-dom/lib/delimiter/addDelimiters.ts");
12961
13166
  Object.defineProperty(exports, "addDelimiters", { enumerable: true, get: function () { return addDelimiters_1.default; } });
13167
+ Object.defineProperty(exports, "addDelimiterAfter", { enumerable: true, get: function () { return addDelimiters_1.addDelimiterAfter; } });
13168
+ Object.defineProperty(exports, "addDelimiterBefore", { enumerable: true, get: function () { return addDelimiters_1.addDelimiterBefore; } });
12962
13169
  var getDelimiterFromElement_1 = __webpack_require__(/*! ./delimiter/getDelimiterFromElement */ "./packages/roosterjs-editor-dom/lib/delimiter/getDelimiterFromElement.ts");
12963
13170
  Object.defineProperty(exports, "getDelimiterFromElement", { enumerable: true, get: function () { return getDelimiterFromElement_1.default; } });
12964
13171
  var getInlineElementAtNode_1 = __webpack_require__(/*! ./inlineElements/getInlineElementAtNode */ "./packages/roosterjs-editor-dom/lib/inlineElements/getInlineElementAtNode.ts");
@@ -20666,8 +20873,7 @@ var DragAndDropHelper = /** @class */ (function () {
20666
20873
  var _a, _b, _c;
20667
20874
  e.preventDefault();
20668
20875
  _this.removeDocumentEvents();
20669
- if (_this.initValue &&
20670
- ((_b = (_a = _this.handler).onDragEnd) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue))) {
20876
+ if ((_b = (_a = _this.handler).onDragEnd) === null || _b === void 0 ? void 0 : _b.call(_a, _this.context, e, _this.initValue)) {
20671
20877
  (_c = _this.onSubmit) === null || _c === void 0 ? void 0 : _c.call(_this, _this.context, _this.trigger);
20672
20878
  }
20673
20879
  };
@@ -20761,7 +20967,7 @@ var AutoFormat = /** @class */ (function () {
20761
20967
  event.eventType === 6 /* MouseUp */) {
20762
20968
  this.lastKeyTyped = '';
20763
20969
  }
20764
- if (event.eventType === 0 /* KeyDown */) {
20970
+ if (event.eventType === 1 /* KeyPress */) {
20765
20971
  var keyTyped = event.rawEvent.key;
20766
20972
  if (keyTyped && keyTyped.length > 1) {
20767
20973
  this.lastKeyTyped = '';
@@ -21102,11 +21308,14 @@ function cacheGetReadonlyEntityElement(event, editor, operation) {
21102
21308
  return entityElement && !entityElement.isContentEditable ? entityElement : null;
21103
21309
  });
21104
21310
  if (element && operation !== undefined) {
21105
- editor.triggerPluginEvent(15 /* EntityOperation */, {
21106
- operation: operation,
21107
- rawEvent: event.rawEvent,
21108
- entity: (0, roosterjs_editor_dom_1.getEntityFromElement)(element),
21109
- });
21311
+ var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21312
+ if (entity) {
21313
+ editor.triggerPluginEvent(15 /* EntityOperation */, {
21314
+ operation: operation,
21315
+ rawEvent: event.rawEvent,
21316
+ entity: entity,
21317
+ });
21318
+ }
21110
21319
  }
21111
21320
  return element;
21112
21321
  }
@@ -21122,20 +21331,23 @@ var EnterBeforeReadonlyEntityFeature = {
21122
21331
  return cacheGetNeighborEntityElement(event, editor, true /*isNext*/, false /*collapseOnly*/);
21123
21332
  },
21124
21333
  handleEvent: function (event, editor) {
21125
- var _a;
21334
+ var _a, _b, _c;
21126
21335
  event.rawEvent.preventDefault();
21127
21336
  var range = editor.getSelectionRange();
21337
+ if (!range) {
21338
+ return;
21339
+ }
21128
21340
  var node = roosterjs_editor_dom_1.Position.getEnd(range).normalize().node;
21129
21341
  var br = editor.getDocument().createElement('BR');
21130
- node.parentNode.insertBefore(br, node.nextSibling);
21342
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, node.nextSibling);
21131
21343
  var block = editor.getBlockElementAtNode(node);
21132
21344
  var newContainer;
21133
21345
  if (block) {
21134
21346
  newContainer = block.collapseToSingleElement();
21135
- (_a = br.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(br);
21347
+ (_b = br.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(br);
21136
21348
  }
21137
- editor.getSelectionRange().deleteContents();
21138
- if (newContainer.nextSibling) {
21349
+ (_c = editor.getSelectionRange()) === null || _c === void 0 ? void 0 : _c.deleteContents();
21350
+ if (newContainer === null || newContainer === void 0 ? void 0 : newContainer.nextSibling) {
21139
21351
  editor.select(newContainer.nextSibling, 0 /* Begin */);
21140
21352
  }
21141
21353
  },
@@ -21188,7 +21400,7 @@ function cacheGetNeighborEntityElement(event, editor, isNext, collapseOnly, oper
21188
21400
  var node = sibling && sibling.getContainerNode();
21189
21401
  if (!collapseOnly) {
21190
21402
  var block = editor.getBlockElementAtNode(pos.node);
21191
- if (!block || !block.contains(node)) {
21403
+ if (!block || (node && !block.contains(node))) {
21192
21404
  node = null;
21193
21405
  }
21194
21406
  }
@@ -21197,14 +21409,205 @@ function cacheGetNeighborEntityElement(event, editor, isNext, collapseOnly, oper
21197
21409
  return entityNode;
21198
21410
  });
21199
21411
  if (element && operation !== undefined) {
21200
- editor.triggerPluginEvent(15 /* EntityOperation */, {
21201
- operation: operation,
21202
- rawEvent: event.rawEvent,
21203
- entity: (0, roosterjs_editor_dom_1.getEntityFromElement)(element),
21204
- });
21412
+ var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21413
+ if (entity) {
21414
+ triggerOperation(entity, editor, operation, event);
21415
+ }
21205
21416
  }
21206
21417
  return element;
21207
21418
  }
21419
+ /**
21420
+ * @requires ExperimentalFeatures.InlineEntityReadOnlyDelimiters to be enabled
21421
+ * Content edit feature to move the cursor from Delimiters around Entities when using Right or Left Arrow Keys
21422
+ */
21423
+ var MoveBetweenDelimitersFeature = {
21424
+ keys: [39 /* RIGHT */, 37 /* LEFT */],
21425
+ shouldHandleEvent: function (event, editor) {
21426
+ if (!editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21427
+ return false;
21428
+ }
21429
+ var element = editor.getElementAtCursor();
21430
+ if (!element) {
21431
+ return false;
21432
+ }
21433
+ var isRTL = (0, roosterjs_editor_dom_1.getComputedStyle)(element, 'direction') === 'rtl';
21434
+ var shouldCheckBefore = isRTL == (event.rawEvent.which === 37 /* LEFT */);
21435
+ return getIsDelimiterAtCursor(event, editor, shouldCheckBefore);
21436
+ },
21437
+ handleEvent: function (event, editor) {
21438
+ var checkBefore = cacheGetCheckBefore(event);
21439
+ var delimiter = cacheDelimiter(event, checkBefore);
21440
+ if (!delimiter) {
21441
+ return;
21442
+ }
21443
+ var _a = getRelatedElements(delimiter, checkBefore), delimiterPair = _a.delimiterPair, entity = _a.entity;
21444
+ if (delimiterPair && entity && (0, roosterjs_editor_dom_1.matchesSelector)(entity, (0, roosterjs_editor_dom_1.getEntitySelector)())) {
21445
+ event.rawEvent.preventDefault();
21446
+ editor.runAsync(function () {
21447
+ var positionType = checkBefore
21448
+ ? event.rawEvent.shiftKey
21449
+ ? -3 /* After */
21450
+ : -1 /* End */
21451
+ : -2 /* Before */;
21452
+ var position = new roosterjs_editor_dom_1.Position(delimiterPair, positionType);
21453
+ if (event.rawEvent.shiftKey) {
21454
+ var selection = delimiterPair.ownerDocument.getSelection();
21455
+ selection === null || selection === void 0 ? void 0 : selection.extend(position.node, position.offset);
21456
+ }
21457
+ else {
21458
+ editor.select(position);
21459
+ }
21460
+ });
21461
+ }
21462
+ },
21463
+ };
21464
+ /**
21465
+ * @requires ExperimentalFeatures.InlineEntityReadOnlyDelimiters to be enabled
21466
+ * Content edit Feature to trigger a Delete Entity Operation when one of the Delimiter is about to be removed with DELETE or Backspace
21467
+ */
21468
+ var RemoveEntityBetweenDelimitersFeature = {
21469
+ keys: [8 /* BACKSPACE */, 46 /* DELETE */],
21470
+ shouldHandleEvent: function (event, editor) {
21471
+ if (!editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21472
+ return false;
21473
+ }
21474
+ var range = editor.getSelectionRange();
21475
+ if (!(range === null || range === void 0 ? void 0 : range.collapsed)) {
21476
+ return false;
21477
+ }
21478
+ var checkBefore = event.rawEvent.which === 46 /* DELETE */;
21479
+ var isDelimiter = getIsDelimiterAtCursor(event, editor, checkBefore);
21480
+ if (isDelimiter) {
21481
+ var delimiter = cacheDelimiter(event, checkBefore);
21482
+ var entityElement = checkBefore
21483
+ ? delimiter === null || delimiter === void 0 ? void 0 : delimiter.nextElementSibling
21484
+ : delimiter === null || delimiter === void 0 ? void 0 : delimiter.previousElementSibling;
21485
+ return !!cacheEntityBetweenDelimiter(event, editor, checkBefore, entityElement);
21486
+ }
21487
+ return false;
21488
+ },
21489
+ handleEvent: function (event, editor) {
21490
+ var checkBefore = event.rawEvent.which === 46 /* DELETE */;
21491
+ cacheEntityBetweenDelimiter(event, editor, checkBefore, null, checkBefore ? 4 /* RemoveFromStart */ : 5 /* RemoveFromEnd */);
21492
+ },
21493
+ };
21494
+ function getIsDelimiterAtCursor(event, editor, checkBefore) {
21495
+ var _a;
21496
+ var position = (_a = editor.getFocusedPosition()) === null || _a === void 0 ? void 0 : _a.normalize();
21497
+ cacheGetCheckBefore(event, checkBefore);
21498
+ if (!position) {
21499
+ return false;
21500
+ }
21501
+ var focusedElement = position.node.nodeType == 3 /* Text */
21502
+ ? position.node
21503
+ : position.node == position.element
21504
+ ? position.element.childNodes.item(position.offset)
21505
+ : position.element;
21506
+ var searcher = editor.getContentSearcherOfCursor(event);
21507
+ var data = checkBefore
21508
+ ? {
21509
+ class: "entityDelimiterBefore" /* DELIMITER_BEFORE */,
21510
+ pairClass: "entityDelimiterAfter" /* DELIMITER_AFTER */,
21511
+ getDelimiterPair: function (element) { var _a; return (_a = element.nextElementSibling) === null || _a === void 0 ? void 0 : _a.nextElementSibling; },
21512
+ getNextSibling: function () {
21513
+ var _a;
21514
+ return (_a = searcher === null || searcher === void 0 ? void 0 : searcher.getInlineElementAfter()) === null || _a === void 0 ? void 0 : _a.getContainerNode();
21515
+ },
21516
+ isAtEndOrBeginning: position.isAtEnd,
21517
+ }
21518
+ : {
21519
+ class: "entityDelimiterAfter" /* DELIMITER_AFTER */,
21520
+ pairClass: "entityDelimiterBefore" /* DELIMITER_BEFORE */,
21521
+ getDelimiterPair: function (element) { var _a; return (_a = element.previousElementSibling) === null || _a === void 0 ? void 0 : _a.previousElementSibling; },
21522
+ getNextSibling: function () {
21523
+ var _a;
21524
+ return (_a = searcher === null || searcher === void 0 ? void 0 : searcher.getInlineElementBefore()) === null || _a === void 0 ? void 0 : _a.getContainerNode();
21525
+ },
21526
+ isAtEndOrBeginning: position.offset == 0,
21527
+ };
21528
+ var sibling = data.getNextSibling();
21529
+ if (data.isAtEndOrBeginning && sibling) {
21530
+ var elAtCursor = editor.getElementAtCursor('.' + data.class, sibling);
21531
+ if (elAtCursor && !!shouldHandle(elAtCursor)) {
21532
+ return true;
21533
+ }
21534
+ }
21535
+ var entityAtCursor = editor.getElementAtCursor('.' + data.class, focusedElement);
21536
+ return !!shouldHandle(entityAtCursor);
21537
+ function shouldHandle(element) {
21538
+ var _a;
21539
+ return (element &&
21540
+ (((_a = data.getDelimiterPair(element)) === null || _a === void 0 ? void 0 : _a.className) || '').indexOf(data.pairClass) > -1 &&
21541
+ cacheDelimiter(event, checkBefore, element));
21542
+ }
21543
+ }
21544
+ function cacheDelimiter(event, checkBefore, delimiter) {
21545
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'delimiter_cache_key_' + checkBefore, function () { return delimiter; });
21546
+ }
21547
+ function cacheEntityBetweenDelimiter(event, editor, checkBefore, entity, operation) {
21548
+ var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'entity_delimiter_cache_key_' + checkBefore, function () { return entity && editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), entity); });
21549
+ if (element && operation !== undefined) {
21550
+ var entity_1 = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21551
+ if (entity_1) {
21552
+ triggerOperation(entity_1, editor, operation, event);
21553
+ }
21554
+ }
21555
+ return element;
21556
+ }
21557
+ function triggerOperation(entity, editor, operation, event) {
21558
+ var _a = entity.wrapper, nextElementSibling = _a.nextElementSibling, previousElementSibling = _a.previousElementSibling;
21559
+ editor.triggerPluginEvent(15 /* EntityOperation */, {
21560
+ operation: operation,
21561
+ rawEvent: event.rawEvent,
21562
+ entity: entity,
21563
+ });
21564
+ if (entity.isReadonly &&
21565
+ !(0, roosterjs_editor_dom_1.isBlockElement)(entity.wrapper) &&
21566
+ editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21567
+ if (event.rawEvent.defaultPrevented) {
21568
+ editor.runAsync(function () {
21569
+ if (!editor.contains(entity.wrapper)) {
21570
+ removeDelimiters(nextElementSibling, previousElementSibling);
21571
+ }
21572
+ else {
21573
+ var delimiterAfter = (0, roosterjs_editor_dom_1.addDelimiters)(entity.wrapper)[0];
21574
+ if (delimiterAfter) {
21575
+ editor.select(delimiterAfter, -3 /* After */);
21576
+ }
21577
+ }
21578
+ });
21579
+ }
21580
+ else if ((0, roosterjs_editor_dom_1.getDelimiterFromElement)(nextElementSibling) &&
21581
+ (0, roosterjs_editor_dom_1.getDelimiterFromElement)(previousElementSibling)) {
21582
+ editor.select((0, roosterjs_editor_dom_1.createRange)(previousElementSibling, nextElementSibling));
21583
+ }
21584
+ }
21585
+ }
21586
+ function removeDelimiters(nextElementSibling, previousElementSibling) {
21587
+ [nextElementSibling, previousElementSibling].forEach(function (sibling) {
21588
+ var _a;
21589
+ if ((0, roosterjs_editor_dom_1.getDelimiterFromElement)(sibling)) {
21590
+ (_a = sibling === null || sibling === void 0 ? void 0 : sibling.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(sibling);
21591
+ }
21592
+ });
21593
+ }
21594
+ function cacheGetCheckBefore(event, checkBefore) {
21595
+ return !!(0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'Check_Before', function () { return checkBefore; });
21596
+ }
21597
+ function getRelatedElements(delimiter, checkBefore) {
21598
+ var _a, _b;
21599
+ var entity;
21600
+ var delimiterPair;
21601
+ if (checkBefore) {
21602
+ entity = delimiter.nextElementSibling;
21603
+ delimiterPair = (_a = entity === null || entity === void 0 ? void 0 : entity.nextElementSibling) !== null && _a !== void 0 ? _a : null;
21604
+ }
21605
+ else {
21606
+ entity = delimiter.previousElementSibling;
21607
+ delimiterPair = (_b = entity === null || entity === void 0 ? void 0 : entity.previousElementSibling) !== null && _b !== void 0 ? _b : null;
21608
+ }
21609
+ return { entity: entity, delimiterPair: delimiterPair };
21610
+ }
21208
21611
  /**
21209
21612
  * @internal
21210
21613
  */
@@ -21214,6 +21617,8 @@ exports.EntityFeatures = {
21214
21617
  enterBeforeReadonlyEntity: EnterBeforeReadonlyEntityFeature,
21215
21618
  backspaceAfterEntity: BackspaceAfterEntityFeature,
21216
21619
  deleteBeforeEntity: DeleteBeforeEntityFeature,
21620
+ moveBetweenDelimitersFeature: MoveBetweenDelimitersFeature,
21621
+ removeEntityBetweenDelimiters: RemoveEntityBetweenDelimitersFeature,
21217
21622
  };
21218
21623
 
21219
21624
 
@@ -21291,9 +21696,11 @@ var MergeInNewLine = {
21291
21696
  if (li.previousSibling) {
21292
21697
  (0, roosterjs_editor_api_1.blockFormat)(editor, function (region, start, end) {
21293
21698
  var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li);
21294
- vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
21295
- vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
21296
- event.rawEvent.preventDefault();
21699
+ if (vList) {
21700
+ vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
21701
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
21702
+ event.rawEvent.preventDefault();
21703
+ }
21297
21704
  });
21298
21705
  }
21299
21706
  else {
@@ -22101,7 +22508,8 @@ var TabInTable = {
22101
22508
  }
22102
22509
  var cell = vtable.getCell(row, col);
22103
22510
  if (cell.td) {
22104
- editor.select(cell.td, 0 /* Begin */);
22511
+ var newPos = new roosterjs_editor_dom_1.Position(cell.td, 0 /* Begin */).normalize();
22512
+ editor.select(newPos);
22105
22513
  break;
22106
22514
  }
22107
22515
  }
@@ -22178,7 +22586,7 @@ var UpDownInTable = {
22178
22586
  selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
22179
22587
  }
22180
22588
  else {
22181
- editor.select(newPos);
22589
+ editor.select(newPos.normalize());
22182
22590
  }
22183
22591
  }
22184
22592
  });
@@ -25775,6 +26183,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
25775
26183
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
25776
26184
  var HTTP = 'http:';
25777
26185
  var HTTPS = 'https:';
26186
+ var NOTES = 'notes:';
25778
26187
  /**
25779
26188
  * @internal
25780
26189
  * Clear local paths and remove link
@@ -25792,7 +26201,10 @@ function validateLink(link, htmlElement) {
25792
26201
  catch (_a) {
25793
26202
  url = undefined;
25794
26203
  }
25795
- if (url && (url.protocol === HTTP || url.protocol === HTTPS)) {
26204
+ if (url &&
26205
+ (url.protocol === HTTP ||
26206
+ url.protocol === HTTPS ||
26207
+ url.protocol === NOTES) /* whitelist Notes protocol */) {
25796
26208
  return link;
25797
26209
  }
25798
26210
  htmlElement.removeAttribute('href');
@@ -30040,6 +30452,8 @@ exports.CompatibleExperimentalFeatures = void 0;
30040
30452
  */
30041
30453
  var CompatibleExperimentalFeatures;
30042
30454
  (function (CompatibleExperimentalFeatures) {
30455
+ // #region Graduated and deprecated features.
30456
+ // These features will be removed in next major release
30043
30457
  /**
30044
30458
  * @deprecated This feature is always enabled
30045
30459
  */
@@ -30091,23 +30505,11 @@ var CompatibleExperimentalFeatures;
30091
30505
  * Align table elements to left, center and right using setAlignment API
30092
30506
  */
30093
30507
  CompatibleExperimentalFeatures["TableAlignment"] = "TableAlignment";
30094
- /**
30095
- * Provide additional Tab Key Features. Requires Text Features Content Editable Features
30096
- */
30097
- CompatibleExperimentalFeatures["TabKeyTextFeatures"] = "TabKeyTextFeatures";
30098
30508
  /**
30099
30509
  * @deprecated this feature is always enabled
30100
30510
  * Provide a circular resize handles that adaptive the number od handles to the size of the image
30101
30511
  */
30102
30512
  CompatibleExperimentalFeatures["AdaptiveHandlesResizer"] = "AdaptiveHandlesResizer";
30103
- /**
30104
- * Align list elements elements to left, center and right using setAlignment API
30105
- */
30106
- CompatibleExperimentalFeatures["ListItemAlignment"] = "ListItemAlignment";
30107
- /**
30108
- * Trigger formatting by a especial characters. Ex: (A), 1. i).
30109
- */
30110
- CompatibleExperimentalFeatures["AutoFormatList"] = "AutoFormatList";
30111
30513
  /**
30112
30514
  * @deprecated this feature is always disabled
30113
30515
  * Automatically transform -- into hyphen, if typed between two words.
@@ -30131,6 +30533,19 @@ var CompatibleExperimentalFeatures;
30131
30533
  * When a html image is selected, the selected image data will be stored by editor core.
30132
30534
  */
30133
30535
  CompatibleExperimentalFeatures["ImageSelection"] = "ImageSelection";
30536
+ //#endregion
30537
+ /**
30538
+ * Provide additional Tab Key Features. Requires Text Features Content Editable Features
30539
+ */
30540
+ CompatibleExperimentalFeatures["TabKeyTextFeatures"] = "TabKeyTextFeatures";
30541
+ /**
30542
+ * Align list elements elements to left, center and right using setAlignment API
30543
+ */
30544
+ CompatibleExperimentalFeatures["ListItemAlignment"] = "ListItemAlignment";
30545
+ /**
30546
+ * Trigger formatting by a especial characters. Ex: (A), 1. i).
30547
+ */
30548
+ CompatibleExperimentalFeatures["AutoFormatList"] = "AutoFormatList";
30134
30549
  /**
30135
30550
  * With this feature enabled, when writing back a list item we will re-use all
30136
30551
  * ancestor list elements, even if they don't match the types currently in the
@@ -30149,6 +30564,10 @@ var CompatibleExperimentalFeatures;
30149
30564
  * if you need them work for dark mode
30150
30565
  */
30151
30566
  CompatibleExperimentalFeatures["VariableBasedDarkColor"] = "VariableBasedDarkColor";
30567
+ /**
30568
+ * Reuse existing DOM structure if possible when convert Content Model back to DOM tree
30569
+ */
30570
+ CompatibleExperimentalFeatures["ReusableContentModel"] = "ReusableContentModel";
30152
30571
  /**
30153
30572
  * Delete table with Backspace key with the whole was selected with table selector
30154
30573
  */