roosterjs 8.43.0 → 8.44.1

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