roosterjs 8.44.1 → 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.
@@ -2213,6 +2213,9 @@ function changeCapitalization(editor, capitalization, language) {
2213
2213
  }
2214
2214
  }, 'changeCapitalization');
2215
2215
  function getCapitalizedText(originalText, language) {
2216
+ if (originalText === null) {
2217
+ return originalText;
2218
+ }
2216
2219
  switch (capitalization) {
2217
2220
  case "lowercase" /* Lowercase */:
2218
2221
  return originalText.toLocaleLowerCase(language);
@@ -2237,6 +2240,8 @@ function changeCapitalization(editor, capitalization, language) {
2237
2240
  return originalText.toLocaleLowerCase(language).replace(regex, function (match) {
2238
2241
  return match.toLocaleUpperCase(language);
2239
2242
  });
2243
+ default:
2244
+ return originalText;
2240
2245
  }
2241
2246
  }
2242
2247
  }
@@ -2380,11 +2385,11 @@ var TAGS_TO_STOP_UNWRAP = ['TD', 'TH', 'TR', 'TABLE', 'TBODY', 'THEAD'];
2380
2385
  */
2381
2386
  function isMultiBlockSelection(editor) {
2382
2387
  var transverser = editor.getSelectionTraverser();
2383
- var blockElement = transverser.currentBlockElement;
2388
+ var blockElement = transverser === null || transverser === void 0 ? void 0 : transverser.currentBlockElement;
2384
2389
  if (!blockElement) {
2385
2390
  return false;
2386
2391
  }
2387
- var nextBlockElement = transverser.getNextBlockElement();
2392
+ var nextBlockElement = transverser === null || transverser === void 0 ? void 0 : transverser.getNextBlockElement();
2388
2393
  //At least two blocks are selected
2389
2394
  return !!nextBlockElement;
2390
2395
  }
@@ -2467,7 +2472,8 @@ function isNodeWholeBlock(node, editor) {
2467
2472
  }
2468
2473
  var isOnlySiblingWithContent_1 = true;
2469
2474
  (_a = currentNode.parentNode) === null || _a === void 0 ? void 0 : _a.childNodes.forEach(function (node) {
2470
- if (node != currentNode && node.textContent.length) {
2475
+ var _a;
2476
+ if (node != currentNode && ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length)) {
2471
2477
  isOnlySiblingWithContent_1 = false;
2472
2478
  }
2473
2479
  });
@@ -2492,7 +2498,7 @@ function clearAutoDetectFormat(editor) {
2492
2498
  var isMultiBlock = isMultiBlockSelection(editor);
2493
2499
  if (!isMultiBlock) {
2494
2500
  var transverser = editor.getSelectionTraverser();
2495
- var inlineElement = transverser.currentInlineElement;
2501
+ var inlineElement = transverser === null || transverser === void 0 ? void 0 : transverser.currentInlineElement;
2496
2502
  var isPartial = inlineElement instanceof roosterjs_editor_dom_1.PartialInlineElement ||
2497
2503
  (inlineElement instanceof roosterjs_editor_dom_1.NodeInlineElement &&
2498
2504
  !isNodeWholeBlock(inlineElement.getContainerNode(), editor));
@@ -2522,8 +2528,11 @@ function clearBlockFormat(editor) {
2522
2528
  (0, roosterjs_editor_dom_1.setStyles)(wrapper, nonborderStyles);
2523
2529
  }
2524
2530
  }
2525
- while (nodes.length > 0 && (0, roosterjs_editor_dom_1.isNodeInRegion)(region, nodes[0].parentNode)) {
2526
- nodes = [(0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes)];
2531
+ while (nodes.length > 0 &&
2532
+ nodes[0].parentNode &&
2533
+ (0, roosterjs_editor_dom_1.isNodeInRegion)(region, nodes[0].parentNode)) {
2534
+ var balancedNodes = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes);
2535
+ nodes = balancedNodes ? [balancedNodes] : [];
2527
2536
  }
2528
2537
  nodes.forEach(clearNodeFormat);
2529
2538
  });
@@ -2575,7 +2584,7 @@ function setDefaultFormat(editor) {
2575
2584
  var setColorIgnoredElements_1 = editor.queryElements('a *, a', 1 /* OnSelection */);
2576
2585
  var shouldApplyInlineStyle = setColorIgnoredElements_1.length > 0
2577
2586
  ? function (element) { return setColorIgnoredElements_1.indexOf(element) == -1; }
2578
- : null;
2587
+ : undefined;
2579
2588
  if (defaultFormat.textColors) {
2580
2589
  (0, setTextColor_1.default)(editor, defaultFormat.textColors, shouldApplyInlineStyle);
2581
2590
  }
@@ -2732,12 +2741,12 @@ function createLink(editor, link, altText, displayText, target) {
2732
2741
  .getDocument()
2733
2742
  .execCommand("createLink" /* CreateLink */, false, normalizedUrl_1);
2734
2743
  var traverser = editor.getSelectionTraverser();
2735
- var currentInline = traverser.getNextInlineElement();
2744
+ var currentInline = traverser === null || traverser === void 0 ? void 0 : traverser.getNextInlineElement();
2736
2745
  // list for removing unwanted lines
2737
2746
  var deletionInlineList = [];
2738
2747
  while (currentInline) {
2739
2748
  deletionInlineList.push(currentInline.getContainerNode());
2740
- currentInline = traverser.getNextInlineElement();
2749
+ currentInline = traverser === null || traverser === void 0 ? void 0 : traverser.getNextInlineElement();
2741
2750
  }
2742
2751
  deletionInlineList.forEach(function (node) { return editor.deleteNode(node); });
2743
2752
  anchor = getAnchorNodeAtCursor(editor);
@@ -2820,7 +2829,7 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
2820
2829
  * @returns An ElementBasedFormatState object
2821
2830
  */
2822
2831
  function getElementBasedFormatState(editor, event) {
2823
- var listTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('OL,UL', null /*startFrom*/, event));
2832
+ var listTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('OL,UL', undefined /*startFrom*/, event));
2824
2833
  // Check if selection is multiline, spans more than one block
2825
2834
  var range = editor.getSelectionRange();
2826
2835
  var multiline = false;
@@ -2829,7 +2838,7 @@ function getElementBasedFormatState(editor, event) {
2829
2838
  var endingBlock = editor.getBlockElementAtNode(range.endContainer);
2830
2839
  multiline = endingBlock && startingBlock ? !endingBlock.equals(startingBlock) : false;
2831
2840
  }
2832
- var headerTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('H1,H2,H3,H4,H5,H6', null /*startFrom*/, event));
2841
+ var headerTag = (0, roosterjs_editor_dom_1.getTagOfNode)(editor.getElementAtCursor('H1,H2,H3,H4,H5,H6', undefined /*startFrom*/, event));
2833
2842
  var table = editor.queryElements('table', 1 /* OnSelection */)[0];
2834
2843
  var tableFormat = table ? (0, roosterjs_editor_dom_1.getTableFormatInfo)(table) : undefined;
2835
2844
  var hasHeader = (table === null || table === void 0 ? void 0 : table.rows[0])
@@ -2846,7 +2855,7 @@ function getElementBasedFormatState(editor, event) {
2846
2855
  isCodeInline: !!editor.queryElements('code', 1 /* OnSelection */)[0],
2847
2856
  isCodeBlock: !!editor.queryElements('pre>code', 1 /* OnSelection */)[0],
2848
2857
  isInTable: !!table,
2849
- tableFormat: tableFormat,
2858
+ tableFormat: tableFormat || {},
2850
2859
  tableHasHeader: hasHeader,
2851
2860
  canMergeTableCell: canMergeTableCell(editor),
2852
2861
  };
@@ -2912,6 +2921,7 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
2912
2921
  * Parent nodes will be split if need
2913
2922
  */
2914
2923
  function insertEntity(editor, type, contentNode, isBlock, isReadonly, position, insertToRegionRoot) {
2924
+ var _a;
2915
2925
  var wrapper = (0, roosterjs_editor_dom_1.wrap)(contentNode, isBlock ? 'DIV' : 'SPAN');
2916
2926
  // For inline & readonly entity, we need to set display to "inline-block" otherwise
2917
2927
  // there will be some weird behavior when move cursor around the entity node.
@@ -2924,7 +2934,7 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2924
2934
  }
2925
2935
  (0, roosterjs_editor_dom_1.commitEntity)(wrapper, type, isReadonly);
2926
2936
  if (!editor.contains(wrapper)) {
2927
- var currentRange = void 0;
2937
+ var currentRange = null;
2928
2938
  var contentPosition = void 0;
2929
2939
  if (typeof position == 'number') {
2930
2940
  contentPosition = position;
@@ -2969,7 +2979,7 @@ function insertEntity(editor, type, contentNode, isBlock, isReadonly, position,
2969
2979
  // Insert an extra empty line for block entity to make sure
2970
2980
  // user can still put cursor below the entity.
2971
2981
  var br = editor.getDocument().createElement('BR');
2972
- wrapper.parentNode.insertBefore(br, wrapper.nextSibling);
2982
+ (_a = wrapper.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, wrapper.nextSibling);
2973
2983
  }
2974
2984
  var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(wrapper);
2975
2985
  if (!isBlock &&
@@ -3028,7 +3038,6 @@ function insertImageWithSrc(editor, src, attributes) {
3028
3038
  return image.setAttribute(attribute, attributes[attribute]);
3029
3039
  });
3030
3040
  }
3031
- image.style.maxWidth = '100%';
3032
3041
  editor.insertNode(image);
3033
3042
  }, 'insertImage');
3034
3043
  }
@@ -3058,7 +3067,9 @@ function removeLink(editor) {
3058
3067
  editor.focus();
3059
3068
  (0, formatUndoSnapshot_1.default)(editor, function (start, end) {
3060
3069
  editor.queryElements('a[href]', 1 /* OnSelection */, roosterjs_editor_dom_1.unwrap);
3061
- editor.select(start, end);
3070
+ if (start && end) {
3071
+ editor.select(start, end);
3072
+ }
3062
3073
  }, 'removeLink');
3063
3074
  }
3064
3075
  exports.default = removeLink;
@@ -3077,14 +3088,15 @@ exports.default = removeLink;
3077
3088
 
3078
3089
  Object.defineProperty(exports, "__esModule", { value: true });
3079
3090
  function replaceWithNode(editor, textOrRange, node, exactMatch, searcher) {
3091
+ var _a, _b;
3080
3092
  // Make sure the text and node is valid
3081
3093
  if (!textOrRange || !node) {
3082
3094
  return false;
3083
3095
  }
3084
3096
  var range;
3085
3097
  if (typeof textOrRange == 'string') {
3086
- searcher = searcher || editor.getContentSearcherOfCursor();
3087
- range = searcher && searcher.getRangeFromText(textOrRange, exactMatch);
3098
+ searcher = (_a = (searcher || editor.getContentSearcherOfCursor())) !== null && _a !== void 0 ? _a : undefined;
3099
+ range = (_b = searcher === null || searcher === void 0 ? void 0 : searcher.getRangeFromText(textOrRange, exactMatch)) !== null && _b !== void 0 ? _b : null;
3088
3100
  }
3089
3101
  else {
3090
3102
  range = textOrRange;
@@ -3092,7 +3104,7 @@ function replaceWithNode(editor, textOrRange, node, exactMatch, searcher) {
3092
3104
  if (range) {
3093
3105
  var backupRange = editor.getSelectionRange();
3094
3106
  // If the range to replace is right before current cursor, it is actually an exact match
3095
- if (backupRange.collapsed &&
3107
+ if ((backupRange === null || backupRange === void 0 ? void 0 : backupRange.collapsed) &&
3096
3108
  range.endContainer == backupRange.startContainer &&
3097
3109
  range.endOffset == backupRange.startOffset) {
3098
3110
  exactMatch = true;
@@ -3169,10 +3181,12 @@ function setAlignment(editor, alignment) {
3169
3181
  var isATable = selection && selection.type === 1 /* TableSelection */;
3170
3182
  var elementAtCursor = editor.getElementAtCursor();
3171
3183
  if (isATable &&
3184
+ selection.coordinates &&
3172
3185
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3173
3186
  alignTable(selection, alignment);
3174
3187
  }
3175
- else if (isList(elementAtCursor) &&
3188
+ else if (elementAtCursor &&
3189
+ isList(elementAtCursor) &&
3176
3190
  editor.isFeatureEnabled("ListItemAlignment" /* ListItemAlignment */)) {
3177
3191
  alignList(editor, alignment);
3178
3192
  }
@@ -3229,7 +3243,9 @@ function alignText(editor, alignment) {
3229
3243
  });
3230
3244
  if (elements.length == 0) {
3231
3245
  var node = editor.getElementAtCursor();
3232
- (0, normalizeBlockquote_1.default)(node);
3246
+ if (node) {
3247
+ (0, normalizeBlockquote_1.default)(node);
3248
+ }
3233
3249
  }
3234
3250
  }
3235
3251
  function isList(element) {
@@ -3240,7 +3256,9 @@ function alignList(editor, alignment) {
3240
3256
  var blocks = (0, roosterjs_editor_dom_1.getSelectedBlockElementsInRegion)(region, undefined /* createBlockIfEmpty */, editor.isFeatureEnabled("DefaultFormatInSpan" /* DefaultFormatInSpan */));
3241
3257
  var startNode = blocks[0].getStartNode();
3242
3258
  var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, true /*includeSiblingLists*/, startNode);
3243
- vList.setAlignment(start, end, alignment);
3259
+ if (start && end) {
3260
+ vList === null || vList === void 0 ? void 0 : vList.setAlignment(start, end, alignment);
3261
+ }
3244
3262
  }, undefined /* beforeRunCallback */, 'alignList');
3245
3263
  }
3246
3264
 
@@ -3304,7 +3322,9 @@ function setDirection(editor, direction) {
3304
3322
  element.setAttribute('dir', direction == 0 /* LeftToRight */ ? 'ltr' : 'rtl');
3305
3323
  element.style.textAlign = direction == 0 /* LeftToRight */ ? 'left' : 'right';
3306
3324
  });
3307
- editor.select(start, end);
3325
+ if (start && end) {
3326
+ editor.select(start, end);
3327
+ }
3308
3328
  }, 'setDirection');
3309
3329
  }
3310
3330
  exports.default = setDirection;
@@ -3446,14 +3466,18 @@ function setIndentation(editor, indentation) {
3446
3466
  isFirstItem(vList, startNode) &&
3447
3467
  shouldHandleWithBlockquotes(indentation, editor, startNode)) {
3448
3468
  var block = editor.getBlockElementAtNode(vList.rootList);
3449
- blockGroups.push([block]);
3469
+ if (block) {
3470
+ blockGroups.push([block]);
3471
+ }
3450
3472
  }
3451
3473
  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([]);
3474
+ if (start && end) {
3475
+ indentation == 1 /* Decrease */
3476
+ ? vList.setIndentation(start, end, indentation, false /* softOutdent */, isTabKeyTextFeaturesEnabled /* preventItemRemoval */)
3477
+ : vList.setIndentation(start, end, indentation);
3478
+ vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
3479
+ blockGroups.push([]);
3480
+ }
3457
3481
  }
3458
3482
  }
3459
3483
  else {
@@ -3464,10 +3488,13 @@ function setIndentation(editor, indentation) {
3464
3488
  }, function () {
3465
3489
  var selection = editor.getSelectionRangeEx();
3466
3490
  if (selection.type == 1 /* TableSelection */ &&
3491
+ selection.coordinates &&
3467
3492
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(new roosterjs_editor_dom_1.VTable(selection.table), selection.coordinates)) {
3468
3493
  if (indentation == 1 /* Decrease */) {
3469
3494
  var quote = editor.getElementAtCursor('blockquote', selection.table);
3470
- (0, roosterjs_editor_dom_1.unwrap)(quote);
3495
+ if (quote) {
3496
+ (0, roosterjs_editor_dom_1.unwrap)(quote);
3497
+ }
3471
3498
  }
3472
3499
  else if (indentation == 0 /* Increase */) {
3473
3500
  (0, roosterjs_editor_dom_1.wrap)(selection.table, 2 /* BlockquoteWrapper */);
@@ -3708,7 +3735,9 @@ function toggleCodeBlock(editor, styler) {
3708
3735
  if (!code.previousSibling && !code.nextSibling) {
3709
3736
  var parent_1 = code.parentNode;
3710
3737
  (0, roosterjs_editor_dom_1.unwrap)(code);
3711
- (0, roosterjs_editor_dom_1.unwrap)(parent_1);
3738
+ if (parent_1) {
3739
+ (0, roosterjs_editor_dom_1.unwrap)(parent_1);
3740
+ }
3712
3741
  }
3713
3742
  }).length == 0;
3714
3743
  }, 'toggleCodeBlock');
@@ -3753,7 +3782,7 @@ function toggleHeader(editor, level) {
3753
3782
  });
3754
3783
  if (level > 0) {
3755
3784
  var traverser = editor.getSelectionTraverser();
3756
- var blockElement = traverser ? traverser.currentBlockElement : null;
3785
+ var blockElement = traverser === null || traverser === void 0 ? void 0 : traverser.currentBlockElement;
3757
3786
  var sanitizer = new roosterjs_editor_dom_1.HtmlSanitizer({
3758
3787
  cssStyleCallbacks: {
3759
3788
  'font-size': function () { return false; },
@@ -3762,7 +3791,7 @@ function toggleHeader(editor, level) {
3762
3791
  while (blockElement) {
3763
3792
  var element = blockElement.collapseToSingleElement();
3764
3793
  sanitizer.sanitize(element);
3765
- blockElement = traverser.getNextBlockElement();
3794
+ blockElement = traverser === null || traverser === void 0 ? void 0 : traverser.getNextBlockElement();
3766
3795
  }
3767
3796
  editor.getDocument().execCommand("formatBlock" /* FormatBlock */, false, "<H" + level + ">");
3768
3797
  }
@@ -4097,12 +4126,21 @@ function editTable(editor, operation) {
4097
4126
  vtable.writeBack();
4098
4127
  editor.transformToDarkColor(vtable.table);
4099
4128
  editor.focus();
4100
- var cellToSelect = calculateCellToSelect(operation, vtable.row, vtable.col);
4101
- editor.select(vtable.getCell(cellToSelect.newRow, cellToSelect.newCol).td, 0 /* Begin */);
4129
+ if (isUndefined(vtable.row) || isUndefined(vtable.col)) {
4130
+ return;
4131
+ }
4132
+ var _a = calculateCellToSelect(operation, vtable.row, vtable.col), newCol = _a.newCol, newRow = _a.newRow;
4133
+ var newTd = vtable.getCell(newRow, newCol).td;
4134
+ if (newTd) {
4135
+ editor.select(newTd, 0 /* Begin */);
4136
+ }
4102
4137
  }, 'editTable');
4103
4138
  }
4104
4139
  }
4105
4140
  exports.default = editTable;
4141
+ function isUndefined(n) {
4142
+ return n == undefined;
4143
+ }
4106
4144
  function calculateCellToSelect(operation, currentRow, currentCol) {
4107
4145
  var newRow = currentRow;
4108
4146
  var newCol = currentCol;
@@ -4128,9 +4166,10 @@ function calculateCellToSelect(operation, currentRow, currentCol) {
4128
4166
  };
4129
4167
  }
4130
4168
  function saveTableSelection(editor, vtable) {
4169
+ var _a;
4131
4170
  var selection = editor.getSelectionRangeEx();
4132
4171
  if (selection && selection.type === 1 /* TableSelection */) {
4133
- vtable.selection = selection.coordinates;
4172
+ vtable.selection = (_a = selection.coordinates) !== null && _a !== void 0 ? _a : null;
4134
4173
  }
4135
4174
  }
4136
4175
 
@@ -4159,12 +4198,17 @@ function formatTable(editor, format, table) {
4159
4198
  table = table || editor.getElementAtCursor('TABLE');
4160
4199
  if (table) {
4161
4200
  (0, formatUndoSnapshot_1.default)(editor, function (start, end) {
4201
+ if (!table) {
4202
+ return;
4203
+ }
4162
4204
  var vtable = new roosterjs_editor_dom_1.VTable(table);
4163
4205
  vtable.applyFormat(format);
4164
4206
  vtable.writeBack();
4165
4207
  editor.transformToDarkColor(vtable.table);
4166
4208
  editor.focus();
4167
- editor.select(start, end);
4209
+ if (start && end) {
4210
+ editor.select(start, end);
4211
+ }
4168
4212
  }, 'formatTable');
4169
4213
  }
4170
4214
  }
@@ -4217,7 +4261,7 @@ function insertTable(editor, columns, rows, format) {
4217
4261
  (0, setBackgroundColor_1.default)(editor, 'transparent');
4218
4262
  }
4219
4263
  var vtable = new roosterjs_editor_dom_1.VTable(table);
4220
- vtable.applyFormat(format);
4264
+ vtable.applyFormat(format || {});
4221
4265
  vtable.writeBack();
4222
4266
  editor.insertNode(table);
4223
4267
  editor.runAsync(function (editor) {
@@ -4293,6 +4337,9 @@ function applyInlineStyle(editor, callback, apiName) {
4293
4337
  var lastNode;
4294
4338
  selection.ranges.forEach(function (range) {
4295
4339
  var contentTraverser = editor.getSelectionTraverser(range);
4340
+ if (!contentTraverser) {
4341
+ return;
4342
+ }
4296
4343
  var inlineElement = contentTraverser && contentTraverser.currentInlineElement;
4297
4344
  while (inlineElement) {
4298
4345
  var nextInlineElement = contentTraverser.getNextInlineElement();
@@ -4391,7 +4438,7 @@ function blockFormat(editor, callback, beforeRunCallback, apiName) {
4391
4438
  (0, commitListChains_1.default)(editor, chains_1);
4392
4439
  }
4393
4440
  }
4394
- if (selection.type == 0 /* Normal */) {
4441
+ if (selection.type == 0 /* Normal */ && start && end) {
4395
4442
  editor.select(start, end);
4396
4443
  }
4397
4444
  else {
@@ -4440,9 +4487,11 @@ function blockWrap(editor, wrapFunction, beforeRunCallback, apiName) {
4440
4487
  }
4441
4488
  }
4442
4489
  while (nodes[0] &&
4490
+ nodes[0].parentNode &&
4443
4491
  (0, roosterjs_editor_dom_1.isNodeInRegion)(region, nodes[0].parentNode) &&
4444
4492
  nodes.some(function (node) { return (0, roosterjs_editor_dom_1.getTagOfNode)(node) == 'LI'; })) {
4445
- nodes = [(0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes)];
4493
+ var result = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(nodes);
4494
+ nodes = result ? [result] : [];
4446
4495
  }
4447
4496
  wrapFunction(nodes);
4448
4497
  }
@@ -4472,7 +4521,10 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
4472
4521
  */
4473
4522
  function collapseSelectedBlocks(editor, forEachCallback) {
4474
4523
  var traverser = editor.getSelectionTraverser();
4475
- var block = traverser && traverser.currentBlockElement;
4524
+ if (!traverser) {
4525
+ return;
4526
+ }
4527
+ var block = traverser.currentBlockElement;
4476
4528
  var blocks = [];
4477
4529
  while (block) {
4478
4530
  if (!isEmptyBlockUnderTR(block)) {
@@ -4520,7 +4572,9 @@ function commitListChains(editor, chains) {
4520
4572
  var end = range && roosterjs_editor_dom_1.Position.getEnd(range);
4521
4573
  var shouldReuseAllAncestorListElements_1 = editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */);
4522
4574
  chains.forEach(function (chain) { return chain.commit(shouldReuseAllAncestorListElements_1); });
4523
- editor.select(start, end);
4575
+ if (start && end) {
4576
+ editor.select(start, end);
4577
+ }
4524
4578
  }
4525
4579
  }
4526
4580
  exports.default = commitListChains;
@@ -4557,7 +4611,7 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
4557
4611
  */
4558
4612
  function execCommand(editor, command, apiName) {
4559
4613
  editor.focus();
4560
- var formatter = function () { return editor.getDocument().execCommand(command, false, null); };
4614
+ var formatter = function () { return editor.getDocument().execCommand(command, false, undefined); };
4561
4615
  var selection = editor.getSelectionRangeEx();
4562
4616
  if (selection && selection.areAllCollapsed) {
4563
4617
  editor.addUndoSnapshot();
@@ -4610,9 +4664,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
4610
4664
  * Default value is false.
4611
4665
  */
4612
4666
  function formatUndoSnapshot(editor, callback, apiName) {
4613
- editor.addUndoSnapshot(callback, "Format" /* Format */, undefined /* canUndoByBackspace */, apiName && {
4614
- formatApiName: apiName,
4615
- });
4667
+ editor.addUndoSnapshot(callback, "Format" /* Format */, undefined /* canUndoByBackspace */, apiName && apiName != ''
4668
+ ? {
4669
+ formatApiName: apiName,
4670
+ }
4671
+ : undefined);
4616
4672
  }
4617
4673
  exports.default = formatUndoSnapshot;
4618
4674
 
@@ -4640,6 +4696,9 @@ function normalizeBlockquote(node, quotesHandled) {
4640
4696
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLElement')) {
4641
4697
  var alignment = node.style.textAlign;
4642
4698
  var quote = (0, roosterjs_editor_dom_1.findClosestElementAncestor)(node, undefined /* root */, 'blockquote');
4699
+ if (!quote) {
4700
+ return;
4701
+ }
4643
4702
  var isNodeRTL = isRTL(node);
4644
4703
  if (quotesHandled) {
4645
4704
  if (quotesHandled.indexOf(quote) > -1) {
@@ -4650,17 +4709,17 @@ function normalizeBlockquote(node, quotesHandled) {
4650
4709
  while (quote) {
4651
4710
  if (alignment == 'center') {
4652
4711
  if (isNodeRTL) {
4653
- delete quote.style.marginInlineEnd;
4712
+ quote.style.removeProperty('marginInlineEnd');
4654
4713
  quote.style.marginInlineStart = 'auto';
4655
4714
  }
4656
4715
  else {
4657
- delete quote.style.marginInlineStart;
4716
+ quote.style.removeProperty('marginInlineStart');
4658
4717
  quote.style.marginInlineEnd = 'auto';
4659
4718
  }
4660
4719
  }
4661
4720
  else {
4662
- delete quote.style.marginInlineStart;
4663
- delete quote.style.marginInlineEnd;
4721
+ quote.style.removeProperty('marginInlineEnd');
4722
+ quote.style.removeProperty('marginInlineStart');
4664
4723
  }
4665
4724
  quote = (0, roosterjs_editor_dom_1.findClosestElementAncestor)(quote.parentElement, undefined /* root */, 'blockquote');
4666
4725
  }
@@ -4707,14 +4766,19 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
4707
4766
  * @param apiNameOverride (Optional) Set a new api name, if empty the api name will be 'toggleListType'.
4708
4767
  */
4709
4768
  function toggleListType(editor, listType, startNumber, includeSiblingLists, orderedStyle, unorderedStyle, apiNameOverride) {
4769
+ if (startNumber === void 0) { startNumber = 0; }
4710
4770
  if (includeSiblingLists === void 0) { includeSiblingLists = true; }
4711
4771
  (0, blockFormat_1.default)(editor, function (region, start, end, chains) {
4712
- var _a;
4772
+ var _a, _b;
4713
4773
  var chain = startNumber > 0 && chains.filter(function (chain) { return chain.canAppendAtCursor(startNumber); })[0];
4714
- var vList = chain && start.equalTo(end)
4715
- ? chain.createVListAtBlock((_a = (0, roosterjs_editor_dom_1.getBlockElementAtNode)(region.rootNode, start.node)) === null || _a === void 0 ? void 0 : _a.collapseToSingleElement(), startNumber)
4774
+ var block = (_b = (0, roosterjs_editor_dom_1.getBlockElementAtNode)(region.rootNode, (_a = start === null || start === void 0 ? void 0 : start.node) !== null && _a !== void 0 ? _a : null)) === null || _b === void 0 ? void 0 : _b.collapseToSingleElement();
4775
+ if (!block) {
4776
+ return;
4777
+ }
4778
+ var vList = chain && end && (start === null || start === void 0 ? void 0 : start.equalTo(end))
4779
+ ? chain.createVListAtBlock(block, startNumber)
4716
4780
  : (0, roosterjs_editor_dom_1.createVListFromRegion)(region, startNumber === 1 ? false : includeSiblingLists);
4717
- if (vList) {
4781
+ if (vList && start && end) {
4718
4782
  vList.changeListType(start, end, listType);
4719
4783
  if (editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
4720
4784
  vList.setListStyleType(orderedStyle, unorderedStyle);
@@ -4920,6 +4984,7 @@ var getStyleBasedFormatState_1 = __webpack_require__(/*! ./getStyleBasedFormatSt
4920
4984
  var hasFocus_1 = __webpack_require__(/*! ./hasFocus */ "./packages/roosterjs-editor-core/lib/coreApi/hasFocus.ts");
4921
4985
  var insertNode_1 = __webpack_require__(/*! ./insertNode */ "./packages/roosterjs-editor-core/lib/coreApi/insertNode.ts");
4922
4986
  var restoreUndoSnapshot_1 = __webpack_require__(/*! ./restoreUndoSnapshot */ "./packages/roosterjs-editor-core/lib/coreApi/restoreUndoSnapshot.ts");
4987
+ var select_1 = __webpack_require__(/*! ./select */ "./packages/roosterjs-editor-core/lib/coreApi/select.ts");
4923
4988
  var selectImage_1 = __webpack_require__(/*! ./selectImage */ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts");
4924
4989
  var selectRange_1 = __webpack_require__(/*! ./selectRange */ "./packages/roosterjs-editor-core/lib/coreApi/selectRange.ts");
4925
4990
  var selectTable_1 = __webpack_require__(/*! ./selectTable */ "./packages/roosterjs-editor-core/lib/coreApi/selectTable.ts");
@@ -4944,6 +5009,7 @@ exports.coreApiMap = {
4944
5009
  hasFocus: hasFocus_1.hasFocus,
4945
5010
  insertNode: insertNode_1.insertNode,
4946
5011
  restoreUndoSnapshot: restoreUndoSnapshot_1.restoreUndoSnapshot,
5012
+ select: select_1.select,
4947
5013
  selectRange: selectRange_1.selectRange,
4948
5014
  setContent: setContent_1.setContent,
4949
5015
  switchShadowEdit: switchShadowEdit_1.switchShadowEdit,
@@ -4983,8 +5049,9 @@ var TAB_SPACES = 6;
4983
5049
  * @param applyCurrentStyle True if apply format of current selection to the pasted content,
4984
5050
  * false to keep original format
4985
5051
  */
4986
- var createPasteFragment = function (core, clipboardData, position, pasteAsText, applyCurrentStyle) {
5052
+ var createPasteFragment = function (core, clipboardData, position, pasteAsText, applyCurrentStyle, pasteAsImage) {
4987
5053
  var _a, _b;
5054
+ if (pasteAsImage === void 0) { pasteAsImage = false; }
4988
5055
  if (!clipboardData) {
4989
5056
  return null;
4990
5057
  }
@@ -5043,7 +5110,7 @@ var createPasteFragment = function (core, clipboardData, position, pasteAsText,
5043
5110
  }
5044
5111
  }
5045
5112
  // Step 3: Fill the BeforePasteEvent object, especially the fragment for paste
5046
- if (!pasteAsText && !text && imageDataUri) {
5113
+ if ((pasteAsImage && imageDataUri) || (!pasteAsText && !text && imageDataUri)) {
5047
5114
  // Paste image
5048
5115
  var img = document.createElement('img');
5049
5116
  img.style.maxWidth = '100%';
@@ -5985,6 +6052,136 @@ var restoreUndoSnapshot = function (core, step) {
5985
6052
  exports.restoreUndoSnapshot = restoreUndoSnapshot;
5986
6053
 
5987
6054
 
6055
+ /***/ }),
6056
+
6057
+ /***/ "./packages/roosterjs-editor-core/lib/coreApi/select.ts":
6058
+ /*!**************************************************************!*\
6059
+ !*** ./packages/roosterjs-editor-core/lib/coreApi/select.ts ***!
6060
+ \**************************************************************/
6061
+ /*! no static exports found */
6062
+ /***/ (function(module, exports, __webpack_require__) {
6063
+
6064
+ "use strict";
6065
+
6066
+ Object.defineProperty(exports, "__esModule", { value: true });
6067
+ exports.select = void 0;
6068
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
6069
+ /**
6070
+ * @internal
6071
+ * Select content according to the given information.
6072
+ * There are a bunch of allowed combination of parameters. See IEditor.select for more details
6073
+ * @param core The editor core object
6074
+ * @param arg1 A DOM Range, or SelectionRangeEx, or NodePosition, or Node, or Selection Path
6075
+ * @param arg2 (optional) A NodePosition, or an offset number, or a PositionType, or a TableSelection
6076
+ * @param arg3 (optional) A Node
6077
+ * @param arg4 (optional) An offset number, or a PositionType
6078
+ */
6079
+ var select = function (core, arg1, arg2, arg3, arg4) {
6080
+ var rangeEx = null;
6081
+ if (isSelectionRangeEx(arg1)) {
6082
+ rangeEx = arg1;
6083
+ }
6084
+ else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLTableElement') && isTableSelection(arg2)) {
6085
+ rangeEx = {
6086
+ type: 1 /* TableSelection */,
6087
+ ranges: [],
6088
+ areAllCollapsed: false,
6089
+ table: arg1,
6090
+ coordinates: arg2,
6091
+ };
6092
+ }
6093
+ else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLImageElement') && typeof arg2 == 'undefined') {
6094
+ rangeEx = {
6095
+ type: 2 /* ImageSelection */,
6096
+ ranges: [],
6097
+ areAllCollapsed: false,
6098
+ image: arg1,
6099
+ };
6100
+ }
6101
+ else {
6102
+ var range = !arg1
6103
+ ? null
6104
+ : (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Range')
6105
+ ? arg1
6106
+ : isSelectionPath(arg1)
6107
+ ? (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, arg1.start, arg1.end)
6108
+ : isNodePosition(arg1) || (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Node')
6109
+ ? (0, roosterjs_editor_dom_1.createRange)(arg1, arg2, arg3, arg4)
6110
+ : null;
6111
+ rangeEx = range
6112
+ ? {
6113
+ type: 0 /* Normal */,
6114
+ ranges: [range],
6115
+ areAllCollapsed: range.collapsed,
6116
+ }
6117
+ : null;
6118
+ }
6119
+ if (rangeEx) {
6120
+ switch (rangeEx.type) {
6121
+ case 1 /* TableSelection */:
6122
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.table)) {
6123
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6124
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, rangeEx.table, rangeEx.coordinates);
6125
+ rangeEx = core.domEvent.tableSelectionRange;
6126
+ }
6127
+ break;
6128
+ case 2 /* ImageSelection */:
6129
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.image)) {
6130
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6131
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, rangeEx.image);
6132
+ rangeEx = core.domEvent.imageSelectionRange;
6133
+ }
6134
+ break;
6135
+ case 0 /* Normal */:
6136
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6137
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6138
+ if ((0, roosterjs_editor_dom_1.contains)(core.contentDiv, rangeEx.ranges[0])) {
6139
+ core.api.selectRange(core, rangeEx.ranges[0]);
6140
+ }
6141
+ else {
6142
+ rangeEx = null;
6143
+ }
6144
+ break;
6145
+ }
6146
+ core.api.triggerEvent(core, {
6147
+ eventType: 22 /* SelectionChanged */,
6148
+ selectionRangeEx: rangeEx,
6149
+ }, true /** broadcast **/);
6150
+ }
6151
+ else {
6152
+ core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
6153
+ core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
6154
+ }
6155
+ return !!rangeEx;
6156
+ };
6157
+ exports.select = select;
6158
+ function isSelectionRangeEx(obj) {
6159
+ var rangeEx = obj;
6160
+ return (rangeEx &&
6161
+ typeof rangeEx == 'object' &&
6162
+ typeof rangeEx.type == 'number' &&
6163
+ Array.isArray(rangeEx.ranges));
6164
+ }
6165
+ function isTableSelection(obj) {
6166
+ var selection = obj;
6167
+ return (selection &&
6168
+ typeof selection == 'object' &&
6169
+ typeof selection.firstCell == 'object' &&
6170
+ typeof selection.lastCell == 'object');
6171
+ }
6172
+ function isSelectionPath(obj) {
6173
+ var path = obj;
6174
+ return path && typeof path == 'object' && Array.isArray(path.start) && Array.isArray(path.end);
6175
+ }
6176
+ function isNodePosition(obj) {
6177
+ var pos = obj;
6178
+ return (pos &&
6179
+ typeof pos == 'object' &&
6180
+ typeof pos.node == 'object' &&
6181
+ typeof pos.offset == 'number');
6182
+ }
6183
+
6184
+
5988
6185
  /***/ }),
5989
6186
 
5990
6187
  /***/ "./packages/roosterjs-editor-core/lib/coreApi/selectImage.ts":
@@ -6219,7 +6416,7 @@ function buildCss(table, coordinates, contentDivSelector) {
6219
6416
  ranges.push(rowRange);
6220
6417
  }
6221
6418
  });
6222
- var css = selectors.join(',') + " {background-color: rgba(198,198,198,0.7) !important; caret-color: transparent}";
6419
+ var css = selectors.join(',') + " {background-color: rgb(198,198,198) !important; caret-color: transparent}";
6223
6420
  return { css: css, ranges: ranges };
6224
6421
  }
6225
6422
  function select(core, table, coordinates) {
@@ -7744,6 +7941,17 @@ exports.default = ImageSelection;
7744
7941
 
7745
7942
  "use strict";
7746
7943
 
7944
+ var __assign = (this && this.__assign) || function () {
7945
+ __assign = Object.assign || function(t) {
7946
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
7947
+ s = arguments[i];
7948
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7949
+ t[p] = s[p];
7950
+ }
7951
+ return t;
7952
+ };
7953
+ return __assign.apply(this, arguments);
7954
+ };
7747
7955
  var _a, _b;
7748
7956
  Object.defineProperty(exports, "__esModule", { value: true });
7749
7957
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
@@ -7788,12 +7996,11 @@ var LifecyclePlugin = /** @class */ (function () {
7788
7996
  */
7789
7997
  function LifecyclePlugin(options, contentDiv) {
7790
7998
  var _this = this;
7791
- var _a, _b, _c;
7999
+ var _a, _b;
7792
8000
  this.editor = null;
7793
8001
  this.initializer = null;
7794
8002
  this.disposer = null;
7795
8003
  this.initialContent = options.initialContent || contentDiv.innerHTML || '';
7796
- this.contentDivFormat = (0, roosterjs_editor_dom_1.getComputedStyles)(contentDiv);
7797
8004
  // Make the container editable and set its selection styles
7798
8005
  if (contentDiv.getAttribute(CONTENT_EDITABLE_ATTRIBUTE_NAME) === null) {
7799
8006
  this.initializer = function () {
@@ -7817,12 +8024,30 @@ var LifecyclePlugin = /** @class */ (function () {
7817
8024
  (0, roosterjs_editor_dom_1.setColor)(contentDiv, textColors, false /*isBackground*/, isDarkMode, false /*shouldAdaptFontColor*/, darkColorHandler);
7818
8025
  (0, roosterjs_editor_dom_1.setColor)(contentDiv, backgroundColors, true /*isBackground*/, isDarkMode, false /*shouldAdaptFontColor*/, darkColorHandler);
7819
8026
  };
8027
+ var getDarkColor = (_a = options.getDarkColor) !== null && _a !== void 0 ? _a : (function (color) { return color; });
8028
+ var defaultFormat = options.defaultFormat ? __assign({}, options.defaultFormat) : null;
8029
+ if (defaultFormat) {
8030
+ if (defaultFormat.textColor && !defaultFormat.textColors) {
8031
+ defaultFormat.textColors = {
8032
+ lightModeColor: defaultFormat.textColor,
8033
+ darkModeColor: getDarkColor(defaultFormat.textColor),
8034
+ };
8035
+ delete defaultFormat.textColor;
8036
+ }
8037
+ if (defaultFormat.backgroundColor && !defaultFormat.backgroundColors) {
8038
+ defaultFormat.backgroundColors = {
8039
+ lightModeColor: defaultFormat.backgroundColor,
8040
+ darkModeColor: getDarkColor(defaultFormat.backgroundColor),
8041
+ };
8042
+ delete defaultFormat.backgroundColor;
8043
+ }
8044
+ }
7820
8045
  this.state = {
7821
8046
  customData: {},
7822
- defaultFormat: (_a = options.defaultFormat) !== null && _a !== void 0 ? _a : null,
8047
+ defaultFormat: defaultFormat,
7823
8048
  isDarkMode: !!options.inDarkMode,
7824
- getDarkColor: (_b = options.getDarkColor) !== null && _b !== void 0 ? _b : (function (color) { return color; }),
7825
- onExternalContentTransform: (_c = options.onExternalContentTransform) !== null && _c !== void 0 ? _c : null,
8049
+ getDarkColor: getDarkColor,
8050
+ onExternalContentTransform: (_b = options.onExternalContentTransform) !== null && _b !== void 0 ? _b : null,
7826
8051
  experimentalFeatures: options.experimentalFeatures || [],
7827
8052
  shadowEditFragment: null,
7828
8053
  shadowEditEntities: null,
@@ -7844,8 +8069,6 @@ var LifecyclePlugin = /** @class */ (function () {
7844
8069
  LifecyclePlugin.prototype.initialize = function (editor) {
7845
8070
  var _a;
7846
8071
  this.editor = editor;
7847
- // Calculate default format
7848
- this.recalculateDefaultFormat();
7849
8072
  // Ensure initial content and its format
7850
8073
  this.editor.setContent(this.initialContent, false /*triggerContentChangedEvent*/);
7851
8074
  // Set content DIV to be editable
@@ -7893,7 +8116,6 @@ var LifecyclePlugin = /** @class */ (function () {
7893
8116
  (event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
7894
8117
  event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
7895
8118
  this.state.isDarkMode = event.source == "SwitchToDarkMode" /* SwitchToDarkMode */;
7896
- this.recalculateDefaultFormat();
7897
8119
  this.adjustColor();
7898
8120
  }
7899
8121
  };
@@ -7908,45 +8130,6 @@ var LifecyclePlugin = /** @class */ (function () {
7908
8130
  catch (_b) { }
7909
8131
  });
7910
8132
  };
7911
- LifecyclePlugin.prototype.recalculateDefaultFormat = function () {
7912
- var _a = this.state, baseFormat = _a.defaultFormat, isDarkMode = _a.isDarkMode;
7913
- if (isDarkMode && baseFormat) {
7914
- if (!baseFormat.backgroundColors) {
7915
- baseFormat.backgroundColors = DARK_MODE_DEFAULT_FORMAT.backgroundColors;
7916
- }
7917
- if (!baseFormat.textColors) {
7918
- baseFormat.textColors = DARK_MODE_DEFAULT_FORMAT.textColors;
7919
- }
7920
- }
7921
- if (baseFormat && (0, roosterjs_editor_dom_1.getObjectKeys)(baseFormat).length === 0) {
7922
- return;
7923
- }
7924
- 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;
7925
- var defaultFormat = this.contentDivFormat;
7926
- this.state.defaultFormat = {
7927
- fontFamily: fontFamily || defaultFormat[0],
7928
- fontSize: fontSize || defaultFormat[1],
7929
- get textColor() {
7930
- return textColors
7931
- ? isDarkMode
7932
- ? textColors.darkModeColor
7933
- : textColors.lightModeColor
7934
- : textColor || defaultFormat[2];
7935
- },
7936
- textColors: textColors,
7937
- get backgroundColor() {
7938
- return backgroundColors
7939
- ? isDarkMode
7940
- ? backgroundColors.darkModeColor
7941
- : backgroundColors.lightModeColor
7942
- : backgroundColor || '';
7943
- },
7944
- backgroundColors: backgroundColors,
7945
- bold: bold,
7946
- italic: italic,
7947
- underline: underline,
7948
- };
7949
- };
7950
8133
  return LifecyclePlugin;
7951
8134
  }());
7952
8135
  exports.default = LifecyclePlugin;
@@ -8565,11 +8748,7 @@ var UndoPlugin = /** @class */ (function () {
8565
8748
  this.addUndoSnapshot();
8566
8749
  break;
8567
8750
  case 7 /* ContentChanged */:
8568
- if (!(this.state.isRestoring ||
8569
- event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
8570
- event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
8571
- this.clearRedoForInput();
8572
- }
8751
+ this.onContentChanged(event);
8573
8752
  break;
8574
8753
  }
8575
8754
  };
@@ -8633,6 +8812,25 @@ var UndoPlugin = /** @class */ (function () {
8633
8812
  }
8634
8813
  this.lastKeyPress = evt.which;
8635
8814
  };
8815
+ UndoPlugin.prototype.onContentChanged = function (event) {
8816
+ if (event.source == "Keyboard" /* Keyboard */) {
8817
+ if (Number.isInteger(event.data)) {
8818
+ // For keyboard event (triggered from Content Model), we can get its keycode from event.data
8819
+ // And when user is keep pressing the same key, mark editor with "hasNewContent" so that next time user
8820
+ // do some other action or press a different key, we will add undo snapshot
8821
+ if (event.data != this.lastKeyPress) {
8822
+ this.addUndoSnapshot();
8823
+ }
8824
+ this.lastKeyPress = event.data;
8825
+ this.state.hasNewContent = true;
8826
+ }
8827
+ }
8828
+ else if (!(this.state.isRestoring ||
8829
+ event.source == "SwitchToDarkMode" /* SwitchToDarkMode */ ||
8830
+ event.source == "SwitchToLightMode" /* SwitchToLightMode */)) {
8831
+ this.clearRedoForInput();
8832
+ }
8833
+ };
8636
8834
  UndoPlugin.prototype.clearRedoForInput = function () {
8637
8835
  this.state.snapshotsService.clearRedo();
8638
8836
  this.lastKeyPress = 0;
@@ -8806,7 +9004,6 @@ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./
8806
9004
  var DELIMITER_SELECTOR = '.' + "entityDelimiterAfter" /* DELIMITER_AFTER */ + ',.' + "entityDelimiterBefore" /* DELIMITER_BEFORE */;
8807
9005
  var ZERO_WIDTH_SPACE = '\u200B';
8808
9006
  var INLINE_ENTITY_SELECTOR = 'span' + (0, roosterjs_editor_dom_1.getEntitySelector)();
8809
- var NBSP = '\u00A0';
8810
9007
  function inlineEntityOnPluginEvent(event, editor) {
8811
9008
  switch (event.eventType) {
8812
9009
  case 7 /* ContentChanged */:
@@ -8818,7 +9015,14 @@ function inlineEntityOnPluginEvent(event, editor) {
8818
9015
  normalizeDelimitersInEditor(editor);
8819
9016
  break;
8820
9017
  case 10 /* BeforePaste */:
8821
- addDelimitersIfNeeded(event.fragment.querySelectorAll(INLINE_ENTITY_SELECTOR));
9018
+ var fragment = event.fragment, sanitizingOption = event.sanitizingOption;
9019
+ addDelimitersIfNeeded(fragment.querySelectorAll(INLINE_ENTITY_SELECTOR));
9020
+ if (sanitizingOption.additionalAllowedCssClasses) {
9021
+ (0, roosterjs_editor_dom_1.arrayPush)(sanitizingOption.additionalAllowedCssClasses, [
9022
+ "entityDelimiterAfter" /* DELIMITER_AFTER */,
9023
+ "entityDelimiterBefore" /* DELIMITER_BEFORE */,
9024
+ ]);
9025
+ }
8822
9026
  break;
8823
9027
  case 8 /* ExtractContentWithDom */:
8824
9028
  case 9 /* BeforeCutCopy */:
@@ -8864,12 +9068,12 @@ function normalizeDelimitersInEditor(editor) {
8864
9068
  exports.normalizeDelimitersInEditor = normalizeDelimitersInEditor;
8865
9069
  function addDelimitersIfNeeded(nodes) {
8866
9070
  nodes.forEach(function (node) {
8867
- if (tryGetEntityFromNode(node)) {
9071
+ if (isEntityElement(node)) {
8868
9072
  (0, roosterjs_editor_dom_1.addDelimiters)(node);
8869
9073
  }
8870
9074
  });
8871
9075
  }
8872
- function tryGetEntityFromNode(node) {
9076
+ function isEntityElement(node) {
8873
9077
  return !!(node &&
8874
9078
  (0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLElement') &&
8875
9079
  isReadOnly((0, roosterjs_editor_dom_1.getEntityFromElement)(node)));
@@ -8898,13 +9102,14 @@ function removeInvalidDelimiters(nodes) {
8898
9102
  }
8899
9103
  });
8900
9104
  }
8901
- function removeDelimiterAttr(node) {
9105
+ function removeDelimiterAttr(node, checkEntity) {
9106
+ if (checkEntity === void 0) { checkEntity = true; }
8902
9107
  if (!node) {
8903
9108
  return;
8904
9109
  }
8905
9110
  var isAfter = node.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */);
8906
9111
  var entitySibling = isAfter ? node.previousElementSibling : node.nextElementSibling;
8907
- if (entitySibling && tryGetEntityFromNode(entitySibling)) {
9112
+ if (checkEntity && entitySibling && isEntityElement(entitySibling)) {
8908
9113
  return;
8909
9114
  }
8910
9115
  node.classList.remove("entityDelimiterAfter" /* DELIMITER_AFTER */, "entityDelimiterBefore" /* DELIMITER_BEFORE */);
@@ -8918,31 +9123,34 @@ function removeDelimiterAttr(node) {
8918
9123
  });
8919
9124
  }
8920
9125
  function handleCollapsedEnter(editor, delimiter) {
9126
+ var _a;
8921
9127
  var isAfter = delimiter.classList.contains("entityDelimiterAfter" /* DELIMITER_AFTER */);
8922
- var sibling = isAfter ? delimiter.nextSibling : delimiter.previousSibling;
8923
- var positionToUse;
8924
- var element;
8925
- if (sibling) {
8926
- positionToUse = new roosterjs_editor_dom_1.Position(sibling, isAfter ? 0 /* Begin */ : -1 /* End */);
8927
- }
8928
- else {
8929
- element = delimiter.insertAdjacentElement(isAfter ? 'afterend' : 'beforebegin', (0, roosterjs_editor_dom_1.createElement)({
8930
- tag: 'span',
8931
- children: [NBSP],
8932
- }, editor.getDocument()));
8933
- if (!element) {
9128
+ var entity = !isAfter ? delimiter.nextSibling : delimiter.previousSibling;
9129
+ var block = (_a = editor.getBlockElementAtNode(delimiter)) === null || _a === void 0 ? void 0 : _a.getStartNode();
9130
+ editor.runAsync(function () {
9131
+ if (!block) {
8934
9132
  return;
8935
9133
  }
8936
- positionToUse = new roosterjs_editor_dom_1.Position(element, 0 /* Begin */);
8937
- }
8938
- if (positionToUse) {
8939
- editor.select(positionToUse);
8940
- editor.runAsync(function (aEditor) {
8941
- var elAfter = aEditor.getElementAtCursor();
8942
- removeDelimiterAttr(elAfter);
8943
- removeNode(element);
8944
- });
8945
- }
9134
+ var blockToCheck = isAfter ? block.nextSibling : block.previousSibling;
9135
+ if (blockToCheck && (0, roosterjs_editor_dom_1.safeInstanceOf)(blockToCheck, 'HTMLElement')) {
9136
+ var delimiters = blockToCheck.querySelectorAll(DELIMITER_SELECTOR);
9137
+ // Check if the last or first delimiter still contain the delimiter class and remove it.
9138
+ var delimiterToCheck = delimiters.item(isAfter ? 0 : delimiters.length - 1);
9139
+ removeDelimiterAttr(delimiterToCheck);
9140
+ }
9141
+ if (isEntityElement(entity)) {
9142
+ var nextElementSibling = entity.nextElementSibling, previousElementSibling = entity.previousElementSibling;
9143
+ [nextElementSibling, previousElementSibling].forEach(function (el) {
9144
+ // Check if after Enter the ZWS got removed but we still have a element with the class
9145
+ // Remove the attributes of the element if it is invalid now.
9146
+ if (el && (0, roosterjs_editor_dom_1.matchesSelector)(el, DELIMITER_SELECTOR) && !(0, roosterjs_editor_dom_1.getDelimiterFromElement)(el)) {
9147
+ removeDelimiterAttr(el, false /* checkEntity */);
9148
+ }
9149
+ });
9150
+ // Add delimiters to the entity if needed because on Enter we can sometimes lose the ZWS of the element.
9151
+ (0, roosterjs_editor_dom_1.addDelimiters)(entity);
9152
+ }
9153
+ });
8946
9154
  }
8947
9155
  var getPosition = function (container) {
8948
9156
  if (container && (0, roosterjs_editor_dom_1.getDelimiterFromElement)(container)) {
@@ -9196,6 +9404,54 @@ exports.default = DarkColorHandlerImpl;
9196
9404
 
9197
9405
  "use strict";
9198
9406
 
9407
+ var __extends = (this && this.__extends) || (function () {
9408
+ var extendStatics = function (d, b) {
9409
+ extendStatics = Object.setPrototypeOf ||
9410
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
9411
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
9412
+ return extendStatics(d, b);
9413
+ };
9414
+ return function (d, b) {
9415
+ if (typeof b !== "function" && b !== null)
9416
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
9417
+ extendStatics(d, b);
9418
+ function __() { this.constructor = d; }
9419
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9420
+ };
9421
+ })();
9422
+ Object.defineProperty(exports, "__esModule", { value: true });
9423
+ var createEditorCore_1 = __webpack_require__(/*! ./createEditorCore */ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts");
9424
+ var EditorBase_1 = __webpack_require__(/*! ./EditorBase */ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts");
9425
+ /**
9426
+ * RoosterJs core editor class
9427
+ */
9428
+ var Editor = /** @class */ (function (_super) {
9429
+ __extends(Editor, _super);
9430
+ /**
9431
+ * Creates an instance of EditorBase
9432
+ * @param contentDiv The DIV HTML element which will be the container element of editor
9433
+ * @param options An optional options object to customize the editor
9434
+ */
9435
+ function Editor(contentDiv, options) {
9436
+ if (options === void 0) { options = {}; }
9437
+ return _super.call(this, contentDiv, options, createEditorCore_1.createEditorCore) || this;
9438
+ }
9439
+ return Editor;
9440
+ }(EditorBase_1.EditorBase));
9441
+ exports.default = Editor;
9442
+
9443
+
9444
+ /***/ }),
9445
+
9446
+ /***/ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts":
9447
+ /*!*****************************************************************!*\
9448
+ !*** ./packages/roosterjs-editor-core/lib/editor/EditorBase.ts ***!
9449
+ \*****************************************************************/
9450
+ /*! no static exports found */
9451
+ /***/ (function(module, exports, __webpack_require__) {
9452
+
9453
+ "use strict";
9454
+
9199
9455
  var __assign = (this && this.__assign) || function () {
9200
9456
  __assign = Object.assign || function(t) {
9201
9457
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -9208,53 +9464,28 @@ var __assign = (this && this.__assign) || function () {
9208
9464
  return __assign.apply(this, arguments);
9209
9465
  };
9210
9466
  Object.defineProperty(exports, "__esModule", { value: true });
9211
- var createCorePlugins_1 = __webpack_require__(/*! ../corePlugins/createCorePlugins */ "./packages/roosterjs-editor-core/lib/corePlugins/createCorePlugins.ts");
9212
- var DarkColorHandlerImpl_1 = __webpack_require__(/*! ./DarkColorHandlerImpl */ "./packages/roosterjs-editor-core/lib/editor/DarkColorHandlerImpl.ts");
9213
- var coreApiMap_1 = __webpack_require__(/*! ../coreApi/coreApiMap */ "./packages/roosterjs-editor-core/lib/coreApi/coreApiMap.ts");
9467
+ exports.EditorBase = void 0;
9468
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
9214
9469
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
9215
9470
  /**
9216
- * RoosterJs core editor class
9471
+ * Base class of editor
9217
9472
  */
9218
- var Editor = /** @class */ (function () {
9473
+ var EditorBase = /** @class */ (function () {
9219
9474
  //#region Lifecycle
9220
9475
  /**
9221
- * Creates an instance of Editor
9476
+ * Creates an instance of EditorBase
9222
9477
  * @param contentDiv The DIV HTML element which will be the container element of editor
9223
9478
  * @param options An optional options object to customize the editor
9224
9479
  */
9225
- function Editor(contentDiv, options) {
9480
+ function EditorBase(contentDiv, options, coreCreator) {
9226
9481
  var _this = this;
9227
- if (options === void 0) { options = {}; }
9228
- var _a;
9229
9482
  this.core = null;
9230
9483
  // 1. Make sure all parameters are valid
9231
9484
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(contentDiv) != 'DIV') {
9232
9485
  throw new Error('contentDiv must be an HTML DIV element');
9233
9486
  }
9234
- // 2. Store options values to local variables
9235
- var corePlugins = (0, createCorePlugins_1.default)(contentDiv, options);
9236
- var plugins = [];
9237
- (0, roosterjs_editor_dom_1.getObjectKeys)(corePlugins).forEach(function (name) {
9238
- if (name == '_placeholder') {
9239
- if (options.plugins) {
9240
- (0, roosterjs_editor_dom_1.arrayPush)(plugins, options.plugins);
9241
- }
9242
- }
9243
- else {
9244
- plugins.push(corePlugins[name]);
9245
- }
9246
- });
9247
- var zoomScale = ((_a = options.zoomScale) !== null && _a !== void 0 ? _a : -1) > 0 ? options.zoomScale : 1;
9248
- 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 ||
9249
- (function () {
9250
- var scrollContainer = _this.getScrollContainer();
9251
- return (0, roosterjs_editor_dom_1.getIntersectedRect)(scrollContainer == contentDiv
9252
- ? [scrollContainer]
9253
- : [scrollContainer, contentDiv]);
9254
- }), imageSelectionBorderColor: options.imageSelectionBorderColor });
9255
- if (this.isFeatureEnabled("VariableBasedDarkColor" /* VariableBasedDarkColor */)) {
9256
- this.core.darkColorHandler = new DarkColorHandlerImpl_1.default(contentDiv, this.core.lifecycle.getDarkColor);
9257
- }
9487
+ // 2. Create editor core
9488
+ this.core = coreCreator(contentDiv, options);
9258
9489
  // 3. Initialize plugins
9259
9490
  this.core.plugins.forEach(function (plugin) { return plugin.initialize(_this); });
9260
9491
  // 4. Ensure user will type in a container node, not the editor content DIV
@@ -9263,7 +9494,7 @@ var Editor = /** @class */ (function () {
9263
9494
  /**
9264
9495
  * Dispose this editor, dispose all plugins and custom data
9265
9496
  */
9266
- Editor.prototype.dispose = function () {
9497
+ EditorBase.prototype.dispose = function () {
9267
9498
  var _a;
9268
9499
  var core = this.getCore();
9269
9500
  for (var i = core.plugins.length - 1; i >= 0; i--) {
@@ -9276,7 +9507,7 @@ var Editor = /** @class */ (function () {
9276
9507
  * Get whether this editor is disposed
9277
9508
  * @returns True if editor is disposed, otherwise false
9278
9509
  */
9279
- Editor.prototype.isDisposed = function () {
9510
+ EditorBase.prototype.isDisposed = function () {
9280
9511
  return !this.core;
9281
9512
  };
9282
9513
  //#endregion
@@ -9291,7 +9522,7 @@ var Editor = /** @class */ (function () {
9291
9522
  * insertOnNewLine: false
9292
9523
  * @returns true if node is inserted. Otherwise false
9293
9524
  */
9294
- Editor.prototype.insertNode = function (node, option) {
9525
+ EditorBase.prototype.insertNode = function (node, option) {
9295
9526
  var core = this.getCore();
9296
9527
  return node ? core.api.insertNode(core, node, option !== null && option !== void 0 ? option : null) : false;
9297
9528
  };
@@ -9300,7 +9531,7 @@ var Editor = /** @class */ (function () {
9300
9531
  * @param node The node to delete
9301
9532
  * @returns true if node is deleted. Otherwise false
9302
9533
  */
9303
- Editor.prototype.deleteNode = function (node) {
9534
+ EditorBase.prototype.deleteNode = function (node) {
9304
9535
  // Only remove the node when it falls within editor
9305
9536
  if (node && this.contains(node) && node.parentNode) {
9306
9537
  node.parentNode.removeChild(node);
@@ -9315,7 +9546,7 @@ var Editor = /** @class */ (function () {
9315
9546
  * @param transformColorForDarkMode (optional) Whether to transform new node to dark mode. Default is false
9316
9547
  * @returns true if node is replaced. Otherwise false
9317
9548
  */
9318
- Editor.prototype.replaceNode = function (existingNode, toNode, transformColorForDarkMode) {
9549
+ EditorBase.prototype.replaceNode = function (existingNode, toNode, transformColorForDarkMode) {
9319
9550
  var core = this.getCore();
9320
9551
  // Only replace the node when it falls within editor
9321
9552
  if (this.contains(existingNode) && toNode) {
@@ -9329,16 +9560,16 @@ var Editor = /** @class */ (function () {
9329
9560
  * @param node The node to create InlineElement
9330
9561
  * @returns The BlockElement result
9331
9562
  */
9332
- Editor.prototype.getBlockElementAtNode = function (node) {
9563
+ EditorBase.prototype.getBlockElementAtNode = function (node) {
9333
9564
  return (0, roosterjs_editor_dom_1.getBlockElementAtNode)(this.getCore().contentDiv, node);
9334
9565
  };
9335
- Editor.prototype.contains = function (arg) {
9566
+ EditorBase.prototype.contains = function (arg) {
9336
9567
  if (!arg) {
9337
9568
  return false;
9338
9569
  }
9339
9570
  return (0, roosterjs_editor_dom_1.contains)(this.getCore().contentDiv, arg);
9340
9571
  };
9341
- Editor.prototype.queryElements = function (selector, scopeOrCallback, callback) {
9572
+ EditorBase.prototype.queryElements = function (selector, scopeOrCallback, callback) {
9342
9573
  if (scopeOrCallback === void 0) { scopeOrCallback = 0 /* Body */; }
9343
9574
  var core = this.getCore();
9344
9575
  var result = [];
@@ -9366,7 +9597,7 @@ var Editor = /** @class */ (function () {
9366
9597
  * @returns When canSplitParent is true, returns all node from start through end after splitting,
9367
9598
  * otherwise just return start and end
9368
9599
  */
9369
- Editor.prototype.collapseNodes = function (start, end, canSplitParent) {
9600
+ EditorBase.prototype.collapseNodes = function (start, end, canSplitParent) {
9370
9601
  return (0, roosterjs_editor_dom_1.collapseNodes)(this.getCore().contentDiv, start, end, canSplitParent);
9371
9602
  };
9372
9603
  //#endregion
@@ -9376,7 +9607,7 @@ var Editor = /** @class */ (function () {
9376
9607
  * @param trim Whether trim the content string before check. Default is false
9377
9608
  * @returns True if there's no visible content, otherwise false
9378
9609
  */
9379
- Editor.prototype.isEmpty = function (trim) {
9610
+ EditorBase.prototype.isEmpty = function (trim) {
9380
9611
  return (0, roosterjs_editor_dom_1.isNodeEmpty)(this.getCore().contentDiv, trim);
9381
9612
  };
9382
9613
  /**
@@ -9384,7 +9615,7 @@ var Editor = /** @class */ (function () {
9384
9615
  * @param mode specify what kind of HTML content to retrieve
9385
9616
  * @returns HTML string representing current editor content
9386
9617
  */
9387
- Editor.prototype.getContent = function (mode) {
9618
+ EditorBase.prototype.getContent = function (mode) {
9388
9619
  if (mode === void 0) { mode = 0 /* CleanHTML */; }
9389
9620
  var core = this.getCore();
9390
9621
  return core.api.getContent(core, mode);
@@ -9394,7 +9625,7 @@ var Editor = /** @class */ (function () {
9394
9625
  * @param content HTML content to set in
9395
9626
  * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
9396
9627
  */
9397
- Editor.prototype.setContent = function (content, triggerContentChangedEvent) {
9628
+ EditorBase.prototype.setContent = function (content, triggerContentChangedEvent) {
9398
9629
  if (triggerContentChangedEvent === void 0) { triggerContentChangedEvent = true; }
9399
9630
  var core = this.getCore();
9400
9631
  core.api.setContent(core, content, triggerContentChangedEvent);
@@ -9408,7 +9639,7 @@ var Editor = /** @class */ (function () {
9408
9639
  * replaceSelection: true
9409
9640
  * insertOnNewLine: false
9410
9641
  */
9411
- Editor.prototype.insertContent = function (content, option) {
9642
+ EditorBase.prototype.insertContent = function (content, option) {
9412
9643
  var _a;
9413
9644
  if (content) {
9414
9645
  var doc = this.getDocument();
@@ -9428,7 +9659,7 @@ var Editor = /** @class */ (function () {
9428
9659
  /**
9429
9660
  * Delete selected content
9430
9661
  */
9431
- Editor.prototype.deleteSelectedContent = function () {
9662
+ EditorBase.prototype.deleteSelectedContent = function () {
9432
9663
  var range = this.getSelectionRange();
9433
9664
  if (range && !range.collapsed) {
9434
9665
  return (0, roosterjs_editor_dom_1.deleteSelectedContent)(this.getCore().contentDiv, range);
@@ -9442,10 +9673,11 @@ var Editor = /** @class */ (function () {
9442
9673
  * @param applyCurrentStyle True if apply format of current selection to the pasted content,
9443
9674
  * false to keep original format. Default value is false. When pasteAsText is true, this parameter is ignored
9444
9675
  */
9445
- Editor.prototype.paste = function (clipboardData, pasteAsText, applyCurrentFormat) {
9676
+ EditorBase.prototype.paste = function (clipboardData, pasteAsText, applyCurrentFormat, pasteAsImage) {
9446
9677
  var _this = this;
9447
9678
  if (pasteAsText === void 0) { pasteAsText = false; }
9448
9679
  if (applyCurrentFormat === void 0) { applyCurrentFormat = false; }
9680
+ if (pasteAsImage === void 0) { pasteAsImage = false; }
9449
9681
  var core = this.getCore();
9450
9682
  if (!clipboardData) {
9451
9683
  return;
@@ -9459,7 +9691,7 @@ var Editor = /** @class */ (function () {
9459
9691
  }
9460
9692
  var range = this.getSelectionRange();
9461
9693
  var pos = range && roosterjs_editor_dom_1.Position.getStart(range);
9462
- var fragment = core.api.createPasteFragment(core, clipboardData, pos, pasteAsText, applyCurrentFormat);
9694
+ var fragment = core.api.createPasteFragment(core, clipboardData, pos, pasteAsText, applyCurrentFormat, pasteAsImage);
9463
9695
  if (fragment) {
9464
9696
  this.addUndoSnapshot(function () {
9465
9697
  _this.insertNode(fragment);
@@ -9476,7 +9708,7 @@ var Editor = /** @class */ (function () {
9476
9708
  * Default value is true
9477
9709
  * @returns current selection range, or null if editor never got focus before
9478
9710
  */
9479
- Editor.prototype.getSelectionRange = function (tryGetFromCache) {
9711
+ EditorBase.prototype.getSelectionRange = function (tryGetFromCache) {
9480
9712
  if (tryGetFromCache === void 0) { tryGetFromCache = true; }
9481
9713
  var core = this.getCore();
9482
9714
  return core.api.getSelectionRange(core, tryGetFromCache);
@@ -9488,7 +9720,7 @@ var Editor = /** @class */ (function () {
9488
9720
  * Default value is true
9489
9721
  * @returns current selection range, or null if editor never got focus before
9490
9722
  */
9491
- Editor.prototype.getSelectionRangeEx = function () {
9723
+ EditorBase.prototype.getSelectionRangeEx = function () {
9492
9724
  var core = this.getCore();
9493
9725
  return core.api.getSelectionRangeEx(core);
9494
9726
  };
@@ -9497,7 +9729,7 @@ var Editor = /** @class */ (function () {
9497
9729
  * It does a live pull on the selection, if nothing retrieved, return whatever we have in cache.
9498
9730
  * @returns current selection path, or null if editor never got focus before
9499
9731
  */
9500
- Editor.prototype.getSelectionPath = function () {
9732
+ EditorBase.prototype.getSelectionPath = function () {
9501
9733
  var range = this.getSelectionRange();
9502
9734
  return range && (0, roosterjs_editor_dom_1.getSelectionPath)(this.getCore().contentDiv, range);
9503
9735
  };
@@ -9505,99 +9737,25 @@ var Editor = /** @class */ (function () {
9505
9737
  * Check if focus is in editor now
9506
9738
  * @returns true if focus is in editor, otherwise false
9507
9739
  */
9508
- Editor.prototype.hasFocus = function () {
9740
+ EditorBase.prototype.hasFocus = function () {
9509
9741
  var core = this.getCore();
9510
9742
  return core.api.hasFocus(core);
9511
9743
  };
9512
9744
  /**
9513
9745
  * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.
9514
9746
  */
9515
- Editor.prototype.focus = function () {
9747
+ EditorBase.prototype.focus = function () {
9516
9748
  var core = this.getCore();
9517
9749
  core.api.focus(core);
9518
9750
  };
9519
- Editor.prototype.select = function (arg1, arg2, arg3, arg4) {
9751
+ EditorBase.prototype.select = function (arg1, arg2, arg3, arg4) {
9520
9752
  var core = this.getCore();
9521
- var rangeEx = null;
9522
- if (isSelectionRangeEx(arg1)) {
9523
- rangeEx = arg1;
9524
- }
9525
- else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLTableElement') && isTableSelection(arg2)) {
9526
- rangeEx = {
9527
- type: 1 /* TableSelection */,
9528
- ranges: [],
9529
- areAllCollapsed: false,
9530
- table: arg1,
9531
- coordinates: arg2,
9532
- };
9533
- }
9534
- else if ((0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'HTMLImageElement') && typeof arg2 == 'undefined') {
9535
- rangeEx = {
9536
- type: 2 /* ImageSelection */,
9537
- ranges: [],
9538
- areAllCollapsed: false,
9539
- image: arg1,
9540
- };
9541
- }
9542
- else {
9543
- var range = !arg1
9544
- ? null
9545
- : (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Range')
9546
- ? arg1
9547
- : isSelectionPath(arg1)
9548
- ? (0, roosterjs_editor_dom_1.createRange)(core.contentDiv, arg1.start, arg1.end)
9549
- : isNodePosition(arg1) || (0, roosterjs_editor_dom_1.safeInstanceOf)(arg1, 'Node')
9550
- ? (0, roosterjs_editor_dom_1.createRange)(arg1, arg2, arg3, arg4)
9551
- : null;
9552
- rangeEx = range
9553
- ? {
9554
- type: 0 /* Normal */,
9555
- ranges: [range],
9556
- areAllCollapsed: range.collapsed,
9557
- }
9558
- : null;
9559
- }
9560
- if (rangeEx) {
9561
- switch (rangeEx.type) {
9562
- case 1 /* TableSelection */:
9563
- if (this.contains(rangeEx.table)) {
9564
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9565
- core.domEvent.tableSelectionRange = core.api.selectTable(core, rangeEx.table, rangeEx.coordinates);
9566
- rangeEx = core.domEvent.tableSelectionRange;
9567
- }
9568
- break;
9569
- case 2 /* ImageSelection */:
9570
- if (this.contains(rangeEx.image)) {
9571
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9572
- core.domEvent.imageSelectionRange = core.api.selectImage(core, rangeEx.image);
9573
- rangeEx = core.domEvent.imageSelectionRange;
9574
- }
9575
- break;
9576
- case 0 /* Normal */:
9577
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9578
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9579
- if (this.contains(rangeEx.ranges[0])) {
9580
- core.api.selectRange(core, rangeEx.ranges[0]);
9581
- }
9582
- else {
9583
- rangeEx = null;
9584
- }
9585
- break;
9586
- }
9587
- this.triggerPluginEvent(22 /* SelectionChanged */, {
9588
- selectionRangeEx: rangeEx,
9589
- }, true /** broadcast **/);
9590
- }
9591
- else {
9592
- core.domEvent.tableSelectionRange = core.api.selectTable(core, null);
9593
- core.domEvent.imageSelectionRange = core.api.selectImage(core, null);
9594
- }
9595
- return !!rangeEx;
9753
+ return core.api.select(core, arg1, arg2, arg3, arg4);
9596
9754
  };
9597
9755
  /**
9598
9756
  * Get current focused position. Return null if editor doesn't have focus at this time.
9599
9757
  */
9600
- Editor.prototype.getFocusedPosition = function () {
9758
+ EditorBase.prototype.getFocusedPosition = function () {
9601
9759
  var _a;
9602
9760
  var sel = (_a = this.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
9603
9761
  if ((sel === null || sel === void 0 ? void 0 : sel.focusNode) && this.contains(sel.focusNode)) {
@@ -9621,7 +9779,7 @@ var Editor = /** @class */ (function () {
9621
9779
  * @param event Optional, if specified, editor will try to get cached result from the event object first.
9622
9780
  * If it is not cached before, query from DOM and cache the result into the event object
9623
9781
  */
9624
- Editor.prototype.getElementAtCursor = function (selector, startFrom, event) {
9782
+ EditorBase.prototype.getElementAtCursor = function (selector, startFrom, event) {
9625
9783
  var _this = this;
9626
9784
  var _a;
9627
9785
  event = startFrom ? undefined : event; // Only use cache when startFrom is not specified, for different start position can have different result
@@ -9640,13 +9798,13 @@ var Editor = /** @class */ (function () {
9640
9798
  * @param position The position to check
9641
9799
  * @returns True if position is at beginning of the editor, otherwise false
9642
9800
  */
9643
- Editor.prototype.isPositionAtBeginning = function (position) {
9801
+ EditorBase.prototype.isPositionAtBeginning = function (position) {
9644
9802
  return (0, roosterjs_editor_dom_1.isPositionAtBeginningOf)(position, this.getCore().contentDiv);
9645
9803
  };
9646
9804
  /**
9647
9805
  * Get impacted regions from selection
9648
9806
  */
9649
- Editor.prototype.getSelectedRegions = function (type) {
9807
+ EditorBase.prototype.getSelectedRegions = function (type) {
9650
9808
  if (type === void 0) { type = 0 /* Table */; }
9651
9809
  var selection = this.getSelectionRangeEx();
9652
9810
  var result = [];
@@ -9660,7 +9818,7 @@ var Editor = /** @class */ (function () {
9660
9818
  };
9661
9819
  //#endregion
9662
9820
  //#region EVENT API
9663
- Editor.prototype.addDomEventHandler = function (nameOrMap, handler) {
9821
+ EditorBase.prototype.addDomEventHandler = function (nameOrMap, handler) {
9664
9822
  var _a;
9665
9823
  var eventsToMap = typeof nameOrMap == 'string' ? (_a = {}, _a[nameOrMap] = handler, _a) : nameOrMap;
9666
9824
  var core = this.getCore();
@@ -9675,7 +9833,7 @@ var Editor = /** @class */ (function () {
9675
9833
  * @returns the event object which is really passed into plugins. Some plugin may modify the event object so
9676
9834
  * the result of this function provides a chance to read the modified result
9677
9835
  */
9678
- Editor.prototype.triggerPluginEvent = function (eventType, data, broadcast) {
9836
+ EditorBase.prototype.triggerPluginEvent = function (eventType, data, broadcast) {
9679
9837
  if (broadcast === void 0) { broadcast = false; }
9680
9838
  var core = this.getCore();
9681
9839
  var event = __assign({ eventType: eventType }, data);
@@ -9687,7 +9845,7 @@ var Editor = /** @class */ (function () {
9687
9845
  * @param source Source of this event, by default is 'SetContent'
9688
9846
  * @param data additional data for this event
9689
9847
  */
9690
- Editor.prototype.triggerContentChangedEvent = function (source, data) {
9848
+ EditorBase.prototype.triggerContentChangedEvent = function (source, data) {
9691
9849
  if (source === void 0) { source = "SetContent" /* SetContent */; }
9692
9850
  this.triggerPluginEvent(7 /* ContentChanged */, {
9693
9851
  source: source,
@@ -9699,7 +9857,7 @@ var Editor = /** @class */ (function () {
9699
9857
  /**
9700
9858
  * Undo last edit operation
9701
9859
  */
9702
- Editor.prototype.undo = function () {
9860
+ EditorBase.prototype.undo = function () {
9703
9861
  this.focus();
9704
9862
  var core = this.getCore();
9705
9863
  core.api.restoreUndoSnapshot(core, -1 /*step*/);
@@ -9707,7 +9865,7 @@ var Editor = /** @class */ (function () {
9707
9865
  /**
9708
9866
  * Redo next edit operation
9709
9867
  */
9710
- Editor.prototype.redo = function () {
9868
+ EditorBase.prototype.redo = function () {
9711
9869
  this.focus();
9712
9870
  var core = this.getCore();
9713
9871
  core.api.restoreUndoSnapshot(core, 1 /*step*/);
@@ -9722,14 +9880,14 @@ var Editor = /** @class */ (function () {
9722
9880
  * a ContentChangedEvent will be fired with change source equal to this value
9723
9881
  * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).
9724
9882
  */
9725
- Editor.prototype.addUndoSnapshot = function (callback, changeSource, canUndoByBackspace, additionalData) {
9883
+ EditorBase.prototype.addUndoSnapshot = function (callback, changeSource, canUndoByBackspace, additionalData) {
9726
9884
  var core = this.getCore();
9727
9885
  core.api.addUndoSnapshot(core, callback !== null && callback !== void 0 ? callback : null, changeSource !== null && changeSource !== void 0 ? changeSource : null, canUndoByBackspace !== null && canUndoByBackspace !== void 0 ? canUndoByBackspace : false, additionalData);
9728
9886
  };
9729
9887
  /**
9730
9888
  * Whether there is an available undo/redo snapshot
9731
9889
  */
9732
- Editor.prototype.getUndoState = function () {
9890
+ EditorBase.prototype.getUndoState = function () {
9733
9891
  var _a = this.getCore().undo, hasNewContent = _a.hasNewContent, snapshotsService = _a.snapshotsService;
9734
9892
  return {
9735
9893
  canUndo: hasNewContent || snapshotsService.canMove(-1 /*previousSnapshot*/),
@@ -9742,13 +9900,13 @@ var Editor = /** @class */ (function () {
9742
9900
  * Get document which contains this editor
9743
9901
  * @returns The HTML document which contains this editor
9744
9902
  */
9745
- Editor.prototype.getDocument = function () {
9903
+ EditorBase.prototype.getDocument = function () {
9746
9904
  return this.getCore().contentDiv.ownerDocument;
9747
9905
  };
9748
9906
  /**
9749
9907
  * Get the scroll container of the editor
9750
9908
  */
9751
- Editor.prototype.getScrollContainer = function () {
9909
+ EditorBase.prototype.getScrollContainer = function () {
9752
9910
  return this.getCore().domEvent.scrollContainer;
9753
9911
  };
9754
9912
  /**
@@ -9759,7 +9917,7 @@ var Editor = /** @class */ (function () {
9759
9917
  * @param disposer An optional disposer function to dispose this custom data when
9760
9918
  * dispose editor.
9761
9919
  */
9762
- Editor.prototype.getCustomData = function (key, getter, disposer) {
9920
+ EditorBase.prototype.getCustomData = function (key, getter, disposer) {
9763
9921
  var core = this.getCore();
9764
9922
  return (core.lifecycle.customData[key] = core.lifecycle.customData[key] || {
9765
9923
  value: getter ? getter() : undefined,
@@ -9770,14 +9928,14 @@ var Editor = /** @class */ (function () {
9770
9928
  * Check if editor is in IME input sequence
9771
9929
  * @returns True if editor is in IME input sequence, otherwise false
9772
9930
  */
9773
- Editor.prototype.isInIME = function () {
9931
+ EditorBase.prototype.isInIME = function () {
9774
9932
  return this.getCore().domEvent.isInIME;
9775
9933
  };
9776
9934
  /**
9777
9935
  * Get default format of this editor
9778
9936
  * @returns Default format object of this editor
9779
9937
  */
9780
- Editor.prototype.getDefaultFormat = function () {
9938
+ EditorBase.prototype.getDefaultFormat = function () {
9781
9939
  var _a;
9782
9940
  return (_a = this.getCore().lifecycle.defaultFormat) !== null && _a !== void 0 ? _a : {};
9783
9941
  };
@@ -9785,14 +9943,14 @@ var Editor = /** @class */ (function () {
9785
9943
  * Get a content traverser for the whole editor
9786
9944
  * @param startNode The node to start from. If not passed, it will start from the beginning of the body
9787
9945
  */
9788
- Editor.prototype.getBodyTraverser = function (startNode) {
9946
+ EditorBase.prototype.getBodyTraverser = function (startNode) {
9789
9947
  return roosterjs_editor_dom_1.ContentTraverser.createBodyTraverser(this.getCore().contentDiv, startNode);
9790
9948
  };
9791
9949
  /**
9792
9950
  * Get a content traverser for current selection
9793
9951
  * @returns A content traverser, or null if editor never got focus before
9794
9952
  */
9795
- Editor.prototype.getSelectionTraverser = function (range) {
9953
+ EditorBase.prototype.getSelectionTraverser = function (range) {
9796
9954
  var _a;
9797
9955
  range = (_a = range !== null && range !== void 0 ? range : this.getSelectionRange()) !== null && _a !== void 0 ? _a : undefined;
9798
9956
  return range
@@ -9804,7 +9962,7 @@ var Editor = /** @class */ (function () {
9804
9962
  * @param startFrom Start position of the traverser. Default value is ContentPosition.SelectionStart
9805
9963
  * @returns A content traverser, or null if editor never got focus before
9806
9964
  */
9807
- Editor.prototype.getBlockTraverser = function (startFrom) {
9965
+ EditorBase.prototype.getBlockTraverser = function (startFrom) {
9808
9966
  if (startFrom === void 0) { startFrom = 3 /* SelectionStart */; }
9809
9967
  var range = this.getSelectionRange();
9810
9968
  return range
@@ -9817,7 +9975,7 @@ var Editor = /** @class */ (function () {
9817
9975
  * If it is not cached before, query from DOM and cache the result into the event object
9818
9976
  * @returns A content traverser, or null if editor never got focus before
9819
9977
  */
9820
- Editor.prototype.getContentSearcherOfCursor = function (event) {
9978
+ EditorBase.prototype.getContentSearcherOfCursor = function (event) {
9821
9979
  var _this = this;
9822
9980
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event !== null && event !== void 0 ? event : null, 'ContentSearcher', function () {
9823
9981
  var range = _this.getSelectionRange();
@@ -9830,7 +9988,7 @@ var Editor = /** @class */ (function () {
9830
9988
  * @param callback The callback function to run
9831
9989
  * @returns a function to cancel this async run
9832
9990
  */
9833
- Editor.prototype.runAsync = function (callback) {
9991
+ EditorBase.prototype.runAsync = function (callback) {
9834
9992
  var _this = this;
9835
9993
  var win = this.getCore().contentDiv.ownerDocument.defaultView || window;
9836
9994
  var handle = win.requestAnimationFrame(function () {
@@ -9847,7 +10005,7 @@ var Editor = /** @class */ (function () {
9847
10005
  * @param name Name of the attribute
9848
10006
  * @param value Value of the attribute
9849
10007
  */
9850
- Editor.prototype.setEditorDomAttribute = function (name, value) {
10008
+ EditorBase.prototype.setEditorDomAttribute = function (name, value) {
9851
10009
  if (value === null) {
9852
10010
  this.getCore().contentDiv.removeAttribute(name);
9853
10011
  }
@@ -9859,7 +10017,7 @@ var Editor = /** @class */ (function () {
9859
10017
  * Get DOM attribute of editor content DIV, null if there is no such attribute.
9860
10018
  * @param name Name of the attribute
9861
10019
  */
9862
- Editor.prototype.getEditorDomAttribute = function (name) {
10020
+ EditorBase.prototype.getEditorDomAttribute = function (name) {
9863
10021
  return this.getCore().contentDiv.getAttribute(name);
9864
10022
  };
9865
10023
  /**
@@ -9871,7 +10029,7 @@ var Editor = /** @class */ (function () {
9871
10029
  * may be different than what user is seeing from the view. When pass false, scroll position will be ignored.
9872
10030
  * @returns An [x, y] array which contains the left and top distances, or null if the given element is not in editor.
9873
10031
  */
9874
- Editor.prototype.getRelativeDistanceToEditor = function (element, addScroll) {
10032
+ EditorBase.prototype.getRelativeDistanceToEditor = function (element, addScroll) {
9875
10033
  if (this.contains(element)) {
9876
10034
  var contentDiv = this.getCore().contentDiv;
9877
10035
  var editorRect = contentDiv.getBoundingClientRect();
@@ -9892,7 +10050,7 @@ var Editor = /** @class */ (function () {
9892
10050
  * Add a Content Edit feature.
9893
10051
  * @param feature The feature to add
9894
10052
  */
9895
- Editor.prototype.addContentEditFeature = function (feature) {
10053
+ EditorBase.prototype.addContentEditFeature = function (feature) {
9896
10054
  var core = this.getCore();
9897
10055
  feature === null || feature === void 0 ? void 0 : feature.keys.forEach(function (key) {
9898
10056
  var array = core.edit.features[key] || [];
@@ -9904,7 +10062,7 @@ var Editor = /** @class */ (function () {
9904
10062
  * Remove a Content Edit feature.
9905
10063
  * @param feature The feature to remove
9906
10064
  */
9907
- Editor.prototype.removeContentEditFeature = function (feature) {
10065
+ EditorBase.prototype.removeContentEditFeature = function (feature) {
9908
10066
  var core = this.getCore();
9909
10067
  feature === null || feature === void 0 ? void 0 : feature.keys.forEach(function (key) {
9910
10068
  var _a;
@@ -9921,7 +10079,7 @@ var Editor = /** @class */ (function () {
9921
10079
  /**
9922
10080
  * Get style based format state from current selection, including font name/size and colors
9923
10081
  */
9924
- Editor.prototype.getStyleBasedFormatState = function (node) {
10082
+ EditorBase.prototype.getStyleBasedFormatState = function (node) {
9925
10083
  var _a;
9926
10084
  if (!node) {
9927
10085
  var range = this.getSelectionRange();
@@ -9935,7 +10093,7 @@ var Editor = /** @class */ (function () {
9935
10093
  * @param forceGetStateFromDOM If set to true, will force get the format state from DOM tree.
9936
10094
  * @returns The pending format state
9937
10095
  */
9938
- Editor.prototype.getPendableFormatState = function (forceGetStateFromDOM) {
10096
+ EditorBase.prototype.getPendableFormatState = function (forceGetStateFromDOM) {
9939
10097
  if (forceGetStateFromDOM === void 0) { forceGetStateFromDOM = false; }
9940
10098
  var core = this.getCore();
9941
10099
  return core.api.getPendableFormatState(core, forceGetStateFromDOM);
@@ -9945,7 +10103,7 @@ var Editor = /** @class */ (function () {
9945
10103
  * @param position The position that user is about to type to
9946
10104
  * @param keyboardEvent Optional keyboard event object
9947
10105
  */
9948
- Editor.prototype.ensureTypeInContainer = function (position, keyboardEvent) {
10106
+ EditorBase.prototype.ensureTypeInContainer = function (position, keyboardEvent) {
9949
10107
  var core = this.getCore();
9950
10108
  core.api.ensureTypeInContainer(core, position, keyboardEvent, this.isFeatureEnabled("DefaultFormatInSpan" /* DefaultFormatInSpan */));
9951
10109
  };
@@ -9955,7 +10113,7 @@ var Editor = /** @class */ (function () {
9955
10113
  * Set the dark mode state and transforms the content to match the new state.
9956
10114
  * @param nextDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
9957
10115
  */
9958
- Editor.prototype.setDarkModeState = function (nextDarkMode) {
10116
+ EditorBase.prototype.setDarkModeState = function (nextDarkMode) {
9959
10117
  var isDarkMode = this.isDarkMode();
9960
10118
  if (isDarkMode == !!nextDarkMode) {
9961
10119
  return;
@@ -9970,21 +10128,21 @@ var Editor = /** @class */ (function () {
9970
10128
  * Check if the editor is in dark mode
9971
10129
  * @returns True if the editor is in dark mode, otherwise false
9972
10130
  */
9973
- Editor.prototype.isDarkMode = function () {
10131
+ EditorBase.prototype.isDarkMode = function () {
9974
10132
  return this.getCore().lifecycle.isDarkMode;
9975
10133
  };
9976
10134
  /**
9977
10135
  * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
9978
10136
  * @param node The node to transform
9979
10137
  */
9980
- Editor.prototype.transformToDarkColor = function (node) {
10138
+ EditorBase.prototype.transformToDarkColor = function (node) {
9981
10139
  var core = this.getCore();
9982
10140
  core.api.transformColor(core, node, true /*includeSelf*/, null /*callback*/, 0 /* LightToDark */);
9983
10141
  };
9984
10142
  /**
9985
10143
  * Get a darkColorHandler object for this editor. It will return null if experimental feature "VariableBasedDarkColor" is not enabled
9986
10144
  */
9987
- Editor.prototype.getDarkColorHandler = function () {
10145
+ EditorBase.prototype.getDarkColorHandler = function () {
9988
10146
  return this.getCore().darkColorHandler || null;
9989
10147
  };
9990
10148
  /**
@@ -9995,29 +10153,29 @@ var Editor = /** @class */ (function () {
9995
10153
  * This function can be called repeated. If editor is already in shadow edit mode, we can still
9996
10154
  * use this function to do more shadow edit operation.
9997
10155
  */
9998
- Editor.prototype.startShadowEdit = function () {
10156
+ EditorBase.prototype.startShadowEdit = function () {
9999
10157
  var core = this.getCore();
10000
10158
  core.api.switchShadowEdit(core, true /*isOn*/);
10001
10159
  };
10002
10160
  /**
10003
10161
  * Leave "Shadow Edit" mode, all changes made during shadow edit will be discarded
10004
10162
  */
10005
- Editor.prototype.stopShadowEdit = function () {
10163
+ EditorBase.prototype.stopShadowEdit = function () {
10006
10164
  var core = this.getCore();
10007
10165
  core.api.switchShadowEdit(core, false /*isOn*/);
10008
10166
  };
10009
10167
  /**
10010
10168
  * Check if editor is in Shadow Edit mode
10011
10169
  */
10012
- Editor.prototype.isInShadowEdit = function () {
10170
+ EditorBase.prototype.isInShadowEdit = function () {
10013
10171
  return !!this.getCore().lifecycle.shadowEditFragment;
10014
10172
  };
10015
10173
  /**
10016
10174
  * Check if the given experimental feature is enabled
10017
10175
  * @param feature The feature to check
10018
10176
  */
10019
- Editor.prototype.isFeatureEnabled = function (feature) {
10020
- return this.getCore().lifecycle.experimentalFeatures.indexOf(feature) >= 0;
10177
+ EditorBase.prototype.isFeatureEnabled = function (feature) {
10178
+ return (0, isFeatureEnabled_1.isFeatureEnabled)(this.getCore().lifecycle.experimentalFeatures, feature);
10021
10179
  };
10022
10180
  /**
10023
10181
  * Get a function to convert HTML string to trusted HTML string.
@@ -10025,13 +10183,13 @@ var Editor = /** @class */ (function () {
10025
10183
  * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
10026
10184
  * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
10027
10185
  */
10028
- Editor.prototype.getTrustedHTMLHandler = function () {
10186
+ EditorBase.prototype.getTrustedHTMLHandler = function () {
10029
10187
  return this.getCore().trustedHTMLHandler;
10030
10188
  };
10031
10189
  /**
10032
10190
  * @deprecated Use getZoomScale() instead
10033
10191
  */
10034
- Editor.prototype.getSizeTransformer = function () {
10192
+ EditorBase.prototype.getSizeTransformer = function () {
10035
10193
  return this.getCore().sizeTransformer;
10036
10194
  };
10037
10195
  /**
@@ -10040,7 +10198,7 @@ var Editor = /** @class */ (function () {
10040
10198
  * to let editor behave correctly especially for those mouse drag/drop behaviors
10041
10199
  * @returns current zoom scale number
10042
10200
  */
10043
- Editor.prototype.getZoomScale = function () {
10201
+ EditorBase.prototype.getZoomScale = function () {
10044
10202
  return this.getCore().zoomScale;
10045
10203
  };
10046
10204
  /**
@@ -10049,7 +10207,7 @@ var Editor = /** @class */ (function () {
10049
10207
  * to let editor behave correctly especially for those mouse drag/drop behaviors
10050
10208
  * @param scale The new scale number to set. It should be positive number and no greater than 10, otherwise it will be ignored.
10051
10209
  */
10052
- Editor.prototype.setZoomScale = function (scale) {
10210
+ EditorBase.prototype.setZoomScale = function (scale) {
10053
10211
  var core = this.getCore();
10054
10212
  if (scale > 0 && scale <= 10) {
10055
10213
  var oldValue = core.zoomScale;
@@ -10065,47 +10223,112 @@ var Editor = /** @class */ (function () {
10065
10223
  /**
10066
10224
  * Retrieves the rect of the visible viewport of the editor.
10067
10225
  */
10068
- Editor.prototype.getVisibleViewport = function () {
10226
+ EditorBase.prototype.getVisibleViewport = function () {
10069
10227
  return this.getCore().getVisibleViewport();
10070
10228
  };
10071
10229
  /**
10072
10230
  * @returns the current EditorCore object
10073
10231
  * @throws a standard Error if there's no core object
10074
10232
  */
10075
- Editor.prototype.getCore = function () {
10233
+ EditorBase.prototype.getCore = function () {
10076
10234
  if (!this.core) {
10077
10235
  throw new Error('Editor is already disposed');
10078
10236
  }
10079
10237
  return this.core;
10080
10238
  };
10081
- return Editor;
10239
+ return EditorBase;
10082
10240
  }());
10083
- exports.default = Editor;
10084
- function isSelectionRangeEx(obj) {
10085
- var rangeEx = obj;
10086
- return (rangeEx &&
10087
- typeof rangeEx == 'object' &&
10088
- typeof rangeEx.type == 'number' &&
10089
- Array.isArray(rangeEx.ranges));
10090
- }
10091
- function isTableSelection(obj) {
10092
- var selection = obj;
10093
- return (selection &&
10094
- typeof selection == 'object' &&
10095
- typeof selection.firstCell == 'object' &&
10096
- typeof selection.lastCell == 'object');
10097
- }
10098
- function isSelectionPath(obj) {
10099
- var path = obj;
10100
- return path && typeof path == 'object' && Array.isArray(path.start) && Array.isArray(path.end);
10101
- }
10102
- function isNodePosition(obj) {
10103
- var pos = obj;
10104
- return (pos &&
10105
- typeof pos == 'object' &&
10106
- typeof pos.node == 'object' &&
10107
- typeof pos.offset == 'number');
10241
+ exports.EditorBase = EditorBase;
10242
+
10243
+
10244
+ /***/ }),
10245
+
10246
+ /***/ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts":
10247
+ /*!***********************************************************************!*\
10248
+ !*** ./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts ***!
10249
+ \***********************************************************************/
10250
+ /*! no static exports found */
10251
+ /***/ (function(module, exports, __webpack_require__) {
10252
+
10253
+ "use strict";
10254
+
10255
+ var __assign = (this && this.__assign) || function () {
10256
+ __assign = Object.assign || function(t) {
10257
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
10258
+ s = arguments[i];
10259
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
10260
+ t[p] = s[p];
10261
+ }
10262
+ return t;
10263
+ };
10264
+ return __assign.apply(this, arguments);
10265
+ };
10266
+ Object.defineProperty(exports, "__esModule", { value: true });
10267
+ exports.createEditorCore = void 0;
10268
+ var createCorePlugins_1 = __webpack_require__(/*! ../corePlugins/createCorePlugins */ "./packages/roosterjs-editor-core/lib/corePlugins/createCorePlugins.ts");
10269
+ var DarkColorHandlerImpl_1 = __webpack_require__(/*! ./DarkColorHandlerImpl */ "./packages/roosterjs-editor-core/lib/editor/DarkColorHandlerImpl.ts");
10270
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
10271
+ var coreApiMap_1 = __webpack_require__(/*! ../coreApi/coreApiMap */ "./packages/roosterjs-editor-core/lib/coreApi/coreApiMap.ts");
10272
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
10273
+ /**
10274
+ * Create a new instance of Editor Core
10275
+ * @param contentDiv The DIV HTML element which will be the container element of editor
10276
+ * @param options An optional options object to customize the editor
10277
+ */
10278
+ var createEditorCore = function (contentDiv, options) {
10279
+ var _a;
10280
+ var corePlugins = (0, createCorePlugins_1.default)(contentDiv, options);
10281
+ var plugins = [];
10282
+ (0, roosterjs_editor_dom_1.getObjectKeys)(corePlugins).forEach(function (name) {
10283
+ if (name == '_placeholder') {
10284
+ if (options.plugins) {
10285
+ (0, roosterjs_editor_dom_1.arrayPush)(plugins, options.plugins);
10286
+ }
10287
+ }
10288
+ else {
10289
+ plugins.push(corePlugins[name]);
10290
+ }
10291
+ });
10292
+ var pluginState = (0, createCorePlugins_1.getPluginState)(corePlugins);
10293
+ var zoomScale = ((_a = options.zoomScale) !== null && _a !== void 0 ? _a : -1) > 0 ? options.zoomScale : 1;
10294
+ var getVisibleViewport = options.getVisibleViewport ||
10295
+ (function () {
10296
+ var scrollContainer = pluginState.domEvent.scrollContainer;
10297
+ return (0, roosterjs_editor_dom_1.getIntersectedRect)(scrollContainer == core.contentDiv
10298
+ ? [scrollContainer]
10299
+ : [scrollContainer, core.contentDiv]);
10300
+ });
10301
+ var core = __assign(__assign({ contentDiv: contentDiv, api: __assign(__assign({}, coreApiMap_1.coreApiMap), (options.coreApiOverride || {})), originalApi: coreApiMap_1.coreApiMap, plugins: plugins.filter(function (x) { return !!x; }) }, pluginState), { trustedHTMLHandler: options.trustedHTMLHandler || (function (html) { return html; }), zoomScale: zoomScale, sizeTransformer: options.sizeTransformer || (function (size) { return size / zoomScale; }), getVisibleViewport: getVisibleViewport, imageSelectionBorderColor: options.imageSelectionBorderColor, darkColorHandler: (0, isFeatureEnabled_1.isFeatureEnabled)(options.experimentalFeatures, "VariableBasedDarkColor" /* VariableBasedDarkColor */)
10302
+ ? new DarkColorHandlerImpl_1.default(contentDiv, pluginState.lifecycle.getDarkColor)
10303
+ : undefined });
10304
+ return core;
10305
+ };
10306
+ exports.createEditorCore = createEditorCore;
10307
+
10308
+
10309
+ /***/ }),
10310
+
10311
+ /***/ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts":
10312
+ /*!***********************************************************************!*\
10313
+ !*** ./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts ***!
10314
+ \***********************************************************************/
10315
+ /*! no static exports found */
10316
+ /***/ (function(module, exports, __webpack_require__) {
10317
+
10318
+ "use strict";
10319
+
10320
+ Object.defineProperty(exports, "__esModule", { value: true });
10321
+ exports.isFeatureEnabled = void 0;
10322
+ /**
10323
+ * Check if the given experimental feature is enabled
10324
+ * @param featureSet All enabled features
10325
+ * @param feature The feature to check
10326
+ * @returns True if the given feature is enabled, otherwise false
10327
+ */
10328
+ function isFeatureEnabled(featureSet, feature) {
10329
+ return (featureSet || []).indexOf(feature) >= 0;
10108
10330
  }
10331
+ exports.isFeatureEnabled = isFeatureEnabled;
10109
10332
 
10110
10333
 
10111
10334
  /***/ }),
@@ -10120,10 +10343,16 @@ function isNodePosition(obj) {
10120
10343
  "use strict";
10121
10344
 
10122
10345
  Object.defineProperty(exports, "__esModule", { value: true });
10123
- exports.Editor = void 0;
10346
+ exports.createEditorCore = exports.isFeatureEnabled = exports.EditorBase = exports.Editor = void 0;
10124
10347
  // Classes
10125
10348
  var Editor_1 = __webpack_require__(/*! ./editor/Editor */ "./packages/roosterjs-editor-core/lib/editor/Editor.ts");
10126
10349
  Object.defineProperty(exports, "Editor", { enumerable: true, get: function () { return Editor_1.default; } });
10350
+ var EditorBase_1 = __webpack_require__(/*! ./editor/EditorBase */ "./packages/roosterjs-editor-core/lib/editor/EditorBase.ts");
10351
+ Object.defineProperty(exports, "EditorBase", { enumerable: true, get: function () { return EditorBase_1.EditorBase; } });
10352
+ var isFeatureEnabled_1 = __webpack_require__(/*! ./editor/isFeatureEnabled */ "./packages/roosterjs-editor-core/lib/editor/isFeatureEnabled.ts");
10353
+ Object.defineProperty(exports, "isFeatureEnabled", { enumerable: true, get: function () { return isFeatureEnabled_1.isFeatureEnabled; } });
10354
+ var createEditorCore_1 = __webpack_require__(/*! ./editor/createEditorCore */ "./packages/roosterjs-editor-core/lib/editor/createEditorCore.ts");
10355
+ Object.defineProperty(exports, "createEditorCore", { enumerable: true, get: function () { return createEditorCore_1.createEditorCore; } });
10127
10356
 
10128
10357
 
10129
10358
  /***/ }),
@@ -10378,6 +10607,9 @@ function getBlockElementAtNode(rootNode, node) {
10378
10607
  // Find the head and leaf node in the block
10379
10608
  var headNode = findHeadTailLeafNode(node, containerBlockNode, false /*isTail*/);
10380
10609
  var tailNode = findHeadTailLeafNode(node, containerBlockNode, true /*isTail*/);
10610
+ if (!headNode || !tailNode) {
10611
+ return null;
10612
+ }
10381
10613
  // At this point, we have the head and tail of a block, here are some examples and where head and tail point to
10382
10614
  // 1) &lt;root&gt;&lt;div&gt;hello&lt;br&gt;&lt;/div&gt;&lt;/root&gt;, head: hello, tail: &lt;br&gt;
10383
10615
  // 2) &lt;root&gt;&lt;div&gt;hello&lt;span style="font-family: Arial"&gt;world&lt;/span&gt;&lt;/div&gt;&lt;/root&gt;, head: hello, tail: world
@@ -11503,7 +11735,7 @@ function insertDelimiter(element, delimiterClass) {
11503
11735
  var insertPosition = delimiterClass == "entityDelimiterAfter" /* DELIMITER_AFTER */ ? 'afterend' : 'beforebegin';
11504
11736
  element.insertAdjacentElement(insertPosition, span);
11505
11737
  }
11506
- return element;
11738
+ return span;
11507
11739
  }
11508
11740
 
11509
11741
 
@@ -21080,15 +21312,16 @@ var ContentEdit = /** @class */ (function () {
21080
21312
  this.editor = editor;
21081
21313
  var allFeatures = (0, getAllFeatures_1.default)();
21082
21314
  (0, roosterjs_editor_dom_1.getObjectKeys)(allFeatures).forEach(function (key) {
21315
+ var _a;
21083
21316
  var feature = allFeatures[key];
21084
21317
  var hasSettingForKey = _this.settingsOverride && _this.settingsOverride[key] !== undefined;
21085
- if ((hasSettingForKey && _this.settingsOverride[key]) ||
21318
+ if ((hasSettingForKey && ((_a = _this.settingsOverride) === null || _a === void 0 ? void 0 : _a[key])) ||
21086
21319
  (!hasSettingForKey && !feature.defaultDisabled)) {
21087
21320
  _this.features.push(feature);
21088
21321
  }
21089
21322
  });
21090
21323
  this.features = this.features.concat(this.additionalFeatures || []);
21091
- this.features.forEach(function (feature) { return _this.editor.addContentEditFeature(feature); });
21324
+ this.features.forEach(function (feature) { var _a; return (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.addContentEditFeature(feature); });
21092
21325
  };
21093
21326
  ContentEdit.prototype.disposeFeatures = function () {
21094
21327
  var _this = this;
@@ -21160,14 +21393,15 @@ function cacheGetLinkData(event, editor) {
21160
21393
  // This helps when we paste a link next to some existing character, and the text we got
21161
21394
  // from clipboard will only contain what we pasted, any existing characters will not
21162
21395
  // be included.
21163
- var clipboardData = event.eventType == 7 /* ContentChanged */ &&
21396
+ var clipboardData = (event.eventType == 7 /* ContentChanged */ &&
21164
21397
  event.source == "Paste" /* Paste */ &&
21165
- event.data;
21166
- var link = (0, roosterjs_editor_dom_1.matchLink)((clipboardData.text || '').trim());
21398
+ event.data) ||
21399
+ null;
21400
+ var link = (0, roosterjs_editor_dom_1.matchLink)(((clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.text) || '').trim());
21167
21401
  var searcher = editor.getContentSearcherOfCursor(event);
21168
21402
  // In case the matched link is already inside a <A> tag, we do a range search.
21169
21403
  // getRangeFromText will return null if the given text is already in a LinkInlineElement
21170
- if (link && searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/)) {
21404
+ if (link && (searcher === null || searcher === void 0 ? void 0 : searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/))) {
21171
21405
  return link;
21172
21406
  }
21173
21407
  var word = searcher && searcher.getWordBefore();
@@ -21192,12 +21426,15 @@ function cacheGetLinkData(event, editor) {
21192
21426
  }
21193
21427
  function hasLinkBeforeCursor(event, editor) {
21194
21428
  var contentSearcher = editor.getContentSearcherOfCursor(event);
21195
- var inline = contentSearcher.getInlineElementBefore();
21429
+ var inline = contentSearcher === null || contentSearcher === void 0 ? void 0 : contentSearcher.getInlineElementBefore();
21196
21430
  return inline instanceof roosterjs_editor_dom_1.LinkInlineElement;
21197
21431
  }
21198
21432
  function autoLink(event, editor) {
21199
- var anchor = editor.getDocument().createElement('a');
21200
21433
  var linkData = cacheGetLinkData(event, editor);
21434
+ if (!linkData) {
21435
+ return;
21436
+ }
21437
+ var anchor = editor.getDocument().createElement('a');
21201
21438
  // Need to get searcher before we enter the async callback since the callback can happen when cursor is moved to next line
21202
21439
  // and at that time a new searcher won't be able to find the link text to replace
21203
21440
  var searcher = editor.getContentSearcherOfCursor();
@@ -21205,7 +21442,7 @@ function autoLink(event, editor) {
21205
21442
  anchor.href = linkData.normalizedUrl;
21206
21443
  editor.runAsync(function (editor) {
21207
21444
  editor.addUndoSnapshot(function () {
21208
- (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher);
21445
+ (0, roosterjs_editor_api_1.replaceWithNode)(editor, linkData.originalUrl, anchor, false /* exactMatch */, searcher !== null && searcher !== void 0 ? searcher : undefined);
21209
21446
  // The content at cursor has changed. Should also clear the cursor data cache
21210
21447
  (0, roosterjs_editor_dom_1.clearEventDataCache)(event);
21211
21448
  return anchor;
@@ -21221,6 +21458,91 @@ exports.AutoLinkFeatures = {
21221
21458
  };
21222
21459
 
21223
21460
 
21461
+ /***/ }),
21462
+
21463
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts":
21464
+ /*!********************************************************************************************!*\
21465
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts ***!
21466
+ \********************************************************************************************/
21467
+ /*! no static exports found */
21468
+ /***/ (function(module, exports, __webpack_require__) {
21469
+
21470
+ "use strict";
21471
+
21472
+ Object.defineProperty(exports, "__esModule", { value: true });
21473
+ exports.CodeFeatures = void 0;
21474
+ var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
21475
+ var RemoveCodeWhenEnterOnEmptyLine = {
21476
+ keys: [13 /* ENTER */],
21477
+ shouldHandleEvent: function (event, editor) {
21478
+ var childOfCode = cacheGetCodeChild(event, editor);
21479
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode);
21480
+ },
21481
+ handleEvent: function (event, editor) {
21482
+ event.rawEvent.preventDefault();
21483
+ editor.addUndoSnapshot(function () {
21484
+ splitCode(event, editor);
21485
+ }, undefined /* changeSource */, true /* canUndoByBackspace */);
21486
+ },
21487
+ };
21488
+ var RemoveCodeWhenBackspaceOnEmptyFirstLine = {
21489
+ keys: [8 /* BACKSPACE */],
21490
+ shouldHandleEvent: function (event, editor) {
21491
+ var childOfCode = cacheGetCodeChild(event, editor);
21492
+ return childOfCode && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfCode) && !childOfCode.previousSibling;
21493
+ },
21494
+ handleEvent: function (event, editor) {
21495
+ event.rawEvent.preventDefault();
21496
+ editor.addUndoSnapshot(function () { return splitCode(event, editor); });
21497
+ },
21498
+ };
21499
+ function cacheGetCodeChild(event, editor) {
21500
+ return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'CODE_CHILD', function () {
21501
+ var _a;
21502
+ var codeElement = (_a = editor.getElementAtCursor('code')) !== null && _a !== void 0 ? _a : editor.queryElements('code', 1 /* OnSelection */)[0];
21503
+ if (codeElement) {
21504
+ var pos = editor.getFocusedPosition();
21505
+ var block = pos && editor.getBlockElementAtNode(pos.normalize().node);
21506
+ if (block) {
21507
+ var node = block.getStartNode() == codeElement.parentNode
21508
+ ? block.getStartNode()
21509
+ : block.collapseToSingleElement();
21510
+ return (0, roosterjs_editor_dom_1.isNodeEmpty)(node) ? node : null;
21511
+ }
21512
+ }
21513
+ return null;
21514
+ });
21515
+ }
21516
+ function splitCode(event, editor) {
21517
+ var currentContainer = cacheGetCodeChild(event, editor);
21518
+ if (!(0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer, 'HTMLElement')) {
21519
+ return;
21520
+ }
21521
+ var codeChild = currentContainer.querySelector('code');
21522
+ if (!codeChild) {
21523
+ var codeParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21524
+ if (codeParent) {
21525
+ (0, roosterjs_editor_dom_1.unwrap)(codeParent);
21526
+ }
21527
+ if ((0, roosterjs_editor_dom_1.safeInstanceOf)(currentContainer.parentElement, 'HTMLPreElement')) {
21528
+ var preParent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(currentContainer);
21529
+ if (preParent) {
21530
+ (0, roosterjs_editor_dom_1.unwrap)(preParent);
21531
+ }
21532
+ }
21533
+ }
21534
+ else {
21535
+ //Content model
21536
+ (0, roosterjs_editor_dom_1.unwrap)(codeChild);
21537
+ }
21538
+ editor.select(currentContainer, 0 /* Begin */);
21539
+ }
21540
+ exports.CodeFeatures = {
21541
+ removeCodeWhenEnterOnEmptyLine: RemoveCodeWhenEnterOnEmptyLine,
21542
+ removeCodeWhenBackspaceOnEmptyFirstLine: RemoveCodeWhenBackspaceOnEmptyFirstLine,
21543
+ };
21544
+
21545
+
21224
21546
  /***/ }),
21225
21547
 
21226
21548
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/cursorFeatures.ts":
@@ -21239,7 +21561,7 @@ var NoCycleCursorMove = {
21239
21561
  keys: [37 /* LEFT */, 39 /* RIGHT */],
21240
21562
  allowFunctionKeys: true,
21241
21563
  shouldHandleEvent: function (event, editor, ctrlOrMeta) {
21242
- var range;
21564
+ var range = null;
21243
21565
  var position;
21244
21566
  if (!ctrlOrMeta ||
21245
21567
  !(range = editor.getSelectionRange()) ||
@@ -21279,6 +21601,7 @@ exports.CursorFeatures = {
21279
21601
  Object.defineProperty(exports, "__esModule", { value: true });
21280
21602
  exports.EntityFeatures = void 0;
21281
21603
  var roosterjs_editor_dom_1 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
21604
+ var roosterjs_editor_dom_2 = __webpack_require__(/*! roosterjs-editor-dom */ "./packages/roosterjs-editor-dom/lib/index.ts");
21282
21605
  /**
21283
21606
  * A content edit feature to trigger EntityOperation event with operation "Click" when user
21284
21607
  * clicks on a readonly entity.
@@ -21302,13 +21625,13 @@ var EscapeFromEntityFeature = {
21302
21625
  },
21303
21626
  };
21304
21627
  function cacheGetReadonlyEntityElement(event, editor, operation) {
21305
- var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'READONLY_ENTITY_ELEMENT', function () {
21628
+ var element = (0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'READONLY_ENTITY_ELEMENT', function () {
21306
21629
  var node = event.rawEvent.target;
21307
- var entityElement = node && editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), node);
21630
+ var entityElement = node && editor.getElementAtCursor((0, roosterjs_editor_dom_2.getEntitySelector)(), node);
21308
21631
  return entityElement && !entityElement.isContentEditable ? entityElement : null;
21309
21632
  });
21310
21633
  if (element && operation !== undefined) {
21311
- var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21634
+ var entity = (0, roosterjs_editor_dom_2.getEntityFromElement)(element);
21312
21635
  if (entity) {
21313
21636
  editor.triggerPluginEvent(15 /* EntityOperation */, {
21314
21637
  operation: operation,
@@ -21337,7 +21660,7 @@ var EnterBeforeReadonlyEntityFeature = {
21337
21660
  if (!range) {
21338
21661
  return;
21339
21662
  }
21340
- var node = roosterjs_editor_dom_1.Position.getEnd(range).normalize().node;
21663
+ var node = roosterjs_editor_dom_2.Position.getEnd(range).normalize().node;
21341
21664
  var br = editor.getDocument().createElement('BR');
21342
21665
  (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, node.nextSibling);
21343
21666
  var block = editor.getBlockElementAtNode(node);
@@ -21379,13 +21702,13 @@ var DeleteBeforeEntityFeature = {
21379
21702
  },
21380
21703
  };
21381
21704
  function cacheGetNeighborEntityElement(event, editor, isNext, collapseOnly, operation) {
21382
- var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'NEIGHBOR_ENTITY_ELEMENT_' + isNext + '_' + collapseOnly, function () {
21705
+ var element = (0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'NEIGHBOR_ENTITY_ELEMENT_' + isNext + '_' + collapseOnly, function () {
21383
21706
  var range = editor.getSelectionRange();
21384
21707
  if (!range || (collapseOnly && !range.collapsed)) {
21385
21708
  return null;
21386
21709
  }
21387
21710
  range.commonAncestorContainer.normalize();
21388
- var pos = roosterjs_editor_dom_1.Position.getEnd(range).normalize();
21711
+ var pos = roosterjs_editor_dom_2.Position.getEnd(range).normalize();
21389
21712
  var isAtBeginOrEnd = pos.offset == 0 || pos.isAtEnd;
21390
21713
  var entityNode = null;
21391
21714
  if (isAtBeginOrEnd) {
@@ -21404,12 +21727,12 @@ function cacheGetNeighborEntityElement(event, editor, isNext, collapseOnly, oper
21404
21727
  node = null;
21405
21728
  }
21406
21729
  }
21407
- entityNode = node && editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), node);
21730
+ entityNode = node && editor.getElementAtCursor((0, roosterjs_editor_dom_2.getEntitySelector)(), node);
21408
21731
  }
21409
21732
  return entityNode;
21410
21733
  });
21411
21734
  if (element && operation !== undefined) {
21412
- var entity = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21735
+ var entity = (0, roosterjs_editor_dom_2.getEntityFromElement)(element);
21413
21736
  if (entity) {
21414
21737
  triggerOperation(entity, editor, operation, event);
21415
21738
  }
@@ -21422,15 +21745,17 @@ function cacheGetNeighborEntityElement(event, editor, isNext, collapseOnly, oper
21422
21745
  */
21423
21746
  var MoveBetweenDelimitersFeature = {
21424
21747
  keys: [39 /* RIGHT */, 37 /* LEFT */],
21748
+ allowFunctionKeys: true,
21425
21749
  shouldHandleEvent: function (event, editor) {
21426
- if (!editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21750
+ if (event.rawEvent.altKey ||
21751
+ !editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21427
21752
  return false;
21428
21753
  }
21429
21754
  var element = editor.getElementAtCursor();
21430
21755
  if (!element) {
21431
21756
  return false;
21432
21757
  }
21433
- var isRTL = (0, roosterjs_editor_dom_1.getComputedStyle)(element, 'direction') === 'rtl';
21758
+ var isRTL = (0, roosterjs_editor_dom_2.getComputedStyle)(element, 'direction') === 'rtl';
21434
21759
  var shouldCheckBefore = isRTL == (event.rawEvent.which === 37 /* LEFT */);
21435
21760
  return getIsDelimiterAtCursor(event, editor, shouldCheckBefore);
21436
21761
  },
@@ -21440,8 +21765,8 @@ var MoveBetweenDelimitersFeature = {
21440
21765
  if (!delimiter) {
21441
21766
  return;
21442
21767
  }
21443
- var _a = getRelatedElements(delimiter, checkBefore), delimiterPair = _a.delimiterPair, entity = _a.entity;
21444
- if (delimiterPair && entity && (0, roosterjs_editor_dom_1.matchesSelector)(entity, (0, roosterjs_editor_dom_1.getEntitySelector)())) {
21768
+ var _a = getRelatedElements(delimiter, checkBefore, editor), delimiterPair = _a.delimiterPair, entity = _a.entity;
21769
+ if (delimiterPair && entity && (0, roosterjs_editor_dom_2.matchesSelector)(entity, (0, roosterjs_editor_dom_2.getEntitySelector)())) {
21445
21770
  event.rawEvent.preventDefault();
21446
21771
  editor.runAsync(function () {
21447
21772
  var positionType = checkBefore
@@ -21449,7 +21774,7 @@ var MoveBetweenDelimitersFeature = {
21449
21774
  ? -3 /* After */
21450
21775
  : -1 /* End */
21451
21776
  : -2 /* Before */;
21452
- var position = new roosterjs_editor_dom_1.Position(delimiterPair, positionType);
21777
+ var position = new roosterjs_editor_dom_2.Position(delimiterPair, positionType);
21453
21778
  if (event.rawEvent.shiftKey) {
21454
21779
  var selection = delimiterPair.ownerDocument.getSelection();
21455
21780
  selection === null || selection === void 0 ? void 0 : selection.extend(position.node, position.offset);
@@ -21503,51 +21828,65 @@ function getIsDelimiterAtCursor(event, editor, checkBefore) {
21503
21828
  : position.node == position.element
21504
21829
  ? position.element.childNodes.item(position.offset)
21505
21830
  : position.element;
21506
- var searcher = editor.getContentSearcherOfCursor(event);
21507
21831
  var data = checkBefore
21508
21832
  ? {
21509
21833
  class: "entityDelimiterBefore" /* DELIMITER_BEFORE */,
21510
21834
  pairClass: "entityDelimiterAfter" /* DELIMITER_AFTER */,
21511
- getDelimiterPair: function (element) { var _a; return (_a = element.nextElementSibling) === null || _a === void 0 ? void 0 : _a.nextElementSibling; },
21512
- getNextSibling: function () {
21513
- var _a;
21514
- return (_a = searcher === null || searcher === void 0 ? void 0 : searcher.getInlineElementAfter()) === null || _a === void 0 ? void 0 : _a.getContainerNode();
21515
- },
21516
21835
  isAtEndOrBeginning: position.isAtEnd,
21517
21836
  }
21518
21837
  : {
21519
21838
  class: "entityDelimiterAfter" /* DELIMITER_AFTER */,
21520
21839
  pairClass: "entityDelimiterBefore" /* DELIMITER_BEFORE */,
21521
- getDelimiterPair: function (element) { var _a; return (_a = element.previousElementSibling) === null || _a === void 0 ? void 0 : _a.previousElementSibling; },
21522
- getNextSibling: function () {
21523
- var _a;
21524
- return (_a = searcher === null || searcher === void 0 ? void 0 : searcher.getInlineElementBefore()) === null || _a === void 0 ? void 0 : _a.getContainerNode();
21525
- },
21526
21840
  isAtEndOrBeginning: position.offset == 0,
21527
21841
  };
21528
- var sibling = data.getNextSibling();
21842
+ var sibling = getNextSibling(editor, focusedElement, checkBefore);
21529
21843
  if (data.isAtEndOrBeginning && sibling) {
21530
21844
  var elAtCursor = editor.getElementAtCursor('.' + data.class, sibling);
21531
21845
  if (elAtCursor && !!shouldHandle(elAtCursor)) {
21532
21846
  return true;
21533
21847
  }
21534
21848
  }
21535
- var entityAtCursor = editor.getElementAtCursor('.' + data.class, focusedElement);
21849
+ var entityAtCursor = focusedElement && editor.getElementAtCursor('.' + data.class, focusedElement);
21536
21850
  return !!shouldHandle(entityAtCursor);
21537
21851
  function shouldHandle(element) {
21538
- var _a;
21539
- return (element &&
21540
- (((_a = data.getDelimiterPair(element)) === null || _a === void 0 ? void 0 : _a.className) || '').indexOf(data.pairClass) > -1 &&
21852
+ if (!element) {
21853
+ return false;
21854
+ }
21855
+ var delimiterPair = getRelatedElements(element, checkBefore, editor).delimiterPair;
21856
+ return (delimiterPair &&
21857
+ (delimiterPair.className || '').indexOf(data.pairClass) > -1 &&
21541
21858
  cacheDelimiter(event, checkBefore, element));
21542
21859
  }
21543
21860
  }
21861
+ function getNextSibling(editor, element, checkBefore) {
21862
+ var traverser = getBlockTraverser(editor, element);
21863
+ if (!traverser) {
21864
+ return undefined;
21865
+ }
21866
+ var traverseFn = function (t) {
21867
+ return checkBefore ? t.getNextInlineElement() : t.getPreviousInlineElement();
21868
+ };
21869
+ var currentInline = traverser.currentInlineElement;
21870
+ while (currentInline && currentInline.getContainerNode() === element) {
21871
+ currentInline = traverseFn(traverser);
21872
+ }
21873
+ return currentInline === null || currentInline === void 0 ? void 0 : currentInline.getContainerNode();
21874
+ }
21875
+ function getBlockTraverser(editor, element) {
21876
+ var _a;
21877
+ if (!element) {
21878
+ return undefined;
21879
+ }
21880
+ var blockElement = (_a = editor.getBlockElementAtNode(element)) === null || _a === void 0 ? void 0 : _a.getStartNode();
21881
+ return blockElement ? roosterjs_editor_dom_1.ContentTraverser.createBodyTraverser(blockElement, element) : undefined;
21882
+ }
21544
21883
  function cacheDelimiter(event, checkBefore, delimiter) {
21545
- return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'delimiter_cache_key_' + checkBefore, function () { return delimiter; });
21884
+ return (0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'delimiter_cache_key_' + checkBefore, function () { return delimiter; });
21546
21885
  }
21547
21886
  function cacheEntityBetweenDelimiter(event, editor, checkBefore, entity, operation) {
21548
- var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'entity_delimiter_cache_key_' + checkBefore, function () { return entity && editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), entity); });
21887
+ var element = (0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'entity_delimiter_cache_key_' + checkBefore, function () { return entity && editor.getElementAtCursor((0, roosterjs_editor_dom_2.getEntitySelector)(), entity); });
21549
21888
  if (element && operation !== undefined) {
21550
- var entity_1 = (0, roosterjs_editor_dom_1.getEntityFromElement)(element);
21889
+ var entity_1 = (0, roosterjs_editor_dom_2.getEntityFromElement)(element);
21551
21890
  if (entity_1) {
21552
21891
  triggerOperation(entity_1, editor, operation, event);
21553
21892
  }
@@ -21562,7 +21901,7 @@ function triggerOperation(entity, editor, operation, event) {
21562
21901
  entity: entity,
21563
21902
  });
21564
21903
  if (entity.isReadonly &&
21565
- !(0, roosterjs_editor_dom_1.isBlockElement)(entity.wrapper) &&
21904
+ !(0, roosterjs_editor_dom_2.isBlockElement)(entity.wrapper) &&
21566
21905
  editor.isFeatureEnabled("InlineEntityReadOnlyDelimiters" /* InlineEntityReadOnlyDelimiters */)) {
21567
21906
  if (event.rawEvent.defaultPrevented) {
21568
21907
  editor.runAsync(function () {
@@ -21570,41 +21909,58 @@ function triggerOperation(entity, editor, operation, event) {
21570
21909
  removeDelimiters(nextElementSibling, previousElementSibling);
21571
21910
  }
21572
21911
  else {
21573
- var delimiterAfter = (0, roosterjs_editor_dom_1.addDelimiters)(entity.wrapper)[0];
21912
+ var delimiterAfter = (0, roosterjs_editor_dom_2.addDelimiters)(entity.wrapper)[0];
21574
21913
  if (delimiterAfter) {
21575
21914
  editor.select(delimiterAfter, -3 /* After */);
21576
21915
  }
21577
21916
  }
21578
21917
  });
21579
21918
  }
21580
- else if ((0, roosterjs_editor_dom_1.getDelimiterFromElement)(nextElementSibling) &&
21581
- (0, roosterjs_editor_dom_1.getDelimiterFromElement)(previousElementSibling)) {
21582
- editor.select((0, roosterjs_editor_dom_1.createRange)(previousElementSibling, nextElementSibling));
21919
+ else if ((0, roosterjs_editor_dom_2.getDelimiterFromElement)(nextElementSibling) &&
21920
+ (0, roosterjs_editor_dom_2.getDelimiterFromElement)(previousElementSibling)) {
21921
+ editor.select((0, roosterjs_editor_dom_2.createRange)(previousElementSibling, nextElementSibling));
21583
21922
  }
21584
21923
  }
21585
21924
  }
21586
21925
  function removeDelimiters(nextElementSibling, previousElementSibling) {
21587
21926
  [nextElementSibling, previousElementSibling].forEach(function (sibling) {
21588
21927
  var _a;
21589
- if ((0, roosterjs_editor_dom_1.getDelimiterFromElement)(sibling)) {
21928
+ if ((0, roosterjs_editor_dom_2.getDelimiterFromElement)(sibling)) {
21590
21929
  (_a = sibling === null || sibling === void 0 ? void 0 : sibling.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(sibling);
21591
21930
  }
21592
21931
  });
21593
21932
  }
21594
21933
  function cacheGetCheckBefore(event, checkBefore) {
21595
- return !!(0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'Check_Before', function () { return checkBefore; });
21934
+ return !!(0, roosterjs_editor_dom_2.cacheGetEventData)(event, 'Check_Before', function () { return checkBefore; });
21596
21935
  }
21597
- function getRelatedElements(delimiter, checkBefore) {
21598
- var _a, _b;
21599
- var entity;
21600
- var delimiterPair;
21601
- if (checkBefore) {
21602
- entity = delimiter.nextElementSibling;
21603
- delimiterPair = (_a = entity === null || entity === void 0 ? void 0 : entity.nextElementSibling) !== null && _a !== void 0 ? _a : null;
21936
+ function getRelatedElements(delimiter, checkBefore, editor) {
21937
+ var entity = null;
21938
+ var delimiterPair = null;
21939
+ var traverser = getBlockTraverser(editor, delimiter);
21940
+ if (!traverser) {
21941
+ return { delimiterPair: delimiterPair, entity: entity };
21604
21942
  }
21605
- else {
21606
- entity = delimiter.previousElementSibling;
21607
- delimiterPair = (_b = entity === null || entity === void 0 ? void 0 : entity.previousElementSibling) !== null && _b !== void 0 ? _b : null;
21943
+ var selector = "." + (checkBefore ? "entityDelimiterAfter" /* DELIMITER_AFTER */ : "entityDelimiterBefore" /* DELIMITER_BEFORE */);
21944
+ var traverseFn = function (t) {
21945
+ return checkBefore ? t.getNextInlineElement() : t.getPreviousInlineElement();
21946
+ };
21947
+ var getElementFromInline = function (element, selector) {
21948
+ var _a;
21949
+ var node = element === null || element === void 0 ? void 0 : element.getContainerNode();
21950
+ return (_a = (node && editor.getElementAtCursor(selector, node))) !== null && _a !== void 0 ? _a : null;
21951
+ };
21952
+ var entitySelector = (0, roosterjs_editor_dom_2.getEntitySelector)();
21953
+ var current = traverser.currentInlineElement;
21954
+ while (current && (!entity || !delimiterPair)) {
21955
+ entity = entity || getElementFromInline(current, entitySelector);
21956
+ delimiterPair = delimiterPair || getElementFromInline(current, selector);
21957
+ // If we found the entity but the next inline after the entity is not a delimiter,
21958
+ // it means that the delimiter pair got removed or is invalid, return null instead.
21959
+ if (entity && !delimiterPair && !getElementFromInline(current, entitySelector)) {
21960
+ delimiterPair = null;
21961
+ break;
21962
+ }
21963
+ current = traverseFn(traverser);
21608
21964
  }
21609
21965
  return { entity: entity, delimiterPair: delimiterPair };
21610
21966
  }
@@ -21655,8 +22011,10 @@ var shouldHandleIndentationEvent = function (indenting) { return function (event
21655
22011
  cacheGetListElement(event, editor));
21656
22012
  }; };
21657
22013
  var handleIndentationEvent = function (indenting) { return function (event, editor) {
22014
+ var currentElement = null;
21658
22015
  var isRTL = event.rawEvent.keyCode !== 9 /* TAB */ &&
21659
- (0, roosterjs_editor_dom_1.getComputedStyle)(editor.getElementAtCursor(), 'direction') == 'rtl';
22016
+ (currentElement = editor.getElementAtCursor()) &&
22017
+ (0, roosterjs_editor_dom_1.getComputedStyle)(currentElement, 'direction') == 'rtl';
21660
22018
  (0, roosterjs_editor_api_1.setIndentation)(editor, isRTL == indenting ? 1 /* Decrease */ : 0 /* Increase */);
21661
22019
  event.rawEvent.preventDefault();
21662
22020
  }; };
@@ -21664,17 +22022,34 @@ var handleIndentationEvent = function (indenting) { return function (event, edit
21664
22022
  * IndentWhenTab edit feature, provides the ability to indent current list when user press TAB
21665
22023
  */
21666
22024
  var IndentWhenTab = {
21667
- keys: [9 /* TAB */, 39 /* RIGHT */],
22025
+ keys: [9 /* TAB */],
21668
22026
  shouldHandleEvent: shouldHandleIndentationEvent(true),
21669
22027
  handleEvent: handleIndentationEvent(true),
21670
- allowFunctionKeys: true,
21671
- defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
21672
22028
  };
21673
22029
  /**
21674
22030
  * OutdentWhenShiftTab edit feature, provides the ability to outdent current list when user press Shift+TAB
21675
22031
  */
21676
22032
  var OutdentWhenShiftTab = {
21677
- keys: [9 /* TAB */, 37 /* LEFT */],
22033
+ keys: [9 /* TAB */],
22034
+ shouldHandleEvent: shouldHandleIndentationEvent(false),
22035
+ handleEvent: handleIndentationEvent(false),
22036
+ allowFunctionKeys: true,
22037
+ };
22038
+ /**
22039
+ * indentWhenAltShiftRight edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Right
22040
+ */
22041
+ var IndentWhenAltShiftRight = {
22042
+ keys: [39 /* RIGHT */],
22043
+ shouldHandleEvent: shouldHandleIndentationEvent(true),
22044
+ handleEvent: handleIndentationEvent(true),
22045
+ allowFunctionKeys: true,
22046
+ defaultDisabled: roosterjs_editor_dom_1.Browser.isMac,
22047
+ };
22048
+ /**
22049
+ * outdentWhenAltShiftLeft edit feature, provides the ability to indent or outdent current list when user press Alt+shift+Left
22050
+ */
22051
+ var OutdentWhenAltShiftLeft = {
22052
+ keys: [37 /* LEFT */],
21678
22053
  shouldHandleEvent: shouldHandleIndentationEvent(false),
21679
22054
  handleEvent: handleIndentationEvent(false),
21680
22055
  allowFunctionKeys: true,
@@ -21687,16 +22062,16 @@ var OutdentWhenShiftTab = {
21687
22062
  var MergeInNewLine = {
21688
22063
  keys: [8 /* BACKSPACE */],
21689
22064
  shouldHandleEvent: function (event, editor) {
21690
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22065
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21691
22066
  var range = editor.getSelectionRange();
21692
22067
  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);
21693
22068
  },
21694
22069
  handleEvent: function (event, editor) {
21695
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21696
- if (li.previousSibling) {
22070
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22071
+ if (li === null || li === void 0 ? void 0 : li.previousSibling) {
21697
22072
  (0, roosterjs_editor_api_1.blockFormat)(editor, function (region, start, end) {
21698
- var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li);
21699
- if (vList) {
22073
+ var vList = (0, roosterjs_editor_dom_1.createVListFromRegion)(region, false /*includeSiblingList*/, li !== null && li !== void 0 ? li : undefined);
22074
+ if (vList && start && end) {
21700
22075
  vList.setIndentation(start, end, 1 /* Decrease */, true /*softOutdent*/);
21701
22076
  vList.writeBack(editor.isFeatureEnabled("ReuseAllAncestorListElements" /* ReuseAllAncestorListElements */));
21702
22077
  event.rawEvent.preventDefault();
@@ -21716,7 +22091,7 @@ var MergeInNewLine = {
21716
22091
  var OutdentWhenBackOn1stEmptyLine = {
21717
22092
  keys: [8 /* BACKSPACE */],
21718
22093
  shouldHandleEvent: function (event, editor) {
21719
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22094
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21720
22095
  return (li &&
21721
22096
  (0, roosterjs_editor_dom_1.isNodeEmpty)(li) &&
21722
22097
  !li.previousSibling &&
@@ -21731,12 +22106,13 @@ var OutdentWhenBackOn1stEmptyLine = {
21731
22106
  var MaintainListChainWhenDelete = {
21732
22107
  keys: [46 /* DELETE */],
21733
22108
  shouldHandleEvent: function (event, editor) {
21734
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
21735
- if (li) {
22109
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
22110
+ var range = editor.getSelectionRange();
22111
+ if (li || !range) {
21736
22112
  return false;
21737
22113
  }
21738
- var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(editor.getSelectionRange()).isAtEnd;
21739
- var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : null;
22114
+ var isAtEnd = roosterjs_editor_dom_1.Position.getEnd(range).isAtEnd;
22115
+ var nextSibling = isAtEnd ? getCacheNextSibling(event, editor) : undefined;
21740
22116
  var isAtEndAndBeforeLI = editor.getElementAtCursor('LI', nextSibling, event);
21741
22117
  return isAtEndAndBeforeLI;
21742
22118
  },
@@ -21752,11 +22128,11 @@ var MaintainListChainWhenDelete = {
21752
22128
  var OutdentWhenEnterOnEmptyLine = {
21753
22129
  keys: [13 /* ENTER */],
21754
22130
  shouldHandleEvent: function (event, editor) {
21755
- var li = editor.getElementAtCursor('LI', null /*startFrom*/, event);
22131
+ var li = editor.getElementAtCursor('LI', undefined /*startFrom*/, event);
21756
22132
  return !event.rawEvent.shiftKey && li && (0, roosterjs_editor_dom_1.isNodeEmpty)(li);
21757
22133
  },
21758
22134
  handleEvent: function (event, editor) {
21759
- editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22135
+ editor.addUndoSnapshot(function () { return toggleListAndPreventDefault(event, editor, false /* includeSiblingLists */); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21760
22136
  },
21761
22137
  defaultDisabled: !roosterjs_editor_dom_1.Browser.isIE && !roosterjs_editor_dom_1.Browser.isChrome,
21762
22138
  };
@@ -21778,9 +22154,10 @@ function isAListPattern(textBeforeCursor) {
21778
22154
  var AutoBullet = {
21779
22155
  keys: [32 /* SPACE */],
21780
22156
  shouldHandleEvent: function (event, editor) {
22157
+ var searcher;
21781
22158
  if (!cacheGetListElement(event, editor) &&
21782
- !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */)) {
21783
- var searcher = editor.getContentSearcherOfCursor(event);
22159
+ !editor.isFeatureEnabled("AutoFormatList" /* AutoFormatList */) &&
22160
+ (searcher = editor.getContentSearcherOfCursor(event))) {
21784
22161
  var textBeforeCursor = searcher.getSubStringBefore(4);
21785
22162
  // Auto list is triggered if:
21786
22163
  // 1. Text before cursor exactly matches '*', '-' or '1.'
@@ -21796,6 +22173,9 @@ var AutoBullet = {
21796
22173
  var _a;
21797
22174
  var regions;
21798
22175
  var searcher = editor.getContentSearcherOfCursor();
22176
+ if (!searcher) {
22177
+ return;
22178
+ }
21799
22179
  var textBeforeCursor = searcher.getSubStringBefore(4);
21800
22180
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21801
22181
  if (!textRange) {
@@ -21816,7 +22196,7 @@ var AutoBullet = {
21816
22196
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, num);
21817
22197
  }
21818
22198
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21819
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22199
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21820
22200
  },
21821
22201
  };
21822
22202
  /**
@@ -21838,15 +22218,18 @@ var AutoBulletList = {
21838
22218
  editor.addUndoSnapshot(function () {
21839
22219
  var _a;
21840
22220
  var searcher = editor.getContentSearcherOfCursor();
22221
+ if (!searcher) {
22222
+ return;
22223
+ }
21841
22224
  var textBeforeCursor = searcher.getSubStringBefore(5);
21842
22225
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21843
22226
  var listStyle = (0, getAutoBulletListStyle_1.default)(textBeforeCursor);
21844
22227
  if (textRange) {
21845
22228
  prepareAutoBullet(editor, textRange);
21846
- (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle, 'autoToggleList' /** apiNameOverride */);
22229
+ (0, roosterjs_editor_api_1.toggleBullet)(editor, listStyle !== null && listStyle !== void 0 ? listStyle : undefined, 'autoToggleList' /** apiNameOverride */);
21847
22230
  }
21848
22231
  (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21849
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22232
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21850
22233
  },
21851
22234
  };
21852
22235
  /**
@@ -21866,8 +22249,11 @@ var AutoNumberingList = {
21866
22249
  editor.insertContent('&nbsp;');
21867
22250
  event.rawEvent.preventDefault();
21868
22251
  editor.addUndoSnapshot(function () {
21869
- var _a;
22252
+ var _a, _b;
21870
22253
  var searcher = editor.getContentSearcherOfCursor();
22254
+ if (!searcher) {
22255
+ return;
22256
+ }
21871
22257
  var textBeforeCursor = searcher.getSubStringBefore(5);
21872
22258
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21873
22259
  if (textRange) {
@@ -21875,19 +22261,20 @@ var AutoNumberingList = {
21875
22261
  ? 1
21876
22262
  : parseInt(textBeforeCursor);
21877
22263
  var isLi = getPreviousListItem(editor, textRange);
21878
- var listStyle = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor);
22264
+ var listStyle = (_a = (0, getAutoNumberingListStyle_1.default)(textBeforeCursor)) !== null && _a !== void 0 ? _a : undefined;
21879
22265
  prepareAutoBullet(editor, textRange);
21880
22266
  (0, roosterjs_editor_api_1.toggleNumbering)(editor, isLi && number !== 1 ? undefined : number /** startNumber */, listStyle, 'autoToggleList' /** apiNameOverride */);
21881
22267
  }
21882
- (_a = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _a === void 0 ? void 0 : _a.deleteContents();
21883
- }, null /*changeSource*/, true /*canUndoByBackspace*/);
22268
+ (_b = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/)) === null || _b === void 0 ? void 0 : _b.deleteContents();
22269
+ }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
21884
22270
  },
21885
22271
  };
21886
22272
  var getPreviousListItem = function (editor, textRange) {
22273
+ var _a;
21887
22274
  var blockElement = editor
21888
22275
  .getBodyTraverser(textRange === null || textRange === void 0 ? void 0 : textRange.startContainer)
21889
22276
  .getPreviousBlockElement();
21890
- var previousNode = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode();
22277
+ var previousNode = (_a = blockElement === null || blockElement === void 0 ? void 0 : blockElement.getEndNode()) !== null && _a !== void 0 ? _a : null;
21891
22278
  return (0, roosterjs_editor_dom_1.getTagOfNode)(previousNode) === 'LI' ? previousNode : undefined;
21892
22279
  };
21893
22280
  var getPreviousListType = function (editor, textRange, listType) {
@@ -21935,13 +22322,14 @@ function getCacheNextSibling(event, editor) {
21935
22322
  var element = (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'nextSibling', function () {
21936
22323
  var _a;
21937
22324
  var range = editor.getSelectionRange();
21938
- var pos = roosterjs_editor_dom_1.Position.getEnd(range).normalize();
21939
- var traverser = editor.getBodyTraverser(pos.node);
22325
+ var pos = range && roosterjs_editor_dom_1.Position.getEnd(range).normalize();
22326
+ var traverser = pos && editor.getBodyTraverser(pos.node);
21940
22327
  return (_a = traverser === null || traverser === void 0 ? void 0 : traverser.getNextBlockElement()) === null || _a === void 0 ? void 0 : _a.getStartNode();
21941
22328
  });
21942
22329
  return element;
21943
22330
  }
21944
22331
  function prepareAutoBullet(editor, range) {
22332
+ var _a;
21945
22333
  var block = editor.getBlockElementAtNode(range.startContainer);
21946
22334
  var endNode = block === null || block === void 0 ? void 0 : block.getEndNode();
21947
22335
  if (endNode && (0, roosterjs_editor_dom_1.getTagOfNode)(endNode) != 'BR') {
@@ -21950,7 +22338,7 @@ function prepareAutoBullet(editor, range) {
21950
22338
  endNode.appendChild(br);
21951
22339
  }
21952
22340
  else {
21953
- endNode.parentNode.insertBefore(br, endNode.nextSibling);
22341
+ (_a = endNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(br, endNode.nextSibling);
21954
22342
  }
21955
22343
  editor.select(range.startContainer, range.startOffset);
21956
22344
  }
@@ -21962,19 +22350,22 @@ function toggleListAndPreventDefault(event, editor, includeSiblingLists) {
21962
22350
  var listElement = listInfo[0];
21963
22351
  var tag = (0, roosterjs_editor_dom_1.getTagOfNode)(listElement);
21964
22352
  if (tag == 'UL' || tag == 'OL') {
21965
- (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, null /* startNumber */, includeSiblingLists);
22353
+ (0, roosterjs_editor_api_1.toggleListType)(editor, tag == 'UL' ? 2 /* Unordered */ : 1 /* Ordered */, undefined /* startNumber */, includeSiblingLists);
21966
22354
  }
21967
22355
  editor.focus();
21968
22356
  event.rawEvent.preventDefault();
21969
22357
  }
21970
22358
  }
21971
22359
  function cacheGetListElement(event, editor) {
21972
- var li = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
22360
+ var li = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
21973
22361
  var listElement = li && (0, roosterjs_editor_dom_1.getTagOfNode)(li) == 'LI' && editor.getElementAtCursor('UL,OL', li);
21974
22362
  return listElement ? [listElement, li] : null;
21975
22363
  }
21976
22364
  function shouldTriggerList(event, editor, getListStyle, listType) {
21977
22365
  var searcher = editor.getContentSearcherOfCursor(event);
22366
+ if (!searcher) {
22367
+ return false;
22368
+ }
21978
22369
  var textBeforeCursor = searcher.getSubStringBefore(4);
21979
22370
  var traverser = editor.getBlockTraverser();
21980
22371
  var text = traverser && traverser.currentBlockElement
@@ -21983,9 +22374,9 @@ function shouldTriggerList(event, editor, getListStyle, listType) {
21983
22374
  var isATheBeginning = text && text === textBeforeCursor;
21984
22375
  var listChains = getListChains(editor);
21985
22376
  var textRange = searcher.getRangeFromText(textBeforeCursor, true /*exactMatch*/);
21986
- var previousListType = getPreviousListType(editor, textRange, listType);
22377
+ var previousListType = textRange && getPreviousListType(editor, textRange, listType);
21987
22378
  var isFirstItem = isFirstItemOfAList(textBeforeCursor);
21988
- var listStyle = getListStyle(textBeforeCursor, listChains, previousListType);
22379
+ var listStyle = getListStyle(textBeforeCursor, listChains, previousListType !== null && previousListType !== void 0 ? previousListType : undefined);
21989
22380
  var shouldTriggerNewListStyle = isFirstItem ||
21990
22381
  !previousListType ||
21991
22382
  previousListType === listStyle ||
@@ -22061,6 +22452,8 @@ exports.ListFeatures = {
22061
22452
  autoNumberingList: AutoNumberingList,
22062
22453
  autoBulletList: AutoBulletList,
22063
22454
  mergeListOnBackspaceAfterList: MergeListOnBackspaceAfterList,
22455
+ outdentWhenAltShiftLeft: OutdentWhenAltShiftLeft,
22456
+ indentWhenAltShiftRight: IndentWhenAltShiftRight,
22064
22457
  };
22065
22458
  function isList(element) {
22066
22459
  return (!!element &&
@@ -22101,8 +22494,8 @@ function generateBasicMarkdownFeature(key, triggerCharacter, elementTag, useShif
22101
22494
  function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22102
22495
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'MARKDOWN_RANGE', function () {
22103
22496
  var searcher = editor.getContentSearcherOfCursor(event);
22104
- var startPosition;
22105
- var endPosition;
22497
+ var startPosition = null;
22498
+ var endPosition = null;
22106
22499
  searcher === null || searcher === void 0 ? void 0 : searcher.forEachTextInlineElement(function (textInlineElement) {
22107
22500
  if (endPosition && startPosition) {
22108
22501
  return true;
@@ -22140,12 +22533,15 @@ function cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter) {
22140
22533
  }
22141
22534
  }
22142
22535
  });
22143
- return !!startPosition && !!endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22536
+ return startPosition && endPosition && (0, roosterjs_editor_dom_1.createRange)(startPosition, endPosition);
22144
22537
  });
22145
22538
  }
22146
22539
  function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22147
22540
  editor.addUndoSnapshot(function () {
22148
22541
  var range = cacheGetRangeForMarkdownOperation(event, editor, triggerCharacter);
22542
+ if (!range) {
22543
+ return;
22544
+ }
22149
22545
  var lastTypedTriggerPosition = new roosterjs_editor_dom_1.Position(range.endContainer, -1 /* End */);
22150
22546
  var hasLastTypedTrigger = range.endOffset + 1 <= lastTypedTriggerPosition.offset;
22151
22547
  if (!!range && hasLastTypedTrigger) {
@@ -22153,7 +22549,7 @@ function handleMarkdownEvent(event, editor, triggerCharacter, elementTag) {
22153
22549
  var textContentRange = range.cloneRange();
22154
22550
  textContentRange.setStart(textContentRange.startContainer, textContentRange.startOffset + 1);
22155
22551
  var text = textContentRange.extractContents().textContent;
22156
- var textNode = editor.getDocument().createTextNode(text);
22552
+ var textNode = editor.getDocument().createTextNode(text !== null && text !== void 0 ? text : '');
22157
22553
  // extract content and put it into a new element.
22158
22554
  var elementToWrap = (0, roosterjs_editor_dom_1.wrap)(textNode, elementTag);
22159
22555
  //include last typed character
@@ -22237,7 +22633,7 @@ var UnquoteWhenEnterOnEmptyLine = {
22237
22633
  return !shift && childOfQuote && (0, roosterjs_editor_dom_1.isNodeEmpty)(childOfQuote);
22238
22634
  },
22239
22635
  handleEvent: function (event, editor) {
22240
- return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, null /*changeSource*/, true /*canUndoByBackspace*/);
22636
+ return editor.addUndoSnapshot(function () { return splitQuote(event, editor); }, undefined /*changeSource*/, true /*canUndoByBackspace*/);
22241
22637
  },
22242
22638
  };
22243
22639
  function cacheGetQuoteChild(event, editor) {
@@ -22259,14 +22655,15 @@ function cacheGetQuoteChild(event, editor) {
22259
22655
  function splitQuote(event, editor) {
22260
22656
  editor.addUndoSnapshot(function () {
22261
22657
  var childOfQuote = cacheGetQuoteChild(event, editor);
22262
- var parent;
22263
- var shouldClearFormat;
22658
+ if (!childOfQuote) {
22659
+ return;
22660
+ }
22264
22661
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childOfQuote) == QUOTE_TAG) {
22265
22662
  childOfQuote = (0, roosterjs_editor_dom_1.wrap)((0, roosterjs_editor_dom_1.toArray)(childOfQuote.childNodes));
22266
22663
  }
22267
- parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22268
- shouldClearFormat = isStyledBlockquote(parent);
22269
- var newParent = (0, roosterjs_editor_dom_1.unwrap)(parent);
22664
+ var parent = (0, roosterjs_editor_dom_1.splitBalancedNodeRange)(childOfQuote);
22665
+ var shouldClearFormat = !!parent && isStyledBlockquote(parent);
22666
+ var newParent = parent && (0, roosterjs_editor_dom_1.unwrap)(parent);
22270
22667
  editor.select(childOfQuote, 0 /* Begin */);
22271
22668
  if (shouldClearFormat) {
22272
22669
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(newParent, 'HTMLLIElement')) {
@@ -22432,7 +22829,8 @@ var InsertLineBeforeStructuredNodeFeature = {
22432
22829
  var element = cacheGetStructuredElement(event, editor);
22433
22830
  var div = (0, roosterjs_editor_dom_1.createElement)(1 /* EmptyLine */, editor.getDocument());
22434
22831
  editor.addUndoSnapshot(function () {
22435
- element.parentNode.insertBefore(div, element);
22832
+ var _a;
22833
+ (_a = element === null || element === void 0 ? void 0 : element.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(div, element);
22436
22834
  // Select the new line when we are in table. This is the same behavior with Word
22437
22835
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(element) == 'TABLE') {
22438
22836
  editor.select(new roosterjs_editor_dom_1.Position(div, 0 /* Begin */).normalize());
@@ -22490,21 +22888,26 @@ var TabInTable = {
22490
22888
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22491
22889
  },
22492
22890
  handleEvent: function (event, editor) {
22891
+ var _a, _b, _c;
22493
22892
  var shift = event.rawEvent.shiftKey;
22494
22893
  var td = cacheGetTableCell(event, editor);
22894
+ if (!td) {
22895
+ return;
22896
+ }
22495
22897
  var vtable = cacheVTable(event, td);
22496
- for (var step = shift ? -1 : 1, row = vtable.row, col = vtable.col + step;; col += step) {
22497
- if (col < 0 || col >= vtable.cells[row].length) {
22898
+ 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) {
22899
+ var tableCells = (_c = vtable.cells) !== null && _c !== void 0 ? _c : [];
22900
+ if (col < 0 || col >= tableCells[row].length) {
22498
22901
  row += step;
22499
22902
  if (row < 0) {
22500
22903
  editor.select(vtable.table, -2 /* Before */);
22501
22904
  break;
22502
22905
  }
22503
- else if (row >= vtable.cells.length) {
22906
+ else if (row >= tableCells.length) {
22504
22907
  (0, roosterjs_editor_api_1.editTable)(editor, 1 /* InsertBelow */);
22505
22908
  break;
22506
22909
  }
22507
- col = shift ? vtable.cells[row].length - 1 : 0;
22910
+ col = shift ? tableCells[row].length - 1 : 0;
22508
22911
  }
22509
22912
  var cell = vtable.getCell(row, col);
22510
22913
  if (cell.td) {
@@ -22530,6 +22933,9 @@ var IndentTableOnTab = {
22530
22933
  var shift = event.rawEvent.shiftKey;
22531
22934
  var selection = editor.getSelectionRangeEx();
22532
22935
  var td = cacheGetTableCell(event, editor);
22936
+ if (!td) {
22937
+ return;
22938
+ }
22533
22939
  var vtable = cacheVTable(event, td);
22534
22940
  if (shift && editor.getElementAtCursor('blockquote', vtable.table, event)) {
22535
22941
  (0, roosterjs_editor_api_1.setIndentation)(editor, 1 /* Decrease */);
@@ -22537,7 +22943,9 @@ var IndentTableOnTab = {
22537
22943
  else if (!shift) {
22538
22944
  (0, roosterjs_editor_api_1.setIndentation)(editor, 0 /* Increase */);
22539
22945
  }
22540
- editor.select(selection.table, selection.coordinates);
22946
+ if (selection.coordinates) {
22947
+ editor.select(selection.table, selection.coordinates);
22948
+ }
22541
22949
  });
22542
22950
  },
22543
22951
  };
@@ -22551,8 +22959,11 @@ var UpDownInTable = {
22551
22959
  return cacheGetTableCell(event, editor) && !cacheIsWholeTableSelected(event, editor);
22552
22960
  },
22553
22961
  handleEvent: function (event, editor) {
22554
- var _a;
22962
+ var _a, _b, _c;
22555
22963
  var td = cacheGetTableCell(event, editor);
22964
+ if (!td) {
22965
+ return;
22966
+ }
22556
22967
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22557
22968
  var isUp = event.rawEvent.which == 38 /* UP */;
22558
22969
  var step = isUp ? -1 : 1;
@@ -22561,8 +22972,8 @@ var UpDownInTable = {
22561
22972
  var targetTd = null;
22562
22973
  if (selection) {
22563
22974
  var anchorNode_1 = selection.anchorNode, anchorOffset_1 = selection.anchorOffset;
22564
- for (var row = vtable.row; row >= 0 && row < vtable.cells.length; row += step) {
22565
- var cell = vtable.getCell(row, vtable.col);
22975
+ for (var row = (_b = vtable.row) !== null && _b !== void 0 ? _b : 0; row >= 0 && vtable.cells && row < vtable.cells.length; row += step) {
22976
+ var cell = vtable.getCell(row, (_c = vtable.col) !== null && _c !== void 0 ? _c : 0);
22566
22977
  if (cell.td && cell.td != td) {
22567
22978
  targetTd = cell.td;
22568
22979
  break;
@@ -22583,7 +22994,9 @@ var UpDownInTable = {
22583
22994
  ? new roosterjs_editor_dom_1.Position(newPos.node, newPos.isAtEnd ? -3 /* After */ : -2 /* Before */)
22584
22995
  : newPos;
22585
22996
  var selection_1 = (_a = editor.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
22586
- selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
22997
+ if (anchorNode_1) {
22998
+ selection_1 === null || selection_1 === void 0 ? void 0 : selection_1.setBaseAndExtent(anchorNode_1, anchorOffset_1, newPos.node, newPos.offset);
22999
+ }
22587
23000
  }
22588
23001
  else {
22589
23002
  editor.select(newPos.normalize());
@@ -22606,6 +23019,9 @@ var DeleteTableWithBackspace = {
22606
23019
  },
22607
23020
  handleEvent: function (event, editor) {
22608
23021
  var td = cacheGetTableCell(event, editor);
23022
+ if (!td) {
23023
+ return;
23024
+ }
22609
23025
  var vtable = new roosterjs_editor_dom_1.VTable(td);
22610
23026
  vtable.edit(4 /* DeleteTable */);
22611
23027
  vtable.writeBack();
@@ -22621,9 +23037,13 @@ function cacheGetTableCell(event, editor) {
22621
23037
  function cacheIsWholeTableSelected(event, editor) {
22622
23038
  return (0, roosterjs_editor_dom_1.cacheGetEventData)(event, 'WHOLE_TABLE_SELECTED_FOR_FEATURES', function () {
22623
23039
  var td = cacheGetTableCell(event, editor);
23040
+ if (!td) {
23041
+ return false;
23042
+ }
22624
23043
  var vtable = cacheVTable(event, td);
22625
23044
  var selection = editor.getSelectionRangeEx();
22626
23045
  return (selection.type == 1 /* TableSelection */ &&
23046
+ selection.coordinates &&
22627
23047
  (0, roosterjs_editor_dom_1.isWholeTableSelected)(vtable, selection.coordinates));
22628
23048
  });
22629
23049
  }
@@ -22673,7 +23093,7 @@ var IndentWhenTabText = {
22673
23093
  if (editor.isFeatureEnabled("TabKeyTextFeatures" /* TabKeyTextFeatures */) &&
22674
23094
  !event.rawEvent.shiftKey) {
22675
23095
  var activeElement = editor.getDocument().activeElement;
22676
- var listOrTable = editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event);
23096
+ var listOrTable = editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event);
22677
23097
  var entity = editor.getElementAtCursor((0, roosterjs_editor_dom_1.getEntitySelector)(), undefined /*startFrom*/, event);
22678
23098
  return (!listOrTable &&
22679
23099
  (entity ? entity.isContentEditable : activeElement.isContentEditable));
@@ -22717,8 +23137,8 @@ var OutdentWhenTabText = {
22717
23137
  var selection = editor.getSelectionRangeEx();
22718
23138
  return (selection.type == 0 /* Normal */ &&
22719
23139
  !selection.areAllCollapsed &&
22720
- editor.getElementAtCursor('blockquote', null, event) &&
22721
- !editor.getElementAtCursor('LI,TABLE', null /*startFrom*/, event) &&
23140
+ editor.getElementAtCursor('blockquote', undefined, event) &&
23141
+ !editor.getElementAtCursor('LI,TABLE', undefined /*startFrom*/, event) &&
22722
23142
  shouldSetIndentation(editor, selection.ranges[0]));
22723
23143
  }
22724
23144
  return false;
@@ -22782,9 +23202,12 @@ function isRangeEmpty(range) {
22782
23202
  function insertTab(editor, event) {
22783
23203
  var span = editor.getDocument().createElement('span');
22784
23204
  var searcher = editor.getContentSearcherOfCursor(event);
23205
+ if (!searcher) {
23206
+ return;
23207
+ }
22785
23208
  var charsBefore = searcher.getSubStringBefore(Number.MAX_SAFE_INTEGER);
22786
23209
  var numberOfChars = TAB_SPACES - (charsBefore.length % TAB_SPACES);
22787
- var span2;
23210
+ var span2 = null;
22788
23211
  var textContent = '';
22789
23212
  for (var index = 0; index < numberOfChars; index++) {
22790
23213
  textContent += '&ensp;';
@@ -22841,7 +23264,8 @@ var shortcutFeatures_1 = __webpack_require__(/*! ./features/shortcutFeatures */
22841
23264
  var structuredNodeFeatures_1 = __webpack_require__(/*! ./features/structuredNodeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/structuredNodeFeatures.ts");
22842
23265
  var tableFeatures_1 = __webpack_require__(/*! ./features/tableFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/tableFeatures.ts");
22843
23266
  var textFeatures_1 = __webpack_require__(/*! ./features/textFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/textFeatures.ts");
22844
- 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);
23267
+ var codeFeatures_1 = __webpack_require__(/*! ./features/codeFeatures */ "./packages/roosterjs-editor-plugins/lib/plugins/ContentEdit/features/codeFeatures.ts");
23268
+ 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);
22845
23269
  /**
22846
23270
  * Get all content edit features provided by roosterjs
22847
23271
  */
@@ -22977,7 +23401,8 @@ var identifyNumberingType = function (text, previousListStyle) {
22977
23401
  return 1 /* Decimal */;
22978
23402
  }
22979
23403
  else if (/[a-z]+/g.test(text)) {
22980
- if ((lowerRomanTypes.indexOf(previousListStyle) > -1 &&
23404
+ if ((previousListStyle != undefined &&
23405
+ lowerRomanTypes.indexOf(previousListStyle) > -1 &&
22981
23406
  lowerRomanNumbers.indexOf(text[0]) > -1) ||
22982
23407
  (!previousListStyle && text === 'i')) {
22983
23408
  return 4 /* LowerRoman */;
@@ -22987,7 +23412,8 @@ var identifyNumberingType = function (text, previousListStyle) {
22987
23412
  }
22988
23413
  }
22989
23414
  else if (/[A-Z]+/g.test(text)) {
22990
- if ((upperRomanTypes.indexOf(previousListStyle) > -1 &&
23415
+ if ((previousListStyle != undefined &&
23416
+ upperRomanTypes.indexOf(previousListStyle) > -1 &&
22991
23417
  upperRomanNumbers.indexOf(text[0]) > -1) ||
22992
23418
  (!previousListStyle && text === 'I')) {
22993
23419
  return 5 /* UpperRoman */;
@@ -23901,7 +24327,7 @@ var ImageEdit = /** @class */ (function () {
23901
24327
  }
23902
24328
  var viewport = (_b = _this.editor) === null || _b === void 0 ? void 0 : _b.getVisibleViewport();
23903
24329
  if (rotateHandle && rotateCenter && viewport) {
23904
- (0, Rotator_1.updateRotateHandlePosition)(_this.editInfo, viewport, marginVertical, rotateCenter, rotateHandle);
24330
+ (0, Rotator_1.updateRotateHandlePosition)(viewport, rotateCenter, rotateHandle);
23905
24331
  }
23906
24332
  updateHandleCursor(resizeHandles, angleRad);
23907
24333
  }
@@ -24044,6 +24470,54 @@ var ImageEdit = /** @class */ (function () {
24044
24470
  this.editor.select(this.image);
24045
24471
  }
24046
24472
  };
24473
+ /**
24474
+ * Flip the image.
24475
+ * @param image The image to be flipped
24476
+ * @param direction
24477
+ */
24478
+ ImageEdit.prototype.flipImage = function (image, direction) {
24479
+ var _a;
24480
+ this.image = image;
24481
+ this.editInfo = (0, editInfo_1.getEditInfoFromImage)(image);
24482
+ var angleRad = this.editInfo.angleRad;
24483
+ var isInVerticalPostion = (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||
24484
+ (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);
24485
+ if (isInVerticalPostion) {
24486
+ if (direction === 'horizontal') {
24487
+ this.editInfo.flippedVertical = !this.editInfo.flippedVertical;
24488
+ }
24489
+ else {
24490
+ this.editInfo.flippedHorizontal = !this.editInfo.flippedHorizontal;
24491
+ }
24492
+ }
24493
+ else {
24494
+ if (direction === 'vertical') {
24495
+ this.editInfo.flippedVertical = !this.editInfo.flippedVertical;
24496
+ }
24497
+ else {
24498
+ this.editInfo.flippedHorizontal = !this.editInfo.flippedHorizontal;
24499
+ }
24500
+ }
24501
+ this.createWrapper(4 /* Rotate */);
24502
+ this.updateWrapper();
24503
+ this.setEditingImage(null);
24504
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.select(image);
24505
+ };
24506
+ /**
24507
+ * Rotate the image in radian angle.
24508
+ * @param image The image to be rotated
24509
+ * @param angleRad The angle in radian that the image must be rotated.
24510
+ */
24511
+ ImageEdit.prototype.rotateImage = function (image, angleRad) {
24512
+ var _a;
24513
+ this.image = image;
24514
+ this.editInfo = (0, editInfo_1.getEditInfoFromImage)(image);
24515
+ this.editInfo.angleRad = this.editInfo.angleRad + angleRad;
24516
+ this.createWrapper(4 /* Rotate */);
24517
+ this.updateWrapper();
24518
+ this.setEditingImage(null);
24519
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.select(image);
24520
+ };
24047
24521
  /**
24048
24522
  * Create editing wrapper for the image
24049
24523
  */
@@ -24054,6 +24528,7 @@ var ImageEdit = /** @class */ (function () {
24054
24528
  //Clone the image and insert the clone in a entity
24055
24529
  this.clonedImage = this.image.cloneNode(true);
24056
24530
  this.clonedImage.removeAttribute('id');
24531
+ this.clonedImage.style.removeProperty('max-width');
24057
24532
  this.wrapper = (0, roosterjs_editor_dom_1.createElement)(6 /* ImageEditWrapper */, this.image.ownerDocument);
24058
24533
  (_b = (_a = this.wrapper) === null || _a === void 0 ? void 0 : _a.firstChild) === null || _b === void 0 ? void 0 : _b.appendChild(this.clonedImage);
24059
24534
  this.wrapper.style.display = roosterjs_editor_dom_1.Browser.isSafari ? 'inline-block' : 'inline-flex';
@@ -24062,6 +24537,7 @@ var ImageEdit = /** @class */ (function () {
24062
24537
  // Set image src to original src to help show editing UI, also it will be used when regenerate image dataURL after editing
24063
24538
  if (this.clonedImage) {
24064
24539
  this.clonedImage.src = this.editInfo.src;
24540
+ setFlipped(this.clonedImage, this.editInfo.flippedHorizontal, this.editInfo.flippedVertical);
24065
24541
  this.clonedImage.style.position = 'absolute';
24066
24542
  }
24067
24543
  // Get HTML for all edit elements (resize handle, rotate handle, crop handle and overlay, ...) and create HTML element
@@ -24219,6 +24695,9 @@ function getColorString(color, isDarkMode) {
24219
24695
  }
24220
24696
  return isDarkMode ? color.darkModeColor.trim() : color.lightModeColor.trim();
24221
24697
  }
24698
+ function setFlipped(element, flipppedHorizontally, flipppedVertically) {
24699
+ element.style.transform = "scale(" + (flipppedHorizontally ? '-1' : '1') + ", " + (flipppedVertically ? '-1' : '1') + ")";
24700
+ }
24222
24701
 
24223
24702
 
24224
24703
  /***/ }),
@@ -24361,6 +24840,7 @@ function resizeByPercentage(editor, image, percentage, minWidth, minHeight) {
24361
24840
  editor.addUndoSnapshot(function () {
24362
24841
  (0, applyChange_1.default)(editor, image, editInfo, lastSrc_1 || '', true /*wasResized*/);
24363
24842
  }, "ImageResize" /* ImageResize */);
24843
+ editor.select(image);
24364
24844
  }
24365
24845
  });
24366
24846
  }
@@ -24505,13 +24985,18 @@ function checkEditInfoState(editInfo, compareTo) {
24505
24985
  if (!editInfo || !editInfo.src || ALL_KEYS.some(function (key) { return !isNumber(editInfo[key]); })) {
24506
24986
  return 0 /* Invalid */;
24507
24987
  }
24508
- else if (ROTATE_CROP_KEYS.every(function (key) { return areSameNumber(editInfo[key], 0); })) {
24988
+ else if (ROTATE_CROP_KEYS.every(function (key) { return areSameNumber(editInfo[key], 0); }) &&
24989
+ !editInfo.flippedHorizontal &&
24990
+ !editInfo.flippedVertical &&
24991
+ (!compareTo || (compareTo && editInfo.angleRad === compareTo.angleRad))) {
24509
24992
  return 1 /* ResizeOnly */;
24510
24993
  }
24511
24994
  else if (compareTo &&
24512
24995
  ROTATE_KEYS.every(function (key) { return areSameNumber(editInfo[key], 0); }) &&
24513
24996
  ROTATE_KEYS.every(function (key) { return areSameNumber(compareTo[key], 0); }) &&
24514
- CROP_KEYS.every(function (key) { return areSameNumber(editInfo[key], compareTo[key]); })) {
24997
+ CROP_KEYS.every(function (key) { return areSameNumber(editInfo[key], compareTo[key]); }) &&
24998
+ compareTo.flippedHorizontal === editInfo.flippedHorizontal &&
24999
+ compareTo.flippedVertical === editInfo.flippedVertical) {
24515
25000
  return 2 /* SameWithLast */;
24516
25001
  }
24517
25002
  else {
@@ -24632,6 +25117,7 @@ function generateDataURL(image, editInfo) {
24632
25117
  if (context) {
24633
25118
  context.translate(targetWidth / 2, targetHeight / 2);
24634
25119
  context.rotate(angle);
25120
+ context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);
24635
25121
  context.drawImage(image, naturalWidth * left, naturalHeight * top, imageWidth, imageHeight, -width / 2, -height / 2, width, height);
24636
25122
  }
24637
25123
  return canvas.toDataURL('image/png', 1.0);
@@ -25137,15 +25623,26 @@ exports.Rotator = {
25137
25623
  * Move rotate handle. When image is very close to the border of editor, rotate handle may not be visible.
25138
25624
  * Fix it by reduce the distance from image to rotate handle
25139
25625
  */
25140
- function updateRotateHandlePosition(editInfo, editorRect, marginVertical, rotateCenter, rotateHandle) {
25626
+ function updateRotateHandlePosition(editorRect, rotateCenter, rotateHandle) {
25141
25627
  var rotateHandleRect = rotateHandle.getBoundingClientRect();
25142
25628
  if (rotateHandleRect) {
25143
25629
  var top_1 = rotateHandleRect.top - editorRect.top;
25144
- var angleRad = editInfo.angleRad, heightPx = editInfo.heightPx;
25145
- var cosAngle = Math.cos(angleRad);
25146
- var adjustedDistance = cosAngle <= 0
25147
- ? Number.MAX_SAFE_INTEGER
25148
- : (top_1 + heightPx / 2 + marginVertical) / cosAngle - heightPx / 2;
25630
+ var left = rotateHandleRect.left - editorRect.left;
25631
+ var right = rotateHandleRect.right - editorRect.right;
25632
+ var bottom = rotateHandleRect.bottom - editorRect.bottom;
25633
+ var adjustedDistance = Number.MAX_SAFE_INTEGER;
25634
+ if (top_1 <= 0) {
25635
+ adjustedDistance = top_1;
25636
+ }
25637
+ else if (left <= 0) {
25638
+ adjustedDistance = left;
25639
+ }
25640
+ else if (right >= 0) {
25641
+ adjustedDistance = right;
25642
+ }
25643
+ else if (bottom >= 0) {
25644
+ adjustedDistance = bottom;
25645
+ }
25149
25646
  var rotateGap = Math.max(Math.min(ROTATE_GAP, adjustedDistance), 0);
25150
25647
  var rotateTop = Math.max(Math.min(ROTATE_SIZE, adjustedDistance - rotateGap), 0);
25151
25648
  rotateCenter.style.top = -rotateGap + 'px';
@@ -25365,6 +25862,7 @@ var Paste = /** @class */ (function () {
25365
25862
  if (convertSingleImageBody === void 0) { convertSingleImageBody = false; }
25366
25863
  this.unknownTagReplacement = unknownTagReplacement;
25367
25864
  this.convertSingleImageBody = convertSingleImageBody;
25865
+ this.editor = null;
25368
25866
  }
25369
25867
  /**
25370
25868
  * Get a friendly name of this plugin
@@ -25390,7 +25888,7 @@ var Paste = /** @class */ (function () {
25390
25888
  * @param event PluginEvent object
25391
25889
  */
25392
25890
  Paste.prototype.onPluginEvent = function (event) {
25393
- if (event.eventType == 10 /* BeforePaste */) {
25891
+ if (this.editor && event.eventType == 10 /* BeforePaste */) {
25394
25892
  var fragment = event.fragment, sanitizingOption = event.sanitizingOption;
25395
25893
  var trustedHTMLHandler = this.editor.getTrustedHTMLHandler();
25396
25894
  switch ((0, getPasteSource_1.default)(event, this.convertSingleImageBody)) {
@@ -25399,22 +25897,23 @@ var Paste = /** @class */ (function () {
25399
25897
  (0, convertPastedContentFromWord_1.default)(event);
25400
25898
  break;
25401
25899
  case 1 /* ExcelDesktop */:
25900
+ case 2 /* ExcelOnline */:
25402
25901
  // Handle HTML copied from Excel
25403
25902
  (0, convertPastedContentFromExcel_1.default)(event, trustedHTMLHandler);
25404
25903
  break;
25405
- case 2 /* PowerPointDesktop */:
25904
+ case 3 /* PowerPointDesktop */:
25406
25905
  (0, convertPastedContentFromPowerPoint_1.default)(event, trustedHTMLHandler);
25407
25906
  break;
25408
- case 4 /* WacComponents */:
25907
+ case 5 /* WacComponents */:
25409
25908
  (0, convertPastedContentFromOfficeOnline_1.default)(fragment);
25410
25909
  break;
25411
- case 3 /* GoogleSheets */:
25910
+ case 4 /* GoogleSheets */:
25412
25911
  sanitizingOption.additionalTagReplacements[constants_1.GOOGLE_SHEET_NODE_NAME] = '*';
25413
25912
  break;
25414
- case 6 /* SingleImage */:
25913
+ case 7 /* SingleImage */:
25415
25914
  (0, convertPasteContentForSingleImage_1.default)(event, trustedHTMLHandler);
25416
25915
  break;
25417
- case 5 /* Default */:
25916
+ case 6 /* Default */:
25418
25917
  (0, convertPastedContentForLI_1.default)(fragment);
25419
25918
  (0, handleLineMerge_1.default)(fragment);
25420
25919
  break;
@@ -25509,12 +26008,28 @@ var DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';
25509
26008
  * @param event The BeforePaste event
25510
26009
  */
25511
26010
  function convertPastedContentFromExcel(event, trustedHTMLHandler) {
26011
+ var _a, _b;
25512
26012
  var fragment = event.fragment, sanitizingOption = event.sanitizingOption, htmlBefore = event.htmlBefore, clipboardData = event.clipboardData;
25513
- var html = excelHandler(clipboardData.html, htmlBefore);
25514
- if (clipboardData.html != html) {
26013
+ var fragmentHTML = (_b = (_a = fragment.firstElementChild) === null || _a === void 0 ? void 0 : _a.outerHTML) !== null && _b !== void 0 ? _b : clipboardData.html;
26014
+ var html = fragmentHTML ? excelHandler(fragmentHTML, htmlBefore) : undefined;
26015
+ if (html && fragmentHTML != html) {
25515
26016
  var doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');
25516
26017
  (0, roosterjs_editor_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
25517
26018
  }
26019
+ // For Excel Online
26020
+ var firstChild = fragment.firstChild;
26021
+ if (firstChild && firstChild.childNodes.length > 0 && (0, roosterjs_editor_dom_1.getTagOfNode)(firstChild) == 'DIV') {
26022
+ var tableFound = Array.from(firstChild.childNodes).every(function (child) {
26023
+ // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag
26024
+ return (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'META'
26025
+ ? true
26026
+ : (0, roosterjs_editor_dom_1.getTagOfNode)(child) == 'TABLE' && child == firstChild.lastChild;
26027
+ });
26028
+ // Extract Table from Div
26029
+ if (tableFound && firstChild.lastChild) {
26030
+ event.fragment.replaceChildren(firstChild.lastChild);
26031
+ }
26032
+ }
25518
26033
  (0, roosterjs_editor_dom_1.chainSanitizerCallback)(sanitizingOption.elementCallbacks, 'TD', function (element) {
25519
26034
  if (element.style.borderStyle == 'none') {
25520
26035
  element.style.border = DEFAULT_BORDER_STYLE;
@@ -25628,21 +26143,23 @@ function handleLineMerge(root) {
25628
26143
  }
25629
26144
  exports.default = handleLineMerge;
25630
26145
  function processBlock(block) {
25631
- var _a, _b;
26146
+ var _a, _b, _c;
25632
26147
  var start = block.start, end = block.end;
25633
26148
  if (start == end && (0, roosterjs_editor_dom_1.getTagOfNode)(start) == 'DIV') {
25634
26149
  var node = (0, roosterjs_editor_dom_1.changeElementTag)(start, 'SPAN');
25635
26150
  block.start = node;
25636
26151
  block.end = node;
25637
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
26152
+ if (node && node.lastChild && (0, roosterjs_editor_dom_1.getTagOfNode)(node.lastChild) == 'BR') {
25638
26153
  node.removeChild(node.lastChild);
25639
26154
  }
25640
26155
  }
25641
26156
  else if ((0, roosterjs_editor_dom_1.getTagOfNode)(end) == 'BR') {
25642
- var node = end.ownerDocument.createTextNode('');
25643
- (_a = end.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(node, end);
25644
- block.end = node;
25645
- (_b = end.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(end);
26157
+ var node = (_a = end.ownerDocument) === null || _a === void 0 ? void 0 : _a.createTextNode('');
26158
+ if (node) {
26159
+ (_b = end.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(node, end);
26160
+ block.end = node;
26161
+ (_c = end.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(end);
26162
+ }
25646
26163
  }
25647
26164
  }
25648
26165
  function checkAndAddBr(root, block, isFirst, firstBlock) {
@@ -25667,7 +26184,8 @@ function checkAndAddBr(root, block, isFirst, firstBlock) {
25667
26184
  // If the first block and the last block are Siblings, add a BR before so the only two
25668
26185
  // lines that are being pasted are not merged.
25669
26186
  var previousSibling = (0, roosterjs_editor_dom_1.getPreviousLeafSibling)(root, block.start);
25670
- if (firstBlock.end.contains(previousSibling)) {
26187
+ if (firstBlock.end.contains(previousSibling) &&
26188
+ !(0, roosterjs_editor_dom_1.findClosestElementAncestor)(block.start, root, 'li')) {
25671
26189
  var br = (_c = block.start.ownerDocument) === null || _c === void 0 ? void 0 : _c.createElement('br');
25672
26190
  if (br) {
25673
26191
  (_d = block.start.parentNode) === null || _d === void 0 ? void 0 : _d.insertBefore(br, block.start);
@@ -25729,8 +26247,9 @@ var convertPastedContentFromWordOnline_1 = __webpack_require__(/*! ./convertPast
25729
26247
  */
25730
26248
  function convertPastedContentFromOfficeOnline(fragment) {
25731
26249
  fragment.querySelectorAll(constants_1.WAC_IDENTIFY_SELECTOR).forEach(function (el) {
25732
- el.style.display = null;
25733
- el.style.margin = null;
26250
+ var element = el;
26251
+ element.style.removeProperty('display');
26252
+ element.style.removeProperty('margin');
25734
26253
  });
25735
26254
  // call conversion function if the pasted content is from word online and
25736
26255
  // has list element in the pasted content.
@@ -25810,6 +26329,7 @@ function convertPastedContentFromWordOnline(fragment) {
25810
26329
  sanitizeListItemContainer(fragment);
25811
26330
  var listItemBlocks = getListItemBlocks(fragment);
25812
26331
  listItemBlocks.forEach(function (itemBlock) {
26332
+ var _a, _b, _c;
25813
26333
  // There are cases where consecutive List Elements are separated into different nodes:
25814
26334
  // <div>
25815
26335
  // <div>
@@ -25839,37 +26359,47 @@ function convertPastedContentFromWordOnline(fragment) {
25839
26359
  // Then we are start processing.
25840
26360
  flattenListBlock(fragment, itemBlock);
25841
26361
  // Find the node to insertBefore, which is next sibling node of the end of a listItemBlock.
25842
- itemBlock.insertPositionNode = itemBlock.endElement.nextSibling;
25843
- var convertedListElement;
26362
+ itemBlock.insertPositionNode = (_b = (_a = itemBlock.endElement) === null || _a === void 0 ? void 0 : _a.nextSibling) !== null && _b !== void 0 ? _b : null;
26363
+ var convertedListElement = undefined;
25844
26364
  var doc = fragment.ownerDocument;
25845
26365
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
25846
26366
  var listType = getContainerListType(listItemContainer); // list type that is contained by iterator.
25847
- // Initialize processed element with proper listType if this is the first element
25848
- if (!convertedListElement) {
25849
- convertedListElement = createNewList(listItemContainer, doc, listType);
25850
- }
25851
- // Get all list items(<li>) in the current iterator element.
25852
- var currentListItems = (0, roosterjs_editor_dom_1.toArray)(listItemContainer.querySelectorAll('li'));
25853
- currentListItems.forEach(function (item) {
25854
- // If item is in root level and the type of list changes then
25855
- // insert the current list into body and then reinitialize the convertedListElement
25856
- // Word Online is using data-aria-level to determine the the depth of the list item.
25857
- var itemLevel = parseInt(item.getAttribute('data-aria-level'));
25858
- // In first level list, there are cases where a consecutive list item DIV may have different list type
25859
- // When that happens we need to insert the processed elements into the document, then change the list type
25860
- // and keep the processing going.
25861
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(convertedListElement) != listType && itemLevel == 1) {
25862
- insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26367
+ if (listType) {
26368
+ // Initialize processed element with proper listType if this is the first element
26369
+ if (!convertedListElement) {
25863
26370
  convertedListElement = createNewList(listItemContainer, doc, listType);
25864
26371
  }
25865
- insertListItem(convertedListElement, item, listType, doc);
25866
- });
26372
+ // Get all list items(<li>) in the current iterator element.
26373
+ var currentListItems = (0, roosterjs_editor_dom_1.toArray)(listItemContainer.querySelectorAll('li'));
26374
+ currentListItems.forEach(function (item) {
26375
+ var _a;
26376
+ // If item is in root level and the type of list changes then
26377
+ // insert the current list into body and then reinitialize the convertedListElement
26378
+ // Word Online is using data-aria-level to determine the the depth of the list item.
26379
+ var itemLevel = parseInt((_a = item.getAttribute('data-aria-level')) !== null && _a !== void 0 ? _a : '');
26380
+ // In first level list, there are cases where a consecutive list item DIV may have different list type
26381
+ // When that happens we need to insert the processed elements into the document, then change the list type
26382
+ // and keep the processing going.
26383
+ if (convertedListElement &&
26384
+ (0, roosterjs_editor_dom_1.getTagOfNode)(convertedListElement) != listType &&
26385
+ itemLevel == 1 &&
26386
+ listType) {
26387
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26388
+ convertedListElement = createNewList(listItemContainer, doc, listType);
26389
+ }
26390
+ if (convertedListElement && listType) {
26391
+ insertListItem(convertedListElement, item, listType, doc);
26392
+ }
26393
+ });
26394
+ }
25867
26395
  });
25868
- insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26396
+ if (convertedListElement) {
26397
+ insertConvertedListToDoc(convertedListElement, fragment, itemBlock);
26398
+ }
25869
26399
  // Once we finish the process the list items and put them into a list.
25870
26400
  // After inserting the processed element,
25871
26401
  // we need to remove all the non processed node from the parent node.
25872
- var parentContainer = itemBlock.startElement.parentNode;
26402
+ var parentContainer = (_c = itemBlock.startElement) === null || _c === void 0 ? void 0 : _c.parentNode;
25873
26403
  if (parentContainer) {
25874
26404
  itemBlock.listItemContainers.forEach(function (listItemContainer) {
25875
26405
  parentContainer.removeChild(listItemContainer);
@@ -25889,8 +26419,9 @@ function convertPastedContentFromWordOnline(fragment) {
25889
26419
  // Removing the nodes that are not img will resolve the additional space
25890
26420
  if ((0, roosterjs_editor_dom_1.safeInstanceOf)(node, 'HTMLSpanElement')) {
25891
26421
  node.childNodes.forEach(function (childNode) {
26422
+ var _a;
25892
26423
  if ((0, roosterjs_editor_dom_1.getTagOfNode)(childNode) != 'IMG') {
25893
- childNode.parentElement.removeChild(childNode);
26424
+ (_a = childNode.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(childNode);
25894
26425
  }
25895
26426
  });
25896
26427
  }
@@ -25932,7 +26463,7 @@ function sanitizeListItemContainer(fragment) {
25932
26463
  function getListItemBlocks(fragment) {
25933
26464
  var listElements = fragment.querySelectorAll('.' + LIST_CONTAINER_ELEMENT_CLASS_NAME);
25934
26465
  var result = [];
25935
- var curListItemBlock;
26466
+ var curListItemBlock = null;
25936
26467
  for (var i = 0; i < listElements.length; i++) {
25937
26468
  var curItem = listElements[i];
25938
26469
  if (!curListItemBlock) {
@@ -25942,8 +26473,9 @@ function getListItemBlocks(fragment) {
25942
26473
  var listItemContainers = curListItemBlock.listItemContainers;
25943
26474
  var lastItemInCurBlock = listItemContainers[listItemContainers.length - 1];
25944
26475
  if (curItem == lastItemInCurBlock.nextSibling ||
25945
- (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
25946
- (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock)) {
26476
+ (lastItemInCurBlock.parentNode &&
26477
+ (0, roosterjs_editor_dom_1.getFirstLeafNode)(curItem) ==
26478
+ (0, roosterjs_editor_dom_1.getNextLeafSibling)(lastItemInCurBlock.parentNode, lastItemInCurBlock))) {
25947
26479
  listItemContainers.push(curItem);
25948
26480
  curListItemBlock.endElement = curItem;
25949
26481
  }
@@ -25954,7 +26486,7 @@ function getListItemBlocks(fragment) {
25954
26486
  }
25955
26487
  }
25956
26488
  }
25957
- if ((curListItemBlock === null || curListItemBlock === void 0 ? void 0 : curListItemBlock.listItemContainers.length) > 0) {
26489
+ if (curListItemBlock && curListItemBlock.listItemContainers.length > 0) {
25958
26490
  result.push(curListItemBlock);
25959
26491
  }
25960
26492
  return result;
@@ -25965,12 +26497,14 @@ function getListItemBlocks(fragment) {
25965
26497
  * @param listItemBlock The list item block needed to be flattened.
25966
26498
  */
25967
26499
  function flattenListBlock(fragment, listItemBlock) {
25968
- var collapsedListItemSections = (0, roosterjs_editor_dom_1.collapseNodes)(fragment, listItemBlock.startElement, listItemBlock.endElement, true);
25969
- collapsedListItemSections.forEach(function (section) {
25970
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(section.firstChild) == 'DIV') {
25971
- (0, roosterjs_editor_dom_1.unwrap)(section);
25972
- }
25973
- });
26500
+ if (listItemBlock.startElement && listItemBlock.endElement) {
26501
+ var collapsedListItemSections = (0, roosterjs_editor_dom_1.collapseNodes)(fragment, listItemBlock.startElement, listItemBlock.endElement, true);
26502
+ collapsedListItemSections.forEach(function (section) {
26503
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(section.firstChild) == 'DIV') {
26504
+ (0, roosterjs_editor_dom_1.unwrap)(section);
26505
+ }
26506
+ });
26507
+ }
25974
26508
  }
25975
26509
  /**
25976
26510
  * Get the list type that the container contains. If there is no list in the container
@@ -26008,14 +26542,16 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26008
26542
  // If the current level is empty, create empty list within the current level
26009
26543
  // then move the level iterator into the next level.
26010
26544
  curListLevel.appendChild(doc.createElement(listType));
26011
- curListLevel = curListLevel.firstElementChild;
26545
+ if (curListLevel.firstElementChild) {
26546
+ curListLevel = curListLevel.firstElementChild;
26547
+ }
26012
26548
  }
26013
26549
  else {
26014
26550
  // If the current level is not empty, the last item in the needs to be a UL or OL
26015
26551
  // and the level iterator should move to the UL/OL at the last position.
26016
26552
  var lastChild = curListLevel.lastElementChild;
26017
26553
  var lastChildTag = (0, roosterjs_editor_dom_1.getTagOfNode)(lastChild);
26018
- if (lastChildTag == 'UL' || lastChildTag == 'OL') {
26554
+ if (lastChild && (lastChildTag == 'UL' || lastChildTag == 'OL')) {
26019
26555
  // If the last child is a list(UL/OL), then move the level iterator to last child.
26020
26556
  curListLevel = lastChild;
26021
26557
  }
@@ -26023,7 +26559,9 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26023
26559
  // If the last child is not a list, then append a new list to the level
26024
26560
  // and move the level iterator to the new level.
26025
26561
  curListLevel.appendChild(doc.createElement(listType));
26026
- curListLevel = curListLevel.lastElementChild;
26562
+ if (curListLevel.lastElementChild) {
26563
+ curListLevel = curListLevel.lastElementChild;
26564
+ }
26027
26565
  }
26028
26566
  }
26029
26567
  itemLevel--;
@@ -26038,6 +26576,7 @@ function insertListItem(listRootElement, itemToInsert, listType, doc) {
26038
26576
  * @param listItemBlock List item block that was converted.
26039
26577
  */
26040
26578
  function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock) {
26579
+ var _a;
26041
26580
  if (!convertedListElement) {
26042
26581
  return;
26043
26582
  }
@@ -26049,7 +26588,7 @@ function insertConvertedListToDoc(convertedListElement, fragment, listItemBlock)
26049
26588
  }
26050
26589
  }
26051
26590
  else {
26052
- var parentNode = listItemBlock.startElement.parentNode;
26591
+ var parentNode = (_a = listItemBlock.startElement) === null || _a === void 0 ? void 0 : _a.parentNode;
26053
26592
  if (parentNode) {
26054
26593
  parentNode.appendChild(convertedListElement);
26055
26594
  }
@@ -26220,7 +26759,7 @@ function validateLink(link, htmlElement) {
26220
26759
  "use strict";
26221
26760
 
26222
26761
  Object.defineProperty(exports, "__esModule", { value: true });
26223
- exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26762
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = exports.WAC_IDENTIFY_SELECTOR = exports.PROG_ID_NAME = exports.GOOGLE_SHEET_NODE_NAME = void 0;
26224
26763
  /**
26225
26764
  * @internal
26226
26765
  * Node attribute used to identify if the content is from Google Sheets.
@@ -26236,6 +26775,11 @@ exports.PROG_ID_NAME = 'ProgId';
26236
26775
  * Selector used to identify Wac Elements
26237
26776
  */
26238
26777
  exports.WAC_IDENTIFY_SELECTOR = 'ul[class^="BulletListStyle"]>.OutlineElement,ol[class^="NumberListStyle"]>.OutlineElement,span.WACImageContainer';
26778
+ /**
26779
+ * @internal
26780
+ * Name of the HTMLMeta Property that identifies pated content as from Excel Desktop
26781
+ */
26782
+ exports.EXCEL_DESKTOP_ATTRIBUTE_NAME = 'xmlns:x';
26239
26783
 
26240
26784
 
26241
26785
  /***/ }),
@@ -26278,6 +26822,7 @@ exports.default = documentContainWacElements;
26278
26822
  Object.defineProperty(exports, "__esModule", { value: true });
26279
26823
  var documentContainWacElements_1 = __webpack_require__(/*! ./documentContainWacElements */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/documentContainWacElements.ts");
26280
26824
  var isExcelDesktopDocument_1 = __webpack_require__(/*! ./isExcelDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelDesktopDocument.ts");
26825
+ var isExcelOnlineDocument_1 = __webpack_require__(/*! ./isExcelOnlineDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts");
26281
26826
  var isGoogleSheetDocument_1 = __webpack_require__(/*! ./isGoogleSheetDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts");
26282
26827
  var isPowerPointDesktopDocument_1 = __webpack_require__(/*! ./isPowerPointDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isPowerPointDesktopDocument.ts");
26283
26828
  var isWordDesktopDocument_1 = __webpack_require__(/*! ./isWordDesktopDocument */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isWordDesktopDocument.ts");
@@ -26285,10 +26830,11 @@ var shouldConvertToSingleImage_1 = __webpack_require__(/*! ./shouldConvertToSing
26285
26830
  var getSourceFunctions = new Map([
26286
26831
  [0 /* WordDesktop */, isWordDesktopDocument_1.default],
26287
26832
  [1 /* ExcelDesktop */, isExcelDesktopDocument_1.default],
26288
- [2 /* PowerPointDesktop */, isPowerPointDesktopDocument_1.default],
26289
- [4 /* WacComponents */, documentContainWacElements_1.default],
26290
- [3 /* GoogleSheets */, isGoogleSheetDocument_1.default],
26291
- [6 /* SingleImage */, shouldConvertToSingleImage_1.default],
26833
+ [2 /* ExcelOnline */, isExcelOnlineDocument_1.default],
26834
+ [3 /* PowerPointDesktop */, isPowerPointDesktopDocument_1.default],
26835
+ [5 /* WacComponents */, documentContainWacElements_1.default],
26836
+ [4 /* GoogleSheets */, isGoogleSheetDocument_1.default],
26837
+ [7 /* SingleImage */, shouldConvertToSingleImage_1.default],
26292
26838
  ]);
26293
26839
  /**
26294
26840
  * @internal
@@ -26311,7 +26857,7 @@ function getPasteSource(event, shouldConvertSingleImage) {
26311
26857
  result = key;
26312
26858
  }
26313
26859
  });
26314
- return result !== null && result !== void 0 ? result : 5 /* Default */;
26860
+ return result !== null && result !== void 0 ? result : 6 /* Default */;
26315
26861
  }
26316
26862
  exports.default = getPasteSource;
26317
26863
 
@@ -26329,9 +26875,7 @@ exports.default = getPasteSource;
26329
26875
 
26330
26876
  Object.defineProperty(exports, "__esModule", { value: true });
26331
26877
  var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26332
- var EXCEL_ATTRIBUTE_NAME = 'xmlns:x';
26333
26878
  var EXCEL_ATTRIBUTE_VALUE = 'urn:schemas-microsoft-com:office:excel';
26334
- var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26335
26879
  /**
26336
26880
  * @internal
26337
26881
  * Checks whether the Array provided contains strings that identify Excel Desktop documents
@@ -26340,12 +26884,42 @@ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26340
26884
  */
26341
26885
  var isExcelDesktopDocument = function (props) {
26342
26886
  var htmlAttributes = props.htmlAttributes;
26343
- return (htmlAttributes[EXCEL_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE ||
26344
- htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE);
26887
+ // The presence of this attribute confirms its origin from Excel Desktop
26888
+ return htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == EXCEL_ATTRIBUTE_VALUE;
26345
26889
  };
26346
26890
  exports.default = isExcelDesktopDocument;
26347
26891
 
26348
26892
 
26893
+ /***/ }),
26894
+
26895
+ /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts":
26896
+ /*!********************************************************************************************************!*\
26897
+ !*** ./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isExcelOnlineDocument.ts ***!
26898
+ \********************************************************************************************************/
26899
+ /*! no static exports found */
26900
+ /***/ (function(module, exports, __webpack_require__) {
26901
+
26902
+ "use strict";
26903
+
26904
+ Object.defineProperty(exports, "__esModule", { value: true });
26905
+ var constants_1 = __webpack_require__(/*! ./constants */ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/constants.ts");
26906
+ // Excel Desktop also has this attribute
26907
+ var EXCEL_ONLINE_ATTRIBUTE_VALUE = 'Excel.Sheet';
26908
+ /**
26909
+ * @internal
26910
+ * Checks whether the Array provided contains strings that identify Excel Online documents
26911
+ * @param props Properties related to the PasteEvent
26912
+ * @returns
26913
+ */
26914
+ var isExcelOnlineDocument = function (props) {
26915
+ var htmlAttributes = props.htmlAttributes;
26916
+ // The presence of Excel.Sheet confirms its origin from Excel, the absence of EXCEL_DESKTOP_ATTRIBUTE_NAME confirms it is from the Online version
26917
+ return (htmlAttributes[constants_1.PROG_ID_NAME] == EXCEL_ONLINE_ATTRIBUTE_VALUE &&
26918
+ htmlAttributes[constants_1.EXCEL_DESKTOP_ATTRIBUTE_NAME] == undefined);
26919
+ };
26920
+ exports.default = isExcelOnlineDocument;
26921
+
26922
+
26349
26923
  /***/ }),
26350
26924
 
26351
26925
  /***/ "./packages/roosterjs-editor-plugins/lib/plugins/Paste/sourceValidations/isGoogleSheetDocument.ts":
@@ -26785,7 +27359,11 @@ var LINE_BREAKS = /[\n|\r]/gi;
26785
27359
  * for numbered headers, and we don't want to convert those, because the numbering would be completely wrong.
26786
27360
  */
26787
27361
  function processNodesDiscovery(wordConverter) {
27362
+ var _a;
26788
27363
  var args = wordConverter.wordConverterArgs;
27364
+ if (!args) {
27365
+ return false;
27366
+ }
26789
27367
  while (args.currentIndex < args.nodes.length) {
26790
27368
  var node = args.nodes.item(args.currentIndex);
26791
27369
  // Try to get the list metadata for the specified node
@@ -26874,7 +27452,7 @@ function processNodesDiscovery(wordConverter) {
26874
27452
  last.appendChild(last.ownerDocument.createElement('br'));
26875
27453
  (0, roosterjs_editor_dom_1.moveChildNodes)(last, node, true /*keepExistingChildren*/);
26876
27454
  // Remove the item that we don't need anymore
26877
- node.parentNode.removeChild(node);
27455
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
26878
27456
  }
26879
27457
  }
26880
27458
  // Move to the next element are return true if more elements need to be processed
@@ -26890,44 +27468,47 @@ exports.processNodesDiscovery = processNodesDiscovery;
26890
27468
  * conversion needed
26891
27469
  */
26892
27470
  function processNodeConvert(wordConverter) {
27471
+ var _a;
26893
27472
  var args = wordConverter.wordConverterArgs;
26894
- args.currentIndex = 0;
26895
- while (args.currentIndex < args.listItems.length) {
26896
- var metadata = args.listItems[args.currentIndex];
26897
- var node = metadata.originalNode;
26898
- var listMetadata = args.lists[metadata.uniqueListId.toString()];
26899
- if (!listMetadata.ignore) {
26900
- // We have a list item that we need to convert, get or create the list
26901
- // that hold this item out
26902
- var list = getOrCreateListForNode(wordConverter, node, metadata, listMetadata);
26903
- if (list) {
26904
- // Clean the element out.. this call gets rid of the fake bullet and unneeded nodes
26905
- cleanupListIgnore(node, LOOKUP_DEPTH);
26906
- // Create a new list item and transfer the children
26907
- var li = node.ownerDocument.createElement('LI');
26908
- if ((0, roosterjs_editor_dom_1.getTagOfNode)(node).startsWith('H')) {
26909
- var clone = node.cloneNode(true /* deep */);
26910
- clone.style.textIndent = '';
26911
- clone.style.marginLeft = '';
26912
- clone.style.marginRight = '';
26913
- li.appendChild(clone);
26914
- }
26915
- else {
26916
- (0, roosterjs_editor_dom_1.moveChildNodes)(li, node);
26917
- }
26918
- // Append the list item into the list
26919
- list.appendChild(li);
26920
- // Remove the node we just converted
26921
- node.parentNode.removeChild(node);
26922
- if (listMetadata.tagName == 'UL') {
26923
- wordConverter.numBulletsConverted++;
26924
- }
26925
- else {
26926
- wordConverter.numNumberedConverted++;
27473
+ if (args) {
27474
+ args.currentIndex = 0;
27475
+ while (args.currentIndex < args.listItems.length) {
27476
+ var metadata = args.listItems[args.currentIndex];
27477
+ var node = metadata.originalNode;
27478
+ var listMetadata = args.lists[metadata.uniqueListId.toString()];
27479
+ if (!listMetadata.ignore) {
27480
+ // We have a list item that we need to convert, get or create the list
27481
+ // that hold this item out
27482
+ var list = getOrCreateListForNode(wordConverter, node, metadata, listMetadata);
27483
+ if (list) {
27484
+ // Clean the element out.. this call gets rid of the fake bullet and unneeded nodes
27485
+ cleanupListIgnore(node, LOOKUP_DEPTH);
27486
+ // Create a new list item and transfer the children
27487
+ var li = node.ownerDocument.createElement('LI');
27488
+ if ((0, roosterjs_editor_dom_1.getTagOfNode)(node).startsWith('H')) {
27489
+ var clone = node.cloneNode(true /* deep */);
27490
+ clone.style.textIndent = '';
27491
+ clone.style.marginLeft = '';
27492
+ clone.style.marginRight = '';
27493
+ li.appendChild(clone);
27494
+ }
27495
+ else {
27496
+ (0, roosterjs_editor_dom_1.moveChildNodes)(li, node);
27497
+ }
27498
+ // Append the list item into the list
27499
+ list.appendChild(li);
27500
+ // Remove the node we just converted
27501
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node);
27502
+ if (listMetadata.tagName == 'UL') {
27503
+ wordConverter.numBulletsConverted++;
27504
+ }
27505
+ else {
27506
+ wordConverter.numNumberedConverted++;
27507
+ }
26927
27508
  }
26928
27509
  }
27510
+ args.currentIndex++;
26929
27511
  }
26930
- args.currentIndex++;
26931
27512
  }
26932
27513
  return wordConverter.numBulletsConverted > 0 || wordConverter.numNumberedConverted > 0;
26933
27514
  }
@@ -26937,6 +27518,7 @@ exports.processNodeConvert = processNodeConvert;
26937
27518
  * items content and the specified metadata
26938
27519
  */
26939
27520
  function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
27521
+ var _a;
26940
27522
  // First get the last list next to this node under the specified level. This code
26941
27523
  // path will return the list or will create lists if needed
26942
27524
  var list = recurringGetOrCreateListAtNode(node, metadata.level, listMetadata);
@@ -26948,7 +27530,7 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
26948
27530
  // is a completely new list, so we'll append a new list for that
26949
27531
  if ((listId && listId != metadata.uniqueListId) || (!listId && list.firstChild)) {
26950
27532
  var newList = node.ownerDocument.createElement(listMetadata.tagName);
26951
- list.parentNode.insertBefore(newList, list.nextSibling);
27533
+ (_a = list.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newList, list.nextSibling);
26952
27534
  list = newList;
26953
27535
  }
26954
27536
  // Set the list id into the custom data
@@ -26963,15 +27545,18 @@ function getOrCreateListForNode(wordConverter, node, metadata, listMetadata) {
26963
27545
  * information already stored in the list itself
26964
27546
  */
26965
27547
  function convertListIfNeeded(wordConverter, list, listMetadata) {
27548
+ var _a, _b, _c;
26966
27549
  // Check if we need to convert the list out
26967
27550
  if (listMetadata.tagName != (0, roosterjs_editor_dom_1.getTagOfNode)(list)) {
26968
27551
  // We have the wrong list type.. convert it, set the id again and transfer all the children
26969
- var newList = list.ownerDocument.createElement(listMetadata.tagName);
26970
- (0, WordCustomData_1.setObject)(wordConverter.wordCustomData, newList, UNIQUE_LIST_ID_CUSTOM_DATA, (0, WordCustomData_1.getObject)(wordConverter.wordCustomData, list, UNIQUE_LIST_ID_CUSTOM_DATA));
26971
- (0, roosterjs_editor_dom_1.moveChildNodes)(newList, list);
26972
- list.parentNode.insertBefore(newList, list);
26973
- list.parentNode.removeChild(list);
26974
- list = newList;
27552
+ var newList = (_a = list.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata.tagName);
27553
+ if (newList) {
27554
+ (0, WordCustomData_1.setObject)(wordConverter.wordCustomData, newList, UNIQUE_LIST_ID_CUSTOM_DATA, (0, WordCustomData_1.getObject)(wordConverter.wordCustomData, list, UNIQUE_LIST_ID_CUSTOM_DATA));
27555
+ (0, roosterjs_editor_dom_1.moveChildNodes)(newList, list);
27556
+ (_b = list.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, list);
27557
+ (_c = list.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(list);
27558
+ list = newList;
27559
+ }
26975
27560
  }
26976
27561
  return list;
26977
27562
  }
@@ -26979,8 +27564,9 @@ function convertListIfNeeded(wordConverter, list, listMetadata) {
26979
27564
  * Gets or creates the specified list
26980
27565
  */
26981
27566
  function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27567
+ var _a, _b;
26982
27568
  var parent = null;
26983
- var possibleList;
27569
+ var possibleList = null;
26984
27570
  if (level == 1) {
26985
27571
  // Root case, we'll check if the list is the previous sibling of the node
26986
27572
  possibleList = getRealPreviousSibling(node);
@@ -26989,7 +27575,9 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
26989
27575
  // If we get here, we are looking for level 2 or deeper... get the upper list
26990
27576
  // and check if the last element is a list
26991
27577
  parent = recurringGetOrCreateListAtNode(node, level - 1, null);
26992
- possibleList = parent.lastChild;
27578
+ if (parent.lastChild) {
27579
+ possibleList = parent.lastChild;
27580
+ }
26993
27581
  }
26994
27582
  // Check the element that we got and verify that it is a list
26995
27583
  if (possibleList && possibleList.nodeType == 1 /* Element */) {
@@ -27001,15 +27589,15 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27001
27589
  }
27002
27590
  // If we get here, it means we don't have a list and we need to create one
27003
27591
  // this code path will always create new lists as UL lists
27004
- var newList = node.ownerDocument.createElement(listMetadata ? listMetadata.tagName : 'UL');
27592
+ var newList = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(listMetadata ? listMetadata.tagName : 'UL');
27005
27593
  if (level == 1) {
27006
27594
  // For level 1, we'll insert the list before the node
27007
- node.parentNode.insertBefore(newList, node);
27595
+ (_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newList, node);
27008
27596
  }
27009
27597
  else {
27010
27598
  // Any level 2 or above, we insert the list as the last
27011
27599
  // child of the upper level list
27012
- parent.appendChild(newList);
27600
+ parent === null || parent === void 0 ? void 0 : parent.appendChild(newList);
27013
27601
  }
27014
27602
  return newList;
27015
27603
  }
@@ -27021,15 +27609,17 @@ function recurringGetOrCreateListAtNode(node, level, listMetadata) {
27021
27609
  function cleanupListIgnore(node, levels) {
27022
27610
  var nodesToRemove = [];
27023
27611
  for (var child = node.firstChild; child; child = child.nextSibling) {
27024
- // Clean up the item internally first if we need to based on the number of levels
27025
- if (child.nodeType == 1 /* Element */ && levels > 1) {
27026
- cleanupListIgnore(child, levels - 1);
27027
- }
27028
- // Try to convert word comments into ignore elements if we haven't done so for this element
27029
- child = fixWordListComments(child, true /*removeComments*/);
27030
- // Check if we can remove this item out
27031
- if (isEmptySpan(child) || isIgnoreNode(child)) {
27032
- nodesToRemove.push(child);
27612
+ if (child) {
27613
+ // Clean up the item internally first if we need to based on the number of levels
27614
+ if (child && child.nodeType == 1 /* Element */ && levels > 1) {
27615
+ cleanupListIgnore(child, levels - 1);
27616
+ }
27617
+ // Try to convert word comments into ignore elements if we haven't done so for this element
27618
+ child = fixWordListComments(child, true /*removeComments*/);
27619
+ // Check if we can remove this item out
27620
+ if (isEmptySpan(child) || isIgnoreNode(child)) {
27621
+ nodesToRemove.push(child);
27622
+ }
27033
27623
  }
27034
27624
  }
27035
27625
  nodesToRemove.forEach(function (child) { return node.removeChild(child); });
@@ -27078,6 +27668,7 @@ function getFakeBulletTagName(fakeBullet) {
27078
27668
  * a bullet string. If not found, it returns null...
27079
27669
  */
27080
27670
  function getFakeBulletText(node, levels) {
27671
+ var _a, _b;
27081
27672
  // Word uses the following format for their bullets:
27082
27673
  // &lt;p style="mso-list:l1 level1 lfo2"&gt;
27083
27674
  // &lt;span style="..."&gt;
@@ -27088,7 +27679,7 @@ function getFakeBulletText(node, levels) {
27088
27679
  //
27089
27680
  // Basically, we need to locate the mso-list:Ignore SPAN, which holds either one text or image node. That
27090
27681
  // text or image node will be the fake bullet we are looking for
27091
- var result = null;
27682
+ var result = '';
27092
27683
  var child = node.firstChild;
27093
27684
  while (!result && child) {
27094
27685
  // First, check if we need to convert the Word list comments into real elements
@@ -27096,7 +27687,7 @@ function getFakeBulletText(node, levels) {
27096
27687
  // Check if this is the node that holds the fake bullets (mso-list: Ignore)
27097
27688
  if (isIgnoreNode(child)) {
27098
27689
  // Yes... this is the node that holds either the text or image data
27099
- result = child.textContent.trim();
27690
+ result = (_b = (_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
27100
27691
  // This is the case for image case
27101
27692
  if (result.length == 0) {
27102
27693
  result = 'o';
@@ -27120,6 +27711,7 @@ function getFakeBulletText(node, levels) {
27120
27711
  * styles of the span, but we'll use these comments to recreate them out
27121
27712
  */
27122
27713
  function fixWordListComments(child, removeComments) {
27714
+ var _a, _b, _c, _d;
27123
27715
  if (child.nodeType == 8 /* Comment */) {
27124
27716
  var value = child.data;
27125
27717
  if (value && value.trim().toLowerCase() == '[if !supportlists]') {
@@ -27142,22 +27734,28 @@ function fixWordListComments(child, removeComments) {
27142
27734
  }
27143
27735
  // if we found the end node, wrap everything out
27144
27736
  if (endComment) {
27145
- var newSpan = child.ownerDocument.createElement('span');
27146
- newSpan.setAttribute('style', 'mso-list: ignore');
27737
+ var newSpan = (_a = child.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement('span');
27738
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.setAttribute('style', 'mso-list: ignore');
27147
27739
  nextElement = getRealNextSibling(child);
27148
27740
  while (nextElement != endComment) {
27149
- nextElement = nextElement.nextSibling;
27150
- newSpan.appendChild(nextElement.previousSibling);
27741
+ nextElement = nextElement === null || nextElement === void 0 ? void 0 : nextElement.nextSibling;
27742
+ if (nextElement.previousSibling) {
27743
+ newSpan === null || newSpan === void 0 ? void 0 : newSpan.appendChild(nextElement.previousSibling);
27744
+ }
27151
27745
  }
27152
27746
  // Insert the element out and use that one as the current child
27153
- endComment.parentNode.insertBefore(newSpan, endComment);
27747
+ if (newSpan) {
27748
+ (_b = endComment.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newSpan, endComment);
27749
+ }
27154
27750
  // Remove the comments out if the call specified it out
27155
27751
  if (removeComments) {
27156
- child.parentNode.removeChild(child);
27157
- endComment.parentNode.removeChild(endComment);
27752
+ (_c = child.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(child);
27753
+ (_d = endComment.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(endComment);
27158
27754
  }
27159
27755
  // Last, make sure we return the new element out instead of the comment
27160
- child = newSpan;
27756
+ if (newSpan) {
27757
+ child = newSpan;
27758
+ }
27161
27759
  }
27162
27760
  }
27163
27761
  }
@@ -27209,6 +27807,7 @@ function getStyleValue(node, styleName) {
27209
27807
  }
27210
27808
  /** Checks if the node is an empty text node that can be ignored */
27211
27809
  function isEmptyTextNode(node) {
27810
+ var _a;
27212
27811
  // No node is empty
27213
27812
  if (!node) {
27214
27813
  return true;
@@ -27216,12 +27815,14 @@ function isEmptyTextNode(node) {
27216
27815
  // Empty text node is empty
27217
27816
  if (node.nodeType == 3 /* Text */) {
27218
27817
  var value = node.nodeValue;
27219
- value = value.replace(LINE_BREAKS, '');
27220
- return value.trim().length == 0;
27818
+ value = (_a = value === null || value === void 0 ? void 0 : value.replace(LINE_BREAKS, '')) !== null && _a !== void 0 ? _a : '';
27819
+ return (value === null || value === void 0 ? void 0 : value.trim().length) == 0;
27221
27820
  }
27222
27821
  // Span or Font with an empty child node is empty
27223
27822
  var tagName = (0, roosterjs_editor_dom_1.getTagOfNode)(node);
27224
- if (node.firstChild == node.lastChild && (tagName == 'SPAN' || tagName == 'FONT')) {
27823
+ if (node.firstChild &&
27824
+ node.firstChild == node.lastChild &&
27825
+ (tagName == 'SPAN' || tagName == 'FONT')) {
27225
27826
  return isEmptyTextNode(node.firstChild);
27226
27827
  }
27227
27828
  // If not found, then this is not empty
@@ -29144,7 +29745,7 @@ var TableInsertHandler = /** @class */ (function () {
29144
29745
  }());
29145
29746
  function getInsertElementData(isHorizontal, isDark, isRTL, backgroundColor) {
29146
29747
  var inserterColor = isDark ? INSERTER_COLOR_DARK_MODE : INSERTER_COLOR;
29147
- 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;
29748
+ 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;
29148
29749
  var leftOrRight = isRTL ? 'right' : 'left';
29149
29750
  var childBaseStyles = "position: absolute; box-sizing: border-box; background-color: " + backgroundColor + ";";
29150
29751
  var childInfo = {
@@ -29743,6 +30344,11 @@ var CompatibleChangeSource;
29743
30344
  * List chain reorganized numbers of lists
29744
30345
  */
29745
30346
  CompatibleChangeSource["ListChain"] = "ListChain";
30347
+ /**
30348
+ * Keyboard event, used by Content Model.
30349
+ * Data of this event will be the key code number
30350
+ */
30351
+ CompatibleChangeSource["Keyboard"] = "Keyboard";
29746
30352
  })(CompatibleChangeSource = exports.CompatibleChangeSource || (exports.CompatibleChangeSource = {}));
29747
30353
 
29748
30354