roosterjs 8.44.2 → 8.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rooster.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,6 +10608,9 @@ 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
@@ -21125,15 +21313,16 @@ var ContentEdit = /** @class */ (function () {
21125
21313
  this.editor = editor;
21126
21314
  var allFeatures = (0, getAllFeatures_1.default)();
21127
21315
  (0, roosterjs_editor_dom_1.getObjectKeys)(allFeatures).forEach(function (key) {
21316
+ var _a;
21128
21317
  var feature = allFeatures[key];
21129
21318
  var hasSettingForKey = _this.settingsOverride && _this.settingsOverride[key] !== undefined;
21130
- if ((hasSettingForKey && _this.settingsOverride[key]) ||
21319
+ if ((hasSettingForKey && ((_a = _this.settingsOverride) === null || _a === void 0 ? void 0 : _a[key])) ||
21131
21320
  (!hasSettingForKey && !feature.defaultDisabled)) {
21132
21321
  _this.features.push(feature);
21133
21322
  }
21134
21323
  });
21135
21324
  this.features = this.features.concat(this.additionalFeatures || []);
21136
- this.features.forEach(function (feature) { return _this.editor.addContentEditFeature(feature); });
21325
+ this.features.forEach(function (feature) { var _a; return (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.addContentEditFeature(feature); });
21137
21326
  };
21138
21327
  ContentEdit.prototype.disposeFeatures = function () {
21139
21328
  var _this = this;
@@ -21205,14 +21394,15 @@ function cacheGetLinkData(event, editor) {
21205
21394
  // This helps when we paste a link next to some existing character, and the text we got
21206
21395
  // from clipboard will only contain what we pasted, any existing characters will not
21207
21396
  // be included.
21208
- var clipboardData = event.eventType == 7 /* ContentChanged */ &&
21397
+ var clipboardData = (event.eventType == 7 /* ContentChanged */ &&
21209
21398
  event.source == "Paste" /* Paste */ &&
21210
- event.data;
21211
- var link = (0, roosterjs_editor_dom_1.matchLink)((clipboardData.text || '').trim());
21399
+ event.data) ||
21400
+ null;
21401
+ var link = (0, roosterjs_editor_dom_1.matchLink)(((clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.text) || '').trim());
21212
21402
  var searcher = editor.getContentSearcherOfCursor(event);
21213
21403
  // In case the matched link is already inside a <A> tag, we do a range search.
21214
21404
  // getRangeFromText will return null if the given text is already in a LinkInlineElement
21215
- if (link && searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/)) {
21405
+ if (link && (searcher === null || searcher === void 0 ? void 0 : searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/))) {
21216
21406
  return link;
21217
21407
  }
21218
21408
  var word = searcher && searcher.getWordBefore();
@@ -21237,12 +21427,15 @@ function cacheGetLinkData(event, editor) {
21237
21427
  }
21238
21428
  function hasLinkBeforeCursor(event, editor) {
21239
21429
  var contentSearcher = editor.getContentSearcherOfCursor(event);
21240
- var inline = contentSearcher.getInlineElementBefore();
21430
+ var inline = contentSearcher === null || contentSearcher === void 0 ? void 0 : contentSearcher.getInlineElementBefore();
21241
21431
  return inline instanceof roosterjs_editor_dom_1.LinkInlineElement;
21242
21432
  }
21243
21433
  function autoLink(event, editor) {
21244
- var anchor = editor.getDocument().createElement('a');
21245
21434
  var linkData = cacheGetLinkData(event, editor);
21435
+ if (!linkData) {
21436
+ return;
21437
+ }
21438
+ var anchor = editor.getDocument().createElement('a');
21246
21439
  // Need to get searcher before we enter the async callback since the callback can happen when cursor is moved to next line
21247
21440
  // and at that time a new searcher won't be able to find the link text to replace
21248
21441
  var searcher = editor.getContentSearcherOfCursor();
@@ -21250,7 +21443,7 @@ function autoLink(event, editor) {
21250
21443
  anchor.href = linkData.normalizedUrl;
21251
21444
  editor.runAsync(function (editor) {
21252
21445
  editor.addUndoSnapshot(function () {
21253
- (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher);
21446
+ (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher !== null && searcher !== void 0 ? searcher : undefined);
21254
21447
  // The content at cursor has changed. Should also clear the cursor data cache
21255
21448
  (0, roosterjs_editor_dom_1.clearEventDataCache)(event);
21256
21449
  return anchor;
@@ -21266,6 +21459,91 @@ exports.AutoLinkFeatures = {
21266
21459
  };
21267
21460
 
21268
21461
 
21462
+ /***/ }),
21463
+
21464
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts":
21465
+ /*!********************************************************************************************!*\
21466
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts ***!
21467
+ \********************************************************************************************/
21468
+ /*! no static exports found */
21469
+ /***/ (function(module, exports, __webpack_require__) {
21470
+
21471
+ "use strict";
21472
+
21473
+ Object.defineProperty(exports, "__esModule", { value: true });
21474
+ exports.CodeFeatures = void 0;
21475
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
21476
+ var RemoveCodeWhenEnterOnEmptyLine = {
21477
+ keys: [13 /* ENTER */],
21478
+ shouldHandleEvent: function (event, editor) {
21479
+ var childOfCode = cacheGetCodeChild(event, editor);
21480
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode);
21481
+ },
21482
+ handleEvent: function (event, editor) {
21483
+ event.rawEvent.preventDefault();
21484
+ editor.addUndoSnapshot(function () {
21485
+ splitCode(event, editor);
21486
+ }, undefined /* changeSource */, true /* canUndoByBackspace */);
21487
+ },
21488
+ };
21489
+ var RemoveCodeWhenBackspaceOnEmptyFirstLine = {
21490
+ keys: [8 /* BACKSPACE */],
21491
+ shouldHandleEvent: function (event, editor) {
21492
+ var childOfCode = cacheGetCodeChild(event, editor);
21493
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode) && !childOfCode.previousSibling;
21494
+ },
21495
+ handleEvent: function (event, editor) {
21496
+ event.rawEvent.preventDefault();
21497
+ editor.addUndoSnapshot(function () { return splitCode(event, editor); });
21498
+ },
21499
+ };
21500
+ function cacheGetCodeChild(event, editor) {
21501
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'CODE_CHILD', function () {
21502
+ var _a;
21503
+ var codeElement = (_a = editor.getElementAtCursor('code')) !== null && _a !== void 0 ? _a : editor.queryElements('code', 1 /* OnSelection */)[0];
21504
+ if (codeElement) {
21505
+ var pos = editor.getFocusedPosition();
21506
+ var block = pos && editor.getBlockElementAtNode(pos.normalize().node);
21507
+ if (block) {
21508
+ var node = block.getStartNode() == codeElement.parentNode
21509
+ ? block.getStartNode()
21510
+ : block.collapseToSingleElement();
21511
+ return (0, roosterjs_editor_dom_1.isNodeEmpty)(node) ? node : null;
21512
+ }
21513
+ }
21514
+ return null;
21515
+ });
21516
+ }
21517
+ function splitCode(event, editor) {
21518
+ var currentContainer = cacheGetCodeChild(event, editor);
21519
+ if (!(0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer, 'HTMLElement')) {
21520
+ return;
21521
+ }
21522
+ var codeChild = currentContainer.querySelector('code');
21523
+ if (!codeChild) {
21524
+ var codeParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21525
+ if (codeParent) {
21526
+ (0, roosterjs_editor_dom_1.unwrap)(codeParent);
21527
+ }
21528
+ if ((0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer.parentElement, 'HTMLPreElement')) {
21529
+ var preParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21530
+ if (preParent) {
21531
+ (0, roosterjs_editor_dom_1.unwrap)(preParent);
21532
+ }
21533
+ }
21534
+ }
21535
+ else {
21536
+ //Content model
21537
+ (0, roosterjs_editor_dom_1.unwrap)(codeChild);
21538
+ }
21539
+ editor.select(currentContainer, 0 /* Begin */);
21540
+ }
21541
+ exports.CodeFeatures = {
21542
+ removeCodeWhenEnterOnEmptyLine: RemoveCodeWhenEnterOnEmptyLine,
21543
+ removeCodeWhenBackspaceOnEmptyFirstLine: RemoveCodeWhenBackspaceOnEmptyFirstLine,
21544
+ };
21545
+
21546
+
21269
21547
  /***/ }),
21270
21548
 
21271
21549
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/cursorFeatures.ts":
@@ -21284,7 +21562,7 @@ var NoCycleCursorMove = {
21284
21562
  keys: [37 /* LEFT */, 39 /* RIGHT */],
21285
21563
  allowFunctionKeys: true,
21286
21564
  shouldHandleEvent: function (event, editor, ctrlOrMeta) {
21287
- var range;
21565
+ var range = null;
21288
21566
  var position;
21289
21567
  if (!ctrlOrMeta ||
21290
21568
  !(range = editor.getSelectionRange()) ||
@@ -21734,8 +22012,10 @@ var shouldHandleIndentationEvent = function (indenting) { return function (event
21734
22012
  cacheGetListElement(event, editor));
21735
22013
  }; };
21736
22014
  var handleIndentationEvent = function (indenting) { return function (event, editor) {
22015
+ var currentElement = null;
21737
22016
  var isRTL = event.rawEvent.keyCode !== 9 /* TAB */ &&
21738
- (0, roosterjs_editor_dom_1.getComputedStyle)(editor.getElementAtCursor(), 'direction') == 'rtl';
22017
+ (currentElement = editor.getElementAtCursor()) &&
22018
+ (0, roosterjs_editor_dom_1.getComputedStyle)(currentElement, 'direction') == 'rtl';
21739
22019
  (0, roosterjs_editor_api_1.setIndentation)(editor, isRTL == indenting ? 1 /* Decrease */ : 0 /* Increase */);
21740
22020
  event.rawEvent.preventDefault();
21741
22021
  }; };
@@ -21743,20 +22023,39 @@ var handleIndentationEvent = function (indenting) { return function (event, edit
21743
22023
  * IndentWhenTab edit feature, provides the ability to indent current list when user press TAB
21744
22024
  */
21745
22025
  var IndentWhenTab = {
21746
- keys: roosterjs_editor_dom_1.Browser.isMac ? [9 /* TAB */] : [9 /* TAB */, 39 /* RIGHT */],
22026
+ keys: [9 /* TAB */],
21747
22027
  shouldHandleEvent: shouldHandleIndentationEvent(true),
21748
22028
  handleEvent: handleIndentationEvent(true),
21749
- allowFunctionKeys: true,
21750
22029
  };
21751
22030
  /**
21752
22031
  * OutdentWhenShiftTab edit feature, provides the ability to outdent current list when user press Shift+TAB
21753
22032
  */
21754
22033
  var OutdentWhenShiftTab = {
21755
- keys: roosterjs_editor_dom_1.Browser.isMac ? [9 /* TAB */] : [9 /* TAB */, 37 /* LEFT */],
22034
+ keys: [9 /* TAB */],
21756
22035
  shouldHandleEvent: shouldHandleIndentationEvent(false),
21757
22036
  handleEvent: handleIndentationEvent(false),
21758
22037
  allowFunctionKeys: true,
21759
22038
  };
22039
+ /**
22040
+ * indentWhenAltShiftRight edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Right
22041
+ */
22042
+ var IndentWhenAltShiftRight = {
22043
+ keys: [39 /* RIGHT */],
22044
+ shouldHandleEvent: shouldHandleIndentationEvent(true),
22045
+ handleEvent: handleIndentationEvent(true),
22046
+ allowFunctionKeys: true,
22047
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
22048
+ };
22049
+ /**
22050
+ * outdentWhenAltShiftLeft edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Left
22051
+ */
22052
+ var OutdentWhenAltShiftLeft = {
22053
+ keys: [37 /* LEFT */],
22054
+ shouldHandleEvent: shouldHandleIndentationEvent(false),
22055
+ handleEvent: handleIndentationEvent(false),
22056
+ allowFunctionKeys: true,
22057
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
22058
+ };
21760
22059
  /**
21761
22060
  * MergeInNewLine edit feature, provides the ability to merge current line into a new line when user press
21762
22061
  * BACKSPACE at beginning of a list item
@@ -21764,16 +22063,16 @@ var OutdentWhenShiftTab = {
21764
22063
  var MergeInNewLine = {
21765
22064
  keys: [8 /* BACKSPACE */],
21766
22065
  shouldHandleEvent: function (event, editor) {
21767
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22066
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21768
22067
  var range = editor.getSelectionRange();
21769
22068
  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
22069
  },
21771
22070
  handleEvent: function (event, editor) {
21772
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21773
- if (li.previousSibling) {
22071
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22072
+ if (li === null || li === void 0 ? void 0 : li.previousSibling) {
21774
22073
  (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) {
22074
+ var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li !== null && li !== void 0 ? li : undefined);
22075
+ if (vList && start && end) {
21777
22076
  vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
21778
22077
  vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
21779
22078
  event.rawEvent.preventDefault();
@@ -21793,7 +22092,7 @@ var MergeInNewLine = {
21793
22092
  var OutdentWhenBackOn1stEmptyLine = {
21794
22093
  keys: [8 /* BACKSPACE */],
21795
22094
  shouldHandleEvent: function (event, editor) {
21796
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22095
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21797
22096
  return (li &&
21798
22097
  (0, roosterjs_editor_dom_1.isNodeEmpty)(li) &&
21799
22098
  !li.previousSibling &&
@@ -21808,12 +22107,13 @@ var OutdentWhenBackOn1stEmptyLine = {
21808
22107
  var MaintainListChainWhenDelete = {
21809
22108
  keys: [46 /* DELETE */],
21810
22109
  shouldHandleEvent: function (event, editor) {
21811
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21812
- if (li) {
22110
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22111
+ var range = editor.getSelectionRange();
22112
+ if (li || !range) {
21813
22113
  return false;
21814
22114
  }
21815
- var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(editor.getSelectionRange()).isAtEnd;
21816
- var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : null;
22115
+ var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(range).isAtEnd;
22116
+ var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : undefined;
21817
22117
  var isAtEndAndBeforeLI = editor.getElementAtCursor('LI', nextSibling, event);
21818
22118
  return isAtEndAndBeforeLI;
21819
22119
  },
@@ -21829,11 +22129,11 @@ var MaintainListChainWhenDelete = {
21829
22129
  var OutdentWhenEnterOnEmptyLine = {
21830
22130
  keys: [13 /* ENTER */],
21831
22131
  shouldHandleEvent: function (event, editor) {
21832
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22132
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21833
22133
  return !event.rawEvent.shiftKey && li && (0, roosterjs_editor_dom_1.isNodeEmpty)(li);
21834
22134
  },
21835
22135
  handleEvent: function (event, editor) {
21836
- editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22136
+ editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21837
22137
  },
21838
22138
  defaultDisabled: !roosterjs_editor_dom_1.Browser.isIE && !roosterjs_editor_dom_1.Browser.isChrome,
21839
22139
  };
@@ -21855,9 +22155,10 @@ function isAListPattern(textBeforeCursor) {
21855
22155
  var AutoBullet = {
21856
22156
  keys: [32 /* SPACE */],
21857
22157
  shouldHandleEvent: function (event, editor) {
22158
+ var searcher;
21858
22159
  if (!cacheGetListElement(event, editor) &&
21859
- !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
21860
- var searcher = editor.getContentSearcherOfCursor(event);
22160
+ !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */) &&
22161
+ (searcher = editor.getContentSearcherOfCursor(event))) {
21861
22162
  var textBeforeCursor = searcher.getSubStringBefore(4);
21862
22163
  // Auto list is triggered if:
21863
22164
  // 1. Text before cursor exactly matches '*', '-' or '1.'
@@ -21873,6 +22174,9 @@ var AutoBullet = {
21873
22174
  var _a;
21874
22175
  var regions;
21875
22176
  var searcher = editor.getContentSearcherOfCursor();
22177
+ if (!searcher) {
22178
+ return;
22179
+ }
21876
22180
  var textBeforeCursor = searcher.getSubStringBefore(4);
21877
22181
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21878
22182
  if (!textRange) {
@@ -21893,7 +22197,7 @@ var AutoBullet = {
21893
22197
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, num);
21894
22198
  }
21895
22199
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21896
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22200
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21897
22201
  },
21898
22202
  };
21899
22203
  /**
@@ -21915,15 +22219,18 @@ var AutoBulletList = {
21915
22219
  editor.addUndoSnapshot(function () {
21916
22220
  var _a;
21917
22221
  var searcher = editor.getContentSearcherOfCursor();
22222
+ if (!searcher) {
22223
+ return;
22224
+ }
21918
22225
  var textBeforeCursor = searcher.getSubStringBefore(5);
21919
22226
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21920
22227
  var listStyle = (0, getAutoBulletListStyle_1.default)(textBeforeCursor);
21921
22228
  if (textRange) {
21922
22229
  prepareAutoBullet(editor, textRange);
21923
- (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle, 'autoToggleList' /** apiNameOverride */);
22230
+ (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle !== null && listStyle !== void 0 ? listStyle : undefined, 'autoToggleList' /** apiNameOverride */);
21924
22231
  }
21925
22232
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21926
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22233
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21927
22234
  },
21928
22235
  };
21929
22236
  /**
@@ -21943,8 +22250,11 @@ var AutoNumberingList = {
21943
22250
  editor.insertContent('&nbsp;');
21944
22251
  event.rawEvent.preventDefault();
21945
22252
  editor.addUndoSnapshot(function () {
21946
- var _a;
22253
+ var _a, _b;
21947
22254
  var searcher = editor.getContentSearcherOfCursor();
22255
+ if (!searcher) {
22256
+ return;
22257
+ }
21948
22258
  var textBeforeCursor = searcher.getSubStringBefore(5);
21949
22259
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21950
22260
  if (textRange) {
@@ -21952,19 +22262,20 @@ var AutoNumberingList = {
21952
22262
  ? 1
21953
22263
  : parseInt(textBeforeCursor);
21954
22264
  var isLi = getPreviousListItem(editor, textRange);
21955
- var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
22265
+ var listStyle = (_a = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor)) !== null && _a !== void 0 ? _a : undefined;
21956
22266
  prepareAutoBullet(editor, textRange);
21957
22267
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, isLi && number !== 1 ? undefined : number /** startNumber */, listStyle, 'autoToggleList' /** apiNameOverride */);
21958
22268
  }
21959
- (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21960
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22269
+ (_b = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _b === void 0 ? void 0 : _b.deleteContents();
22270
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21961
22271
  },
21962
22272
  };
21963
22273
  var getPreviousListItem = function (editor, textRange) {
22274
+ var _a;
21964
22275
  var blockElement = editor
21965
22276
  .getBodyTraverser(textRange === null || textRange === void 0 ? void 0 : textRange.startContainer)
21966
22277
  .getPreviousBlockElement();
21967
- var previousNode = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode();
22278
+ var previousNode = (_a = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode()) !== null && _a !== void 0 ? _a : null;
21968
22279
  return (0, roosterjs_editor_dom_1.getTagOfNode)(previousNode) === 'LI' ? previousNode : undefined;
21969
22280
  };
21970
22281
  var getPreviousListType = function (editor, textRange, listType) {
@@ -22012,13 +22323,14 @@ function getCacheNextSibling(event, editor) {
22012
22323
  var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'nextSibling', function () {
22013
22324
  var _a;
22014
22325
  var range = editor.getSelectionRange();
22015
- var pos = roosterjs_editor_dom_1.Position.getEnd(range).normalize();
22016
- var traverser = editor.getBodyTraverser(pos.node);
22326
+ var pos = range && roosterjs_editor_dom_1.Position.getEnd(range).normalize();
22327
+ var traverser = pos && editor.getBodyTraverser(pos.node);
22017
22328
  return (_a = traverser === null || traverser === void 0 ? void 0 : traverser.getNextBlockElement()) === null || _a === void 0 ? void 0 : _a.getStartNode();
22018
22329
  });
22019
22330
  return element;
22020
22331
  }
22021
22332
  function prepareAutoBullet(editor, range) {
22333
+ var _a;
22022
22334
  var block = editor.getBlockElementAtNode(range.startContainer);
22023
22335
  var endNode = block === null || block === void 0 ? void 0 : block.getEndNode();
22024
22336
  if (endNode && (0, roosterjs_editor_dom_1.getTagOfNode)(endNode) != 'BR') {
@@ -22027,7 +22339,7 @@ function prepareAutoBullet(editor, range) {
22027
22339
  endNode.appendChild(br);
22028
22340
  }
22029
22341
  else {
22030
- endNode.parentNode.insertBefore(br, endNode.nextSibling);
22342
+ (_a = endNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, endNode.nextSibling);
22031
22343
  }
22032
22344
  editor.select(range.startContainer, range.startOffset);
22033
22345
  }
@@ -22039,19 +22351,22 @@ function toggleListAndPreventDefault(event, editor, includeSiblingLists) {
22039
22351
  var listElement = listInfo[0];
22040
22352
  var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(listElement);
22041
22353
  if (tag == 'UL' || tag == 'OL') {
22042
- (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, null /* startNumber */, includeSiblingLists);
22354
+ (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, undefined /* startNumber */, includeSiblingLists);
22043
22355
  }
22044
22356
  editor.focus();
22045
22357
  event.rawEvent.preventDefault();
22046
22358
  }
22047
22359
  }
22048
22360
  function cacheGetListElement(event, editor) {
22049
- var li = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
22361
+ var li = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
22050
22362
  var listElement = li && (0, roosterjs_editor_dom_1.getTagOfNode)(li) == 'LI' && editor.getElementAtCursor('UL,OL', li);
22051
22363
  return listElement ? [listElement, li] : null;
22052
22364
  }
22053
22365
  function shouldTriggerList(event, editor, getListStyle, listType) {
22054
22366
  var searcher = editor.getContentSearcherOfCursor(event);
22367
+ if (!searcher) {
22368
+ return false;
22369
+ }
22055
22370
  var textBeforeCursor = searcher.getSubStringBefore(4);
22056
22371
  var traverser = editor.getBlockTraverser();
22057
22372
  var text = traverser && traverser.currentBlockElement
@@ -22060,9 +22375,9 @@ function shouldTriggerList(event, editor, getListStyle, listType) {
22060
22375
  var isATheBeginning = text && text === textBeforeCursor;
22061
22376
  var listChains = getListChains(editor);
22062
22377
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
22063
- var previousListType = getPreviousListType(editor, textRange, listType);
22378
+ var previousListType = textRange && getPreviousListType(editor, textRange, listType);
22064
22379
  var isFirstItem = isFirstItemOfAList(textBeforeCursor);
22065
- var listStyle = getListStyle(textBeforeCursor, listChains, previousListType);
22380
+ var listStyle = getListStyle(textBeforeCursor, listChains, previousListType !== null && previousListType !== void 0 ? previousListType : undefined);
22066
22381
  var shouldTriggerNewListStyle = isFirstItem ||
22067
22382
  !previousListType ||
22068
22383
  previousListType === listStyle ||
@@ -22138,6 +22453,8 @@ exports.ListFeatures = {
22138
22453
  autoNumberingList: AutoNumberingList,
22139
22454
  autoBulletList: AutoBulletList,
22140
22455
  mergeListOnBackspaceAfterList: MergeListOnBackspaceAfterList,
22456
+ outdentWhenAltShiftLeft: OutdentWhenAltShiftLeft,
22457
+ indentWhenAltShiftRight: IndentWhenAltShiftRight,
22141
22458
  };
22142
22459
  function isList(element) {
22143
22460
  return (!!element &&
@@ -22178,8 +22495,8 @@ function generateBasicMarkdownFeature(key, triggerCharacter, elementTag, useShif
22178
22495
  function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22179
22496
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'MARKDOWN_RANGE', function () {
22180
22497
  var searcher = editor.getContentSearcherOfCursor(event);
22181
- var startPosition;
22182
- var endPosition;
22498
+ var startPosition = null;
22499
+ var endPosition = null;
22183
22500
  searcher === null || searcher === void 0 ? void 0 : searcher.forEachTextInlineElement(function (textInlineElement) {
22184
22501
  if (endPosition && startPosition) {
22185
22502
  return true;
@@ -22217,12 +22534,15 @@ function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22217
22534
  }
22218
22535
  }
22219
22536
  });
22220
- return !!startPosition && !!endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22537
+ return startPosition && endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22221
22538
  });
22222
22539
  }
22223
22540
  function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22224
22541
  editor.addUndoSnapshot(function () {
22225
22542
  var range = cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter);
22543
+ if (!range) {
22544
+ return;
22545
+ }
22226
22546
  var lastTypedTriggerPosition = new roosterjs_editor_dom_1.Position(range.endContainer, -1 /* End */);
22227
22547
  var hasLastTypedTrigger = range.endOffset + 1 <= lastTypedTriggerPosition.offset;
22228
22548
  if (!!range && hasLastTypedTrigger) {
@@ -22230,7 +22550,7 @@ function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22230
22550
  var textContentRange = range.cloneRange();
22231
22551
  textContentRange.setStart(textContentRange.startContainer, textContentRange.startOffset + 1);
22232
22552
  var text = textContentRange.extractContents().textContent;
22233
- var textNode = editor.getDocument().createTextNode(text);
22553
+ var textNode = editor.getDocument().createTextNode(text !== null && text !== void 0 ? text : '');
22234
22554
  // extract content and put it into a new element.
22235
22555
  var elementToWrap = (0, roosterjs_editor_dom_1.wrap)(textNode, elementTag);
22236
22556
  //include last typed character
@@ -22314,7 +22634,7 @@ var UnquoteWhenEnterOnEmptyLine = {
22314
22634
  return !shift && childOfQuote && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfQuote);
22315
22635
  },
22316
22636
  handleEvent: function (event, editor) {
22317
- return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22637
+ return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
22318
22638
  },
22319
22639
  };
22320
22640
  function cacheGetQuoteChild(event, editor) {
@@ -22336,14 +22656,15 @@ function cacheGetQuoteChild(event, editor) {
22336
22656
  function splitQuote(event, editor) {
22337
22657
  editor.addUndoSnapshot(function () {
22338
22658
  var childOfQuote = cacheGetQuoteChild(event, editor);
22339
- var parent;
22340
- var shouldClearFormat;
22659
+ if (!childOfQuote) {
22660
+ return;
22661
+ }
22341
22662
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childOfQuote) == QUOTE_TAG) {
22342
22663
  childOfQuote = (0, roosterjs_editor_dom_1.wrap)((0, roosterjs_editor_dom_1.toArray)(childOfQuote.childNodes));
22343
22664
  }
22344
- parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22345
- shouldClearFormat = isStyledBlockquote(parent);
22346
- var newParent = (0, roosterjs_editor_dom_1.unwrap)(parent);
22665
+ var parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22666
+ var shouldClearFormat = !!parent && isStyledBlockquote(parent);
22667
+ var newParent = parent && (0, roosterjs_editor_dom_1.unwrap)(parent);
22347
22668
  editor.select(childOfQuote, 0 /* Begin */);
22348
22669
  if (shouldClearFormat) {
22349
22670
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(newParent, 'HTMLLIElement')) {
@@ -22509,7 +22830,8 @@ var InsertLineBeforeStructuredNodeFeature = {
22509
22830
  var element = cacheGetStructuredElement(event, editor);
22510
22831
  var div = (0, roosterjs_editor_dom_1.createElement)(1 /* EmptyLine */, editor.getDocument());
22511
22832
  editor.addUndoSnapshot(function () {
22512
- element.parentNode.insertBefore(div, element);
22833
+ var _a;
22834
+ (_a = element === null || element === void 0 ? void 0 : element.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(div, element);
22513
22835
  // Select the new line when we are in table. This is the same behavior with Word
22514
22836
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(element) == 'TABLE') {
22515
22837
  editor.select(new roosterjs_editor_dom_1.Position(div, 0 /* Begin */).normalize());
@@ -22567,21 +22889,26 @@ var TabInTable = {
22567
22889
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22568
22890
  },
22569
22891
  handleEvent: function (event, editor) {
22892
+ var _a, _b, _c;
22570
22893
  var shift = event.rawEvent.shiftKey;
22571
22894
  var td = cacheGetTableCell(event, editor);
22895
+ if (!td) {
22896
+ return;
22897
+ }
22572
22898
  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) {
22899
+ 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) {
22900
+ var tableCells = (_c = vtable.cells) !== null && _c !== void 0 ? _c : [];
22901
+ if (col < 0 || col >= tableCells[row].length) {
22575
22902
  row += step;
22576
22903
  if (row < 0) {
22577
22904
  editor.select(vtable.table, -2 /* Before */);
22578
22905
  break;
22579
22906
  }
22580
- else if (row >= vtable.cells.length) {
22907
+ else if (row >= tableCells.length) {
22581
22908
  (0, roosterjs_editor_api_1.editTable)(editor, 1 /* InsertBelow */);
22582
22909
  break;
22583
22910
  }
22584
- col = shift ? vtable.cells[row].length - 1 : 0;
22911
+ col = shift ? tableCells[row].length - 1 : 0;
22585
22912
  }
22586
22913
  var cell = vtable.getCell(row, col);
22587
22914
  if (cell.td) {
@@ -22607,6 +22934,9 @@ var IndentTableOnTab = {
22607
22934
  var shift = event.rawEvent.shiftKey;
22608
22935
  var selection = editor.getSelectionRangeEx();
22609
22936
  var td = cacheGetTableCell(event, editor);
22937
+ if (!td) {
22938
+ return;
22939
+ }
22610
22940
  var vtable = cacheVTable(event, td);
22611
22941
  if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
22612
22942
  (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
@@ -22614,7 +22944,9 @@ var IndentTableOnTab = {
22614
22944
  else if (!shift) {
22615
22945
  (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
22616
22946
  }
22617
- editor.select(selection.table, selection.coordinates);
22947
+ if (selection.coordinates) {
22948
+ editor.select(selection.table, selection.coordinates);
22949
+ }
22618
22950
  });
22619
22951
  },
22620
22952
  };
@@ -22628,8 +22960,11 @@ var UpDownInTable = {
22628
22960
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22629
22961
  },
22630
22962
  handleEvent: function (event, editor) {
22631
- var _a;
22963
+ var _a, _b, _c;
22632
22964
  var td = cacheGetTableCell(event, editor);
22965
+ if (!td) {
22966
+ return;
22967
+ }
22633
22968
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22634
22969
  var isUp = event.rawEvent.which == 38 /* UP */;
22635
22970
  var step = isUp ? -1 : 1;
@@ -22638,8 +22973,8 @@ var UpDownInTable = {
22638
22973
  var targetTd = null;
22639
22974
  if (selection) {
22640
22975
  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);
22976
+ for (var row = (_b = vtable.row) !== null && _b !== void 0 ? _b : 0; row >= 0 && vtable.cells && row < vtable.cells.length; row += step) {
22977
+ var cell = vtable.getCell(row, (_c = vtable.col) !== null && _c !== void 0 ? _c : 0);
22643
22978
  if (cell.td && cell.td != td) {
22644
22979
  targetTd = cell.td;
22645
22980
  break;
@@ -22660,7 +22995,9 @@ var UpDownInTable = {
22660
22995
  ? new roosterjs_editor_dom_1.Position(newPos.node, newPos.isAtEnd ? -3 /* After */ : -2 /* Before */)
22661
22996
  : newPos;
22662
22997
  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);
22998
+ if (anchorNode_1) {
22999
+ selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
23000
+ }
22664
23001
  }
22665
23002
  else {
22666
23003
  editor.select(newPos.normalize());
@@ -22683,6 +23020,9 @@ var DeleteTableWithBackspace = {
22683
23020
  },
22684
23021
  handleEvent: function (event, editor) {
22685
23022
  var td = cacheGetTableCell(event, editor);
23023
+ if (!td) {
23024
+ return;
23025
+ }
22686
23026
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22687
23027
  vtable.edit(4 /* DeleteTable */);
22688
23028
  vtable.writeBack();
@@ -22698,9 +23038,13 @@ function cacheGetTableCell(event, editor) {
22698
23038
  function cacheIsWholeTableSelected(event, editor) {
22699
23039
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
22700
23040
  var td = cacheGetTableCell(event, editor);
23041
+ if (!td) {
23042
+ return false;
23043
+ }
22701
23044
  var vtable = cacheVTable(event, td);
22702
23045
  var selection = editor.getSelectionRangeEx();
22703
23046
  return (selection.type == 1 /* TableSelection */ &&
23047
+ selection.coordinates &&
22704
23048
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
22705
23049
  });
22706
23050
  }
@@ -22750,7 +23094,7 @@ var IndentWhenTabText = {
22750
23094
  if (editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */) &&
22751
23095
  !event.rawEvent.shiftKey) {
22752
23096
  var activeElement = editor.getDocument().activeElement;
22753
- var listOrTable = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
23097
+ var listOrTable = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
22754
23098
  var entity = editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), undefined /*startFrom*/, event);
22755
23099
  return (!listOrTable &&
22756
23100
  (entity ? entity.isContentEditable : activeElement.isContentEditable));
@@ -22794,8 +23138,8 @@ var OutdentWhenTabText = {
22794
23138
  var selection = editor.getSelectionRangeEx();
22795
23139
  return (selection.type == 0 /* Normal */ &&
22796
23140
  !selection.areAllCollapsed &&
22797
- editor.getElementAtCursor('blockquote', null, event) &&
22798
- !editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event) &&
23141
+ editor.getElementAtCursor('blockquote', undefined, event) &&
23142
+ !editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event) &&
22799
23143
  shouldSetIndentation(editor, selection.ranges[0]));
22800
23144
  }
22801
23145
  return false;
@@ -22859,9 +23203,12 @@ function isRangeEmpty(range) {
22859
23203
  function insertTab(editor, event) {
22860
23204
  var span = editor.getDocument().createElement('span');
22861
23205
  var searcher = editor.getContentSearcherOfCursor(event);
23206
+ if (!searcher) {
23207
+ return;
23208
+ }
22862
23209
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
22863
23210
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
22864
- var span2;
23211
+ var span2 = null;
22865
23212
  var textContent = '';
22866
23213
  for (var index = 0; index < numberOfChars; index++) {
22867
23214
  textContent += '&ensp;';
@@ -22918,7 +23265,8 @@ var shortcutFeatures_1 = __webpack_require__(/*! ./features/shortcutFeatures */
22918
23265
  var structuredNodeFeatures_1 = __webpack_require__(/*! ./features/structuredNodeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/structuredNodeFeatures.ts");
22919
23266
  var tableFeatures_1 = __webpack_require__(/*! ./features/tableFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/tableFeatures.ts");
22920
23267
  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);
23268
+ var codeFeatures_1 = __webpack_require__(/*! ./features/codeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts");
23269
+ 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
23270
  /**
22923
23271
  * Get all content edit features provided by roosterjs
22924
23272
  */
@@ -23054,7 +23402,8 @@ var identifyNumberingType = function (text, previousListStyle) {
23054
23402
  return 1 /* Decimal */;
23055
23403
  }
23056
23404
  else if (/[a-z]+/g.test(text)) {
23057
- if ((lowerRomanTypes.indexOf(previousListStyle) > -1 &&
23405
+ if ((previousListStyle != undefined &&
23406
+ lowerRomanTypes.indexOf(previousListStyle) > -1 &&
23058
23407
  lowerRomanNumbers.indexOf(text[0]) > -1) ||
23059
23408
  (!previousListStyle && text === 'i')) {
23060
23409
  return 4 /* LowerRoman */;
@@ -23064,7 +23413,8 @@ var identifyNumberingType = function (text, previousListStyle) {
23064
23413
  }
23065
23414
  }
23066
23415
  else if (/[A-Z]+/g.test(text)) {
23067
- if ((upperRomanTypes.indexOf(previousListStyle) > -1 &&
23416
+ if ((previousListStyle != undefined &&
23417
+ upperRomanTypes.indexOf(previousListStyle) > -1 &&
23068
23418
  upperRomanNumbers.indexOf(text[0]) > -1) ||
23069
23419
  (!previousListStyle && text === 'I')) {
23070
23420
  return 5 /* UpperRoman */;
@@ -24179,6 +24529,7 @@ var ImageEdit = /** @class */ (function () {
24179
24529
  //Clone the image and insert the clone in a entity
24180
24530
  this.clonedImage = this.image.cloneNode(true);
24181
24531
  this.clonedImage.removeAttribute('id');
24532
+ this.clonedImage.style.removeProperty('max-width');
24182
24533
  this.wrapper = (0, roosterjs_editor_dom_1.createElement)(6 /* ImageEditWrapper */, this.image.ownerDocument);
24183
24534
  (_b = (_a = this.wrapper) === null || _a === void 0 ? void 0 : _a.firstChild) === null || _b === void 0 ? void 0 : _b.appendChild(this.clonedImage);
24184
24535
  this.wrapper.style.display = roosterjs_editor_dom_1.Browser.isSafari ? 'inline-block' : 'inline-flex';
@@ -24490,6 +24841,7 @@ function resizeByPercentage(editor, image, percentage, minWidth, minHeight) {
24490
24841
  editor.addUndoSnapshot(function () {
24491
24842
  (0, applyChange_1.default)(editor, image, editInfo, lastSrc_1 || '', true /*wasResized*/);
24492
24843
  }, "ImageResize" /* ImageResize */);
24844
+ editor.select(image);
24493
24845
  }
24494
24846
  });
24495
24847
  }
@@ -25511,6 +25863,7 @@ var Paste = /** @class */ (function () {
25511
25863
  if (convertSingleImageBody === void 0) { convertSingleImageBody = false; }
25512
25864
  this.unknownTagReplacement = unknownTagReplacement;
25513
25865
  this.convertSingleImageBody = convertSingleImageBody;
25866
+ this.editor = null;
25514
25867
  }
25515
25868
  /**
25516
25869
  * Get a friendly name of this plugin
@@ -25536,7 +25889,7 @@ var Paste = /** @class */ (function () {
25536
25889
  * @param event PluginEvent object
25537
25890
  */
25538
25891
  Paste.prototype.onPluginEvent = function (event) {
25539
- if (event.eventType == 10 /* BeforePaste */) {
25892
+ if (this.editor && event.eventType == 10 /* BeforePaste */) {
25540
25893
  var fragment = event.fragment, sanitizingOption = event.sanitizingOption;
25541
25894
  var trustedHTMLHandler = this.editor.getTrustedHTMLHandler();
25542
25895
  switch ((0, getPasteSource_1.default)(event, this.convertSingleImageBody)) {
@@ -25545,22 +25898,23 @@ var Paste = /** @class */ (function () {
25545
25898
  (0, convertPastedContentFromWord_1.default)(event);
25546
25899
  break;
25547
25900
  case 1 /* ExcelDesktop */:
25901
+ case 2 /* ExcelOnline */:
25548
25902
  // Handle HTML copied from Excel
25549
25903
  (0, convertPastedContentFromExcel_1.default)(event, trustedHTMLHandler);
25550
25904
  break;
25551
- case 2 /* PowerPointDesktop */:
25905
+ case 3 /* PowerPointDesktop */:
25552
25906
  (0, convertPastedContentFromPowerPoint_1.default)(event, trustedHTMLHandler);
25553
25907
  break;
25554
- case 4 /* WacComponents */:
25908
+ case 5 /* WacComponents */:
25555
25909
  (0, convertPastedContentFromOfficeOnline_1.default)(fragment);
25556
25910
  break;
25557
- case 3 /* GoogleSheets */:
25911
+ case 4 /* GoogleSheets */:
25558
25912
  sanitizingOption.additionalTagReplacements[constants_1.GOOGLE_SHEET_NODE_NAME] = '*';
25559
25913
  break;
25560
- case 6 /* SingleImage */:
25914
+ case 7 /* SingleImage */:
25561
25915
  (0, convertPasteContentForSingleImage_1.default)(event, trustedHTMLHandler);
25562
25916
  break;
25563
- case 5 /* Default */:
25917
+ case 6 /* Default */:
25564
25918
  (0, convertPastedContentForLI_1.default)(fragment);
25565
25919
  (0, handleLineMerge_1.default)(fragment);
25566
25920
  break;
@@ -25655,12 +26009,28 @@ var DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';
25655
26009
  * @param event The BeforePaste event
25656
26010
  */
25657
26011
  function convertPastedContentFromExcel(event, trustedHTMLHandler) {
26012
+ var _a, _b;
25658
26013
  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) {
26014
+ var fragmentHTML = (_b = (_a = fragment.firstElementChild) === null || _a === void 0 ? void 0 : _a.outerHTML) !== null && _b !== void 0 ? _b : clipboardData.html;
26015
+ var html = fragmentHTML ? excelHandler(fragmentHTML, htmlBefore) : undefined;
26016
+ if (html && fragmentHTML != html) {
25661
26017
  var doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');
25662
26018
  (0, roosterjs_editor_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
25663
26019
  }
26020
+ // For Excel Online
26021
+ var firstChild = fragment.firstChild;
26022
+ if (firstChild && firstChild.childNodes.length > 0 && (0, roosterjs_editor_dom_1.getTagOfNode)(firstChild) == 'DIV') {
26023
+ var tableFound = Array.from(firstChild.childNodes).every(function (child) {
26024
+ // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag
26025
+ return (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'META'
26026
+ ? true
26027
+ : (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'TABLE' && child == firstChild.lastChild;
26028
+ });
26029
+ // Extract Table from Div
26030
+ if (tableFound && firstChild.lastChild) {
26031
+ event.fragment.replaceChildren(firstChild.lastChild);
26032
+ }
26033
+ }
25664
26034
  (0, roosterjs_editor_dom_1.chainSanitizerCallback)(sanitizingOption.elementCallbacks, 'TD', function (element) {
25665
26035
  if (element.style.borderStyle == 'none') {
25666
26036
  element.style.border = DEFAULT_BORDER_STYLE;
@@ -25774,21 +26144,23 @@ function handleLineMerge(root) {
25774
26144
  }
25775
26145
  exports.default = handleLineMerge;
25776
26146
  function processBlock(block) {
25777
- var _a, _b;
26147
+ var _a, _b, _c;
25778
26148
  var start = block.start, end = block.end;
25779
26149
  if (start == end && (0, roosterjs_editor_dom_1.getTagOfNode)(start) == 'DIV') {
25780
26150
  var node = (0, roosterjs_editor_dom_1.changeElementTag)(start, 'SPAN');
25781
26151
  block.start = node;
25782
26152
  block.end = node;
25783
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
26153
+ if (node && node.lastChild && (0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
25784
26154
  node.removeChild(node.lastChild);
25785
26155
  }
25786
26156
  }
25787
26157
  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);
26158
+ var node = (_a = end.ownerDocument) === null || _a === void 0 ? void 0 : _a.createTextNode('');
26159
+ if (node) {
26160
+ (_b = end.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(node, end);
26161
+ block.end = node;
26162
+ (_c = end.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(end);
26163
+ }
25792
26164
  }
25793
26165
  }
25794
26166
  function checkAndAddBr(root, block, isFirst, firstBlock) {
@@ -25876,8 +26248,9 @@ var convertPastedContentFromWordOnline_1 = __webpack_require__(/*! ./convertPast
25876
26248
  */
25877
26249
  function convertPastedContentFromOfficeOnline(fragment) {
25878
26250
  fragment.querySelectorAll(constants_1.WAC_IDENTIFY_SELECTOR).forEach(function (el) {
25879
- el.style.display = null;
25880
- el.style.margin = null;
26251
+ var element = el;
26252
+ element.style.removeProperty('display');
26253
+ element.style.removeProperty('margin');
25881
26254
  });
25882
26255
  // call conversion function if the pasted content is from word online and
25883
26256
  // has list element in the pasted content.
@@ -25957,6 +26330,7 @@ function convertPastedContentFromWordOnline(fragment) {
25957
26330
  sanitizeListItemContainer(fragment);
25958
26331
  var listItemBlocks = getListItemBlocks(fragment);
25959
26332
  listItemBlocks.forEach(function (itemBlock) {
26333
+ var _a, _b, _c;
25960
26334
  // There are cases where consecutive List Elements are separated into different nodes:
25961
26335
  // <div>
25962
26336
  // <div>
@@ -25986,37 +26360,47 @@ function convertPastedContentFromWordOnline(fragment) {
25986
26360
  // Then we are start processing.
25987
26361
  flattenListBlock(fragment, itemBlock);
25988
26362
  // 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;
26363
+ itemBlock.insertPositionNode = (_b = (_a = itemBlock.endElement) === null || _a === void 0 ? void 0 : _a.nextSibling) !== null && _b !== void 0 ? _b : null;
26364
+ var convertedListElement = undefined;
25991
26365
  var doc = fragment.ownerDocument;
25992
26366
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
25993
26367
  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);
26368
+ if (listType) {
26369
+ // Initialize processed element with proper listType if this is the first element
26370
+ if (!convertedListElement) {
26010
26371
  convertedListElement = createNewList(listItemContainer, doc, listType);
26011
26372
  }
26012
- insertListItem(convertedListElement, item, listType, doc);
26013
- });
26373
+ // Get all list items(<li>) in the current iterator element.
26374
+ var currentListItems = (0, roosterjs_editor_dom_1.toArray)(listItemContainer.querySelectorAll('li'));
26375
+ currentListItems.forEach(function (item) {
26376
+ var _a;
26377
+ // If item is in root level and the type of list changes then
26378
+ // insert the current list into body and then reinitialize the convertedListElement
26379
+ // Word Online is using data-aria-level to determine the the depth of the list item.
26380
+ var itemLevel = parseInt((_a = item.getAttribute('data-aria-level')) !== null && _a !== void 0 ? _a : '');
26381
+ // In first level list, there are cases where a consecutive list item DIV may have different list type
26382
+ // When that happens we need to insert the processed elements into the document, then change the list type
26383
+ // and keep the processing going.
26384
+ if (convertedListElement &&
26385
+ (0, roosterjs_editor_dom_1.getTagOfNode)(convertedListElement) != listType &&
26386
+ itemLevel == 1 &&
26387
+ listType) {
26388
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26389
+ convertedListElement = createNewList(listItemContainer, doc, listType);
26390
+ }
26391
+ if (convertedListElement && listType) {
26392
+ insertListItem(convertedListElement, item, listType, doc);
26393
+ }
26394
+ });
26395
+ }
26014
26396
  });
26015
- insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26397
+ if (convertedListElement) {
26398
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26399
+ }
26016
26400
  // Once we finish the process the list items and put them into a list.
26017
26401
  // After inserting the processed element,
26018
26402
  // we need to remove all the non processed node from the parent node.
26019
- var parentContainer = itemBlock.startElement.parentNode;
26403
+ var parentContainer = (_c = itemBlock.startElement) === null || _c === void 0 ? void 0 : _c.parentNode;
26020
26404
  if (parentContainer) {
26021
26405
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
26022
26406
  parentContainer.removeChild(listItemContainer);
@@ -26036,8 +26420,9 @@ function convertPastedContentFromWordOnline(fragment) {
26036
26420
  // Removing the nodes that are not img will resolve the additional space
26037
26421
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLSpanElement')) {
26038
26422
  node.childNodes.forEach(function (childNode) {
26423
+ var _a;
26039
26424
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childNode) != 'IMG') {
26040
- childNode.parentElement.removeChild(childNode);
26425
+ (_a = childNode.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(childNode);
26041
26426
  }
26042
26427
  });
26043
26428
  }
@@ -26079,7 +26464,7 @@ function sanitizeListItemContainer(fragment) {
26079
26464
  function getListItemBlocks(fragment) {
26080
26465
  var listElements = fragment.querySelectorAll('.' + LIST_CONTAINER_ELEMENT_CLASS_NAME);
26081
26466
  var result = [];
26082
- var curListItemBlock;
26467
+ var curListItemBlock = null;
26083
26468
  for (var i = 0; i < listElements.length; i++) {
26084
26469
  var curItem = listElements[i];
26085
26470
  if (!curListItemBlock) {
@@ -26089,8 +26474,9 @@ function getListItemBlocks(fragment) {
26089
26474
  var listItemContainers = curListItemBlock.listItemContainers;
26090
26475
  var lastItemInCurBlock = listItemContainers[listItemContainers.length - 1];
26091
26476
  if (curItem == lastItemInCurBlock.nextSibling ||
26092
- (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
26093
- (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock)) {
26477
+ (lastItemInCurBlock.parentNode &&
26478
+ (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
26479
+ (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock))) {
26094
26480
  listItemContainers.push(curItem);
26095
26481
  curListItemBlock.endElement = curItem;
26096
26482
  }
@@ -26101,7 +26487,7 @@ function getListItemBlocks(fragment) {
26101
26487
  }
26102
26488
  }
26103
26489
  }
26104
- if ((curListItemBlock === null || curListItemBlock === void 0 ? void 0 : curListItemBlock.listItemContainers.length) > 0) {
26490
+ if (curListItemBlock && curListItemBlock.listItemContainers.length > 0) {
26105
26491
  result.push(curListItemBlock);
26106
26492
  }
26107
26493
  return result;
@@ -26112,12 +26498,14 @@ function getListItemBlocks(fragment) {
26112
26498
  * @param listItemBlock The list item block needed to be flattened.
26113
26499
  */
26114
26500
  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
- });
26501
+ if (listItemBlock.startElement && listItemBlock.endElement) {
26502
+ var collapsedListItemSections = (0, roosterjs_editor_dom_1.collapseNodes)(fragment, listItemBlock.startElement, listItemBlock.endElement, true);
26503
+ collapsedListItemSections.forEach(function (section) {
26504
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(section.firstChild) == 'DIV') {
26505
+ (0, roosterjs_editor_dom_1.unwrap)(section);
26506
+ }
26507
+ });
26508
+ }
26121
26509
  }
26122
26510
  /**
26123
26511
  * Get the list type that the container contains. If there is no list in the container
@@ -26155,14 +26543,16 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26155
26543
  // If the current level is empty, create empty list within the current level
26156
26544
  // then move the level iterator into the next level.
26157
26545
  curListLevel.appendChild(doc.createElement(listType));
26158
- curListLevel = curListLevel.firstElementChild;
26546
+ if (curListLevel.firstElementChild) {
26547
+ curListLevel = curListLevel.firstElementChild;
26548
+ }
26159
26549
  }
26160
26550
  else {
26161
26551
  // If the current level is not empty, the last item in the needs to be a UL or OL
26162
26552
  // and the level iterator should move to the UL/OL at the last position.
26163
26553
  var lastChild = curListLevel.lastElementChild;
26164
26554
  var lastChildTag = (0, roosterjs_editor_dom_1.getTagOfNode)(lastChild);
26165
- if (lastChildTag == 'UL' || lastChildTag == 'OL') {
26555
+ if (lastChild && (lastChildTag == 'UL' || lastChildTag == 'OL')) {
26166
26556
  // If the last child is a list(UL/OL), then move the level iterator to last child.
26167
26557
  curListLevel = lastChild;
26168
26558
  }
@@ -26170,7 +26560,9 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26170
26560
  // If the last child is not a list, then append a new list to the level
26171
26561
  // and move the level iterator to the new level.
26172
26562
  curListLevel.appendChild(doc.createElement(listType));
26173
- curListLevel = curListLevel.lastElementChild;
26563
+ if (curListLevel.lastElementChild) {
26564
+ curListLevel = curListLevel.lastElementChild;
26565
+ }
26174
26566
  }
26175
26567
  }
26176
26568
  itemLevel--;
@@ -26185,6 +26577,7 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26185
26577
  * @param listItemBlock List item block that was converted.
26186
26578
  */
26187
26579
  function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock) {
26580
+ var _a;
26188
26581
  if (!convertedListElement) {
26189
26582
  return;
26190
26583
  }
@@ -26196,7 +26589,7 @@ function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock)
26196
26589
  }
26197
26590
  }
26198
26591
  else {
26199
- var parentNode = listItemBlock.startElement.parentNode;
26592
+ var parentNode = (_a = listItemBlock.startElement) === null || _a === void 0 ? void 0 : _a.parentNode;
26200
26593
  if (parentNode) {
26201
26594
  parentNode.appendChild(convertedListElement);
26202
26595
  }
@@ -26367,7 +26760,7 @@ function validateLink(link, htmlElement) {
26367
26760
  "use strict";
26368
26761
 
26369
26762
  Object.defineProperty(exports, "__esModule", { value: true });
26370
- exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26763
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26371
26764
  /**
26372
26765
  * @internal
26373
26766
  * Node attribute used to identify if the content is from Google Sheets.
@@ -26383,6 +26776,11 @@ exports.PROG_ID_NAME = 'ProgId';
26383
26776
  * Selector used to identify Wac Elements
26384
26777
  */
26385
26778
  exports.WAC_IDENTIFY_SELECTOR = 'ul[class^="BulletListStyle"]>.OutlineElement,ol[class^="NumberListStyle"]>.OutlineElement,span.WACImageContainer';
26779
+ /**
26780
+ * @internal
26781
+ * Name of the HTMLMeta Property that identifies pated content as from Excel Desktop
26782
+ */
26783
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = 'xmlns:x';
26386
26784
 
26387
26785
 
26388
26786
  /***/ }),
@@ -26425,6 +26823,7 @@ exports.default = documentContainWacElements;
26425
26823
  Object.defineProperty(exports, "__esModule", { value: true });
26426
26824
  var documentContainWacElements_1 = __webpack_require__(/*! ./documentContainWacElements */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/documentContainWacElements.ts");
26427
26825
  var isExcelDesktopDocument_1 = __webpack_require__(/*! ./isExcelDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelDesktopDocument.ts");
26826
+ var isExcelOnlineDocument_1 = __webpack_require__(/*! ./isExcelOnlineDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts");
26428
26827
  var isGoogleSheetDocument_1 = __webpack_require__(/*! ./isGoogleSheetDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts");
26429
26828
  var isPowerPointDesktopDocument_1 = __webpack_require__(/*! ./isPowerPointDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isPowerPointDesktopDocument.ts");
26430
26829
  var isWordDesktopDocument_1 = __webpack_require__(/*! ./isWordDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isWordDesktopDocument.ts");
@@ -26432,10 +26831,11 @@ var shouldConvertToSingleImage_1 = __webpack_require__(/*! ./shouldConvertToSing
26432
26831
  var getSourceFunctions = new Map([
26433
26832
  [0 /* WordDesktop */, isWordDesktopDocument_1.default],
26434
26833
  [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],
26834
+ [2 /* ExcelOnline */, isExcelOnlineDocument_1.default],
26835
+ [3 /* PowerPointDesktop */, isPowerPointDesktopDocument_1.default],
26836
+ [5 /* WacComponents */, documentContainWacElements_1.default],
26837
+ [4 /* GoogleSheets */, isGoogleSheetDocument_1.default],
26838
+ [7 /* SingleImage */, shouldConvertToSingleImage_1.default],
26439
26839
  ]);
26440
26840
  /**
26441
26841
  * @internal
@@ -26458,7 +26858,7 @@ function getPasteSource(event, shouldConvertSingleImage) {
26458
26858
  result = key;
26459
26859
  }
26460
26860
  });
26461
- return result !== null && result !== void 0 ? result : 5 /* Default */;
26861
+ return result !== null && result !== void 0 ? result : 6 /* Default */;
26462
26862
  }
26463
26863
  exports.default = getPasteSource;
26464
26864
 
@@ -26476,9 +26876,7 @@ exports.default = getPasteSource;
26476
26876
 
26477
26877
  Object.defineProperty(exports, "__esModule", { value: true });
26478
26878
  var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26479
- var EXCEL_ATTRIBUTE_NAME = 'xmlns:x';
26480
26879
  var EXCEL_ATTRIBUTE_VALUE = 'urn:schemas-microsoft-com:office:excel';
26481
- var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26482
26880
  /**
26483
26881
  * @internal
26484
26882
  * Checks whether the Array provided contains strings that identify Excel Desktop documents
@@ -26487,12 +26885,42 @@ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26487
26885
  */
26488
26886
  var isExcelDesktopDocument = function (props) {
26489
26887
  var htmlAttributes = props.htmlAttributes;
26490
- return (htmlAttributes[EXCEL_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE ||
26491
- htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE);
26888
+ // The presence of this attribute confirms its origin from Excel Desktop
26889
+ return htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE;
26492
26890
  };
26493
26891
  exports.default = isExcelDesktopDocument;
26494
26892
 
26495
26893
 
26894
+ /***/ }),
26895
+
26896
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts":
26897
+ /*!********************************************************************************************************!*\
26898
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts ***!
26899
+ \********************************************************************************************************/
26900
+ /*! no static exports found */
26901
+ /***/ (function(module, exports, __webpack_require__) {
26902
+
26903
+ "use strict";
26904
+
26905
+ Object.defineProperty(exports, "__esModule", { value: true });
26906
+ var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26907
+ // Excel Desktop also has this attribute
26908
+ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26909
+ /**
26910
+ * @internal
26911
+ * Checks whether the Array provided contains strings that identify Excel Online documents
26912
+ * @param props Properties related to the PasteEvent
26913
+ * @returns
26914
+ */
26915
+ var isExcelOnlineDocument = function (props) {
26916
+ var htmlAttributes = props.htmlAttributes;
26917
+ // The presence of Excel.Sheet confirms its origin from Excel, the absence of EXCEL_DESKTOP_ATTRIBUTE_NAME confirms it is from the Online version
26918
+ return (htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE &&
26919
+ htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == undefined);
26920
+ };
26921
+ exports.default = isExcelOnlineDocument;
26922
+
26923
+
26496
26924
  /***/ }),
26497
26925
 
26498
26926
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts":
@@ -26932,7 +27360,11 @@ var LINE_BREAKS = /[\n|\r]/gi;
26932
27360
  * for numbered headers, and we don't want to convert those, because the numbering would be completely wrong.
26933
27361
  */
26934
27362
  function processNodesDiscovery(wordConverter) {
27363
+ var _a;
26935
27364
  var args = wordConverter.wordConverterArgs;
27365
+ if (!args) {
27366
+ return false;
27367
+ }
26936
27368
  while (args.currentIndex < args.nodes.length) {
26937
27369
  var node = args.nodes.item(args.currentIndex);
26938
27370
  // Try to get the list metadata for the specified node
@@ -27021,7 +27453,7 @@ function processNodesDiscovery(wordConverter) {
27021
27453
  last.appendChild(last.ownerDocument.createElement('br'));
27022
27454
  (0, roosterjs_editor_dom_1.moveChildNodes)(last, node, true /*keepExistingChildren*/);
27023
27455
  // Remove the item that we don't need anymore
27024
- node.parentNode.removeChild(node);
27456
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
27025
27457
  }
27026
27458
  }
27027
27459
  // Move to the next element are return true if more elements need to be processed
@@ -27037,44 +27469,47 @@ exports.processNodesDiscovery = processNodesDiscovery;
27037
27469
  * conversion needed
27038
27470
  */
27039
27471
  function processNodeConvert(wordConverter) {
27472
+ var _a;
27040
27473
  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++;
27474
+ if (args) {
27475
+ args.currentIndex = 0;
27476
+ while (args.currentIndex < args.listItems.length) {
27477
+ var metadata = args.listItems[args.currentIndex];
27478
+ var node = metadata.originalNode;
27479
+ var listMetadata = args.lists[metadata.uniqueListId.toString()];
27480
+ if (!listMetadata.ignore) {
27481
+ // We have a list item that we need to convert, get or create the list
27482
+ // that hold this item out
27483
+ var list = getOrCreateListForNode(wordConverter, node, metadata, listMetadata);
27484
+ if (list) {
27485
+ // Clean the element out.. this call gets rid of the fake bullet and unneeded nodes
27486
+ cleanupListIgnore(node, LOOKUP_DEPTH);
27487
+ // Create a new list item and transfer the children
27488
+ var li = node.ownerDocument.createElement('LI');
27489
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(node).startsWith('H')) {
27490
+ var clone = node.cloneNode(true /* deep */);
27491
+ clone.style.textIndent = '';
27492
+ clone.style.marginLeft = '';
27493
+ clone.style.marginRight = '';
27494
+ li.appendChild(clone);
27495
+ }
27496
+ else {
27497
+ (0, roosterjs_editor_dom_1.moveChildNodes)(li, node);
27498
+ }
27499
+ // Append the list item into the list
27500
+ list.appendChild(li);
27501
+ // Remove the node we just converted
27502
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
27503
+ if (listMetadata.tagName == 'UL') {
27504
+ wordConverter.numBulletsConverted++;
27505
+ }
27506
+ else {
27507
+ wordConverter.numNumberedConverted++;
27508
+ }
27074
27509
  }
27075
27510
  }
27511
+ args.currentIndex++;
27076
27512
  }
27077
- args.currentIndex++;
27078
27513
  }
27079
27514
  return wordConverter.numBulletsConverted > 0 || wordConverter.numNumberedConverted > 0;
27080
27515
  }
@@ -27084,6 +27519,7 @@ exports.processNodeConvert = processNodeConvert;
27084
27519
  * items content and the specified metadata
27085
27520
  */
27086
27521
  function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27522
+ var _a;
27087
27523
  // First get the last list next to this node under the specified level. This code
27088
27524
  // path will return the list or will create lists if needed
27089
27525
  var list = recurringGetOrCreateListAtNode(node, metadata.level, listMetadata);
@@ -27095,7 +27531,7 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27095
27531
  // is a completely new list, so we'll append a new list for that
27096
27532
  if ((listId && listId != metadata.uniqueListId) || (!listId && list.firstChild)) {
27097
27533
  var newList = node.ownerDocument.createElement(listMetadata.tagName);
27098
- list.parentNode.insertBefore(newList, list.nextSibling);
27534
+ (_a = list.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newList, list.nextSibling);
27099
27535
  list = newList;
27100
27536
  }
27101
27537
  // Set the list id into the custom data
@@ -27110,15 +27546,18 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27110
27546
  * information already stored in the list itself
27111
27547
  */
27112
27548
  function convertListIfNeeded(wordConverter, list, listMetadata) {
27549
+ var _a, _b, _c;
27113
27550
  // Check if we need to convert the list out
27114
27551
  if (listMetadata.tagName != (0, roosterjs_editor_dom_1.getTagOfNode)(list)) {
27115
27552
  // 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;
27553
+ var newList = (_a = list.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata.tagName);
27554
+ if (newList) {
27555
+ (0, WordCustomData_1.setObject)(wordConverter.wordCustomData, newList, UNIQUE_LIST_ID_CUSTOM_DATA, (0, WordCustomData_1.getObject)(wordConverter.wordCustomData, list, UNIQUE_LIST_ID_CUSTOM_DATA));
27556
+ (0, roosterjs_editor_dom_1.moveChildNodes)(newList, list);
27557
+ (_b = list.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, list);
27558
+ (_c = list.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(list);
27559
+ list = newList;
27560
+ }
27122
27561
  }
27123
27562
  return list;
27124
27563
  }
@@ -27126,8 +27565,9 @@ function convertListIfNeeded(wordConverter, list, listMetadata) {
27126
27565
  * Gets or creates the specified list
27127
27566
  */
27128
27567
  function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27568
+ var _a, _b;
27129
27569
  var parent = null;
27130
- var possibleList;
27570
+ var possibleList = null;
27131
27571
  if (level == 1) {
27132
27572
  // Root case, we'll check if the list is the previous sibling of the node
27133
27573
  possibleList = getRealPreviousSibling(node);
@@ -27136,7 +27576,9 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27136
27576
  // If we get here, we are looking for level 2 or deeper... get the upper list
27137
27577
  // and check if the last element is a list
27138
27578
  parent = recurringGetOrCreateListAtNode(node, level - 1, null);
27139
- possibleList = parent.lastChild;
27579
+ if (parent.lastChild) {
27580
+ possibleList = parent.lastChild;
27581
+ }
27140
27582
  }
27141
27583
  // Check the element that we got and verify that it is a list
27142
27584
  if (possibleList && possibleList.nodeType == 1 /* Element */) {
@@ -27148,15 +27590,15 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27148
27590
  }
27149
27591
  // If we get here, it means we don't have a list and we need to create one
27150
27592
  // this code path will always create new lists as UL lists
27151
- var newList = node.ownerDocument.createElement(listMetadata ? listMetadata.tagName : 'UL');
27593
+ var newList = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata ? listMetadata.tagName : 'UL');
27152
27594
  if (level == 1) {
27153
27595
  // For level 1, we'll insert the list before the node
27154
- node.parentNode.insertBefore(newList, node);
27596
+ (_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, node);
27155
27597
  }
27156
27598
  else {
27157
27599
  // Any level 2 or above, we insert the list as the last
27158
27600
  // child of the upper level list
27159
- parent.appendChild(newList);
27601
+ parent === null || parent === void 0 ? void 0 : parent.appendChild(newList);
27160
27602
  }
27161
27603
  return newList;
27162
27604
  }
@@ -27168,15 +27610,17 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27168
27610
  function cleanupListIgnore(node, levels) {
27169
27611
  var nodesToRemove = [];
27170
27612
  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);
27613
+ if (child) {
27614
+ // Clean up the item internally first if we need to based on the number of levels
27615
+ if (child && child.nodeType == 1 /* Element */ && levels > 1) {
27616
+ cleanupListIgnore(child, levels - 1);
27617
+ }
27618
+ // Try to convert word comments into ignore elements if we haven't done so for this element
27619
+ child = fixWordListComments(child, true /*removeComments*/);
27620
+ // Check if we can remove this item out
27621
+ if (isEmptySpan(child) || isIgnoreNode(child)) {
27622
+ nodesToRemove.push(child);
27623
+ }
27180
27624
  }
27181
27625
  }
27182
27626
  nodesToRemove.forEach(function (child) { return node.removeChild(child); });
@@ -27225,6 +27669,7 @@ function getFakeBulletTagName(fakeBullet) {
27225
27669
  * a bullet string. If not found, it returns null...
27226
27670
  */
27227
27671
  function getFakeBulletText(node, levels) {
27672
+ var _a, _b;
27228
27673
  // Word uses the following format for their bullets:
27229
27674
  // &lt;p style="mso-list:l1 level1 lfo2"&gt;
27230
27675
  // &lt;span style="..."&gt;
@@ -27235,7 +27680,7 @@ function getFakeBulletText(node, levels) {
27235
27680
  //
27236
27681
  // Basically, we need to locate the mso-list:Ignore SPAN, which holds either one text or image node. That
27237
27682
  // text or image node will be the fake bullet we are looking for
27238
- var result = null;
27683
+ var result = '';
27239
27684
  var child = node.firstChild;
27240
27685
  while (!result && child) {
27241
27686
  // First, check if we need to convert the Word list comments into real elements
@@ -27243,7 +27688,7 @@ function getFakeBulletText(node, levels) {
27243
27688
  // Check if this is the node that holds the fake bullets (mso-list: Ignore)
27244
27689
  if (isIgnoreNode(child)) {
27245
27690
  // Yes... this is the node that holds either the text or image data
27246
- result = child.textContent.trim();
27691
+ result = (_b = (_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
27247
27692
  // This is the case for image case
27248
27693
  if (result.length == 0) {
27249
27694
  result = 'o';
@@ -27267,6 +27712,7 @@ function getFakeBulletText(node, levels) {
27267
27712
  * styles of the span, but we'll use these comments to recreate them out
27268
27713
  */
27269
27714
  function fixWordListComments(child, removeComments) {
27715
+ var _a, _b, _c, _d;
27270
27716
  if (child.nodeType == 8 /* Comment */) {
27271
27717
  var value = child.data;
27272
27718
  if (value && value.trim().toLowerCase() == '[if !supportlists]') {
@@ -27289,22 +27735,28 @@ function fixWordListComments(child, removeComments) {
27289
27735
  }
27290
27736
  // if we found the end node, wrap everything out
27291
27737
  if (endComment) {
27292
- var newSpan = child.ownerDocument.createElement('span');
27293
- newSpan.setAttribute('style', 'mso-list: ignore');
27738
+ var newSpan = (_a = child.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement('span');
27739
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.setAttribute('style', 'mso-list: ignore');
27294
27740
  nextElement = getRealNextSibling(child);
27295
27741
  while (nextElement != endComment) {
27296
- nextElement = nextElement.nextSibling;
27297
- newSpan.appendChild(nextElement.previousSibling);
27742
+ nextElement = nextElement === null || nextElement === void 0 ? void 0 : nextElement.nextSibling;
27743
+ if (nextElement.previousSibling) {
27744
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.appendChild(nextElement.previousSibling);
27745
+ }
27298
27746
  }
27299
27747
  // Insert the element out and use that one as the current child
27300
- endComment.parentNode.insertBefore(newSpan, endComment);
27748
+ if (newSpan) {
27749
+ (_b = endComment.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newSpan, endComment);
27750
+ }
27301
27751
  // Remove the comments out if the call specified it out
27302
27752
  if (removeComments) {
27303
- child.parentNode.removeChild(child);
27304
- endComment.parentNode.removeChild(endComment);
27753
+ (_c = child.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(child);
27754
+ (_d = endComment.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(endComment);
27305
27755
  }
27306
27756
  // Last, make sure we return the new element out instead of the comment
27307
- child = newSpan;
27757
+ if (newSpan) {
27758
+ child = newSpan;
27759
+ }
27308
27760
  }
27309
27761
  }
27310
27762
  }
@@ -27356,6 +27808,7 @@ function getStyleValue(node, styleName) {
27356
27808
  }
27357
27809
  /** Checks if the node is an empty text node that can be ignored */
27358
27810
  function isEmptyTextNode(node) {
27811
+ var _a;
27359
27812
  // No node is empty
27360
27813
  if (!node) {
27361
27814
  return true;
@@ -27363,12 +27816,14 @@ function isEmptyTextNode(node) {
27363
27816
  // Empty text node is empty
27364
27817
  if (node.nodeType == 3 /* Text */) {
27365
27818
  var value = node.nodeValue;
27366
- value = value.replace(LINE_BREAKS, '');
27367
- return value.trim().length == 0;
27819
+ value = (_a = value === null || value === void 0 ? void 0 : value.replace(LINE_BREAKS, '')) !== null && _a !== void 0 ? _a : '';
27820
+ return (value === null || value === void 0 ? void 0 : value.trim().length) == 0;
27368
27821
  }
27369
27822
  // Span or Font with an empty child node is empty
27370
27823
  var tagName = (0, roosterjs_editor_dom_1.getTagOfNode)(node);
27371
- if (node.firstChild == node.lastChild && (tagName == 'SPAN' || tagName == 'FONT')) {
27824
+ if (node.firstChild &&
27825
+ node.firstChild == node.lastChild &&
27826
+ (tagName == 'SPAN' || tagName == 'FONT')) {
27372
27827
  return isEmptyTextNode(node.firstChild);
27373
27828
  }
27374
27829
  // If not found, then this is not empty
@@ -29291,7 +29746,7 @@ var TableInsertHandler = /** @class */ (function () {
29291
29746
  }());
29292
29747
  function getInsertElementData(isHorizontal, isDark, isRTL, backgroundColor) {
29293
29748
  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;
29749
+ 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
29750
  var leftOrRight = isRTL ? 'right' : 'left';
29296
29751
  var childBaseStyles = "position: absolute; box-sizing: border-box; background-color: " + backgroundColor + ";";
29297
29752
  var childInfo = {
@@ -29890,6 +30345,11 @@ var CompatibleChangeSource;
29890
30345
  * List chain reorganized numbers of lists
29891
30346
  */
29892
30347
  CompatibleChangeSource["ListChain"] = "ListChain";
30348
+ /**
30349
+ * Keyboard event, used by Content Model.
30350
+ * Data of this event will be the key code number
30351
+ */
30352
+ CompatibleChangeSource["Keyboard"] = "Keyboard";
29893
30353
  })(CompatibleChangeSource = exports.CompatibleChangeSource || (exports.CompatibleChangeSource = {}));
29894
30354
 
29895
30355