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