roosterjs 8.44.2 → 8.45.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.
@@ -2213,6 +2213,9 @@ function changeCapitalization(editor, capitalization, language) {
2213
2213
  }
2214
2214
  }, 'changeCapitalization');
2215
2215
  function getCapitalizedText(originalText, language) {
2216
+ if (originalText === null) {
2217
+ return originalText;
2218
+ }
2216
2219
  switch (capitalization) {
2217
2220
  case "lowercase" /* Lowercase */:
2218
2221
  return originalText.toLocaleLowerCase(language);
@@ -2237,6 +2240,8 @@ function changeCapitalization(editor, capitalization, language) {
2237
2240
  return originalText.toLocaleLowerCase(language).replace(regex, function (match) {
2238
2241
  return match.toLocaleUpperCase(language);
2239
2242
  });
2243
+ default:
2244
+ return originalText;
2240
2245
  }
2241
2246
  }
2242
2247
  }
@@ -2380,11 +2385,11 @@ var TAGS_TO_STOP_UNWRAP = ['TD', 'TH', 'TR', 'TABLE', 'TBODY', 'THEAD'];
2380
2385
  */
2381
2386
  function isMultiBlockSelection(editor) {
2382
2387
  var transverser = editor.getSelectionTraverser();
2383
- var blockElement = transverser.currentBlockElement;
2388
+ var blockElement = transverser === null || transverser === void 0 ? void 0 : transverser.currentBlockElement;
2384
2389
  if (!blockElement) {
2385
2390
  return false;
2386
2391
  }
2387
- var nextBlockElement = transverser.getNextBlockElement();
2392
+ var nextBlockElement = transverser === null || transverser === void 0 ? void 0 : transverser.getNextBlockElement();
2388
2393
  //At least two blocks are selected
2389
2394
  return !!nextBlockElement;
2390
2395
  }
@@ -2467,7 +2472,8 @@ function isNodeWholeBlock(node, editor) {
2467
2472
  }
2468
2473
  var isOnlySiblingWithContent_1 = true;
2469
2474
  (_a = currentNode.parentNode) === null || _a === void 0 ? void 0 : _a.childNodes.forEach(function (node) {
2470
- if (node != currentNode && node.textContent.length) {
2475
+ var _a;
2476
+ if (node != currentNode && ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length)) {
2471
2477
  isOnlySiblingWithContent_1 = false;
2472
2478
  }
2473
2479
  });
@@ -2492,7 +2498,7 @@ function clearAutoDetectFormat(editor) {
2492
2498
  var isMultiBlock = isMultiBlockSelection(editor);
2493
2499
  if (!isMultiBlock) {
2494
2500
  var transverser = editor.getSelectionTraverser();
2495
- var inlineElement = transverser.currentInlineElement;
2501
+ var inlineElement = transverser === null || transverser === void 0 ? void 0 : transverser.currentInlineElement;
2496
2502
  var isPartial = inlineElement instanceof roosterjs_editor_dom_1.PartialInlineElement ||
2497
2503
  (inlineElement instanceof roosterjs_editor_dom_1.NodeInlineElement &&
2498
2504
  !isNodeWholeBlock(inlineElement.getContainerNode(), editor));
@@ -2522,8 +2528,11 @@ function clearBlockFormat(editor) {
2522
2528
  (0, roosterjs_editor_dom_1.setStyles)(wrapper, nonborderStyles);
2523
2529
  }
2524
2530
  }
2525
- while (nodes.length > 0 && (0, roosterjs_editor_dom_1.isNodeInRegion)(region, nodes[0].parentNode)) {
2526
- nodes = [(0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes)];
2531
+ while (nodes.length > 0 &&
2532
+ nodes[0].parentNode &&
2533
+ (0, roosterjs_editor_dom_1.isNodeInRegion)(region, nodes[0].parentNode)) {
2534
+ var balancedNodes = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes);
2535
+ nodes = balancedNodes ? [balancedNodes] : [];
2527
2536
  }
2528
2537
  nodes.forEach(clearNodeFormat);
2529
2538
  });
@@ -2575,7 +2584,7 @@ function setDefaultFormat(editor) {
2575
2584
  var setColorIgnoredElements_1 = editor.queryElements('a *, a', 1 /* OnSelection */);
2576
2585
  var shouldApplyInlineStyle = setColorIgnoredElements_1.length > 0
2577
2586
  ? function (element) { return setColorIgnoredElements_1.indexOf(element) == -1; }
2578
- : null;
2587
+ : undefined;
2579
2588
  if (defaultFormat.textColors) {
2580
2589
  (0, setTextColor_1.default)(editor, defaultFormat.textColors, shouldApplyInlineStyle);
2581
2590
  }
@@ -2732,12 +2741,12 @@ function createLink(editor, link, altText, displayText, target) {
2732
2741
  .getDocument()
2733
2742
  .execCommand("createLink" /* CreateLink */, false, normalizedUrl_1);
2734
2743
  var traverser = editor.getSelectionTraverser();
2735
- var currentInline = traverser.getNextInlineElement();
2744
+ var currentInline = traverser === null || traverser === void 0 ? void 0 : traverser.getNextInlineElement();
2736
2745
  // list for removing unwanted lines
2737
2746
  var deletionInlineList = [];
2738
2747
  while (currentInline) {
2739
2748
  deletionInlineList.push(currentInline.getContainerNode());
2740
- currentInline = traverser.getNextInlineElement();
2749
+ currentInline = traverser === null || traverser === void 0 ? void 0 : traverser.getNextInlineElement();
2741
2750
  }
2742
2751
  deletionInlineList.forEach(function (node) { return editor.deleteNode(node); });
2743
2752
  anchor = getAnchorNodeAtCursor(editor);
@@ -2820,7 +2829,7 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
2820
2829
  * @returns An ElementBasedFormatState object
2821
2830
  */
2822
2831
  function getElementBasedFormatState(editor, event) {
2823
- var listTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('OL,UL', null /*startFrom*/, event));
2832
+ var listTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('OL,UL', undefined /*startFrom*/, event));
2824
2833
  // Check if selection is multiline, spans more than one block
2825
2834
  var range = editor.getSelectionRange();
2826
2835
  var multiline = false;
@@ -2829,7 +2838,7 @@ function getElementBasedFormatState(editor, event) {
2829
2838
  var endingBlock = editor.getBlockElementAtNode(range.endContainer);
2830
2839
  multiline = endingBlock && startingBlock ? !endingBlock.equals(startingBlock) : false;
2831
2840
  }
2832
- var headerTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('H1,H2,H3,H4,H5,H6', null /*startFrom*/, event));
2841
+ var headerTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('H1,H2,H3,H4,H5,H6', undefined /*startFrom*/, event));
2833
2842
  var table = editor.queryElements('table', 1 /* OnSelection */)[0];
2834
2843
  var tableFormat = table ? (0, roosterjs_editor_dom_1.getTableFormatInfo)(table) : undefined;
2835
2844
  var hasHeader = (table === null || table === void 0 ? void 0 : table.rows[0])
@@ -2846,7 +2855,7 @@ function getElementBasedFormatState(editor, event) {
2846
2855
  isCodeInline: !!editor.queryElements('code', 1 /* OnSelection */)[0],
2847
2856
  isCodeBlock: !!editor.queryElements('pre>code', 1 /* OnSelection */)[0],
2848
2857
  isInTable: !!table,
2849
- tableFormat: tableFormat,
2858
+ tableFormat: tableFormat || {},
2850
2859
  tableHasHeader: hasHeader,
2851
2860
  canMergeTableCell: canMergeTableCell(editor),
2852
2861
  };
@@ -2912,6 +2921,7 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
2912
2921
  * Parent nodes will be split if need
2913
2922
  */
2914
2923
  function insertEntity(editor, type, contentNode, isBlock, isReadonly, position, insertToRegionRoot) {
2924
+ var _a;
2915
2925
  var wrapper = (0, roosterjs_editor_dom_1.wrap)(contentNode, isBlock ? 'DIV' : 'SPAN');
2916
2926
  // For inline & readonly entity, we need to set display to "inline-block" otherwise
2917
2927
  // there will be some weird behavior when move cursor around the entity node.
@@ -2924,7 +2934,7 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2924
2934
  }
2925
2935
  (0, roosterjs_editor_dom_1.commitEntity)(wrapper, type, isReadonly);
2926
2936
  if (!editor.contains(wrapper)) {
2927
- var currentRange = void 0;
2937
+ var currentRange = null;
2928
2938
  var contentPosition = void 0;
2929
2939
  if (typeof position == 'number') {
2930
2940
  contentPosition = position;
@@ -2969,7 +2979,7 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2969
2979
  // Insert an extra empty line for block entity to make sure
2970
2980
  // user can still put cursor below the entity.
2971
2981
  var br = editor.getDocument().createElement('BR');
2972
- wrapper.parentNode.insertBefore(br, wrapper.nextSibling);
2982
+ (_a = wrapper.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, wrapper.nextSibling);
2973
2983
  }
2974
2984
  var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(wrapper);
2975
2985
  if (!isBlock &&
@@ -3057,7 +3067,9 @@ function removeLink(editor) {
3057
3067
  editor.focus();
3058
3068
  (0, formatUndoSnapshot_1.default)(editor, function (start, end) {
3059
3069
  editor.queryElements('a[href]', 1 /* OnSelection */, roosterjs_editor_dom_1.unwrap);
3060
- editor.select(start, end);
3070
+ if (start && end) {
3071
+ editor.select(start, end);
3072
+ }
3061
3073
  }, 'removeLink');
3062
3074
  }
3063
3075
  exports.default = removeLink;
@@ -3076,14 +3088,15 @@ exports.default = removeLink;
3076
3088
 
3077
3089
  Object.defineProperty(exports, "__esModule", { value: true });
3078
3090
  function replaceWithNode(editor, textOrRange, node, exactMatch, searcher) {
3091
+ var _a, _b;
3079
3092
  // Make sure the text and node is valid
3080
3093
  if (!textOrRange || !node) {
3081
3094
  return false;
3082
3095
  }
3083
3096
  var range;
3084
3097
  if (typeof textOrRange == 'string') {
3085
- searcher = searcher || editor.getContentSearcherOfCursor();
3086
- range = searcher && searcher.getRangeFromText(textOrRange, exactMatch);
3098
+ searcher = (_a = (searcher || editor.getContentSearcherOfCursor())) !== null && _a !== void 0 ? _a : undefined;
3099
+ range = (_b = searcher === null || searcher === void 0 ? void 0 : searcher.getRangeFromText(textOrRange, exactMatch)) !== null && _b !== void 0 ? _b : null;
3087
3100
  }
3088
3101
  else {
3089
3102
  range = textOrRange;
@@ -3091,7 +3104,7 @@ function replaceWithNode(editor, textOrRange, node, exactMatch, searcher) {
3091
3104
  if (range) {
3092
3105
  var backupRange = editor.getSelectionRange();
3093
3106
  // If the range to replace is right before current cursor, it is actually an exact match
3094
- if (backupRange.collapsed &&
3107
+ if ((backupRange === null || backupRange === void 0 ? void 0 : backupRange.collapsed) &&
3095
3108
  range.endContainer == backupRange.startContainer &&
3096
3109
  range.endOffset == backupRange.startOffset) {
3097
3110
  exactMatch = true;
@@ -3168,10 +3181,12 @@ function setAlignment(editor, alignment) {
3168
3181
  var isATable = selection && selection.type === 1 /* TableSelection */;
3169
3182
  var elementAtCursor = editor.getElementAtCursor();
3170
3183
  if (isATable &&
3184
+ selection.coordinates &&
3171
3185
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3172
3186
  alignTable(selection, alignment);
3173
3187
  }
3174
- else if (isList(elementAtCursor) &&
3188
+ else if (elementAtCursor &&
3189
+ isList(elementAtCursor) &&
3175
3190
  editor.isFeatureEnabled("ListItemAlignment" /* ListItemAlignment */)) {
3176
3191
  alignList(editor, alignment);
3177
3192
  }
@@ -3228,7 +3243,9 @@ function alignText(editor, alignment) {
3228
3243
  });
3229
3244
  if (elements.length == 0) {
3230
3245
  var node = editor.getElementAtCursor();
3231
- (0, normalizeBlockquote_1.default)(node);
3246
+ if (node) {
3247
+ (0, normalizeBlockquote_1.default)(node);
3248
+ }
3232
3249
  }
3233
3250
  }
3234
3251
  function isList(element) {
@@ -3239,7 +3256,9 @@ function alignList(editor, alignment) {
3239
3256
  var blocks = (0, roosterjs_editor_dom_1.getSelectedBlockElementsInRegion)(region, undefined /* createBlockIfEmpty */, editor.isFeatureEnabled("DefaultFormatInSpan" /* DefaultFormatInSpan */));
3240
3257
  var startNode = blocks[0].getStartNode();
3241
3258
  var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, true /*includeSiblingLists*/, startNode);
3242
- vList.setAlignment(start, end, alignment);
3259
+ if (start && end) {
3260
+ vList === null || vList === void 0 ? void 0 : vList.setAlignment(start, end, alignment);
3261
+ }
3243
3262
  }, undefined /* beforeRunCallback */, 'alignList');
3244
3263
  }
3245
3264
 
@@ -3303,7 +3322,9 @@ function setDirection(editor, direction) {
3303
3322
  element.setAttribute('dir', direction == 0 /* LeftToRight */ ? 'ltr' : 'rtl');
3304
3323
  element.style.textAlign = direction == 0 /* LeftToRight */ ? 'left' : 'right';
3305
3324
  });
3306
- editor.select(start, end);
3325
+ if (start && end) {
3326
+ editor.select(start, end);
3327
+ }
3307
3328
  }, 'setDirection');
3308
3329
  }
3309
3330
  exports.default = setDirection;
@@ -3445,14 +3466,18 @@ function setIndentation(editor, indentation) {
3445
3466
  isFirstItem(vList, startNode) &&
3446
3467
  shouldHandleWithBlockquotes(indentation, editor, startNode)) {
3447
3468
  var block = editor.getBlockElementAtNode(vList.rootList);
3448
- blockGroups.push([block]);
3469
+ if (block) {
3470
+ blockGroups.push([block]);
3471
+ }
3449
3472
  }
3450
3473
  else {
3451
- indentation == 1 /* Decrease */
3452
- ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3453
- : vList.setIndentation(start, end, indentation);
3454
- vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
3455
- blockGroups.push([]);
3474
+ if (start && end) {
3475
+ indentation == 1 /* Decrease */
3476
+ ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3477
+ : vList.setIndentation(start, end, indentation);
3478
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
3479
+ blockGroups.push([]);
3480
+ }
3456
3481
  }
3457
3482
  }
3458
3483
  else {
@@ -3463,10 +3488,13 @@ function setIndentation(editor, indentation) {
3463
3488
  }, function () {
3464
3489
  var selection = editor.getSelectionRangeEx();
3465
3490
  if (selection.type == 1 /* TableSelection */ &&
3491
+ selection.coordinates &&
3466
3492
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3467
3493
  if (indentation == 1 /* Decrease */) {
3468
3494
  var quote = editor.getElementAtCursor('blockquote', selection.table);
3469
- (0, roosterjs_editor_dom_1.unwrap)(quote);
3495
+ if (quote) {
3496
+ (0, roosterjs_editor_dom_1.unwrap)(quote);
3497
+ }
3470
3498
  }
3471
3499
  else if (indentation == 0 /* Increase */) {
3472
3500
  (0, roosterjs_editor_dom_1.wrap)(selection.table, 2 /* BlockquoteWrapper */);
@@ -3707,7 +3735,9 @@ function toggleCodeBlock(editor, styler) {
3707
3735
  if (!code.previousSibling && !code.nextSibling) {
3708
3736
  var parent_1 = code.parentNode;
3709
3737
  (0, roosterjs_editor_dom_1.unwrap)(code);
3710
- (0, roosterjs_editor_dom_1.unwrap)(parent_1);
3738
+ if (parent_1) {
3739
+ (0, roosterjs_editor_dom_1.unwrap)(parent_1);
3740
+ }
3711
3741
  }
3712
3742
  }).length == 0;
3713
3743
  }, 'toggleCodeBlock');
@@ -3752,7 +3782,7 @@ function toggleHeader(editor, level) {
3752
3782
  });
3753
3783
  if (level > 0) {
3754
3784
  var traverser = editor.getSelectionTraverser();
3755
- var blockElement = traverser ? traverser.currentBlockElement : null;
3785
+ var blockElement = traverser === null || traverser === void 0 ? void 0 : traverser.currentBlockElement;
3756
3786
  var sanitizer = new roosterjs_editor_dom_1.HtmlSanitizer({
3757
3787
  cssStyleCallbacks: {
3758
3788
  'font-size': function () { return false; },
@@ -3761,7 +3791,7 @@ function toggleHeader(editor, level) {
3761
3791
  while (blockElement) {
3762
3792
  var element = blockElement.collapseToSingleElement();
3763
3793
  sanitizer.sanitize(element);
3764
- blockElement = traverser.getNextBlockElement();
3794
+ blockElement = traverser === null || traverser === void 0 ? void 0 : traverser.getNextBlockElement();
3765
3795
  }
3766
3796
  editor.getDocument().execCommand("formatBlock" /* FormatBlock */, false, "<H" + level + ">");
3767
3797
  }
@@ -4954,6 +4984,7 @@ var getStyleBasedFormatState_1 = __webpack_require__(/*! ./getStyleBasedFormatSt
4954
4984
  var hasFocus_1 = __webpack_require__(/*! ./hasFocus */ "./packages/roosterjs-editor-core/lib/coreApi/hasFocus.ts");
4955
4985
  var insertNode_1 = __webpack_require__(/*! ./insertNode */ "./packages/roosterjs-editor-core/lib/coreApi/insertNode.ts");
4956
4986
  var restoreUndoSnapshot_1 = __webpack_require__(/*! ./restoreUndoSnapshot */ "./packages/roosterjs-editor-core/lib/coreApi/restoreUndoSnapshot.ts");
4987
+ var select_1 = __webpack_require__(/*! ./select */ "./packages/roosterjs-editor-core/lib/coreApi/select.ts");
4957
4988
  var selectImage_1 = __webpack_require__(/*! ./selectImage */ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts");
4958
4989
  var selectRange_1 = __webpack_require__(/*! ./selectRange */ "./packages/roosterjs-editor-core/lib/coreApi/selectRange.ts");
4959
4990
  var selectTable_1 = __webpack_require__(/*! ./selectTable */ "./packages/roosterjs-editor-core/lib/coreApi/selectTable.ts");
@@ -4978,6 +5009,7 @@ exports.coreApiMap = {
4978
5009
  hasFocus: hasFocus_1.hasFocus,
4979
5010
  insertNode: insertNode_1.insertNode,
4980
5011
  restoreUndoSnapshot: restoreUndoSnapshot_1.restoreUndoSnapshot,
5012
+ select: select_1.select,
4981
5013
  selectRange: selectRange_1.selectRange,
4982
5014
  setContent: setContent_1.setContent,
4983
5015
  switchShadowEdit: switchShadowEdit_1.switchShadowEdit,
@@ -5017,8 +5049,9 @@ var TAB_SPACES = 6;
5017
5049
  * @param applyCurrentStyle True if apply format of current selection to the pasted content,
5018
5050
  * false to keep original format
5019
5051
  */
5020
- var createPasteFragment = function (core, clipboardData, position, pasteAsText, applyCurrentStyle) {
5052
+ var createPasteFragment = function (core, clipboardData, position, pasteAsText, applyCurrentStyle, pasteAsImage) {
5021
5053
  var _a, _b;
5054
+ if (pasteAsImage === void 0) { pasteAsImage = false; }
5022
5055
  if (!clipboardData) {
5023
5056
  return null;
5024
5057
  }
@@ -5077,7 +5110,7 @@ var createPasteFragment = function (core, clipboardData, position, pasteAsText,
5077
5110
  }
5078
5111
  }
5079
5112
  // Step 3: Fill the BeforePasteEvent object, especially the fragment for paste
5080
- if (!pasteAsText && !text && imageDataUri) {
5113
+ if ((pasteAsImage && imageDataUri) || (!pasteAsText && !text && imageDataUri)) {
5081
5114
  // Paste image
5082
5115
  var img = document.createElement('img');
5083
5116
  img.style.maxWidth = '100%';
@@ -6019,6 +6052,136 @@ var restoreUndoSnapshot = function (core, step) {
6019
6052
  exports.restoreUndoSnapshot = restoreUndoSnapshot;
6020
6053
 
6021
6054
 
6055
+ /***/ }),
6056
+
6057
+ /***/ "./packages/roosterjs-editor-core/lib/coreApi/select.ts":
6058
+ /*!**************************************************************!*\
6059
+ !*** ./packages/roosterjs-editor-core/lib/coreApi/select.ts ***!
6060
+ \**************************************************************/
6061
+ /*! no static exports found */
6062
+ /***/ (function(module, exports, __webpack_require__) {
6063
+
6064
+ "use strict";
6065
+
6066
+ Object.defineProperty(exports, "__esModule", { value: true });
6067
+ exports.select = void 0;
6068
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
6069
+ /**
6070
+ * @internal
6071
+ * Select content according to the given information.
6072
+ * There are a bunch of allowed combination of parameters. See IEditor.select for more details
6073
+ * @param core The editor core object
6074
+ * @param arg1 A DOM Range, or SelectionRangeEx, or NodePosition, or Node, or Selection Path
6075
+ * @param arg2 (optional) A NodePosition, or an offset number, or a PositionType, or a TableSelection
6076
+ * @param arg3 (optional) A Node
6077
+ * @param arg4 (optional) An offset number, or a PositionType
6078
+ */
6079
+ var select = function (core, arg1, arg2, arg3, arg4) {
6080
+ var rangeEx = null;
6081
+ if (isSelectionRangeEx(arg1)) {
6082
+ rangeEx = arg1;
6083
+ }
6084
+ else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLTableElement') && isTableSelection(arg2)) {
6085
+ rangeEx = {
6086
+ type: 1 /* TableSelection */,
6087
+ ranges: [],
6088
+ areAllCollapsed: false,
6089
+ table: arg1,
6090
+ coordinates: arg2,
6091
+ };
6092
+ }
6093
+ else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLImageElement') && typeof arg2 == 'undefined') {
6094
+ rangeEx = {
6095
+ type: 2 /* ImageSelection */,
6096
+ ranges: [],
6097
+ areAllCollapsed: false,
6098
+ image: arg1,
6099
+ };
6100
+ }
6101
+ else {
6102
+ var range = !arg1
6103
+ ? null
6104
+ : (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Range')
6105
+ ? arg1
6106
+ : isSelectionPath(arg1)
6107
+ ? (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, arg1.start, arg1.end)
6108
+ : isNodePosition(arg1) || (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Node')
6109
+ ? (0, roosterjs_editor_dom_1.createRange)(arg1, arg2, arg3, arg4)
6110
+ : null;
6111
+ rangeEx = range
6112
+ ? {
6113
+ type: 0 /* Normal */,
6114
+ ranges: [range],
6115
+ areAllCollapsed: range.collapsed,
6116
+ }
6117
+ : null;
6118
+ }
6119
+ if (rangeEx) {
6120
+ switch (rangeEx.type) {
6121
+ case 1 /* TableSelection */:
6122
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.table)) {
6123
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6124
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, rangeEx.table, rangeEx.coordinates);
6125
+ rangeEx = core.domEvent.tableSelectionRange;
6126
+ }
6127
+ break;
6128
+ case 2 /* ImageSelection */:
6129
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.image)) {
6130
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6131
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, rangeEx.image);
6132
+ rangeEx = core.domEvent.imageSelectionRange;
6133
+ }
6134
+ break;
6135
+ case 0 /* Normal */:
6136
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6137
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6138
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.ranges[0])) {
6139
+ core.api.selectRange(core, rangeEx.ranges[0]);
6140
+ }
6141
+ else {
6142
+ rangeEx = null;
6143
+ }
6144
+ break;
6145
+ }
6146
+ core.api.triggerEvent(core, {
6147
+ eventType: 22 /* SelectionChanged */,
6148
+ selectionRangeEx: rangeEx,
6149
+ }, true /** broadcast **/);
6150
+ }
6151
+ else {
6152
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6153
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6154
+ }
6155
+ return !!rangeEx;
6156
+ };
6157
+ exports.select = select;
6158
+ function isSelectionRangeEx(obj) {
6159
+ var rangeEx = obj;
6160
+ return (rangeEx &&
6161
+ typeof rangeEx == 'object' &&
6162
+ typeof rangeEx.type == 'number' &&
6163
+ Array.isArray(rangeEx.ranges));
6164
+ }
6165
+ function isTableSelection(obj) {
6166
+ var selection = obj;
6167
+ return (selection &&
6168
+ typeof selection == 'object' &&
6169
+ typeof selection.firstCell == 'object' &&
6170
+ typeof selection.lastCell == 'object');
6171
+ }
6172
+ function isSelectionPath(obj) {
6173
+ var path = obj;
6174
+ return path && typeof path == 'object' && Array.isArray(path.start) && Array.isArray(path.end);
6175
+ }
6176
+ function isNodePosition(obj) {
6177
+ var pos = obj;
6178
+ return (pos &&
6179
+ typeof pos == 'object' &&
6180
+ typeof pos.node == 'object' &&
6181
+ typeof pos.offset == 'number');
6182
+ }
6183
+
6184
+
6022
6185
  /***/ }),
6023
6186
 
6024
6187
  /***/ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts":
@@ -6253,7 +6416,7 @@ function buildCss(table, coordinates, contentDivSelector) {
6253
6416
  ranges.push(rowRange);
6254
6417
  }
6255
6418
  });
6256
- var css = selectors.join(',') + " {background-color: rgba(198,198,198,0.7) !important; caret-color: transparent}";
6419
+ var css = selectors.join(',') + " {background-color: rgb(198,198,198) !important; caret-color: transparent}";
6257
6420
  return { css: css, ranges: ranges };
6258
6421
  }
6259
6422
  function select(core, table, coordinates) {
@@ -7778,6 +7941,17 @@ exports.default = ImageSelection;
7778
7941
 
7779
7942
  "use strict";
7780
7943
 
7944
+ var __assign = (this && this.__assign) || function () {
7945
+ __assign = Object.assign || function(t) {
7946
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
7947
+ s = arguments[i];
7948
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7949
+ t[p] = s[p];
7950
+ }
7951
+ return t;
7952
+ };
7953
+ return __assign.apply(this, arguments);
7954
+ };
7781
7955
  var _a, _b;
7782
7956
  Object.defineProperty(exports, "__esModule", { value: true });
7783
7957
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
@@ -7822,12 +7996,11 @@ var LifecyclePlugin = /** @class */ (function () {
7822
7996
  */
7823
7997
  function LifecyclePlugin(options, contentDiv) {
7824
7998
  var _this = this;
7825
- var _a, _b, _c;
7999
+ var _a, _b;
7826
8000
  this.editor = null;
7827
8001
  this.initializer = null;
7828
8002
  this.disposer = null;
7829
8003
  this.initialContent = options.initialContent || contentDiv.innerHTML || '';
7830
- this.contentDivFormat = (0, roosterjs_editor_dom_1.getComputedStyles)(contentDiv);
7831
8004
  // Make the container editable and set its selection styles
7832
8005
  if (contentDiv.getAttribute(CONTENT_EDITABLE_ATTRIBUTE_NAME) === null) {
7833
8006
  this.initializer = function () {
@@ -7851,12 +8024,30 @@ var LifecyclePlugin = /** @class */ (function () {
7851
8024
  (0, roosterjs_editor_dom_1.setColor)(contentDiv, textColors, false /*isBackground*/, isDarkMode, false /*shouldAdaptFontColor*/, darkColorHandler);
7852
8025
  (0, roosterjs_editor_dom_1.setColor)(contentDiv, backgroundColors, true /*isBackground*/, isDarkMode, false /*shouldAdaptFontColor*/, darkColorHandler);
7853
8026
  };
8027
+ var getDarkColor = (_a = options.getDarkColor) !== null && _a !== void 0 ? _a : (function (color) { return color; });
8028
+ var defaultFormat = options.defaultFormat ? __assign({}, options.defaultFormat) : null;
8029
+ if (defaultFormat) {
8030
+ if (defaultFormat.textColor && !defaultFormat.textColors) {
8031
+ defaultFormat.textColors = {
8032
+ lightModeColor: defaultFormat.textColor,
8033
+ darkModeColor: getDarkColor(defaultFormat.textColor),
8034
+ };
8035
+ delete defaultFormat.textColor;
8036
+ }
8037
+ if (defaultFormat.backgroundColor && !defaultFormat.backgroundColors) {
8038
+ defaultFormat.backgroundColors = {
8039
+ lightModeColor: defaultFormat.backgroundColor,
8040
+ darkModeColor: getDarkColor(defaultFormat.backgroundColor),
8041
+ };
8042
+ delete defaultFormat.backgroundColor;
8043
+ }
8044
+ }
7854
8045
  this.state = {
7855
8046
  customData: {},
7856
- defaultFormat: (_a = options.defaultFormat) !== null && _a !== void 0 ? _a : null,
8047
+ defaultFormat: defaultFormat,
7857
8048
  isDarkMode: !!options.inDarkMode,
7858
- getDarkColor: (_b = options.getDarkColor) !== null && _b !== void 0 ? _b : (function (color) { return color; }),
7859
- onExternalContentTransform: (_c = options.onExternalContentTransform) !== null && _c !== void 0 ? _c : null,
8049
+ getDarkColor: getDarkColor,
8050
+ onExternalContentTransform: (_b = options.onExternalContentTransform) !== null && _b !== void 0 ? _b : null,
7860
8051
  experimentalFeatures: options.experimentalFeatures || [],
7861
8052
  shadowEditFragment: null,
7862
8053
  shadowEditEntities: null,
@@ -7878,8 +8069,6 @@ var LifecyclePlugin = /** @class */ (function () {
7878
8069
  LifecyclePlugin.prototype.initialize = function (editor) {
7879
8070
  var _a;
7880
8071
  this.editor = editor;
7881
- // Calculate default format
7882
- this.recalculateDefaultFormat();
7883
8072
  // Ensure initial content and its format
7884
8073
  this.editor.setContent(this.initialContent, false /*triggerContentChangedEvent*/);
7885
8074
  // Set content DIV to be editable
@@ -7927,7 +8116,6 @@ var LifecyclePlugin = /** @class */ (function () {
7927
8116
  (event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
7928
8117
  event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
7929
8118
  this.state.isDarkMode = event.source == "SwitchToDarkMode" /* SwitchToDarkMode */;
7930
- this.recalculateDefaultFormat();
7931
8119
  this.adjustColor();
7932
8120
  }
7933
8121
  };
@@ -7942,45 +8130,6 @@ var LifecyclePlugin = /** @class */ (function () {
7942
8130
  catch (_b) { }
7943
8131
  });
7944
8132
  };
7945
- LifecyclePlugin.prototype.recalculateDefaultFormat = function () {
7946
- var _a = this.state, baseFormat = _a.defaultFormat, isDarkMode = _a.isDarkMode;
7947
- if (isDarkMode && baseFormat) {
7948
- if (!baseFormat.backgroundColors) {
7949
- baseFormat.backgroundColors = DARK_MODE_DEFAULT_FORMAT.backgroundColors;
7950
- }
7951
- if (!baseFormat.textColors) {
7952
- baseFormat.textColors = DARK_MODE_DEFAULT_FORMAT.textColors;
7953
- }
7954
- }
7955
- if (baseFormat && (0, roosterjs_editor_dom_1.getObjectKeys)(baseFormat).length === 0) {
7956
- return;
7957
- }
7958
- var _b = baseFormat || {}, fontFamily = _b.fontFamily, fontSize = _b.fontSize, textColor = _b.textColor, textColors = _b.textColors, backgroundColor = _b.backgroundColor, backgroundColors = _b.backgroundColors, bold = _b.bold, italic = _b.italic, underline = _b.underline;
7959
- var defaultFormat = this.contentDivFormat;
7960
- this.state.defaultFormat = {
7961
- fontFamily: fontFamily || defaultFormat[0],
7962
- fontSize: fontSize || defaultFormat[1],
7963
- get textColor() {
7964
- return textColors
7965
- ? isDarkMode
7966
- ? textColors.darkModeColor
7967
- : textColors.lightModeColor
7968
- : textColor || defaultFormat[2];
7969
- },
7970
- textColors: textColors,
7971
- get backgroundColor() {
7972
- return backgroundColors
7973
- ? isDarkMode
7974
- ? backgroundColors.darkModeColor
7975
- : backgroundColors.lightModeColor
7976
- : backgroundColor || '';
7977
- },
7978
- backgroundColors: backgroundColors,
7979
- bold: bold,
7980
- italic: italic,
7981
- underline: underline,
7982
- };
7983
- };
7984
8133
  return LifecyclePlugin;
7985
8134
  }());
7986
8135
  exports.default = LifecyclePlugin;
@@ -8599,11 +8748,7 @@ var UndoPlugin = /** @class */ (function () {
8599
8748
  this.addUndoSnapshot();
8600
8749
  break;
8601
8750
  case 7 /* ContentChanged */:
8602
- if (!(this.state.isRestoring ||
8603
- event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
8604
- event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
8605
- this.clearRedoForInput();
8606
- }
8751
+ this.onContentChanged(event);
8607
8752
  break;
8608
8753
  }
8609
8754
  };
@@ -8667,6 +8812,25 @@ var UndoPlugin = /** @class */ (function () {
8667
8812
  }
8668
8813
  this.lastKeyPress = evt.which;
8669
8814
  };
8815
+ UndoPlugin.prototype.onContentChanged = function (event) {
8816
+ if (event.source == "Keyboard" /* Keyboard */) {
8817
+ if (Number.isInteger(event.data)) {
8818
+ // For keyboard event (triggered from Content Model), we can get its keycode from event.data
8819
+ // And when user is keep pressing the same key, mark editor with "hasNewContent" so that next time user
8820
+ // do some other action or press a different key, we will add undo snapshot
8821
+ if (event.data != this.lastKeyPress) {
8822
+ this.addUndoSnapshot();
8823
+ }
8824
+ this.lastKeyPress = event.data;
8825
+ this.state.hasNewContent = true;
8826
+ }
8827
+ }
8828
+ else if (!(this.state.isRestoring ||
8829
+ event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
8830
+ event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
8831
+ this.clearRedoForInput();
8832
+ }
8833
+ };
8670
8834
  UndoPlugin.prototype.clearRedoForInput = function () {
8671
8835
  this.state.snapshotsService.clearRedo();
8672
8836
  this.lastKeyPress = 0;
@@ -9240,6 +9404,54 @@ exports.default = DarkColorHandlerImpl;
9240
9404
 
9241
9405
  "use strict";
9242
9406
 
9407
+ var __extends = (this && this.__extends) || (function () {
9408
+ var extendStatics = function (d, b) {
9409
+ extendStatics = Object.setPrototypeOf ||
9410
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
9411
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
9412
+ return extendStatics(d, b);
9413
+ };
9414
+ return function (d, b) {
9415
+ if (typeof b !== "function" && b !== null)
9416
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
9417
+ extendStatics(d, b);
9418
+ function __() { this.constructor = d; }
9419
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9420
+ };
9421
+ })();
9422
+ Object.defineProperty(exports, "__esModule", { value: true });
9423
+ var createEditorCore_1 = __webpack_require__(/*! ./createEditorCore */ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts");
9424
+ var EditorBase_1 = __webpack_require__(/*! ./EditorBase */ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts");
9425
+ /**
9426
+ * RoosterJs core editor class
9427
+ */
9428
+ var Editor = /** @class */ (function (_super) {
9429
+ __extends(Editor, _super);
9430
+ /**
9431
+ * Creates an instance of EditorBase
9432
+ * @param contentDiv The DIV HTML element which will be the container element of editor
9433
+ * @param options An optional options object to customize the editor
9434
+ */
9435
+ function Editor(contentDiv, options) {
9436
+ if (options === void 0) { options = {}; }
9437
+ return _super.call(this, contentDiv, options, createEditorCore_1.createEditorCore) || this;
9438
+ }
9439
+ return Editor;
9440
+ }(EditorBase_1.EditorBase));
9441
+ exports.default = Editor;
9442
+
9443
+
9444
+ /***/ }),
9445
+
9446
+ /***/ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts":
9447
+ /*!*****************************************************************!*\
9448
+ !*** ./packages/roosterjs-editor-core/lib/editor/EditorBase.ts ***!
9449
+ \*****************************************************************/
9450
+ /*! no static exports found */
9451
+ /***/ (function(module, exports, __webpack_require__) {
9452
+
9453
+ "use strict";
9454
+
9243
9455
  var __assign = (this && this.__assign) || function () {
9244
9456
  __assign = Object.assign || function(t) {
9245
9457
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -9252,53 +9464,28 @@ var __assign = (this && this.__assign) || function () {
9252
9464
  return __assign.apply(this, arguments);
9253
9465
  };
9254
9466
  Object.defineProperty(exports, "__esModule", { value: true });
9255
- var createCorePlugins_1 = __webpack_require__(/*! ../corePlugins/createCorePlugins */ "./packages/roosterjs-editor-core/lib/corePlugins/createCorePlugins.ts");
9256
- var DarkColorHandlerImpl_1 = __webpack_require__(/*! ./DarkColorHandlerImpl */ "./packages/roosterjs-editor-core/lib/editor/DarkColorHandlerImpl.ts");
9257
- var coreApiMap_1 = __webpack_require__(/*! ../coreApi/coreApiMap */ "./packages/roosterjs-editor-core/lib/coreApi/coreApiMap.ts");
9467
+ exports.EditorBase = void 0;
9468
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
9258
9469
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
9259
9470
  /**
9260
- * RoosterJs core editor class
9471
+ * Base class of editor
9261
9472
  */
9262
- var Editor = /** @class */ (function () {
9473
+ var EditorBase = /** @class */ (function () {
9263
9474
  //#region Lifecycle
9264
9475
  /**
9265
- * Creates an instance of Editor
9476
+ * Creates an instance of EditorBase
9266
9477
  * @param contentDiv The DIV HTML element which will be the container element of editor
9267
9478
  * @param options An optional options object to customize the editor
9268
9479
  */
9269
- function Editor(contentDiv, options) {
9480
+ function EditorBase(contentDiv, options, coreCreator) {
9270
9481
  var _this = this;
9271
- if (options === void 0) { options = {}; }
9272
- var _a;
9273
9482
  this.core = null;
9274
9483
  // 1. Make sure all parameters are valid
9275
9484
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(contentDiv) != 'DIV') {
9276
9485
  throw new Error('contentDiv must be an HTML DIV element');
9277
9486
  }
9278
- // 2. Store options values to local variables
9279
- var corePlugins = (0, createCorePlugins_1.default)(contentDiv, options);
9280
- var plugins = [];
9281
- (0, roosterjs_editor_dom_1.getObjectKeys)(corePlugins).forEach(function (name) {
9282
- if (name == '_placeholder') {
9283
- if (options.plugins) {
9284
- (0, roosterjs_editor_dom_1.arrayPush)(plugins, options.plugins);
9285
- }
9286
- }
9287
- else {
9288
- plugins.push(corePlugins[name]);
9289
- }
9290
- });
9291
- var zoomScale = ((_a = options.zoomScale) !== null && _a !== void 0 ? _a : -1) > 0 ? options.zoomScale : 1;
9292
- this.core = __assign(__assign({ contentDiv: contentDiv, api: __assign(__assign({}, coreApiMap_1.coreApiMap), (options.coreApiOverride || {})), originalApi: coreApiMap_1.coreApiMap, plugins: plugins.filter(function (x) { return !!x; }) }, (0, createCorePlugins_1.getPluginState)(corePlugins)), { trustedHTMLHandler: options.trustedHTMLHandler || (function (html) { return html; }), zoomScale: zoomScale, sizeTransformer: options.sizeTransformer || (function (size) { return size / zoomScale; }), getVisibleViewport: options.getVisibleViewport ||
9293
- (function () {
9294
- var scrollContainer = _this.getScrollContainer();
9295
- return (0, roosterjs_editor_dom_1.getIntersectedRect)(scrollContainer == contentDiv
9296
- ? [scrollContainer]
9297
- : [scrollContainer, contentDiv]);
9298
- }), imageSelectionBorderColor: options.imageSelectionBorderColor });
9299
- if (this.isFeatureEnabled("VariableBasedDarkColor" /* VariableBasedDarkColor */)) {
9300
- this.core.darkColorHandler = new DarkColorHandlerImpl_1.default(contentDiv, this.core.lifecycle.getDarkColor);
9301
- }
9487
+ // 2. Create editor core
9488
+ this.core = coreCreator(contentDiv, options);
9302
9489
  // 3. Initialize plugins
9303
9490
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
9304
9491
  // 4. Ensure user will type in a container node, not the editor content DIV
@@ -9307,7 +9494,7 @@ var Editor = /** @class */ (function () {
9307
9494
  /**
9308
9495
  * Dispose this editor, dispose all plugins and custom data
9309
9496
  */
9310
- Editor.prototype.dispose = function () {
9497
+ EditorBase.prototype.dispose = function () {
9311
9498
  var _a;
9312
9499
  var core = this.getCore();
9313
9500
  for (var i = core.plugins.length - 1; i >= 0; i--) {
@@ -9320,7 +9507,7 @@ var Editor = /** @class */ (function () {
9320
9507
  * Get whether this editor is disposed
9321
9508
  * @returns True if editor is disposed, otherwise false
9322
9509
  */
9323
- Editor.prototype.isDisposed = function () {
9510
+ EditorBase.prototype.isDisposed = function () {
9324
9511
  return !this.core;
9325
9512
  };
9326
9513
  //#endregion
@@ -9335,7 +9522,7 @@ var Editor = /** @class */ (function () {
9335
9522
  * insertOnNewLine: false
9336
9523
  * @returns true if node is inserted. Otherwise false
9337
9524
  */
9338
- Editor.prototype.insertNode = function (node, option) {
9525
+ EditorBase.prototype.insertNode = function (node, option) {
9339
9526
  var core = this.getCore();
9340
9527
  return node ? core.api.insertNode(core, node, option !== null && option !== void 0 ? option : null) : false;
9341
9528
  };
@@ -9344,7 +9531,7 @@ var Editor = /** @class */ (function () {
9344
9531
  * @param node The node to delete
9345
9532
  * @returns true if node is deleted. Otherwise false
9346
9533
  */
9347
- Editor.prototype.deleteNode = function (node) {
9534
+ EditorBase.prototype.deleteNode = function (node) {
9348
9535
  // Only remove the node when it falls within editor
9349
9536
  if (node && this.contains(node) && node.parentNode) {
9350
9537
  node.parentNode.removeChild(node);
@@ -9359,7 +9546,7 @@ var Editor = /** @class */ (function () {
9359
9546
  * @param transformColorForDarkMode (optional) Whether to transform new node to dark mode. Default is false
9360
9547
  * @returns true if node is replaced. Otherwise false
9361
9548
  */
9362
- Editor.prototype.replaceNode = function (existingNode, toNode, transformColorForDarkMode) {
9549
+ EditorBase.prototype.replaceNode = function (existingNode, toNode, transformColorForDarkMode) {
9363
9550
  var core = this.getCore();
9364
9551
  // Only replace the node when it falls within editor
9365
9552
  if (this.contains(existingNode) && toNode) {
@@ -9373,16 +9560,16 @@ var Editor = /** @class */ (function () {
9373
9560
  * @param node The node to create InlineElement
9374
9561
  * @returns The BlockElement result
9375
9562
  */
9376
- Editor.prototype.getBlockElementAtNode = function (node) {
9563
+ EditorBase.prototype.getBlockElementAtNode = function (node) {
9377
9564
  return (0, roosterjs_editor_dom_1.getBlockElementAtNode)(this.getCore().contentDiv, node);
9378
9565
  };
9379
- Editor.prototype.contains = function (arg) {
9566
+ EditorBase.prototype.contains = function (arg) {
9380
9567
  if (!arg) {
9381
9568
  return false;
9382
9569
  }
9383
9570
  return (0, roosterjs_editor_dom_1.contains)(this.getCore().contentDiv, arg);
9384
9571
  };
9385
- Editor.prototype.queryElements = function (selector, scopeOrCallback, callback) {
9572
+ EditorBase.prototype.queryElements = function (selector, scopeOrCallback, callback) {
9386
9573
  if (scopeOrCallback === void 0) { scopeOrCallback = 0 /* Body */; }
9387
9574
  var core = this.getCore();
9388
9575
  var result = [];
@@ -9410,7 +9597,7 @@ var Editor = /** @class */ (function () {
9410
9597
  * @returns When canSplitParent is true, returns all node from start through end after splitting,
9411
9598
  * otherwise just return start and end
9412
9599
  */
9413
- Editor.prototype.collapseNodes = function (start, end, canSplitParent) {
9600
+ EditorBase.prototype.collapseNodes = function (start, end, canSplitParent) {
9414
9601
  return (0, roosterjs_editor_dom_1.collapseNodes)(this.getCore().contentDiv, start, end, canSplitParent);
9415
9602
  };
9416
9603
  //#endregion
@@ -9420,7 +9607,7 @@ var Editor = /** @class */ (function () {
9420
9607
  * @param trim Whether trim the content string before check. Default is false
9421
9608
  * @returns True if there's no visible content, otherwise false
9422
9609
  */
9423
- Editor.prototype.isEmpty = function (trim) {
9610
+ EditorBase.prototype.isEmpty = function (trim) {
9424
9611
  return (0, roosterjs_editor_dom_1.isNodeEmpty)(this.getCore().contentDiv, trim);
9425
9612
  };
9426
9613
  /**
@@ -9428,7 +9615,7 @@ var Editor = /** @class */ (function () {
9428
9615
  * @param mode specify what kind of HTML content to retrieve
9429
9616
  * @returns HTML string representing current editor content
9430
9617
  */
9431
- Editor.prototype.getContent = function (mode) {
9618
+ EditorBase.prototype.getContent = function (mode) {
9432
9619
  if (mode === void 0) { mode = 0 /* CleanHTML */; }
9433
9620
  var core = this.getCore();
9434
9621
  return core.api.getContent(core, mode);
@@ -9438,7 +9625,7 @@ var Editor = /** @class */ (function () {
9438
9625
  * @param content HTML content to set in
9439
9626
  * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
9440
9627
  */
9441
- Editor.prototype.setContent = function (content, triggerContentChangedEvent) {
9628
+ EditorBase.prototype.setContent = function (content, triggerContentChangedEvent) {
9442
9629
  if (triggerContentChangedEvent === void 0) { triggerContentChangedEvent = true; }
9443
9630
  var core = this.getCore();
9444
9631
  core.api.setContent(core, content, triggerContentChangedEvent);
@@ -9452,7 +9639,7 @@ var Editor = /** @class */ (function () {
9452
9639
  * replaceSelection: true
9453
9640
  * insertOnNewLine: false
9454
9641
  */
9455
- Editor.prototype.insertContent = function (content, option) {
9642
+ EditorBase.prototype.insertContent = function (content, option) {
9456
9643
  var _a;
9457
9644
  if (content) {
9458
9645
  var doc = this.getDocument();
@@ -9472,7 +9659,7 @@ var Editor = /** @class */ (function () {
9472
9659
  /**
9473
9660
  * Delete selected content
9474
9661
  */
9475
- Editor.prototype.deleteSelectedContent = function () {
9662
+ EditorBase.prototype.deleteSelectedContent = function () {
9476
9663
  var range = this.getSelectionRange();
9477
9664
  if (range && !range.collapsed) {
9478
9665
  return (0, roosterjs_editor_dom_1.deleteSelectedContent)(this.getCore().contentDiv, range);
@@ -9486,10 +9673,11 @@ var Editor = /** @class */ (function () {
9486
9673
  * @param applyCurrentStyle True if apply format of current selection to the pasted content,
9487
9674
  * false to keep original format. Default value is false. When pasteAsText is true, this parameter is ignored
9488
9675
  */
9489
- Editor.prototype.paste = function (clipboardData, pasteAsText, applyCurrentFormat) {
9676
+ EditorBase.prototype.paste = function (clipboardData, pasteAsText, applyCurrentFormat, pasteAsImage) {
9490
9677
  var _this = this;
9491
9678
  if (pasteAsText === void 0) { pasteAsText = false; }
9492
9679
  if (applyCurrentFormat === void 0) { applyCurrentFormat = false; }
9680
+ if (pasteAsImage === void 0) { pasteAsImage = false; }
9493
9681
  var core = this.getCore();
9494
9682
  if (!clipboardData) {
9495
9683
  return;
@@ -9503,7 +9691,7 @@ var Editor = /** @class */ (function () {
9503
9691
  }
9504
9692
  var range = this.getSelectionRange();
9505
9693
  var pos = range && roosterjs_editor_dom_1.Position.getStart(range);
9506
- var fragment = core.api.createPasteFragment(core, clipboardData, pos, pasteAsText, applyCurrentFormat);
9694
+ var fragment = core.api.createPasteFragment(core, clipboardData, pos, pasteAsText, applyCurrentFormat, pasteAsImage);
9507
9695
  if (fragment) {
9508
9696
  this.addUndoSnapshot(function () {
9509
9697
  _this.insertNode(fragment);
@@ -9520,7 +9708,7 @@ var Editor = /** @class */ (function () {
9520
9708
  * Default value is true
9521
9709
  * @returns current selection range, or null if editor never got focus before
9522
9710
  */
9523
- Editor.prototype.getSelectionRange = function (tryGetFromCache) {
9711
+ EditorBase.prototype.getSelectionRange = function (tryGetFromCache) {
9524
9712
  if (tryGetFromCache === void 0) { tryGetFromCache = true; }
9525
9713
  var core = this.getCore();
9526
9714
  return core.api.getSelectionRange(core, tryGetFromCache);
@@ -9532,7 +9720,7 @@ var Editor = /** @class */ (function () {
9532
9720
  * Default value is true
9533
9721
  * @returns current selection range, or null if editor never got focus before
9534
9722
  */
9535
- Editor.prototype.getSelectionRangeEx = function () {
9723
+ EditorBase.prototype.getSelectionRangeEx = function () {
9536
9724
  var core = this.getCore();
9537
9725
  return core.api.getSelectionRangeEx(core);
9538
9726
  };
@@ -9541,7 +9729,7 @@ var Editor = /** @class */ (function () {
9541
9729
  * It does a live pull on the selection, if nothing retrieved, return whatever we have in cache.
9542
9730
  * @returns current selection path, or null if editor never got focus before
9543
9731
  */
9544
- Editor.prototype.getSelectionPath = function () {
9732
+ EditorBase.prototype.getSelectionPath = function () {
9545
9733
  var range = this.getSelectionRange();
9546
9734
  return range && (0, roosterjs_editor_dom_1.getSelectionPath)(this.getCore().contentDiv, range);
9547
9735
  };
@@ -9549,99 +9737,25 @@ var Editor = /** @class */ (function () {
9549
9737
  * Check if focus is in editor now
9550
9738
  * @returns true if focus is in editor, otherwise false
9551
9739
  */
9552
- Editor.prototype.hasFocus = function () {
9740
+ EditorBase.prototype.hasFocus = function () {
9553
9741
  var core = this.getCore();
9554
9742
  return core.api.hasFocus(core);
9555
9743
  };
9556
9744
  /**
9557
9745
  * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.
9558
9746
  */
9559
- Editor.prototype.focus = function () {
9747
+ EditorBase.prototype.focus = function () {
9560
9748
  var core = this.getCore();
9561
9749
  core.api.focus(core);
9562
9750
  };
9563
- Editor.prototype.select = function (arg1, arg2, arg3, arg4) {
9751
+ EditorBase.prototype.select = function (arg1, arg2, arg3, arg4) {
9564
9752
  var core = this.getCore();
9565
- var rangeEx = null;
9566
- if (isSelectionRangeEx(arg1)) {
9567
- rangeEx = arg1;
9568
- }
9569
- else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLTableElement') && isTableSelection(arg2)) {
9570
- rangeEx = {
9571
- type: 1 /* TableSelection */,
9572
- ranges: [],
9573
- areAllCollapsed: false,
9574
- table: arg1,
9575
- coordinates: arg2,
9576
- };
9577
- }
9578
- else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLImageElement') && typeof arg2 == 'undefined') {
9579
- rangeEx = {
9580
- type: 2 /* ImageSelection */,
9581
- ranges: [],
9582
- areAllCollapsed: false,
9583
- image: arg1,
9584
- };
9585
- }
9586
- else {
9587
- var range = !arg1
9588
- ? null
9589
- : (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Range')
9590
- ? arg1
9591
- : isSelectionPath(arg1)
9592
- ? (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, arg1.start, arg1.end)
9593
- : isNodePosition(arg1) || (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Node')
9594
- ? (0, roosterjs_editor_dom_1.createRange)(arg1, arg2, arg3, arg4)
9595
- : null;
9596
- rangeEx = range
9597
- ? {
9598
- type: 0 /* Normal */,
9599
- ranges: [range],
9600
- areAllCollapsed: range.collapsed,
9601
- }
9602
- : null;
9603
- }
9604
- if (rangeEx) {
9605
- switch (rangeEx.type) {
9606
- case 1 /* TableSelection */:
9607
- if (this.contains(rangeEx.table)) {
9608
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9609
- core.domEvent.tableSelectionRange = core.api.selectTable(core, rangeEx.table, rangeEx.coordinates);
9610
- rangeEx = core.domEvent.tableSelectionRange;
9611
- }
9612
- break;
9613
- case 2 /* ImageSelection */:
9614
- if (this.contains(rangeEx.image)) {
9615
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9616
- core.domEvent.imageSelectionRange = core.api.selectImage(core, rangeEx.image);
9617
- rangeEx = core.domEvent.imageSelectionRange;
9618
- }
9619
- break;
9620
- case 0 /* Normal */:
9621
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9622
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9623
- if (this.contains(rangeEx.ranges[0])) {
9624
- core.api.selectRange(core, rangeEx.ranges[0]);
9625
- }
9626
- else {
9627
- rangeEx = null;
9628
- }
9629
- break;
9630
- }
9631
- this.triggerPluginEvent(22 /* SelectionChanged */, {
9632
- selectionRangeEx: rangeEx,
9633
- }, true /** broadcast **/);
9634
- }
9635
- else {
9636
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9637
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9638
- }
9639
- return !!rangeEx;
9753
+ return core.api.select(core, arg1, arg2, arg3, arg4);
9640
9754
  };
9641
9755
  /**
9642
9756
  * Get current focused position. Return null if editor doesn't have focus at this time.
9643
9757
  */
9644
- Editor.prototype.getFocusedPosition = function () {
9758
+ EditorBase.prototype.getFocusedPosition = function () {
9645
9759
  var _a;
9646
9760
  var sel = (_a = this.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
9647
9761
  if ((sel === null || sel === void 0 ? void 0 : sel.focusNode) && this.contains(sel.focusNode)) {
@@ -9665,7 +9779,7 @@ var Editor = /** @class */ (function () {
9665
9779
  * @param event Optional, if specified, editor will try to get cached result from the event object first.
9666
9780
  * If it is not cached before, query from DOM and cache the result into the event object
9667
9781
  */
9668
- Editor.prototype.getElementAtCursor = function (selector, startFrom, event) {
9782
+ EditorBase.prototype.getElementAtCursor = function (selector, startFrom, event) {
9669
9783
  var _this = this;
9670
9784
  var _a;
9671
9785
  event = startFrom ? undefined : event; // Only use cache when startFrom is not specified, for different start position can have different result
@@ -9684,13 +9798,13 @@ var Editor = /** @class */ (function () {
9684
9798
  * @param position The position to check
9685
9799
  * @returns True if position is at beginning of the editor, otherwise false
9686
9800
  */
9687
- Editor.prototype.isPositionAtBeginning = function (position) {
9801
+ EditorBase.prototype.isPositionAtBeginning = function (position) {
9688
9802
  return (0, roosterjs_editor_dom_1.isPositionAtBeginningOf)(position, this.getCore().contentDiv);
9689
9803
  };
9690
9804
  /**
9691
9805
  * Get impacted regions from selection
9692
9806
  */
9693
- Editor.prototype.getSelectedRegions = function (type) {
9807
+ EditorBase.prototype.getSelectedRegions = function (type) {
9694
9808
  if (type === void 0) { type = 0 /* Table */; }
9695
9809
  var selection = this.getSelectionRangeEx();
9696
9810
  var result = [];
@@ -9704,7 +9818,7 @@ var Editor = /** @class */ (function () {
9704
9818
  };
9705
9819
  //#endregion
9706
9820
  //#region EVENT API
9707
- Editor.prototype.addDomEventHandler = function (nameOrMap, handler) {
9821
+ EditorBase.prototype.addDomEventHandler = function (nameOrMap, handler) {
9708
9822
  var _a;
9709
9823
  var eventsToMap = typeof nameOrMap == 'string' ? (_a = {}, _a[nameOrMap] = handler, _a) : nameOrMap;
9710
9824
  var core = this.getCore();
@@ -9719,7 +9833,7 @@ var Editor = /** @class */ (function () {
9719
9833
  * @returns the event object which is really passed into plugins. Some plugin may modify the event object so
9720
9834
  * the result of this function provides a chance to read the modified result
9721
9835
  */
9722
- Editor.prototype.triggerPluginEvent = function (eventType, data, broadcast) {
9836
+ EditorBase.prototype.triggerPluginEvent = function (eventType, data, broadcast) {
9723
9837
  if (broadcast === void 0) { broadcast = false; }
9724
9838
  var core = this.getCore();
9725
9839
  var event = __assign({ eventType: eventType }, data);
@@ -9731,7 +9845,7 @@ var Editor = /** @class */ (function () {
9731
9845
  * @param source Source of this event, by default is 'SetContent'
9732
9846
  * @param data additional data for this event
9733
9847
  */
9734
- Editor.prototype.triggerContentChangedEvent = function (source, data) {
9848
+ EditorBase.prototype.triggerContentChangedEvent = function (source, data) {
9735
9849
  if (source === void 0) { source = "SetContent" /* SetContent */; }
9736
9850
  this.triggerPluginEvent(7 /* ContentChanged */, {
9737
9851
  source: source,
@@ -9743,7 +9857,7 @@ var Editor = /** @class */ (function () {
9743
9857
  /**
9744
9858
  * Undo last edit operation
9745
9859
  */
9746
- Editor.prototype.undo = function () {
9860
+ EditorBase.prototype.undo = function () {
9747
9861
  this.focus();
9748
9862
  var core = this.getCore();
9749
9863
  core.api.restoreUndoSnapshot(core, -1 /*step*/);
@@ -9751,7 +9865,7 @@ var Editor = /** @class */ (function () {
9751
9865
  /**
9752
9866
  * Redo next edit operation
9753
9867
  */
9754
- Editor.prototype.redo = function () {
9868
+ EditorBase.prototype.redo = function () {
9755
9869
  this.focus();
9756
9870
  var core = this.getCore();
9757
9871
  core.api.restoreUndoSnapshot(core, 1 /*step*/);
@@ -9766,14 +9880,14 @@ var Editor = /** @class */ (function () {
9766
9880
  * a ContentChangedEvent will be fired with change source equal to this value
9767
9881
  * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).
9768
9882
  */
9769
- Editor.prototype.addUndoSnapshot = function (callback, changeSource, canUndoByBackspace, additionalData) {
9883
+ EditorBase.prototype.addUndoSnapshot = function (callback, changeSource, canUndoByBackspace, additionalData) {
9770
9884
  var core = this.getCore();
9771
9885
  core.api.addUndoSnapshot(core, callback !== null && callback !== void 0 ? callback : null, changeSource !== null && changeSource !== void 0 ? changeSource : null, canUndoByBackspace !== null && canUndoByBackspace !== void 0 ? canUndoByBackspace : false, additionalData);
9772
9886
  };
9773
9887
  /**
9774
9888
  * Whether there is an available undo/redo snapshot
9775
9889
  */
9776
- Editor.prototype.getUndoState = function () {
9890
+ EditorBase.prototype.getUndoState = function () {
9777
9891
  var _a = this.getCore().undo, hasNewContent = _a.hasNewContent, snapshotsService = _a.snapshotsService;
9778
9892
  return {
9779
9893
  canUndo: hasNewContent || snapshotsService.canMove(-1 /*previousSnapshot*/),
@@ -9786,13 +9900,13 @@ var Editor = /** @class */ (function () {
9786
9900
  * Get document which contains this editor
9787
9901
  * @returns The HTML document which contains this editor
9788
9902
  */
9789
- Editor.prototype.getDocument = function () {
9903
+ EditorBase.prototype.getDocument = function () {
9790
9904
  return this.getCore().contentDiv.ownerDocument;
9791
9905
  };
9792
9906
  /**
9793
9907
  * Get the scroll container of the editor
9794
9908
  */
9795
- Editor.prototype.getScrollContainer = function () {
9909
+ EditorBase.prototype.getScrollContainer = function () {
9796
9910
  return this.getCore().domEvent.scrollContainer;
9797
9911
  };
9798
9912
  /**
@@ -9803,7 +9917,7 @@ var Editor = /** @class */ (function () {
9803
9917
  * @param disposer An optional disposer function to dispose this custom data when
9804
9918
  * dispose editor.
9805
9919
  */
9806
- Editor.prototype.getCustomData = function (key, getter, disposer) {
9920
+ EditorBase.prototype.getCustomData = function (key, getter, disposer) {
9807
9921
  var core = this.getCore();
9808
9922
  return (core.lifecycle.customData[key] = core.lifecycle.customData[key] || {
9809
9923
  value: getter ? getter() : undefined,
@@ -9814,14 +9928,14 @@ var Editor = /** @class */ (function () {
9814
9928
  * Check if editor is in IME input sequence
9815
9929
  * @returns True if editor is in IME input sequence, otherwise false
9816
9930
  */
9817
- Editor.prototype.isInIME = function () {
9931
+ EditorBase.prototype.isInIME = function () {
9818
9932
  return this.getCore().domEvent.isInIME;
9819
9933
  };
9820
9934
  /**
9821
9935
  * Get default format of this editor
9822
9936
  * @returns Default format object of this editor
9823
9937
  */
9824
- Editor.prototype.getDefaultFormat = function () {
9938
+ EditorBase.prototype.getDefaultFormat = function () {
9825
9939
  var _a;
9826
9940
  return (_a = this.getCore().lifecycle.defaultFormat) !== null && _a !== void 0 ? _a : {};
9827
9941
  };
@@ -9829,14 +9943,14 @@ var Editor = /** @class */ (function () {
9829
9943
  * Get a content traverser for the whole editor
9830
9944
  * @param startNode The node to start from. If not passed, it will start from the beginning of the body
9831
9945
  */
9832
- Editor.prototype.getBodyTraverser = function (startNode) {
9946
+ EditorBase.prototype.getBodyTraverser = function (startNode) {
9833
9947
  return roosterjs_editor_dom_1.ContentTraverser.createBodyTraverser(this.getCore().contentDiv, startNode);
9834
9948
  };
9835
9949
  /**
9836
9950
  * Get a content traverser for current selection
9837
9951
  * @returns A content traverser, or null if editor never got focus before
9838
9952
  */
9839
- Editor.prototype.getSelectionTraverser = function (range) {
9953
+ EditorBase.prototype.getSelectionTraverser = function (range) {
9840
9954
  var _a;
9841
9955
  range = (_a = range !== null && range !== void 0 ? range : this.getSelectionRange()) !== null && _a !== void 0 ? _a : undefined;
9842
9956
  return range
@@ -9848,7 +9962,7 @@ var Editor = /** @class */ (function () {
9848
9962
  * @param startFrom Start position of the traverser. Default value is ContentPosition.SelectionStart
9849
9963
  * @returns A content traverser, or null if editor never got focus before
9850
9964
  */
9851
- Editor.prototype.getBlockTraverser = function (startFrom) {
9965
+ EditorBase.prototype.getBlockTraverser = function (startFrom) {
9852
9966
  if (startFrom === void 0) { startFrom = 3 /* SelectionStart */; }
9853
9967
  var range = this.getSelectionRange();
9854
9968
  return range
@@ -9861,7 +9975,7 @@ var Editor = /** @class */ (function () {
9861
9975
  * If it is not cached before, query from DOM and cache the result into the event object
9862
9976
  * @returns A content traverser, or null if editor never got focus before
9863
9977
  */
9864
- Editor.prototype.getContentSearcherOfCursor = function (event) {
9978
+ EditorBase.prototype.getContentSearcherOfCursor = function (event) {
9865
9979
  var _this = this;
9866
9980
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event !== null && event !== void 0 ? event : null, 'ContentSearcher', function () {
9867
9981
  var range = _this.getSelectionRange();
@@ -9874,7 +9988,7 @@ var Editor = /** @class */ (function () {
9874
9988
  * @param callback The callback function to run
9875
9989
  * @returns a function to cancel this async run
9876
9990
  */
9877
- Editor.prototype.runAsync = function (callback) {
9991
+ EditorBase.prototype.runAsync = function (callback) {
9878
9992
  var _this = this;
9879
9993
  var win = this.getCore().contentDiv.ownerDocument.defaultView || window;
9880
9994
  var handle = win.requestAnimationFrame(function () {
@@ -9891,7 +10005,7 @@ var Editor = /** @class */ (function () {
9891
10005
  * @param name Name of the attribute
9892
10006
  * @param value Value of the attribute
9893
10007
  */
9894
- Editor.prototype.setEditorDomAttribute = function (name, value) {
10008
+ EditorBase.prototype.setEditorDomAttribute = function (name, value) {
9895
10009
  if (value === null) {
9896
10010
  this.getCore().contentDiv.removeAttribute(name);
9897
10011
  }
@@ -9903,7 +10017,7 @@ var Editor = /** @class */ (function () {
9903
10017
  * Get DOM attribute of editor content DIV, null if there is no such attribute.
9904
10018
  * @param name Name of the attribute
9905
10019
  */
9906
- Editor.prototype.getEditorDomAttribute = function (name) {
10020
+ EditorBase.prototype.getEditorDomAttribute = function (name) {
9907
10021
  return this.getCore().contentDiv.getAttribute(name);
9908
10022
  };
9909
10023
  /**
@@ -9915,7 +10029,7 @@ var Editor = /** @class */ (function () {
9915
10029
  * may be different than what user is seeing from the view. When pass false, scroll position will be ignored.
9916
10030
  * @returns An [x, y] array which contains the left and top distances, or null if the given element is not in editor.
9917
10031
  */
9918
- Editor.prototype.getRelativeDistanceToEditor = function (element, addScroll) {
10032
+ EditorBase.prototype.getRelativeDistanceToEditor = function (element, addScroll) {
9919
10033
  if (this.contains(element)) {
9920
10034
  var contentDiv = this.getCore().contentDiv;
9921
10035
  var editorRect = contentDiv.getBoundingClientRect();
@@ -9936,7 +10050,7 @@ var Editor = /** @class */ (function () {
9936
10050
  * Add a Content Edit feature.
9937
10051
  * @param feature The feature to add
9938
10052
  */
9939
- Editor.prototype.addContentEditFeature = function (feature) {
10053
+ EditorBase.prototype.addContentEditFeature = function (feature) {
9940
10054
  var core = this.getCore();
9941
10055
  feature === null || feature === void 0 ? void 0 : feature.keys.forEach(function (key) {
9942
10056
  var array = core.edit.features[key] || [];
@@ -9948,7 +10062,7 @@ var Editor = /** @class */ (function () {
9948
10062
  * Remove a Content Edit feature.
9949
10063
  * @param feature The feature to remove
9950
10064
  */
9951
- Editor.prototype.removeContentEditFeature = function (feature) {
10065
+ EditorBase.prototype.removeContentEditFeature = function (feature) {
9952
10066
  var core = this.getCore();
9953
10067
  feature === null || feature === void 0 ? void 0 : feature.keys.forEach(function (key) {
9954
10068
  var _a;
@@ -9965,7 +10079,7 @@ var Editor = /** @class */ (function () {
9965
10079
  /**
9966
10080
  * Get style based format state from current selection, including font name/size and colors
9967
10081
  */
9968
- Editor.prototype.getStyleBasedFormatState = function (node) {
10082
+ EditorBase.prototype.getStyleBasedFormatState = function (node) {
9969
10083
  var _a;
9970
10084
  if (!node) {
9971
10085
  var range = this.getSelectionRange();
@@ -9979,7 +10093,7 @@ var Editor = /** @class */ (function () {
9979
10093
  * @param forceGetStateFromDOM If set to true, will force get the format state from DOM tree.
9980
10094
  * @returns The pending format state
9981
10095
  */
9982
- Editor.prototype.getPendableFormatState = function (forceGetStateFromDOM) {
10096
+ EditorBase.prototype.getPendableFormatState = function (forceGetStateFromDOM) {
9983
10097
  if (forceGetStateFromDOM === void 0) { forceGetStateFromDOM = false; }
9984
10098
  var core = this.getCore();
9985
10099
  return core.api.getPendableFormatState(core, forceGetStateFromDOM);
@@ -9989,7 +10103,7 @@ var Editor = /** @class */ (function () {
9989
10103
  * @param position The position that user is about to type to
9990
10104
  * @param keyboardEvent Optional keyboard event object
9991
10105
  */
9992
- Editor.prototype.ensureTypeInContainer = function (position, keyboardEvent) {
10106
+ EditorBase.prototype.ensureTypeInContainer = function (position, keyboardEvent) {
9993
10107
  var core = this.getCore();
9994
10108
  core.api.ensureTypeInContainer(core, position, keyboardEvent, this.isFeatureEnabled("DefaultFormatInSpan" /* DefaultFormatInSpan */));
9995
10109
  };
@@ -9999,7 +10113,7 @@ var Editor = /** @class */ (function () {
9999
10113
  * Set the dark mode state and transforms the content to match the new state.
10000
10114
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
10001
10115
  */
10002
- Editor.prototype.setDarkModeState = function (nextDarkMode) {
10116
+ EditorBase.prototype.setDarkModeState = function (nextDarkMode) {
10003
10117
  var isDarkMode = this.isDarkMode();
10004
10118
  if (isDarkMode == !!nextDarkMode) {
10005
10119
  return;
@@ -10014,21 +10128,21 @@ var Editor = /** @class */ (function () {
10014
10128
  * Check if the editor is in dark mode
10015
10129
  * @returns True if the editor is in dark mode, otherwise false
10016
10130
  */
10017
- Editor.prototype.isDarkMode = function () {
10131
+ EditorBase.prototype.isDarkMode = function () {
10018
10132
  return this.getCore().lifecycle.isDarkMode;
10019
10133
  };
10020
10134
  /**
10021
10135
  * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
10022
10136
  * @param node The node to transform
10023
10137
  */
10024
- Editor.prototype.transformToDarkColor = function (node) {
10138
+ EditorBase.prototype.transformToDarkColor = function (node) {
10025
10139
  var core = this.getCore();
10026
10140
  core.api.transformColor(core, node, true /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
10027
10141
  };
10028
10142
  /**
10029
10143
  * Get a darkColorHandler object for this editor. It will return null if experimental feature "VariableBasedDarkColor" is not enabled
10030
10144
  */
10031
- Editor.prototype.getDarkColorHandler = function () {
10145
+ EditorBase.prototype.getDarkColorHandler = function () {
10032
10146
  return this.getCore().darkColorHandler || null;
10033
10147
  };
10034
10148
  /**
@@ -10039,29 +10153,29 @@ var Editor = /** @class */ (function () {
10039
10153
  * This function can be called repeated. If editor is already in shadow edit mode, we can still
10040
10154
  * use this function to do more shadow edit operation.
10041
10155
  */
10042
- Editor.prototype.startShadowEdit = function () {
10156
+ EditorBase.prototype.startShadowEdit = function () {
10043
10157
  var core = this.getCore();
10044
10158
  core.api.switchShadowEdit(core, true /*isOn*/);
10045
10159
  };
10046
10160
  /**
10047
10161
  * Leave "Shadow Edit" mode, all changes made during shadow edit will be discarded
10048
10162
  */
10049
- Editor.prototype.stopShadowEdit = function () {
10163
+ EditorBase.prototype.stopShadowEdit = function () {
10050
10164
  var core = this.getCore();
10051
10165
  core.api.switchShadowEdit(core, false /*isOn*/);
10052
10166
  };
10053
10167
  /**
10054
10168
  * Check if editor is in Shadow Edit mode
10055
10169
  */
10056
- Editor.prototype.isInShadowEdit = function () {
10170
+ EditorBase.prototype.isInShadowEdit = function () {
10057
10171
  return !!this.getCore().lifecycle.shadowEditFragment;
10058
10172
  };
10059
10173
  /**
10060
10174
  * Check if the given experimental feature is enabled
10061
10175
  * @param feature The feature to check
10062
10176
  */
10063
- Editor.prototype.isFeatureEnabled = function (feature) {
10064
- return this.getCore().lifecycle.experimentalFeatures.indexOf(feature) >= 0;
10177
+ EditorBase.prototype.isFeatureEnabled = function (feature) {
10178
+ return (0, isFeatureEnabled_1.isFeatureEnabled)(this.getCore().lifecycle.experimentalFeatures, feature);
10065
10179
  };
10066
10180
  /**
10067
10181
  * Get a function to convert HTML string to trusted HTML string.
@@ -10069,13 +10183,13 @@ var Editor = /** @class */ (function () {
10069
10183
  * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
10070
10184
  * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
10071
10185
  */
10072
- Editor.prototype.getTrustedHTMLHandler = function () {
10186
+ EditorBase.prototype.getTrustedHTMLHandler = function () {
10073
10187
  return this.getCore().trustedHTMLHandler;
10074
10188
  };
10075
10189
  /**
10076
10190
  * @deprecated Use getZoomScale() instead
10077
10191
  */
10078
- Editor.prototype.getSizeTransformer = function () {
10192
+ EditorBase.prototype.getSizeTransformer = function () {
10079
10193
  return this.getCore().sizeTransformer;
10080
10194
  };
10081
10195
  /**
@@ -10084,7 +10198,7 @@ var Editor = /** @class */ (function () {
10084
10198
  * to let editor behave correctly especially for those mouse drag/drop behaviors
10085
10199
  * @returns current zoom scale number
10086
10200
  */
10087
- Editor.prototype.getZoomScale = function () {
10201
+ EditorBase.prototype.getZoomScale = function () {
10088
10202
  return this.getCore().zoomScale;
10089
10203
  };
10090
10204
  /**
@@ -10093,7 +10207,7 @@ var Editor = /** @class */ (function () {
10093
10207
  * to let editor behave correctly especially for those mouse drag/drop behaviors
10094
10208
  * @param scale The new scale number to set. It should be positive number and no greater than 10, otherwise it will be ignored.
10095
10209
  */
10096
- Editor.prototype.setZoomScale = function (scale) {
10210
+ EditorBase.prototype.setZoomScale = function (scale) {
10097
10211
  var core = this.getCore();
10098
10212
  if (scale > 0 && scale <= 10) {
10099
10213
  var oldValue = core.zoomScale;
@@ -10109,47 +10223,112 @@ var Editor = /** @class */ (function () {
10109
10223
  /**
10110
10224
  * Retrieves the rect of the visible viewport of the editor.
10111
10225
  */
10112
- Editor.prototype.getVisibleViewport = function () {
10226
+ EditorBase.prototype.getVisibleViewport = function () {
10113
10227
  return this.getCore().getVisibleViewport();
10114
10228
  };
10115
10229
  /**
10116
10230
  * @returns the current EditorCore object
10117
10231
  * @throws a standard Error if there's no core object
10118
10232
  */
10119
- Editor.prototype.getCore = function () {
10233
+ EditorBase.prototype.getCore = function () {
10120
10234
  if (!this.core) {
10121
10235
  throw new Error('Editor is already disposed');
10122
10236
  }
10123
10237
  return this.core;
10124
10238
  };
10125
- return Editor;
10239
+ return EditorBase;
10126
10240
  }());
10127
- exports.default = Editor;
10128
- function isSelectionRangeEx(obj) {
10129
- var rangeEx = obj;
10130
- return (rangeEx &&
10131
- typeof rangeEx == 'object' &&
10132
- typeof rangeEx.type == 'number' &&
10133
- Array.isArray(rangeEx.ranges));
10134
- }
10135
- function isTableSelection(obj) {
10136
- var selection = obj;
10137
- return (selection &&
10138
- typeof selection == 'object' &&
10139
- typeof selection.firstCell == 'object' &&
10140
- typeof selection.lastCell == 'object');
10141
- }
10142
- function isSelectionPath(obj) {
10143
- var path = obj;
10144
- return path && typeof path == 'object' && Array.isArray(path.start) && Array.isArray(path.end);
10145
- }
10146
- function isNodePosition(obj) {
10147
- var pos = obj;
10148
- return (pos &&
10149
- typeof pos == 'object' &&
10150
- typeof pos.node == 'object' &&
10151
- typeof pos.offset == 'number');
10241
+ exports.EditorBase = EditorBase;
10242
+
10243
+
10244
+ /***/ }),
10245
+
10246
+ /***/ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts":
10247
+ /*!***********************************************************************!*\
10248
+ !*** ./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts ***!
10249
+ \***********************************************************************/
10250
+ /*! no static exports found */
10251
+ /***/ (function(module, exports, __webpack_require__) {
10252
+
10253
+ "use strict";
10254
+
10255
+ var __assign = (this && this.__assign) || function () {
10256
+ __assign = Object.assign || function(t) {
10257
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
10258
+ s = arguments[i];
10259
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
10260
+ t[p] = s[p];
10261
+ }
10262
+ return t;
10263
+ };
10264
+ return __assign.apply(this, arguments);
10265
+ };
10266
+ Object.defineProperty(exports, "__esModule", { value: true });
10267
+ exports.createEditorCore = void 0;
10268
+ var createCorePlugins_1 = __webpack_require__(/*! ../corePlugins/createCorePlugins */ "./packages/roosterjs-editor-core/lib/corePlugins/createCorePlugins.ts");
10269
+ var DarkColorHandlerImpl_1 = __webpack_require__(/*! ./DarkColorHandlerImpl */ "./packages/roosterjs-editor-core/lib/editor/DarkColorHandlerImpl.ts");
10270
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
10271
+ var coreApiMap_1 = __webpack_require__(/*! ../coreApi/coreApiMap */ "./packages/roosterjs-editor-core/lib/coreApi/coreApiMap.ts");
10272
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
10273
+ /**
10274
+ * Create a new instance of Editor Core
10275
+ * @param contentDiv The DIV HTML element which will be the container element of editor
10276
+ * @param options An optional options object to customize the editor
10277
+ */
10278
+ var createEditorCore = function (contentDiv, options) {
10279
+ var _a;
10280
+ var corePlugins = (0, createCorePlugins_1.default)(contentDiv, options);
10281
+ var plugins = [];
10282
+ (0, roosterjs_editor_dom_1.getObjectKeys)(corePlugins).forEach(function (name) {
10283
+ if (name == '_placeholder') {
10284
+ if (options.plugins) {
10285
+ (0, roosterjs_editor_dom_1.arrayPush)(plugins, options.plugins);
10286
+ }
10287
+ }
10288
+ else {
10289
+ plugins.push(corePlugins[name]);
10290
+ }
10291
+ });
10292
+ var pluginState = (0, createCorePlugins_1.getPluginState)(corePlugins);
10293
+ var zoomScale = ((_a = options.zoomScale) !== null && _a !== void 0 ? _a : -1) > 0 ? options.zoomScale : 1;
10294
+ var getVisibleViewport = options.getVisibleViewport ||
10295
+ (function () {
10296
+ var scrollContainer = pluginState.domEvent.scrollContainer;
10297
+ return (0, roosterjs_editor_dom_1.getIntersectedRect)(scrollContainer == core.contentDiv
10298
+ ? [scrollContainer]
10299
+ : [scrollContainer, core.contentDiv]);
10300
+ });
10301
+ var core = __assign(__assign({ contentDiv: contentDiv, api: __assign(__assign({}, coreApiMap_1.coreApiMap), (options.coreApiOverride || {})), originalApi: coreApiMap_1.coreApiMap, plugins: plugins.filter(function (x) { return !!x; }) }, pluginState), { trustedHTMLHandler: options.trustedHTMLHandler || (function (html) { return html; }), zoomScale: zoomScale, sizeTransformer: options.sizeTransformer || (function (size) { return size / zoomScale; }), getVisibleViewport: getVisibleViewport, imageSelectionBorderColor: options.imageSelectionBorderColor, darkColorHandler: (0, isFeatureEnabled_1.isFeatureEnabled)(options.experimentalFeatures, "VariableBasedDarkColor" /* VariableBasedDarkColor */)
10302
+ ? new DarkColorHandlerImpl_1.default(contentDiv, pluginState.lifecycle.getDarkColor)
10303
+ : undefined });
10304
+ return core;
10305
+ };
10306
+ exports.createEditorCore = createEditorCore;
10307
+
10308
+
10309
+ /***/ }),
10310
+
10311
+ /***/ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts":
10312
+ /*!***********************************************************************!*\
10313
+ !*** ./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts ***!
10314
+ \***********************************************************************/
10315
+ /*! no static exports found */
10316
+ /***/ (function(module, exports, __webpack_require__) {
10317
+
10318
+ "use strict";
10319
+
10320
+ Object.defineProperty(exports, "__esModule", { value: true });
10321
+ exports.isFeatureEnabled = void 0;
10322
+ /**
10323
+ * Check if the given experimental feature is enabled
10324
+ * @param featureSet All enabled features
10325
+ * @param feature The feature to check
10326
+ * @returns True if the given feature is enabled, otherwise false
10327
+ */
10328
+ function isFeatureEnabled(featureSet, feature) {
10329
+ return (featureSet || []).indexOf(feature) >= 0;
10152
10330
  }
10331
+ exports.isFeatureEnabled = isFeatureEnabled;
10153
10332
 
10154
10333
 
10155
10334
  /***/ }),
@@ -10164,10 +10343,16 @@ function isNodePosition(obj) {
10164
10343
  "use strict";
10165
10344
 
10166
10345
  Object.defineProperty(exports, "__esModule", { value: true });
10167
- exports.Editor = void 0;
10346
+ exports.createEditorCore = exports.isFeatureEnabled = exports.EditorBase = exports.Editor = void 0;
10168
10347
  // Classes
10169
10348
  var Editor_1 = __webpack_require__(/*! ./editor/Editor */ "./packages/roosterjs-editor-core/lib/editor/Editor.ts");
10170
10349
  Object.defineProperty(exports, "Editor", { enumerable: true, get: function () { return Editor_1.default; } });
10350
+ var EditorBase_1 = __webpack_require__(/*! ./editor/EditorBase */ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts");
10351
+ Object.defineProperty(exports, "EditorBase", { enumerable: true, get: function () { return EditorBase_1.EditorBase; } });
10352
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./editor/isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
10353
+ Object.defineProperty(exports, "isFeatureEnabled", { enumerable: true, get: function () { return isFeatureEnabled_1.isFeatureEnabled; } });
10354
+ var createEditorCore_1 = __webpack_require__(/*! ./editor/createEditorCore */ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts");
10355
+ Object.defineProperty(exports, "createEditorCore", { enumerable: true, get: function () { return createEditorCore_1.createEditorCore; } });
10171
10356
 
10172
10357
 
10173
10358
  /***/ }),
@@ -10422,12 +10607,18 @@ function getBlockElementAtNode(rootNode, node) {
10422
10607
  // Find the head and leaf node in the block
10423
10608
  var headNode = findHeadTailLeafNode(node, containerBlockNode, false /*isTail*/);
10424
10609
  var tailNode = findHeadTailLeafNode(node, containerBlockNode, true /*isTail*/);
10610
+ if (!headNode || !tailNode) {
10611
+ return null;
10612
+ }
10425
10613
  // At this point, we have the head and tail of a block, here are some examples and where head and tail point to
10426
10614
  // 1) &lt;root&gt;&lt;div&gt;hello&lt;br&gt;&lt;/div&gt;&lt;/root&gt;, head: hello, tail: &lt;br&gt;
10427
10615
  // 2) &lt;root&gt;&lt;div&gt;hello&lt;span style="font-family: Arial"&gt;world&lt;/span&gt;&lt;/div&gt;&lt;/root&gt;, head: hello, tail: world
10428
10616
  // Both are actually completely and exclusively wrapped in a parent div, and can be represented with a Node block
10429
10617
  // So we shall try to collapse as much as we can to the nearest common ancestor
10430
10618
  var nodes = (0, collapseNodes_1.default)(rootNode, headNode, tailNode, false /*canSplitParent*/);
10619
+ if (nodes.length === 0) {
10620
+ return null;
10621
+ }
10431
10622
  headNode = nodes[0];
10432
10623
  tailNode = nodes[nodes.length - 1];
10433
10624
  if (headNode.parentNode != tailNode.parentNode) {
@@ -21124,15 +21315,16 @@ var ContentEdit = /** @class */ (function () {
21124
21315
  this.editor = editor;
21125
21316
  var allFeatures = (0, getAllFeatures_1.default)();
21126
21317
  (0, roosterjs_editor_dom_1.getObjectKeys)(allFeatures).forEach(function (key) {
21318
+ var _a;
21127
21319
  var feature = allFeatures[key];
21128
21320
  var hasSettingForKey = _this.settingsOverride && _this.settingsOverride[key] !== undefined;
21129
- if ((hasSettingForKey && _this.settingsOverride[key]) ||
21321
+ if ((hasSettingForKey && ((_a = _this.settingsOverride) === null || _a === void 0 ? void 0 : _a[key])) ||
21130
21322
  (!hasSettingForKey && !feature.defaultDisabled)) {
21131
21323
  _this.features.push(feature);
21132
21324
  }
21133
21325
  });
21134
21326
  this.features = this.features.concat(this.additionalFeatures || []);
21135
- this.features.forEach(function (feature) { return _this.editor.addContentEditFeature(feature); });
21327
+ this.features.forEach(function (feature) { var _a; return (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.addContentEditFeature(feature); });
21136
21328
  };
21137
21329
  ContentEdit.prototype.disposeFeatures = function () {
21138
21330
  var _this = this;
@@ -21204,14 +21396,15 @@ function cacheGetLinkData(event, editor) {
21204
21396
  // This helps when we paste a link next to some existing character, and the text we got
21205
21397
  // from clipboard will only contain what we pasted, any existing characters will not
21206
21398
  // be included.
21207
- var clipboardData = event.eventType == 7 /* ContentChanged */ &&
21399
+ var clipboardData = (event.eventType == 7 /* ContentChanged */ &&
21208
21400
  event.source == "Paste" /* Paste */ &&
21209
- event.data;
21210
- var link = (0, roosterjs_editor_dom_1.matchLink)((clipboardData.text || '').trim());
21401
+ event.data) ||
21402
+ null;
21403
+ var link = (0, roosterjs_editor_dom_1.matchLink)(((clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.text) || '').trim());
21211
21404
  var searcher = editor.getContentSearcherOfCursor(event);
21212
21405
  // In case the matched link is already inside a <A> tag, we do a range search.
21213
21406
  // getRangeFromText will return null if the given text is already in a LinkInlineElement
21214
- if (link && searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/)) {
21407
+ if (link && (searcher === null || searcher === void 0 ? void 0 : searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/))) {
21215
21408
  return link;
21216
21409
  }
21217
21410
  var word = searcher && searcher.getWordBefore();
@@ -21236,12 +21429,15 @@ function cacheGetLinkData(event, editor) {
21236
21429
  }
21237
21430
  function hasLinkBeforeCursor(event, editor) {
21238
21431
  var contentSearcher = editor.getContentSearcherOfCursor(event);
21239
- var inline = contentSearcher.getInlineElementBefore();
21432
+ var inline = contentSearcher === null || contentSearcher === void 0 ? void 0 : contentSearcher.getInlineElementBefore();
21240
21433
  return inline instanceof roosterjs_editor_dom_1.LinkInlineElement;
21241
21434
  }
21242
21435
  function autoLink(event, editor) {
21243
- var anchor = editor.getDocument().createElement('a');
21244
21436
  var linkData = cacheGetLinkData(event, editor);
21437
+ if (!linkData) {
21438
+ return;
21439
+ }
21440
+ var anchor = editor.getDocument().createElement('a');
21245
21441
  // Need to get searcher before we enter the async callback since the callback can happen when cursor is moved to next line
21246
21442
  // and at that time a new searcher won't be able to find the link text to replace
21247
21443
  var searcher = editor.getContentSearcherOfCursor();
@@ -21249,7 +21445,7 @@ function autoLink(event, editor) {
21249
21445
  anchor.href = linkData.normalizedUrl;
21250
21446
  editor.runAsync(function (editor) {
21251
21447
  editor.addUndoSnapshot(function () {
21252
- (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher);
21448
+ (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher !== null && searcher !== void 0 ? searcher : undefined);
21253
21449
  // The content at cursor has changed. Should also clear the cursor data cache
21254
21450
  (0, roosterjs_editor_dom_1.clearEventDataCache)(event);
21255
21451
  return anchor;
@@ -21265,6 +21461,91 @@ exports.AutoLinkFeatures = {
21265
21461
  };
21266
21462
 
21267
21463
 
21464
+ /***/ }),
21465
+
21466
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts":
21467
+ /*!********************************************************************************************!*\
21468
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts ***!
21469
+ \********************************************************************************************/
21470
+ /*! no static exports found */
21471
+ /***/ (function(module, exports, __webpack_require__) {
21472
+
21473
+ "use strict";
21474
+
21475
+ Object.defineProperty(exports, "__esModule", { value: true });
21476
+ exports.CodeFeatures = void 0;
21477
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
21478
+ var RemoveCodeWhenEnterOnEmptyLine = {
21479
+ keys: [13 /* ENTER */],
21480
+ shouldHandleEvent: function (event, editor) {
21481
+ var childOfCode = cacheGetCodeChild(event, editor);
21482
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode);
21483
+ },
21484
+ handleEvent: function (event, editor) {
21485
+ event.rawEvent.preventDefault();
21486
+ editor.addUndoSnapshot(function () {
21487
+ splitCode(event, editor);
21488
+ }, undefined /* changeSource */, true /* canUndoByBackspace */);
21489
+ },
21490
+ };
21491
+ var RemoveCodeWhenBackspaceOnEmptyFirstLine = {
21492
+ keys: [8 /* BACKSPACE */],
21493
+ shouldHandleEvent: function (event, editor) {
21494
+ var childOfCode = cacheGetCodeChild(event, editor);
21495
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode) && !childOfCode.previousSibling;
21496
+ },
21497
+ handleEvent: function (event, editor) {
21498
+ event.rawEvent.preventDefault();
21499
+ editor.addUndoSnapshot(function () { return splitCode(event, editor); });
21500
+ },
21501
+ };
21502
+ function cacheGetCodeChild(event, editor) {
21503
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'CODE_CHILD', function () {
21504
+ var _a;
21505
+ var codeElement = (_a = editor.getElementAtCursor('code')) !== null && _a !== void 0 ? _a : editor.queryElements('code', 1 /* OnSelection */)[0];
21506
+ if (codeElement) {
21507
+ var pos = editor.getFocusedPosition();
21508
+ var block = pos && editor.getBlockElementAtNode(pos.normalize().node);
21509
+ if (block) {
21510
+ var node = block.getStartNode() == codeElement.parentNode
21511
+ ? block.getStartNode()
21512
+ : block.collapseToSingleElement();
21513
+ return (0, roosterjs_editor_dom_1.isNodeEmpty)(node) ? node : null;
21514
+ }
21515
+ }
21516
+ return null;
21517
+ });
21518
+ }
21519
+ function splitCode(event, editor) {
21520
+ var currentContainer = cacheGetCodeChild(event, editor);
21521
+ if (!(0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer, 'HTMLElement')) {
21522
+ return;
21523
+ }
21524
+ var codeChild = currentContainer.querySelector('code');
21525
+ if (!codeChild) {
21526
+ var codeParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21527
+ if (codeParent) {
21528
+ (0, roosterjs_editor_dom_1.unwrap)(codeParent);
21529
+ }
21530
+ if ((0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer.parentElement, 'HTMLPreElement')) {
21531
+ var preParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21532
+ if (preParent) {
21533
+ (0, roosterjs_editor_dom_1.unwrap)(preParent);
21534
+ }
21535
+ }
21536
+ }
21537
+ else {
21538
+ //Content model
21539
+ (0, roosterjs_editor_dom_1.unwrap)(codeChild);
21540
+ }
21541
+ editor.select(currentContainer, 0 /* Begin */);
21542
+ }
21543
+ exports.CodeFeatures = {
21544
+ removeCodeWhenEnterOnEmptyLine: RemoveCodeWhenEnterOnEmptyLine,
21545
+ removeCodeWhenBackspaceOnEmptyFirstLine: RemoveCodeWhenBackspaceOnEmptyFirstLine,
21546
+ };
21547
+
21548
+
21268
21549
  /***/ }),
21269
21550
 
21270
21551
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/cursorFeatures.ts":
@@ -21283,7 +21564,7 @@ var NoCycleCursorMove = {
21283
21564
  keys: [37 /* LEFT */, 39 /* RIGHT */],
21284
21565
  allowFunctionKeys: true,
21285
21566
  shouldHandleEvent: function (event, editor, ctrlOrMeta) {
21286
- var range;
21567
+ var range = null;
21287
21568
  var position;
21288
21569
  if (!ctrlOrMeta ||
21289
21570
  !(range = editor.getSelectionRange()) ||
@@ -21600,7 +21881,10 @@ function getBlockTraverser(editor, element) {
21600
21881
  return undefined;
21601
21882
  }
21602
21883
  var blockElement = (_a = editor.getBlockElementAtNode(element)) === null || _a === void 0 ? void 0 : _a.getStartNode();
21603
- return blockElement ? roosterjs_editor_dom_1.ContentTraverser.createBodyTraverser(blockElement, element) : undefined;
21884
+ if (!blockElement || !(0, roosterjs_editor_dom_2.isBlockElement)(blockElement)) {
21885
+ return undefined;
21886
+ }
21887
+ return roosterjs_editor_dom_1.ContentTraverser.createBodyTraverser(blockElement, element);
21604
21888
  }
21605
21889
  function cacheDelimiter(event, checkBefore, delimiter) {
21606
21890
  return (0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'delimiter_cache_key_' + checkBefore, function () { return delimiter; });
@@ -21733,8 +22017,10 @@ var shouldHandleIndentationEvent = function (indenting) { return function (event
21733
22017
  cacheGetListElement(event, editor));
21734
22018
  }; };
21735
22019
  var handleIndentationEvent = function (indenting) { return function (event, editor) {
22020
+ var currentElement = null;
21736
22021
  var isRTL = event.rawEvent.keyCode !== 9 /* TAB */ &&
21737
- (0, roosterjs_editor_dom_1.getComputedStyle)(editor.getElementAtCursor(), 'direction') == 'rtl';
22022
+ (currentElement = editor.getElementAtCursor()) &&
22023
+ (0, roosterjs_editor_dom_1.getComputedStyle)(currentElement, 'direction') == 'rtl';
21738
22024
  (0, roosterjs_editor_api_1.setIndentation)(editor, isRTL == indenting ? 1 /* Decrease */ : 0 /* Increase */);
21739
22025
  event.rawEvent.preventDefault();
21740
22026
  }; };
@@ -21742,20 +22028,39 @@ var handleIndentationEvent = function (indenting) { return function (event, edit
21742
22028
  * IndentWhenTab edit feature, provides the ability to indent current list when user press TAB
21743
22029
  */
21744
22030
  var IndentWhenTab = {
21745
- keys: roosterjs_editor_dom_1.Browser.isMac ? [9 /* TAB */] : [9 /* TAB */, 39 /* RIGHT */],
22031
+ keys: [9 /* TAB */],
21746
22032
  shouldHandleEvent: shouldHandleIndentationEvent(true),
21747
22033
  handleEvent: handleIndentationEvent(true),
21748
- allowFunctionKeys: true,
21749
22034
  };
21750
22035
  /**
21751
22036
  * OutdentWhenShiftTab edit feature, provides the ability to outdent current list when user press Shift+TAB
21752
22037
  */
21753
22038
  var OutdentWhenShiftTab = {
21754
- keys: roosterjs_editor_dom_1.Browser.isMac ? [9 /* TAB */] : [9 /* TAB */, 37 /* LEFT */],
22039
+ keys: [9 /* TAB */],
21755
22040
  shouldHandleEvent: shouldHandleIndentationEvent(false),
21756
22041
  handleEvent: handleIndentationEvent(false),
21757
22042
  allowFunctionKeys: true,
21758
22043
  };
22044
+ /**
22045
+ * indentWhenAltShiftRight edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Right
22046
+ */
22047
+ var IndentWhenAltShiftRight = {
22048
+ keys: [39 /* RIGHT */],
22049
+ shouldHandleEvent: shouldHandleIndentationEvent(true),
22050
+ handleEvent: handleIndentationEvent(true),
22051
+ allowFunctionKeys: true,
22052
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
22053
+ };
22054
+ /**
22055
+ * outdentWhenAltShiftLeft edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Left
22056
+ */
22057
+ var OutdentWhenAltShiftLeft = {
22058
+ keys: [37 /* LEFT */],
22059
+ shouldHandleEvent: shouldHandleIndentationEvent(false),
22060
+ handleEvent: handleIndentationEvent(false),
22061
+ allowFunctionKeys: true,
22062
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
22063
+ };
21759
22064
  /**
21760
22065
  * MergeInNewLine edit feature, provides the ability to merge current line into a new line when user press
21761
22066
  * BACKSPACE at beginning of a list item
@@ -21763,16 +22068,16 @@ var OutdentWhenShiftTab = {
21763
22068
  var MergeInNewLine = {
21764
22069
  keys: [8 /* BACKSPACE */],
21765
22070
  shouldHandleEvent: function (event, editor) {
21766
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22071
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21767
22072
  var range = editor.getSelectionRange();
21768
22073
  return li && (range === null || range === void 0 ? void 0 : range.collapsed) && (0, roosterjs_editor_dom_1.isPositionAtBeginningOf)(roosterjs_editor_dom_1.Position.getStart(range), li);
21769
22074
  },
21770
22075
  handleEvent: function (event, editor) {
21771
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21772
- if (li.previousSibling) {
22076
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22077
+ if (li === null || li === void 0 ? void 0 : li.previousSibling) {
21773
22078
  (0, roosterjs_editor_api_1.blockFormat)(editor, function (region, start, end) {
21774
- var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li);
21775
- if (vList) {
22079
+ var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li !== null && li !== void 0 ? li : undefined);
22080
+ if (vList && start && end) {
21776
22081
  vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
21777
22082
  vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
21778
22083
  event.rawEvent.preventDefault();
@@ -21792,7 +22097,7 @@ var MergeInNewLine = {
21792
22097
  var OutdentWhenBackOn1stEmptyLine = {
21793
22098
  keys: [8 /* BACKSPACE */],
21794
22099
  shouldHandleEvent: function (event, editor) {
21795
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22100
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21796
22101
  return (li &&
21797
22102
  (0, roosterjs_editor_dom_1.isNodeEmpty)(li) &&
21798
22103
  !li.previousSibling &&
@@ -21807,12 +22112,13 @@ var OutdentWhenBackOn1stEmptyLine = {
21807
22112
  var MaintainListChainWhenDelete = {
21808
22113
  keys: [46 /* DELETE */],
21809
22114
  shouldHandleEvent: function (event, editor) {
21810
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21811
- if (li) {
22115
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22116
+ var range = editor.getSelectionRange();
22117
+ if (li || !range) {
21812
22118
  return false;
21813
22119
  }
21814
- var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(editor.getSelectionRange()).isAtEnd;
21815
- var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : null;
22120
+ var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(range).isAtEnd;
22121
+ var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : undefined;
21816
22122
  var isAtEndAndBeforeLI = editor.getElementAtCursor('LI', nextSibling, event);
21817
22123
  return isAtEndAndBeforeLI;
21818
22124
  },
@@ -21828,11 +22134,11 @@ var MaintainListChainWhenDelete = {
21828
22134
  var OutdentWhenEnterOnEmptyLine = {
21829
22135
  keys: [13 /* ENTER */],
21830
22136
  shouldHandleEvent: function (event, editor) {
21831
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22137
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21832
22138
  return !event.rawEvent.shiftKey && li && (0, roosterjs_editor_dom_1.isNodeEmpty)(li);
21833
22139
  },
21834
22140
  handleEvent: function (event, editor) {
21835
- editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22141
+ editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21836
22142
  },
21837
22143
  defaultDisabled: !roosterjs_editor_dom_1.Browser.isIE && !roosterjs_editor_dom_1.Browser.isChrome,
21838
22144
  };
@@ -21854,9 +22160,10 @@ function isAListPattern(textBeforeCursor) {
21854
22160
  var AutoBullet = {
21855
22161
  keys: [32 /* SPACE */],
21856
22162
  shouldHandleEvent: function (event, editor) {
22163
+ var searcher;
21857
22164
  if (!cacheGetListElement(event, editor) &&
21858
- !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
21859
- var searcher = editor.getContentSearcherOfCursor(event);
22165
+ !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */) &&
22166
+ (searcher = editor.getContentSearcherOfCursor(event))) {
21860
22167
  var textBeforeCursor = searcher.getSubStringBefore(4);
21861
22168
  // Auto list is triggered if:
21862
22169
  // 1. Text before cursor exactly matches '*', '-' or '1.'
@@ -21872,6 +22179,9 @@ var AutoBullet = {
21872
22179
  var _a;
21873
22180
  var regions;
21874
22181
  var searcher = editor.getContentSearcherOfCursor();
22182
+ if (!searcher) {
22183
+ return;
22184
+ }
21875
22185
  var textBeforeCursor = searcher.getSubStringBefore(4);
21876
22186
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21877
22187
  if (!textRange) {
@@ -21892,7 +22202,7 @@ var AutoBullet = {
21892
22202
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, num);
21893
22203
  }
21894
22204
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21895
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22205
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21896
22206
  },
21897
22207
  };
21898
22208
  /**
@@ -21914,15 +22224,18 @@ var AutoBulletList = {
21914
22224
  editor.addUndoSnapshot(function () {
21915
22225
  var _a;
21916
22226
  var searcher = editor.getContentSearcherOfCursor();
22227
+ if (!searcher) {
22228
+ return;
22229
+ }
21917
22230
  var textBeforeCursor = searcher.getSubStringBefore(5);
21918
22231
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21919
22232
  var listStyle = (0, getAutoBulletListStyle_1.default)(textBeforeCursor);
21920
22233
  if (textRange) {
21921
22234
  prepareAutoBullet(editor, textRange);
21922
- (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle, 'autoToggleList' /** apiNameOverride */);
22235
+ (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle !== null && listStyle !== void 0 ? listStyle : undefined, 'autoToggleList' /** apiNameOverride */);
21923
22236
  }
21924
22237
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21925
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22238
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21926
22239
  },
21927
22240
  };
21928
22241
  /**
@@ -21942,8 +22255,11 @@ var AutoNumberingList = {
21942
22255
  editor.insertContent('&nbsp;');
21943
22256
  event.rawEvent.preventDefault();
21944
22257
  editor.addUndoSnapshot(function () {
21945
- var _a;
22258
+ var _a, _b;
21946
22259
  var searcher = editor.getContentSearcherOfCursor();
22260
+ if (!searcher) {
22261
+ return;
22262
+ }
21947
22263
  var textBeforeCursor = searcher.getSubStringBefore(5);
21948
22264
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21949
22265
  if (textRange) {
@@ -21951,19 +22267,20 @@ var AutoNumberingList = {
21951
22267
  ? 1
21952
22268
  : parseInt(textBeforeCursor);
21953
22269
  var isLi = getPreviousListItem(editor, textRange);
21954
- var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
22270
+ var listStyle = (_a = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor)) !== null && _a !== void 0 ? _a : undefined;
21955
22271
  prepareAutoBullet(editor, textRange);
21956
22272
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, isLi && number !== 1 ? undefined : number /** startNumber */, listStyle, 'autoToggleList' /** apiNameOverride */);
21957
22273
  }
21958
- (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21959
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22274
+ (_b = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _b === void 0 ? void 0 : _b.deleteContents();
22275
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21960
22276
  },
21961
22277
  };
21962
22278
  var getPreviousListItem = function (editor, textRange) {
22279
+ var _a;
21963
22280
  var blockElement = editor
21964
22281
  .getBodyTraverser(textRange === null || textRange === void 0 ? void 0 : textRange.startContainer)
21965
22282
  .getPreviousBlockElement();
21966
- var previousNode = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode();
22283
+ var previousNode = (_a = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode()) !== null && _a !== void 0 ? _a : null;
21967
22284
  return (0, roosterjs_editor_dom_1.getTagOfNode)(previousNode) === 'LI' ? previousNode : undefined;
21968
22285
  };
21969
22286
  var getPreviousListType = function (editor, textRange, listType) {
@@ -22011,13 +22328,14 @@ function getCacheNextSibling(event, editor) {
22011
22328
  var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'nextSibling', function () {
22012
22329
  var _a;
22013
22330
  var range = editor.getSelectionRange();
22014
- var pos = roosterjs_editor_dom_1.Position.getEnd(range).normalize();
22015
- var traverser = editor.getBodyTraverser(pos.node);
22331
+ var pos = range && roosterjs_editor_dom_1.Position.getEnd(range).normalize();
22332
+ var traverser = pos && editor.getBodyTraverser(pos.node);
22016
22333
  return (_a = traverser === null || traverser === void 0 ? void 0 : traverser.getNextBlockElement()) === null || _a === void 0 ? void 0 : _a.getStartNode();
22017
22334
  });
22018
22335
  return element;
22019
22336
  }
22020
22337
  function prepareAutoBullet(editor, range) {
22338
+ var _a;
22021
22339
  var block = editor.getBlockElementAtNode(range.startContainer);
22022
22340
  var endNode = block === null || block === void 0 ? void 0 : block.getEndNode();
22023
22341
  if (endNode && (0, roosterjs_editor_dom_1.getTagOfNode)(endNode) != 'BR') {
@@ -22026,7 +22344,7 @@ function prepareAutoBullet(editor, range) {
22026
22344
  endNode.appendChild(br);
22027
22345
  }
22028
22346
  else {
22029
- endNode.parentNode.insertBefore(br, endNode.nextSibling);
22347
+ (_a = endNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, endNode.nextSibling);
22030
22348
  }
22031
22349
  editor.select(range.startContainer, range.startOffset);
22032
22350
  }
@@ -22038,19 +22356,22 @@ function toggleListAndPreventDefault(event, editor, includeSiblingLists) {
22038
22356
  var listElement = listInfo[0];
22039
22357
  var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(listElement);
22040
22358
  if (tag == 'UL' || tag == 'OL') {
22041
- (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, null /* startNumber */, includeSiblingLists);
22359
+ (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, undefined /* startNumber */, includeSiblingLists);
22042
22360
  }
22043
22361
  editor.focus();
22044
22362
  event.rawEvent.preventDefault();
22045
22363
  }
22046
22364
  }
22047
22365
  function cacheGetListElement(event, editor) {
22048
- var li = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
22366
+ var li = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
22049
22367
  var listElement = li && (0, roosterjs_editor_dom_1.getTagOfNode)(li) == 'LI' && editor.getElementAtCursor('UL,OL', li);
22050
22368
  return listElement ? [listElement, li] : null;
22051
22369
  }
22052
22370
  function shouldTriggerList(event, editor, getListStyle, listType) {
22053
22371
  var searcher = editor.getContentSearcherOfCursor(event);
22372
+ if (!searcher) {
22373
+ return false;
22374
+ }
22054
22375
  var textBeforeCursor = searcher.getSubStringBefore(4);
22055
22376
  var traverser = editor.getBlockTraverser();
22056
22377
  var text = traverser && traverser.currentBlockElement
@@ -22059,9 +22380,9 @@ function shouldTriggerList(event, editor, getListStyle, listType) {
22059
22380
  var isATheBeginning = text && text === textBeforeCursor;
22060
22381
  var listChains = getListChains(editor);
22061
22382
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
22062
- var previousListType = getPreviousListType(editor, textRange, listType);
22383
+ var previousListType = textRange && getPreviousListType(editor, textRange, listType);
22063
22384
  var isFirstItem = isFirstItemOfAList(textBeforeCursor);
22064
- var listStyle = getListStyle(textBeforeCursor, listChains, previousListType);
22385
+ var listStyle = getListStyle(textBeforeCursor, listChains, previousListType !== null && previousListType !== void 0 ? previousListType : undefined);
22065
22386
  var shouldTriggerNewListStyle = isFirstItem ||
22066
22387
  !previousListType ||
22067
22388
  previousListType === listStyle ||
@@ -22137,6 +22458,8 @@ exports.ListFeatures = {
22137
22458
  autoNumberingList: AutoNumberingList,
22138
22459
  autoBulletList: AutoBulletList,
22139
22460
  mergeListOnBackspaceAfterList: MergeListOnBackspaceAfterList,
22461
+ outdentWhenAltShiftLeft: OutdentWhenAltShiftLeft,
22462
+ indentWhenAltShiftRight: IndentWhenAltShiftRight,
22140
22463
  };
22141
22464
  function isList(element) {
22142
22465
  return (!!element &&
@@ -22177,8 +22500,8 @@ function generateBasicMarkdownFeature(key, triggerCharacter, elementTag, useShif
22177
22500
  function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22178
22501
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'MARKDOWN_RANGE', function () {
22179
22502
  var searcher = editor.getContentSearcherOfCursor(event);
22180
- var startPosition;
22181
- var endPosition;
22503
+ var startPosition = null;
22504
+ var endPosition = null;
22182
22505
  searcher === null || searcher === void 0 ? void 0 : searcher.forEachTextInlineElement(function (textInlineElement) {
22183
22506
  if (endPosition && startPosition) {
22184
22507
  return true;
@@ -22216,12 +22539,15 @@ function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22216
22539
  }
22217
22540
  }
22218
22541
  });
22219
- return !!startPosition && !!endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22542
+ return startPosition && endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22220
22543
  });
22221
22544
  }
22222
22545
  function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22223
22546
  editor.addUndoSnapshot(function () {
22224
22547
  var range = cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter);
22548
+ if (!range) {
22549
+ return;
22550
+ }
22225
22551
  var lastTypedTriggerPosition = new roosterjs_editor_dom_1.Position(range.endContainer, -1 /* End */);
22226
22552
  var hasLastTypedTrigger = range.endOffset + 1 <= lastTypedTriggerPosition.offset;
22227
22553
  if (!!range && hasLastTypedTrigger) {
@@ -22229,7 +22555,7 @@ function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22229
22555
  var textContentRange = range.cloneRange();
22230
22556
  textContentRange.setStart(textContentRange.startContainer, textContentRange.startOffset + 1);
22231
22557
  var text = textContentRange.extractContents().textContent;
22232
- var textNode = editor.getDocument().createTextNode(text);
22558
+ var textNode = editor.getDocument().createTextNode(text !== null && text !== void 0 ? text : '');
22233
22559
  // extract content and put it into a new element.
22234
22560
  var elementToWrap = (0, roosterjs_editor_dom_1.wrap)(textNode, elementTag);
22235
22561
  //include last typed character
@@ -22313,7 +22639,7 @@ var UnquoteWhenEnterOnEmptyLine = {
22313
22639
  return !shift && childOfQuote && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfQuote);
22314
22640
  },
22315
22641
  handleEvent: function (event, editor) {
22316
- return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22642
+ return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
22317
22643
  },
22318
22644
  };
22319
22645
  function cacheGetQuoteChild(event, editor) {
@@ -22335,14 +22661,15 @@ function cacheGetQuoteChild(event, editor) {
22335
22661
  function splitQuote(event, editor) {
22336
22662
  editor.addUndoSnapshot(function () {
22337
22663
  var childOfQuote = cacheGetQuoteChild(event, editor);
22338
- var parent;
22339
- var shouldClearFormat;
22664
+ if (!childOfQuote) {
22665
+ return;
22666
+ }
22340
22667
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childOfQuote) == QUOTE_TAG) {
22341
22668
  childOfQuote = (0, roosterjs_editor_dom_1.wrap)((0, roosterjs_editor_dom_1.toArray)(childOfQuote.childNodes));
22342
22669
  }
22343
- parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22344
- shouldClearFormat = isStyledBlockquote(parent);
22345
- var newParent = (0, roosterjs_editor_dom_1.unwrap)(parent);
22670
+ var parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22671
+ var shouldClearFormat = !!parent && isStyledBlockquote(parent);
22672
+ var newParent = parent && (0, roosterjs_editor_dom_1.unwrap)(parent);
22346
22673
  editor.select(childOfQuote, 0 /* Begin */);
22347
22674
  if (shouldClearFormat) {
22348
22675
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(newParent, 'HTMLLIElement')) {
@@ -22508,7 +22835,8 @@ var InsertLineBeforeStructuredNodeFeature = {
22508
22835
  var element = cacheGetStructuredElement(event, editor);
22509
22836
  var div = (0, roosterjs_editor_dom_1.createElement)(1 /* EmptyLine */, editor.getDocument());
22510
22837
  editor.addUndoSnapshot(function () {
22511
- element.parentNode.insertBefore(div, element);
22838
+ var _a;
22839
+ (_a = element === null || element === void 0 ? void 0 : element.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(div, element);
22512
22840
  // Select the new line when we are in table. This is the same behavior with Word
22513
22841
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(element) == 'TABLE') {
22514
22842
  editor.select(new roosterjs_editor_dom_1.Position(div, 0 /* Begin */).normalize());
@@ -22566,21 +22894,26 @@ var TabInTable = {
22566
22894
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22567
22895
  },
22568
22896
  handleEvent: function (event, editor) {
22897
+ var _a, _b, _c;
22569
22898
  var shift = event.rawEvent.shiftKey;
22570
22899
  var td = cacheGetTableCell(event, editor);
22900
+ if (!td) {
22901
+ return;
22902
+ }
22571
22903
  var vtable = cacheVTable(event, td);
22572
- for (var step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
22573
- if (col < 0 || col >= vtable.cells[row].length) {
22904
+ for (var step = shift ? -1 : 1, row = (_a = vtable.row) !== null && _a !== void 0 ? _a : 0, col = ((_b = vtable.col) !== null && _b !== void 0 ? _b : 0) + step;; col += step) {
22905
+ var tableCells = (_c = vtable.cells) !== null && _c !== void 0 ? _c : [];
22906
+ if (col < 0 || col >= tableCells[row].length) {
22574
22907
  row += step;
22575
22908
  if (row < 0) {
22576
22909
  editor.select(vtable.table, -2 /* Before */);
22577
22910
  break;
22578
22911
  }
22579
- else if (row >= vtable.cells.length) {
22912
+ else if (row >= tableCells.length) {
22580
22913
  (0, roosterjs_editor_api_1.editTable)(editor, 1 /* InsertBelow */);
22581
22914
  break;
22582
22915
  }
22583
- col = shift ? vtable.cells[row].length - 1 : 0;
22916
+ col = shift ? tableCells[row].length - 1 : 0;
22584
22917
  }
22585
22918
  var cell = vtable.getCell(row, col);
22586
22919
  if (cell.td) {
@@ -22606,6 +22939,9 @@ var IndentTableOnTab = {
22606
22939
  var shift = event.rawEvent.shiftKey;
22607
22940
  var selection = editor.getSelectionRangeEx();
22608
22941
  var td = cacheGetTableCell(event, editor);
22942
+ if (!td) {
22943
+ return;
22944
+ }
22609
22945
  var vtable = cacheVTable(event, td);
22610
22946
  if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
22611
22947
  (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
@@ -22613,7 +22949,9 @@ var IndentTableOnTab = {
22613
22949
  else if (!shift) {
22614
22950
  (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
22615
22951
  }
22616
- editor.select(selection.table, selection.coordinates);
22952
+ if (selection.coordinates) {
22953
+ editor.select(selection.table, selection.coordinates);
22954
+ }
22617
22955
  });
22618
22956
  },
22619
22957
  };
@@ -22627,8 +22965,11 @@ var UpDownInTable = {
22627
22965
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22628
22966
  },
22629
22967
  handleEvent: function (event, editor) {
22630
- var _a;
22968
+ var _a, _b, _c;
22631
22969
  var td = cacheGetTableCell(event, editor);
22970
+ if (!td) {
22971
+ return;
22972
+ }
22632
22973
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22633
22974
  var isUp = event.rawEvent.which == 38 /* UP */;
22634
22975
  var step = isUp ? -1 : 1;
@@ -22637,8 +22978,8 @@ var UpDownInTable = {
22637
22978
  var targetTd = null;
22638
22979
  if (selection) {
22639
22980
  var anchorNode_1 = selection.anchorNode, anchorOffset_1 = selection.anchorOffset;
22640
- for (var row = vtable.row; row >= 0 && row < vtable.cells.length; row += step) {
22641
- var cell = vtable.getCell(row, vtable.col);
22981
+ for (var row = (_b = vtable.row) !== null && _b !== void 0 ? _b : 0; row >= 0 && vtable.cells && row < vtable.cells.length; row += step) {
22982
+ var cell = vtable.getCell(row, (_c = vtable.col) !== null && _c !== void 0 ? _c : 0);
22642
22983
  if (cell.td && cell.td != td) {
22643
22984
  targetTd = cell.td;
22644
22985
  break;
@@ -22659,7 +23000,9 @@ var UpDownInTable = {
22659
23000
  ? new roosterjs_editor_dom_1.Position(newPos.node, newPos.isAtEnd ? -3 /* After */ : -2 /* Before */)
22660
23001
  : newPos;
22661
23002
  var selection_1 = (_a = editor.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
22662
- selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
23003
+ if (anchorNode_1) {
23004
+ selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
23005
+ }
22663
23006
  }
22664
23007
  else {
22665
23008
  editor.select(newPos.normalize());
@@ -22682,6 +23025,9 @@ var DeleteTableWithBackspace = {
22682
23025
  },
22683
23026
  handleEvent: function (event, editor) {
22684
23027
  var td = cacheGetTableCell(event, editor);
23028
+ if (!td) {
23029
+ return;
23030
+ }
22685
23031
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22686
23032
  vtable.edit(4 /* DeleteTable */);
22687
23033
  vtable.writeBack();
@@ -22697,9 +23043,13 @@ function cacheGetTableCell(event, editor) {
22697
23043
  function cacheIsWholeTableSelected(event, editor) {
22698
23044
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
22699
23045
  var td = cacheGetTableCell(event, editor);
23046
+ if (!td) {
23047
+ return false;
23048
+ }
22700
23049
  var vtable = cacheVTable(event, td);
22701
23050
  var selection = editor.getSelectionRangeEx();
22702
23051
  return (selection.type == 1 /* TableSelection */ &&
23052
+ selection.coordinates &&
22703
23053
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
22704
23054
  });
22705
23055
  }
@@ -22749,7 +23099,7 @@ var IndentWhenTabText = {
22749
23099
  if (editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */) &&
22750
23100
  !event.rawEvent.shiftKey) {
22751
23101
  var activeElement = editor.getDocument().activeElement;
22752
- var listOrTable = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
23102
+ var listOrTable = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
22753
23103
  var entity = editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), undefined /*startFrom*/, event);
22754
23104
  return (!listOrTable &&
22755
23105
  (entity ? entity.isContentEditable : activeElement.isContentEditable));
@@ -22793,8 +23143,8 @@ var OutdentWhenTabText = {
22793
23143
  var selection = editor.getSelectionRangeEx();
22794
23144
  return (selection.type == 0 /* Normal */ &&
22795
23145
  !selection.areAllCollapsed &&
22796
- editor.getElementAtCursor('blockquote', null, event) &&
22797
- !editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event) &&
23146
+ editor.getElementAtCursor('blockquote', undefined, event) &&
23147
+ !editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event) &&
22798
23148
  shouldSetIndentation(editor, selection.ranges[0]));
22799
23149
  }
22800
23150
  return false;
@@ -22858,9 +23208,12 @@ function isRangeEmpty(range) {
22858
23208
  function insertTab(editor, event) {
22859
23209
  var span = editor.getDocument().createElement('span');
22860
23210
  var searcher = editor.getContentSearcherOfCursor(event);
23211
+ if (!searcher) {
23212
+ return;
23213
+ }
22861
23214
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
22862
23215
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
22863
- var span2;
23216
+ var span2 = null;
22864
23217
  var textContent = '';
22865
23218
  for (var index = 0; index < numberOfChars; index++) {
22866
23219
  textContent += '&ensp;';
@@ -22917,7 +23270,8 @@ var shortcutFeatures_1 = __webpack_require__(/*! ./features/shortcutFeatures */
22917
23270
  var structuredNodeFeatures_1 = __webpack_require__(/*! ./features/structuredNodeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/structuredNodeFeatures.ts");
22918
23271
  var tableFeatures_1 = __webpack_require__(/*! ./features/tableFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/tableFeatures.ts");
22919
23272
  var textFeatures_1 = __webpack_require__(/*! ./features/textFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/textFeatures.ts");
22920
- var allFeatures = __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, listFeatures_1.ListFeatures), quoteFeatures_1.QuoteFeatures), tableFeatures_1.TableFeatures), structuredNodeFeatures_1.StructuredNodeFeatures), autoLinkFeatures_1.AutoLinkFeatures), shortcutFeatures_1.ShortcutFeatures), cursorFeatures_1.CursorFeatures), markdownFeatures_1.MarkdownFeatures), entityFeatures_1.EntityFeatures), textFeatures_1.TextFeatures);
23273
+ var codeFeatures_1 = __webpack_require__(/*! ./features/codeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts");
23274
+ var allFeatures = __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, listFeatures_1.ListFeatures), quoteFeatures_1.QuoteFeatures), tableFeatures_1.TableFeatures), structuredNodeFeatures_1.StructuredNodeFeatures), autoLinkFeatures_1.AutoLinkFeatures), shortcutFeatures_1.ShortcutFeatures), cursorFeatures_1.CursorFeatures), markdownFeatures_1.MarkdownFeatures), entityFeatures_1.EntityFeatures), textFeatures_1.TextFeatures), codeFeatures_1.CodeFeatures);
22921
23275
  /**
22922
23276
  * Get all content edit features provided by roosterjs
22923
23277
  */
@@ -23053,7 +23407,8 @@ var identifyNumberingType = function (text, previousListStyle) {
23053
23407
  return 1 /* Decimal */;
23054
23408
  }
23055
23409
  else if (/[a-z]+/g.test(text)) {
23056
- if ((lowerRomanTypes.indexOf(previousListStyle) > -1 &&
23410
+ if ((previousListStyle != undefined &&
23411
+ lowerRomanTypes.indexOf(previousListStyle) > -1 &&
23057
23412
  lowerRomanNumbers.indexOf(text[0]) > -1) ||
23058
23413
  (!previousListStyle && text === 'i')) {
23059
23414
  return 4 /* LowerRoman */;
@@ -23063,7 +23418,8 @@ var identifyNumberingType = function (text, previousListStyle) {
23063
23418
  }
23064
23419
  }
23065
23420
  else if (/[A-Z]+/g.test(text)) {
23066
- if ((upperRomanTypes.indexOf(previousListStyle) > -1 &&
23421
+ if ((previousListStyle != undefined &&
23422
+ upperRomanTypes.indexOf(previousListStyle) > -1 &&
23067
23423
  upperRomanNumbers.indexOf(text[0]) > -1) ||
23068
23424
  (!previousListStyle && text === 'I')) {
23069
23425
  return 5 /* UpperRoman */;
@@ -24178,6 +24534,7 @@ var ImageEdit = /** @class */ (function () {
24178
24534
  //Clone the image and insert the clone in a entity
24179
24535
  this.clonedImage = this.image.cloneNode(true);
24180
24536
  this.clonedImage.removeAttribute('id');
24537
+ this.clonedImage.style.removeProperty('max-width');
24181
24538
  this.wrapper = (0, roosterjs_editor_dom_1.createElement)(6 /* ImageEditWrapper */, this.image.ownerDocument);
24182
24539
  (_b = (_a = this.wrapper) === null || _a === void 0 ? void 0 : _a.firstChild) === null || _b === void 0 ? void 0 : _b.appendChild(this.clonedImage);
24183
24540
  this.wrapper.style.display = roosterjs_editor_dom_1.Browser.isSafari ? 'inline-block' : 'inline-flex';
@@ -24489,6 +24846,7 @@ function resizeByPercentage(editor, image, percentage, minWidth, minHeight) {
24489
24846
  editor.addUndoSnapshot(function () {
24490
24847
  (0, applyChange_1.default)(editor, image, editInfo, lastSrc_1 || '', true /*wasResized*/);
24491
24848
  }, "ImageResize" /* ImageResize */);
24849
+ editor.select(image);
24492
24850
  }
24493
24851
  });
24494
24852
  }
@@ -25510,6 +25868,7 @@ var Paste = /** @class */ (function () {
25510
25868
  if (convertSingleImageBody === void 0) { convertSingleImageBody = false; }
25511
25869
  this.unknownTagReplacement = unknownTagReplacement;
25512
25870
  this.convertSingleImageBody = convertSingleImageBody;
25871
+ this.editor = null;
25513
25872
  }
25514
25873
  /**
25515
25874
  * Get a friendly name of this plugin
@@ -25535,7 +25894,7 @@ var Paste = /** @class */ (function () {
25535
25894
  * @param event PluginEvent object
25536
25895
  */
25537
25896
  Paste.prototype.onPluginEvent = function (event) {
25538
- if (event.eventType == 10 /* BeforePaste */) {
25897
+ if (this.editor && event.eventType == 10 /* BeforePaste */) {
25539
25898
  var fragment = event.fragment, sanitizingOption = event.sanitizingOption;
25540
25899
  var trustedHTMLHandler = this.editor.getTrustedHTMLHandler();
25541
25900
  switch ((0, getPasteSource_1.default)(event, this.convertSingleImageBody)) {
@@ -25544,22 +25903,23 @@ var Paste = /** @class */ (function () {
25544
25903
  (0, convertPastedContentFromWord_1.default)(event);
25545
25904
  break;
25546
25905
  case 1 /* ExcelDesktop */:
25906
+ case 2 /* ExcelOnline */:
25547
25907
  // Handle HTML copied from Excel
25548
25908
  (0, convertPastedContentFromExcel_1.default)(event, trustedHTMLHandler);
25549
25909
  break;
25550
- case 2 /* PowerPointDesktop */:
25910
+ case 3 /* PowerPointDesktop */:
25551
25911
  (0, convertPastedContentFromPowerPoint_1.default)(event, trustedHTMLHandler);
25552
25912
  break;
25553
- case 4 /* WacComponents */:
25913
+ case 5 /* WacComponents */:
25554
25914
  (0, convertPastedContentFromOfficeOnline_1.default)(fragment);
25555
25915
  break;
25556
- case 3 /* GoogleSheets */:
25916
+ case 4 /* GoogleSheets */:
25557
25917
  sanitizingOption.additionalTagReplacements[constants_1.GOOGLE_SHEET_NODE_NAME] = '*';
25558
25918
  break;
25559
- case 6 /* SingleImage */:
25919
+ case 7 /* SingleImage */:
25560
25920
  (0, convertPasteContentForSingleImage_1.default)(event, trustedHTMLHandler);
25561
25921
  break;
25562
- case 5 /* Default */:
25922
+ case 6 /* Default */:
25563
25923
  (0, convertPastedContentForLI_1.default)(fragment);
25564
25924
  (0, handleLineMerge_1.default)(fragment);
25565
25925
  break;
@@ -25654,12 +26014,28 @@ var DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';
25654
26014
  * @param event The BeforePaste event
25655
26015
  */
25656
26016
  function convertPastedContentFromExcel(event, trustedHTMLHandler) {
26017
+ var _a, _b;
25657
26018
  var fragment = event.fragment, sanitizingOption = event.sanitizingOption, htmlBefore = event.htmlBefore, clipboardData = event.clipboardData;
25658
- var html = excelHandler(clipboardData.html, htmlBefore);
25659
- if (clipboardData.html != html) {
26019
+ var fragmentHTML = (_b = (_a = fragment.firstElementChild) === null || _a === void 0 ? void 0 : _a.outerHTML) !== null && _b !== void 0 ? _b : clipboardData.html;
26020
+ var html = fragmentHTML ? excelHandler(fragmentHTML, htmlBefore) : undefined;
26021
+ if (html && fragmentHTML != html) {
25660
26022
  var doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');
25661
26023
  (0, roosterjs_editor_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
25662
26024
  }
26025
+ // For Excel Online
26026
+ var firstChild = fragment.firstChild;
26027
+ if (firstChild && firstChild.childNodes.length > 0 && (0, roosterjs_editor_dom_1.getTagOfNode)(firstChild) == 'DIV') {
26028
+ var tableFound = Array.from(firstChild.childNodes).every(function (child) {
26029
+ // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag
26030
+ return (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'META'
26031
+ ? true
26032
+ : (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'TABLE' && child == firstChild.lastChild;
26033
+ });
26034
+ // Extract Table from Div
26035
+ if (tableFound && firstChild.lastChild) {
26036
+ event.fragment.replaceChildren(firstChild.lastChild);
26037
+ }
26038
+ }
25663
26039
  (0, roosterjs_editor_dom_1.chainSanitizerCallback)(sanitizingOption.elementCallbacks, 'TD', function (element) {
25664
26040
  if (element.style.borderStyle == 'none') {
25665
26041
  element.style.border = DEFAULT_BORDER_STYLE;
@@ -25773,21 +26149,23 @@ function handleLineMerge(root) {
25773
26149
  }
25774
26150
  exports.default = handleLineMerge;
25775
26151
  function processBlock(block) {
25776
- var _a, _b;
26152
+ var _a, _b, _c;
25777
26153
  var start = block.start, end = block.end;
25778
26154
  if (start == end && (0, roosterjs_editor_dom_1.getTagOfNode)(start) == 'DIV') {
25779
26155
  var node = (0, roosterjs_editor_dom_1.changeElementTag)(start, 'SPAN');
25780
26156
  block.start = node;
25781
26157
  block.end = node;
25782
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
26158
+ if (node && node.lastChild && (0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
25783
26159
  node.removeChild(node.lastChild);
25784
26160
  }
25785
26161
  }
25786
26162
  else if ((0, roosterjs_editor_dom_1.getTagOfNode)(end) == 'BR') {
25787
- var node = end.ownerDocument.createTextNode('');
25788
- (_a = end.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(node, end);
25789
- block.end = node;
25790
- (_b = end.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(end);
26163
+ var node = (_a = end.ownerDocument) === null || _a === void 0 ? void 0 : _a.createTextNode('');
26164
+ if (node) {
26165
+ (_b = end.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(node, end);
26166
+ block.end = node;
26167
+ (_c = end.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(end);
26168
+ }
25791
26169
  }
25792
26170
  }
25793
26171
  function checkAndAddBr(root, block, isFirst, firstBlock) {
@@ -25875,8 +26253,9 @@ var convertPastedContentFromWordOnline_1 = __webpack_require__(/*! ./convertPast
25875
26253
  */
25876
26254
  function convertPastedContentFromOfficeOnline(fragment) {
25877
26255
  fragment.querySelectorAll(constants_1.WAC_IDENTIFY_SELECTOR).forEach(function (el) {
25878
- el.style.display = null;
25879
- el.style.margin = null;
26256
+ var element = el;
26257
+ element.style.removeProperty('display');
26258
+ element.style.removeProperty('margin');
25880
26259
  });
25881
26260
  // call conversion function if the pasted content is from word online and
25882
26261
  // has list element in the pasted content.
@@ -25956,6 +26335,7 @@ function convertPastedContentFromWordOnline(fragment) {
25956
26335
  sanitizeListItemContainer(fragment);
25957
26336
  var listItemBlocks = getListItemBlocks(fragment);
25958
26337
  listItemBlocks.forEach(function (itemBlock) {
26338
+ var _a, _b, _c;
25959
26339
  // There are cases where consecutive List Elements are separated into different nodes:
25960
26340
  // <div>
25961
26341
  // <div>
@@ -25985,37 +26365,47 @@ function convertPastedContentFromWordOnline(fragment) {
25985
26365
  // Then we are start processing.
25986
26366
  flattenListBlock(fragment, itemBlock);
25987
26367
  // Find the node to insertBefore, which is next sibling node of the end of a listItemBlock.
25988
- itemBlock.insertPositionNode = itemBlock.endElement.nextSibling;
25989
- var convertedListElement;
26368
+ itemBlock.insertPositionNode = (_b = (_a = itemBlock.endElement) === null || _a === void 0 ? void 0 : _a.nextSibling) !== null && _b !== void 0 ? _b : null;
26369
+ var convertedListElement = undefined;
25990
26370
  var doc = fragment.ownerDocument;
25991
26371
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
25992
26372
  var listType = getContainerListType(listItemContainer); // list type that is contained by iterator.
25993
- // Initialize processed element with proper listType if this is the first element
25994
- if (!convertedListElement) {
25995
- convertedListElement = createNewList(listItemContainer, doc, listType);
25996
- }
25997
- // Get all list items(<li>) in the current iterator element.
25998
- var currentListItems = (0, roosterjs_editor_dom_1.toArray)(listItemContainer.querySelectorAll('li'));
25999
- currentListItems.forEach(function (item) {
26000
- // If item is in root level and the type of list changes then
26001
- // insert the current list into body and then reinitialize the convertedListElement
26002
- // Word Online is using data-aria-level to determine the the depth of the list item.
26003
- var itemLevel = parseInt(item.getAttribute('data-aria-level'));
26004
- // In first level list, there are cases where a consecutive list item DIV may have different list type
26005
- // When that happens we need to insert the processed elements into the document, then change the list type
26006
- // and keep the processing going.
26007
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(convertedListElement) != listType && itemLevel == 1) {
26008
- insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26373
+ if (listType) {
26374
+ // Initialize processed element with proper listType if this is the first element
26375
+ if (!convertedListElement) {
26009
26376
  convertedListElement = createNewList(listItemContainer, doc, listType);
26010
26377
  }
26011
- insertListItem(convertedListElement, item, listType, doc);
26012
- });
26378
+ // Get all list items(<li>) in the current iterator element.
26379
+ var currentListItems = (0, roosterjs_editor_dom_1.toArray)(listItemContainer.querySelectorAll('li'));
26380
+ currentListItems.forEach(function (item) {
26381
+ var _a;
26382
+ // If item is in root level and the type of list changes then
26383
+ // insert the current list into body and then reinitialize the convertedListElement
26384
+ // Word Online is using data-aria-level to determine the the depth of the list item.
26385
+ var itemLevel = parseInt((_a = item.getAttribute('data-aria-level')) !== null && _a !== void 0 ? _a : '');
26386
+ // In first level list, there are cases where a consecutive list item DIV may have different list type
26387
+ // When that happens we need to insert the processed elements into the document, then change the list type
26388
+ // and keep the processing going.
26389
+ if (convertedListElement &&
26390
+ (0, roosterjs_editor_dom_1.getTagOfNode)(convertedListElement) != listType &&
26391
+ itemLevel == 1 &&
26392
+ listType) {
26393
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26394
+ convertedListElement = createNewList(listItemContainer, doc, listType);
26395
+ }
26396
+ if (convertedListElement && listType) {
26397
+ insertListItem(convertedListElement, item, listType, doc);
26398
+ }
26399
+ });
26400
+ }
26013
26401
  });
26014
- insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26402
+ if (convertedListElement) {
26403
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26404
+ }
26015
26405
  // Once we finish the process the list items and put them into a list.
26016
26406
  // After inserting the processed element,
26017
26407
  // we need to remove all the non processed node from the parent node.
26018
- var parentContainer = itemBlock.startElement.parentNode;
26408
+ var parentContainer = (_c = itemBlock.startElement) === null || _c === void 0 ? void 0 : _c.parentNode;
26019
26409
  if (parentContainer) {
26020
26410
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
26021
26411
  parentContainer.removeChild(listItemContainer);
@@ -26035,8 +26425,9 @@ function convertPastedContentFromWordOnline(fragment) {
26035
26425
  // Removing the nodes that are not img will resolve the additional space
26036
26426
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLSpanElement')) {
26037
26427
  node.childNodes.forEach(function (childNode) {
26428
+ var _a;
26038
26429
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childNode) != 'IMG') {
26039
- childNode.parentElement.removeChild(childNode);
26430
+ (_a = childNode.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(childNode);
26040
26431
  }
26041
26432
  });
26042
26433
  }
@@ -26078,7 +26469,7 @@ function sanitizeListItemContainer(fragment) {
26078
26469
  function getListItemBlocks(fragment) {
26079
26470
  var listElements = fragment.querySelectorAll('.' + LIST_CONTAINER_ELEMENT_CLASS_NAME);
26080
26471
  var result = [];
26081
- var curListItemBlock;
26472
+ var curListItemBlock = null;
26082
26473
  for (var i = 0; i < listElements.length; i++) {
26083
26474
  var curItem = listElements[i];
26084
26475
  if (!curListItemBlock) {
@@ -26088,8 +26479,9 @@ function getListItemBlocks(fragment) {
26088
26479
  var listItemContainers = curListItemBlock.listItemContainers;
26089
26480
  var lastItemInCurBlock = listItemContainers[listItemContainers.length - 1];
26090
26481
  if (curItem == lastItemInCurBlock.nextSibling ||
26091
- (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
26092
- (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock)) {
26482
+ (lastItemInCurBlock.parentNode &&
26483
+ (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
26484
+ (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock))) {
26093
26485
  listItemContainers.push(curItem);
26094
26486
  curListItemBlock.endElement = curItem;
26095
26487
  }
@@ -26100,7 +26492,7 @@ function getListItemBlocks(fragment) {
26100
26492
  }
26101
26493
  }
26102
26494
  }
26103
- if ((curListItemBlock === null || curListItemBlock === void 0 ? void 0 : curListItemBlock.listItemContainers.length) > 0) {
26495
+ if (curListItemBlock && curListItemBlock.listItemContainers.length > 0) {
26104
26496
  result.push(curListItemBlock);
26105
26497
  }
26106
26498
  return result;
@@ -26111,12 +26503,14 @@ function getListItemBlocks(fragment) {
26111
26503
  * @param listItemBlock The list item block needed to be flattened.
26112
26504
  */
26113
26505
  function flattenListBlock(fragment, listItemBlock) {
26114
- var collapsedListItemSections = (0, roosterjs_editor_dom_1.collapseNodes)(fragment, listItemBlock.startElement, listItemBlock.endElement, true);
26115
- collapsedListItemSections.forEach(function (section) {
26116
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(section.firstChild) == 'DIV') {
26117
- (0, roosterjs_editor_dom_1.unwrap)(section);
26118
- }
26119
- });
26506
+ if (listItemBlock.startElement && listItemBlock.endElement) {
26507
+ var collapsedListItemSections = (0, roosterjs_editor_dom_1.collapseNodes)(fragment, listItemBlock.startElement, listItemBlock.endElement, true);
26508
+ collapsedListItemSections.forEach(function (section) {
26509
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(section.firstChild) == 'DIV') {
26510
+ (0, roosterjs_editor_dom_1.unwrap)(section);
26511
+ }
26512
+ });
26513
+ }
26120
26514
  }
26121
26515
  /**
26122
26516
  * Get the list type that the container contains. If there is no list in the container
@@ -26154,14 +26548,16 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26154
26548
  // If the current level is empty, create empty list within the current level
26155
26549
  // then move the level iterator into the next level.
26156
26550
  curListLevel.appendChild(doc.createElement(listType));
26157
- curListLevel = curListLevel.firstElementChild;
26551
+ if (curListLevel.firstElementChild) {
26552
+ curListLevel = curListLevel.firstElementChild;
26553
+ }
26158
26554
  }
26159
26555
  else {
26160
26556
  // If the current level is not empty, the last item in the needs to be a UL or OL
26161
26557
  // and the level iterator should move to the UL/OL at the last position.
26162
26558
  var lastChild = curListLevel.lastElementChild;
26163
26559
  var lastChildTag = (0, roosterjs_editor_dom_1.getTagOfNode)(lastChild);
26164
- if (lastChildTag == 'UL' || lastChildTag == 'OL') {
26560
+ if (lastChild && (lastChildTag == 'UL' || lastChildTag == 'OL')) {
26165
26561
  // If the last child is a list(UL/OL), then move the level iterator to last child.
26166
26562
  curListLevel = lastChild;
26167
26563
  }
@@ -26169,7 +26565,9 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26169
26565
  // If the last child is not a list, then append a new list to the level
26170
26566
  // and move the level iterator to the new level.
26171
26567
  curListLevel.appendChild(doc.createElement(listType));
26172
- curListLevel = curListLevel.lastElementChild;
26568
+ if (curListLevel.lastElementChild) {
26569
+ curListLevel = curListLevel.lastElementChild;
26570
+ }
26173
26571
  }
26174
26572
  }
26175
26573
  itemLevel--;
@@ -26184,6 +26582,7 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26184
26582
  * @param listItemBlock List item block that was converted.
26185
26583
  */
26186
26584
  function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock) {
26585
+ var _a;
26187
26586
  if (!convertedListElement) {
26188
26587
  return;
26189
26588
  }
@@ -26195,7 +26594,7 @@ function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock)
26195
26594
  }
26196
26595
  }
26197
26596
  else {
26198
- var parentNode = listItemBlock.startElement.parentNode;
26597
+ var parentNode = (_a = listItemBlock.startElement) === null || _a === void 0 ? void 0 : _a.parentNode;
26199
26598
  if (parentNode) {
26200
26599
  parentNode.appendChild(convertedListElement);
26201
26600
  }
@@ -26366,7 +26765,7 @@ function validateLink(link, htmlElement) {
26366
26765
  "use strict";
26367
26766
 
26368
26767
  Object.defineProperty(exports, "__esModule", { value: true });
26369
- exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26768
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26370
26769
  /**
26371
26770
  * @internal
26372
26771
  * Node attribute used to identify if the content is from Google Sheets.
@@ -26382,6 +26781,11 @@ exports.PROG_ID_NAME = 'ProgId';
26382
26781
  * Selector used to identify Wac Elements
26383
26782
  */
26384
26783
  exports.WAC_IDENTIFY_SELECTOR = 'ul[class^="BulletListStyle"]>.OutlineElement,ol[class^="NumberListStyle"]>.OutlineElement,span.WACImageContainer';
26784
+ /**
26785
+ * @internal
26786
+ * Name of the HTMLMeta Property that identifies pated content as from Excel Desktop
26787
+ */
26788
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = 'xmlns:x';
26385
26789
 
26386
26790
 
26387
26791
  /***/ }),
@@ -26424,6 +26828,7 @@ exports.default = documentContainWacElements;
26424
26828
  Object.defineProperty(exports, "__esModule", { value: true });
26425
26829
  var documentContainWacElements_1 = __webpack_require__(/*! ./documentContainWacElements */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/documentContainWacElements.ts");
26426
26830
  var isExcelDesktopDocument_1 = __webpack_require__(/*! ./isExcelDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelDesktopDocument.ts");
26831
+ var isExcelOnlineDocument_1 = __webpack_require__(/*! ./isExcelOnlineDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts");
26427
26832
  var isGoogleSheetDocument_1 = __webpack_require__(/*! ./isGoogleSheetDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts");
26428
26833
  var isPowerPointDesktopDocument_1 = __webpack_require__(/*! ./isPowerPointDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isPowerPointDesktopDocument.ts");
26429
26834
  var isWordDesktopDocument_1 = __webpack_require__(/*! ./isWordDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isWordDesktopDocument.ts");
@@ -26431,10 +26836,11 @@ var shouldConvertToSingleImage_1 = __webpack_require__(/*! ./shouldConvertToSing
26431
26836
  var getSourceFunctions = new Map([
26432
26837
  [0 /* WordDesktop */, isWordDesktopDocument_1.default],
26433
26838
  [1 /* ExcelDesktop */, isExcelDesktopDocument_1.default],
26434
- [2 /* PowerPointDesktop */, isPowerPointDesktopDocument_1.default],
26435
- [4 /* WacComponents */, documentContainWacElements_1.default],
26436
- [3 /* GoogleSheets */, isGoogleSheetDocument_1.default],
26437
- [6 /* SingleImage */, shouldConvertToSingleImage_1.default],
26839
+ [2 /* ExcelOnline */, isExcelOnlineDocument_1.default],
26840
+ [3 /* PowerPointDesktop */, isPowerPointDesktopDocument_1.default],
26841
+ [5 /* WacComponents */, documentContainWacElements_1.default],
26842
+ [4 /* GoogleSheets */, isGoogleSheetDocument_1.default],
26843
+ [7 /* SingleImage */, shouldConvertToSingleImage_1.default],
26438
26844
  ]);
26439
26845
  /**
26440
26846
  * @internal
@@ -26457,7 +26863,7 @@ function getPasteSource(event, shouldConvertSingleImage) {
26457
26863
  result = key;
26458
26864
  }
26459
26865
  });
26460
- return result !== null && result !== void 0 ? result : 5 /* Default */;
26866
+ return result !== null && result !== void 0 ? result : 6 /* Default */;
26461
26867
  }
26462
26868
  exports.default = getPasteSource;
26463
26869
 
@@ -26475,9 +26881,7 @@ exports.default = getPasteSource;
26475
26881
 
26476
26882
  Object.defineProperty(exports, "__esModule", { value: true });
26477
26883
  var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26478
- var EXCEL_ATTRIBUTE_NAME = 'xmlns:x';
26479
26884
  var EXCEL_ATTRIBUTE_VALUE = 'urn:schemas-microsoft-com:office:excel';
26480
- var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26481
26885
  /**
26482
26886
  * @internal
26483
26887
  * Checks whether the Array provided contains strings that identify Excel Desktop documents
@@ -26486,12 +26890,42 @@ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26486
26890
  */
26487
26891
  var isExcelDesktopDocument = function (props) {
26488
26892
  var htmlAttributes = props.htmlAttributes;
26489
- return (htmlAttributes[EXCEL_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE ||
26490
- htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE);
26893
+ // The presence of this attribute confirms its origin from Excel Desktop
26894
+ return htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE;
26491
26895
  };
26492
26896
  exports.default = isExcelDesktopDocument;
26493
26897
 
26494
26898
 
26899
+ /***/ }),
26900
+
26901
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts":
26902
+ /*!********************************************************************************************************!*\
26903
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts ***!
26904
+ \********************************************************************************************************/
26905
+ /*! no static exports found */
26906
+ /***/ (function(module, exports, __webpack_require__) {
26907
+
26908
+ "use strict";
26909
+
26910
+ Object.defineProperty(exports, "__esModule", { value: true });
26911
+ var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26912
+ // Excel Desktop also has this attribute
26913
+ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26914
+ /**
26915
+ * @internal
26916
+ * Checks whether the Array provided contains strings that identify Excel Online documents
26917
+ * @param props Properties related to the PasteEvent
26918
+ * @returns
26919
+ */
26920
+ var isExcelOnlineDocument = function (props) {
26921
+ var htmlAttributes = props.htmlAttributes;
26922
+ // The presence of Excel.Sheet confirms its origin from Excel, the absence of EXCEL_DESKTOP_ATTRIBUTE_NAME confirms it is from the Online version
26923
+ return (htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE &&
26924
+ htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == undefined);
26925
+ };
26926
+ exports.default = isExcelOnlineDocument;
26927
+
26928
+
26495
26929
  /***/ }),
26496
26930
 
26497
26931
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts":
@@ -26931,7 +27365,11 @@ var LINE_BREAKS = /[\n|\r]/gi;
26931
27365
  * for numbered headers, and we don't want to convert those, because the numbering would be completely wrong.
26932
27366
  */
26933
27367
  function processNodesDiscovery(wordConverter) {
27368
+ var _a;
26934
27369
  var args = wordConverter.wordConverterArgs;
27370
+ if (!args) {
27371
+ return false;
27372
+ }
26935
27373
  while (args.currentIndex < args.nodes.length) {
26936
27374
  var node = args.nodes.item(args.currentIndex);
26937
27375
  // Try to get the list metadata for the specified node
@@ -27020,7 +27458,7 @@ function processNodesDiscovery(wordConverter) {
27020
27458
  last.appendChild(last.ownerDocument.createElement('br'));
27021
27459
  (0, roosterjs_editor_dom_1.moveChildNodes)(last, node, true /*keepExistingChildren*/);
27022
27460
  // Remove the item that we don't need anymore
27023
- node.parentNode.removeChild(node);
27461
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
27024
27462
  }
27025
27463
  }
27026
27464
  // Move to the next element are return true if more elements need to be processed
@@ -27036,44 +27474,47 @@ exports.processNodesDiscovery = processNodesDiscovery;
27036
27474
  * conversion needed
27037
27475
  */
27038
27476
  function processNodeConvert(wordConverter) {
27477
+ var _a;
27039
27478
  var args = wordConverter.wordConverterArgs;
27040
- args.currentIndex = 0;
27041
- while (args.currentIndex < args.listItems.length) {
27042
- var metadata = args.listItems[args.currentIndex];
27043
- var node = metadata.originalNode;
27044
- var listMetadata = args.lists[metadata.uniqueListId.toString()];
27045
- if (!listMetadata.ignore) {
27046
- // We have a list item that we need to convert, get or create the list
27047
- // that hold this item out
27048
- var list = getOrCreateListForNode(wordConverter, node, metadata, listMetadata);
27049
- if (list) {
27050
- // Clean the element out.. this call gets rid of the fake bullet and unneeded nodes
27051
- cleanupListIgnore(node, LOOKUP_DEPTH);
27052
- // Create a new list item and transfer the children
27053
- var li = node.ownerDocument.createElement('LI');
27054
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(node).startsWith('H')) {
27055
- var clone = node.cloneNode(true /* deep */);
27056
- clone.style.textIndent = '';
27057
- clone.style.marginLeft = '';
27058
- clone.style.marginRight = '';
27059
- li.appendChild(clone);
27060
- }
27061
- else {
27062
- (0, roosterjs_editor_dom_1.moveChildNodes)(li, node);
27063
- }
27064
- // Append the list item into the list
27065
- list.appendChild(li);
27066
- // Remove the node we just converted
27067
- node.parentNode.removeChild(node);
27068
- if (listMetadata.tagName == 'UL') {
27069
- wordConverter.numBulletsConverted++;
27070
- }
27071
- else {
27072
- wordConverter.numNumberedConverted++;
27479
+ if (args) {
27480
+ args.currentIndex = 0;
27481
+ while (args.currentIndex < args.listItems.length) {
27482
+ var metadata = args.listItems[args.currentIndex];
27483
+ var node = metadata.originalNode;
27484
+ var listMetadata = args.lists[metadata.uniqueListId.toString()];
27485
+ if (!listMetadata.ignore) {
27486
+ // We have a list item that we need to convert, get or create the list
27487
+ // that hold this item out
27488
+ var list = getOrCreateListForNode(wordConverter, node, metadata, listMetadata);
27489
+ if (list) {
27490
+ // Clean the element out.. this call gets rid of the fake bullet and unneeded nodes
27491
+ cleanupListIgnore(node, LOOKUP_DEPTH);
27492
+ // Create a new list item and transfer the children
27493
+ var li = node.ownerDocument.createElement('LI');
27494
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(node).startsWith('H')) {
27495
+ var clone = node.cloneNode(true /* deep */);
27496
+ clone.style.textIndent = '';
27497
+ clone.style.marginLeft = '';
27498
+ clone.style.marginRight = '';
27499
+ li.appendChild(clone);
27500
+ }
27501
+ else {
27502
+ (0, roosterjs_editor_dom_1.moveChildNodes)(li, node);
27503
+ }
27504
+ // Append the list item into the list
27505
+ list.appendChild(li);
27506
+ // Remove the node we just converted
27507
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
27508
+ if (listMetadata.tagName == 'UL') {
27509
+ wordConverter.numBulletsConverted++;
27510
+ }
27511
+ else {
27512
+ wordConverter.numNumberedConverted++;
27513
+ }
27073
27514
  }
27074
27515
  }
27516
+ args.currentIndex++;
27075
27517
  }
27076
- args.currentIndex++;
27077
27518
  }
27078
27519
  return wordConverter.numBulletsConverted > 0 || wordConverter.numNumberedConverted > 0;
27079
27520
  }
@@ -27083,6 +27524,7 @@ exports.processNodeConvert = processNodeConvert;
27083
27524
  * items content and the specified metadata
27084
27525
  */
27085
27526
  function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27527
+ var _a;
27086
27528
  // First get the last list next to this node under the specified level. This code
27087
27529
  // path will return the list or will create lists if needed
27088
27530
  var list = recurringGetOrCreateListAtNode(node, metadata.level, listMetadata);
@@ -27094,7 +27536,7 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27094
27536
  // is a completely new list, so we'll append a new list for that
27095
27537
  if ((listId && listId != metadata.uniqueListId) || (!listId && list.firstChild)) {
27096
27538
  var newList = node.ownerDocument.createElement(listMetadata.tagName);
27097
- list.parentNode.insertBefore(newList, list.nextSibling);
27539
+ (_a = list.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newList, list.nextSibling);
27098
27540
  list = newList;
27099
27541
  }
27100
27542
  // Set the list id into the custom data
@@ -27109,15 +27551,18 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27109
27551
  * information already stored in the list itself
27110
27552
  */
27111
27553
  function convertListIfNeeded(wordConverter, list, listMetadata) {
27554
+ var _a, _b, _c;
27112
27555
  // Check if we need to convert the list out
27113
27556
  if (listMetadata.tagName != (0, roosterjs_editor_dom_1.getTagOfNode)(list)) {
27114
27557
  // We have the wrong list type.. convert it, set the id again and transfer all the children
27115
- var newList = list.ownerDocument.createElement(listMetadata.tagName);
27116
- (0, WordCustomData_1.setObject)(wordConverter.wordCustomData, newList, UNIQUE_LIST_ID_CUSTOM_DATA, (0, WordCustomData_1.getObject)(wordConverter.wordCustomData, list, UNIQUE_LIST_ID_CUSTOM_DATA));
27117
- (0, roosterjs_editor_dom_1.moveChildNodes)(newList, list);
27118
- list.parentNode.insertBefore(newList, list);
27119
- list.parentNode.removeChild(list);
27120
- list = newList;
27558
+ var newList = (_a = list.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata.tagName);
27559
+ if (newList) {
27560
+ (0, WordCustomData_1.setObject)(wordConverter.wordCustomData, newList, UNIQUE_LIST_ID_CUSTOM_DATA, (0, WordCustomData_1.getObject)(wordConverter.wordCustomData, list, UNIQUE_LIST_ID_CUSTOM_DATA));
27561
+ (0, roosterjs_editor_dom_1.moveChildNodes)(newList, list);
27562
+ (_b = list.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, list);
27563
+ (_c = list.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(list);
27564
+ list = newList;
27565
+ }
27121
27566
  }
27122
27567
  return list;
27123
27568
  }
@@ -27125,8 +27570,9 @@ function convertListIfNeeded(wordConverter, list, listMetadata) {
27125
27570
  * Gets or creates the specified list
27126
27571
  */
27127
27572
  function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27573
+ var _a, _b;
27128
27574
  var parent = null;
27129
- var possibleList;
27575
+ var possibleList = null;
27130
27576
  if (level == 1) {
27131
27577
  // Root case, we'll check if the list is the previous sibling of the node
27132
27578
  possibleList = getRealPreviousSibling(node);
@@ -27135,7 +27581,9 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27135
27581
  // If we get here, we are looking for level 2 or deeper... get the upper list
27136
27582
  // and check if the last element is a list
27137
27583
  parent = recurringGetOrCreateListAtNode(node, level - 1, null);
27138
- possibleList = parent.lastChild;
27584
+ if (parent.lastChild) {
27585
+ possibleList = parent.lastChild;
27586
+ }
27139
27587
  }
27140
27588
  // Check the element that we got and verify that it is a list
27141
27589
  if (possibleList && possibleList.nodeType == 1 /* Element */) {
@@ -27147,15 +27595,15 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27147
27595
  }
27148
27596
  // If we get here, it means we don't have a list and we need to create one
27149
27597
  // this code path will always create new lists as UL lists
27150
- var newList = node.ownerDocument.createElement(listMetadata ? listMetadata.tagName : 'UL');
27598
+ var newList = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata ? listMetadata.tagName : 'UL');
27151
27599
  if (level == 1) {
27152
27600
  // For level 1, we'll insert the list before the node
27153
- node.parentNode.insertBefore(newList, node);
27601
+ (_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, node);
27154
27602
  }
27155
27603
  else {
27156
27604
  // Any level 2 or above, we insert the list as the last
27157
27605
  // child of the upper level list
27158
- parent.appendChild(newList);
27606
+ parent === null || parent === void 0 ? void 0 : parent.appendChild(newList);
27159
27607
  }
27160
27608
  return newList;
27161
27609
  }
@@ -27167,15 +27615,17 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27167
27615
  function cleanupListIgnore(node, levels) {
27168
27616
  var nodesToRemove = [];
27169
27617
  for (var child = node.firstChild; child; child = child.nextSibling) {
27170
- // Clean up the item internally first if we need to based on the number of levels
27171
- if (child.nodeType == 1 /* Element */ && levels > 1) {
27172
- cleanupListIgnore(child, levels - 1);
27173
- }
27174
- // Try to convert word comments into ignore elements if we haven't done so for this element
27175
- child = fixWordListComments(child, true /*removeComments*/);
27176
- // Check if we can remove this item out
27177
- if (isEmptySpan(child) || isIgnoreNode(child)) {
27178
- nodesToRemove.push(child);
27618
+ if (child) {
27619
+ // Clean up the item internally first if we need to based on the number of levels
27620
+ if (child && child.nodeType == 1 /* Element */ && levels > 1) {
27621
+ cleanupListIgnore(child, levels - 1);
27622
+ }
27623
+ // Try to convert word comments into ignore elements if we haven't done so for this element
27624
+ child = fixWordListComments(child, true /*removeComments*/);
27625
+ // Check if we can remove this item out
27626
+ if (isEmptySpan(child) || isIgnoreNode(child)) {
27627
+ nodesToRemove.push(child);
27628
+ }
27179
27629
  }
27180
27630
  }
27181
27631
  nodesToRemove.forEach(function (child) { return node.removeChild(child); });
@@ -27224,6 +27674,7 @@ function getFakeBulletTagName(fakeBullet) {
27224
27674
  * a bullet string. If not found, it returns null...
27225
27675
  */
27226
27676
  function getFakeBulletText(node, levels) {
27677
+ var _a, _b;
27227
27678
  // Word uses the following format for their bullets:
27228
27679
  // &lt;p style="mso-list:l1 level1 lfo2"&gt;
27229
27680
  // &lt;span style="..."&gt;
@@ -27234,7 +27685,7 @@ function getFakeBulletText(node, levels) {
27234
27685
  //
27235
27686
  // Basically, we need to locate the mso-list:Ignore SPAN, which holds either one text or image node. That
27236
27687
  // text or image node will be the fake bullet we are looking for
27237
- var result = null;
27688
+ var result = '';
27238
27689
  var child = node.firstChild;
27239
27690
  while (!result && child) {
27240
27691
  // First, check if we need to convert the Word list comments into real elements
@@ -27242,7 +27693,7 @@ function getFakeBulletText(node, levels) {
27242
27693
  // Check if this is the node that holds the fake bullets (mso-list: Ignore)
27243
27694
  if (isIgnoreNode(child)) {
27244
27695
  // Yes... this is the node that holds either the text or image data
27245
- result = child.textContent.trim();
27696
+ result = (_b = (_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
27246
27697
  // This is the case for image case
27247
27698
  if (result.length == 0) {
27248
27699
  result = 'o';
@@ -27266,6 +27717,7 @@ function getFakeBulletText(node, levels) {
27266
27717
  * styles of the span, but we'll use these comments to recreate them out
27267
27718
  */
27268
27719
  function fixWordListComments(child, removeComments) {
27720
+ var _a, _b, _c, _d;
27269
27721
  if (child.nodeType == 8 /* Comment */) {
27270
27722
  var value = child.data;
27271
27723
  if (value && value.trim().toLowerCase() == '[if !supportlists]') {
@@ -27288,22 +27740,28 @@ function fixWordListComments(child, removeComments) {
27288
27740
  }
27289
27741
  // if we found the end node, wrap everything out
27290
27742
  if (endComment) {
27291
- var newSpan = child.ownerDocument.createElement('span');
27292
- newSpan.setAttribute('style', 'mso-list: ignore');
27743
+ var newSpan = (_a = child.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement('span');
27744
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.setAttribute('style', 'mso-list: ignore');
27293
27745
  nextElement = getRealNextSibling(child);
27294
27746
  while (nextElement != endComment) {
27295
- nextElement = nextElement.nextSibling;
27296
- newSpan.appendChild(nextElement.previousSibling);
27747
+ nextElement = nextElement === null || nextElement === void 0 ? void 0 : nextElement.nextSibling;
27748
+ if (nextElement.previousSibling) {
27749
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.appendChild(nextElement.previousSibling);
27750
+ }
27297
27751
  }
27298
27752
  // Insert the element out and use that one as the current child
27299
- endComment.parentNode.insertBefore(newSpan, endComment);
27753
+ if (newSpan) {
27754
+ (_b = endComment.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newSpan, endComment);
27755
+ }
27300
27756
  // Remove the comments out if the call specified it out
27301
27757
  if (removeComments) {
27302
- child.parentNode.removeChild(child);
27303
- endComment.parentNode.removeChild(endComment);
27758
+ (_c = child.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(child);
27759
+ (_d = endComment.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(endComment);
27304
27760
  }
27305
27761
  // Last, make sure we return the new element out instead of the comment
27306
- child = newSpan;
27762
+ if (newSpan) {
27763
+ child = newSpan;
27764
+ }
27307
27765
  }
27308
27766
  }
27309
27767
  }
@@ -27355,6 +27813,7 @@ function getStyleValue(node, styleName) {
27355
27813
  }
27356
27814
  /** Checks if the node is an empty text node that can be ignored */
27357
27815
  function isEmptyTextNode(node) {
27816
+ var _a;
27358
27817
  // No node is empty
27359
27818
  if (!node) {
27360
27819
  return true;
@@ -27362,12 +27821,14 @@ function isEmptyTextNode(node) {
27362
27821
  // Empty text node is empty
27363
27822
  if (node.nodeType == 3 /* Text */) {
27364
27823
  var value = node.nodeValue;
27365
- value = value.replace(LINE_BREAKS, '');
27366
- return value.trim().length == 0;
27824
+ value = (_a = value === null || value === void 0 ? void 0 : value.replace(LINE_BREAKS, '')) !== null && _a !== void 0 ? _a : '';
27825
+ return (value === null || value === void 0 ? void 0 : value.trim().length) == 0;
27367
27826
  }
27368
27827
  // Span or Font with an empty child node is empty
27369
27828
  var tagName = (0, roosterjs_editor_dom_1.getTagOfNode)(node);
27370
- if (node.firstChild == node.lastChild && (tagName == 'SPAN' || tagName == 'FONT')) {
27829
+ if (node.firstChild &&
27830
+ node.firstChild == node.lastChild &&
27831
+ (tagName == 'SPAN' || tagName == 'FONT')) {
27371
27832
  return isEmptyTextNode(node.firstChild);
27372
27833
  }
27373
27834
  // If not found, then this is not empty
@@ -29290,7 +29751,7 @@ var TableInsertHandler = /** @class */ (function () {
29290
29751
  }());
29291
29752
  function getInsertElementData(isHorizontal, isDark, isRTL, backgroundColor) {
29292
29753
  var inserterColor = isDark ? INSERTER_COLOR_DARK_MODE : INSERTER_COLOR;
29293
- var outerDivStyle = "position: fixed; width: " + INSERTER_SIDE_LENGTH + "px; height: " + INSERTER_SIDE_LENGTH + "px; font-size: 16px; color: " + inserterColor + "; line-height: 10px; vertical-align: middle; text-align: center; cursor: pointer; border: solid " + INSERTER_BORDER_SIZE + "px " + inserterColor + "; border-radius: 50%; background-color: " + backgroundColor;
29754
+ var outerDivStyle = "position: fixed; width: " + INSERTER_SIDE_LENGTH + "px; height: " + INSERTER_SIDE_LENGTH + "px; font-size: 16px; color: " + inserterColor + "; line-height: 8px; vertical-align: middle; text-align: center; cursor: pointer; border: solid " + INSERTER_BORDER_SIZE + "px " + inserterColor + "; border-radius: 50%; background-color: " + backgroundColor;
29294
29755
  var leftOrRight = isRTL ? 'right' : 'left';
29295
29756
  var childBaseStyles = "position: absolute; box-sizing: border-box; background-color: " + backgroundColor + ";";
29296
29757
  var childInfo = {
@@ -29889,6 +30350,11 @@ var CompatibleChangeSource;
29889
30350
  * List chain reorganized numbers of lists
29890
30351
  */
29891
30352
  CompatibleChangeSource["ListChain"] = "ListChain";
30353
+ /**
30354
+ * Keyboard event, used by Content Model.
30355
+ * Data of this event will be the key code number
30356
+ */
30357
+ CompatibleChangeSource["Keyboard"] = "Keyboard";
29892
30358
  })(CompatibleChangeSource = exports.CompatibleChangeSource || (exports.CompatibleChangeSource = {}));
29893
30359
 
29894
30360