@mx-space/cli 0.14.2 → 0.15.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.
Files changed (52) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +35 -11
  3. package/dist/{Lexical.dev-CtGmYDoh.mjs → Lexical.dev-Cck4n26y.mjs} +240 -325
  4. package/dist/{Lexical.node-8sRFmq2X.mjs → Lexical.node-D6wf2D5M.mjs} +2 -2
  5. package/dist/{Lexical.prod-D-VfeKDz.mjs → Lexical.prod-DCwS1oTq.mjs} +1753 -1783
  6. package/dist/{LexicalClipboard.dev-CzQ15z6E.mjs → LexicalClipboard.dev-CMkPHV7O.mjs} +6 -6
  7. package/dist/{LexicalClipboard.node-D4gMGws6.mjs → LexicalClipboard.node-m4nZ7IYw.mjs} +2 -2
  8. package/dist/{LexicalClipboard.prod-CltkQpzS.mjs → LexicalClipboard.prod-B_rN1vE1.mjs} +6 -6
  9. package/dist/{LexicalCodeCore.dev-DkYBZRGB.mjs → LexicalCodeCore.dev-DyJw3i8V.mjs} +56 -68
  10. package/dist/{LexicalCodeCore.prod-COc3_QL8.mjs → LexicalCodeCore.prod-DPXLHQLF.mjs} +144 -156
  11. package/dist/{LexicalDragon.dev-Dv5_WUae.mjs → LexicalDragon.dev-ZkNfMwrE.mjs} +3 -3
  12. package/dist/{LexicalDragon.node-DgjrmWkd.mjs → LexicalDragon.node-Ds9oLUFh.mjs} +2 -2
  13. package/dist/{LexicalDragon.prod-DnpbDe-_.mjs → LexicalDragon.prod-B58ic2av.mjs} +3 -3
  14. package/dist/{LexicalExtension.dev-JMH_6-OZ.mjs → LexicalExtension.dev-DvwHs1Xv.mjs} +10 -19
  15. package/dist/{LexicalExtension.node-BUozzx4t.mjs → LexicalExtension.node-5OymZQfy.mjs} +2 -2
  16. package/dist/{LexicalExtension.prod-UiyDgmou.mjs → LexicalExtension.prod-Ce0T5smQ.mjs} +73 -82
  17. package/dist/{LexicalHeadless.dev-BfLGciiX.mjs → LexicalHeadless.dev-DA0WldSR.mjs} +2 -2
  18. package/dist/{LexicalHeadless.prod-CWF7edmQ.mjs → LexicalHeadless.prod-1kQgKB6c.mjs} +2 -2
  19. package/dist/{LexicalHtml.dev-D5EF5PGW.mjs → LexicalHtml.dev-BDB7CUrx.mjs} +6 -6
  20. package/dist/{LexicalHtml.node-BYbzHNVe.mjs → LexicalHtml.node-DpVNt7It.mjs} +2 -2
  21. package/dist/{LexicalHtml.prod-D_FfkvVD.mjs → LexicalHtml.prod-HkxM5scw.mjs} +6 -6
  22. package/dist/{LexicalLink.dev-D3Pgh6ik.mjs → LexicalLink.dev-C5zNJlrm.mjs} +17 -41
  23. package/dist/{LexicalLink.prod-XZoAYVYD.mjs → LexicalLink.prod-Bkt9hQAt.mjs} +113 -137
  24. package/dist/{LexicalList.dev-B5d3ObhB.mjs → LexicalList.dev-B7VgME-m.mjs} +15 -47
  25. package/dist/{LexicalList.prod-OQDpVAEb.mjs → LexicalList.prod-B8c7TDjH.mjs} +208 -224
  26. package/dist/{LexicalMarkdown.dev-BkM8G3DG.mjs → LexicalMarkdown.dev-B5z9kLbV.mjs} +5 -4
  27. package/dist/{LexicalMarkdown.prod-DcVXCex6.mjs → LexicalMarkdown.prod-wKzw7FFH.mjs} +5 -4
  28. package/dist/{LexicalRichText.dev-DppD7IrA.mjs → LexicalRichText.dev-CUd6Li5F.mjs} +76 -82
  29. package/dist/{LexicalRichText.node-CPSn7dkg.mjs → LexicalRichText.node-BKfaQ-CH.mjs} +8 -8
  30. package/dist/{LexicalRichText.prod-h7JPxFNp.mjs → LexicalRichText.prod-SBewjJHx.mjs} +86 -96
  31. package/dist/{LexicalSelection.dev-CD0SLbxP.mjs → LexicalSelection.dev-D27JOCqj.mjs} +2 -2
  32. package/dist/{LexicalSelection.node-CGlJgUlZ.mjs → LexicalSelection.node-DBEwPjBu.mjs} +2 -2
  33. package/dist/{LexicalSelection.prod-DbVZN5AV.mjs → LexicalSelection.prod-OaYhXHOL.mjs} +2 -2
  34. package/dist/{LexicalTable.dev-D0HU14UV.mjs → LexicalTable.dev-6IFFOAE0.mjs} +260 -131
  35. package/dist/{LexicalTable.prod-BcPNSrxP.mjs → LexicalTable.prod-2CaLZ7fH.mjs} +686 -630
  36. package/dist/{LexicalUtils.dev-iKy_TrRT.mjs → LexicalUtils.dev-DJA7J_7v.mjs} +3 -3
  37. package/dist/{LexicalUtils.node-CIgMS8cG.mjs → LexicalUtils.node-Df9oPTlA.mjs} +2 -2
  38. package/dist/{LexicalUtils.prod-DIAsKJzu.mjs → LexicalUtils.prod-Bb7V4Ewg.mjs} +3 -3
  39. package/dist/bin/mxs.mjs +1 -1
  40. package/dist/esm-CDcJmHkG.mjs +2 -0
  41. package/dist/{esm-CwXl1N0a.mjs → esm-DLzrv7gD.mjs} +165 -131
  42. package/dist/index.d.mts +16 -16
  43. package/dist/index.mjs +1 -1
  44. package/dist/{mxs-iW9DgqSZ.mjs → mxs-BIRW5Axj.mjs} +1434 -2233
  45. package/dist/vendor/litexml/cli.mjs +2462 -2557
  46. package/dist/vendor/litexml/litexml-html-preview-client.css +80 -47
  47. package/dist/vendor/litexml/litexml-html-preview-client.js +5276 -4906
  48. package/dist/vendor/litexml/style.css +6 -2
  49. package/package.json +31 -32
  50. package/skills/commands-ai.md +45 -12
  51. package/skills/overview.md +1 -1
  52. package/dist/esm-CH7CrOvh.mjs +0 -2
@@ -1,4 +1,4 @@
1
- //#region ../../node_modules/.pnpm/lexical@0.48.0_typescript@6.0.3/node_modules/lexical/dist/Lexical.dev.mjs
1
+ //#region ../../node_modules/.pnpm/lexical@0.49.0_typescript@6.0.3/node_modules/lexical/dist/Lexical.dev.mjs
2
2
  /**
3
3
  * Copyright (c) Meta Platforms, Inc. and affiliates.
4
4
  *
@@ -448,7 +448,7 @@ function indexPath(root, child) {
448
448
  */
449
449
  let envLexicalVersion;
450
450
  try {
451
- envLexicalVersion = "0.48.0+dev.esm";
451
+ envLexicalVersion = "0.49.0+dev.esm";
452
452
  } catch (_unused) {}
453
453
  const LEXICAL_VERSION = envLexicalVersion ?? "\"<unknown>+source\"";
454
454
  /**
@@ -2970,7 +2970,7 @@ function onSelectionChange(domSelection, editor, isActive) {
2970
2970
  selection.format = hasTextNodes ? combinedFormat : 0;
2971
2971
  }
2972
2972
  }
2973
- dispatchCommand(editor, SELECTION_CHANGE_COMMAND, void 0);
2973
+ dispatchCommand(editor, SELECTION_CHANGE_COMMAND);
2974
2974
  });
2975
2975
  }
2976
2976
  function $updateSelectionFormatStyle(selection, format, style) {
@@ -3004,6 +3004,27 @@ function onClick(event, editor) {
3004
3004
  if (isHTMLElement(domAnchorNode) || isDOMTextNode(domAnchorNode)) $setSelection($internalCreateRangeSelection(lastSelection, domSelection, editor, event));
3005
3005
  }
3006
3006
  }
3007
+ if (IS_FIREFOX && domSelection !== null && domSelection.rangeCount === 0) {
3008
+ const rootElement = editor._rootElement;
3009
+ if (rootElement !== null && event.target === rootElement) {
3010
+ const clientY = event.clientY;
3011
+ let offset = rootElement.childNodes.length;
3012
+ for (let i = 0; i < rootElement.childNodes.length; i++) {
3013
+ const child = rootElement.childNodes[i];
3014
+ if (isHTMLElement(child)) {
3015
+ const rect = child.getBoundingClientRect();
3016
+ if (clientY <= (rect.top + rect.bottom) / 2) {
3017
+ offset = i;
3018
+ break;
3019
+ }
3020
+ }
3021
+ }
3022
+ domSelection.setBaseAndExtent(rootElement, offset, rootElement, offset);
3023
+ const newSelection = $internalCreateRangeSelection(lastSelection, domSelection, editor, event);
3024
+ if (newSelection !== null) $setSelection(newSelection);
3025
+ else domSelection.removeAllRanges();
3026
+ }
3027
+ }
3007
3028
  dispatchCommand(editor, CLICK_COMMAND, event);
3008
3029
  });
3009
3030
  }
@@ -3180,7 +3201,7 @@ function $handleBeforeInput(event) {
3180
3201
  dispatchCommand(editor, INSERT_LINE_BREAK_COMMAND, false);
3181
3202
  } else if (data === DOUBLE_LINE_BREAK) {
3182
3203
  event.preventDefault();
3183
- dispatchCommand(editor, INSERT_PARAGRAPH_COMMAND, void 0);
3204
+ dispatchCommand(editor, INSERT_PARAGRAPH_COMMAND);
3184
3205
  } else if (data == null && event.dataTransfer) {
3185
3206
  const text = event.dataTransfer.getData("text/plain");
3186
3207
  event.preventDefault();
@@ -3219,7 +3240,7 @@ function $handleBeforeInput(event) {
3219
3240
  if (inputState.isInsertLineBreak && !IS_IOS) {
3220
3241
  inputState.isInsertLineBreak = false;
3221
3242
  dispatchCommand(editor, INSERT_LINE_BREAK_COMMAND, false);
3222
- } else dispatchCommand(editor, INSERT_PARAGRAPH_COMMAND, void 0);
3243
+ } else dispatchCommand(editor, INSERT_PARAGRAPH_COMMAND);
3223
3244
  break;
3224
3245
  case "insertFromPaste":
3225
3246
  case "insertFromPasteAsQuotation":
@@ -3266,10 +3287,10 @@ function $handleBeforeInput(event) {
3266
3287
  dispatchCommand(editor, FORMAT_TEXT_COMMAND, "underline");
3267
3288
  break;
3268
3289
  case "historyUndo":
3269
- dispatchCommand(editor, UNDO_COMMAND, void 0);
3290
+ dispatchCommand(editor, UNDO_COMMAND);
3270
3291
  break;
3271
3292
  case "historyRedo":
3272
- dispatchCommand(editor, REDO_COMMAND, void 0);
3293
+ dispatchCommand(editor, REDO_COMMAND);
3273
3294
  break;
3274
3295
  }
3275
3296
  return true;
@@ -3510,10 +3531,10 @@ function $handleKeyDown(event) {
3510
3531
  } else if (isTab(event)) dispatchCommand(editor, KEY_TAB_COMMAND, event);
3511
3532
  else if (isUndo(event)) {
3512
3533
  event.preventDefault();
3513
- dispatchCommand(editor, UNDO_COMMAND, void 0);
3534
+ dispatchCommand(editor, UNDO_COMMAND);
3514
3535
  } else if (isRedo(event)) {
3515
3536
  event.preventDefault();
3516
- dispatchCommand(editor, REDO_COMMAND, void 0);
3537
+ dispatchCommand(editor, REDO_COMMAND);
3517
3538
  } else {
3518
3539
  const prevSelection = editor._editorState._selection;
3519
3540
  if (isSelectAll(event)) {
@@ -5173,7 +5194,7 @@ function $isInlineFormattable(node) {
5173
5194
  return node != null && node.__isInlineFormattable === true;
5174
5195
  }
5175
5196
  /** @noInheritDoc */
5176
- var TextNode = class TextNode extends LexicalNode {
5197
+ var TextNode = class extends LexicalNode {
5177
5198
  /** @internal */
5178
5199
  __text;
5179
5200
  /** @internal */
@@ -5188,11 +5209,57 @@ var TextNode = class TextNode extends LexicalNode {
5188
5209
  get __isInlineFormattable() {
5189
5210
  return true;
5190
5211
  }
5191
- static getType() {
5192
- return "text";
5193
- }
5194
- static clone(node) {
5195
- return new TextNode(node.__text, node.__key);
5212
+ $config() {
5213
+ return this.config("text", { importDOM: {
5214
+ "#text": () => ({
5215
+ conversion: $convertTextDOMNode,
5216
+ priority: 0
5217
+ }),
5218
+ b: () => ({
5219
+ conversion: convertBringAttentionToElement,
5220
+ priority: 0
5221
+ }),
5222
+ code: () => ({
5223
+ conversion: convertTextFormatElement,
5224
+ priority: 0
5225
+ }),
5226
+ em: () => ({
5227
+ conversion: convertTextFormatElement,
5228
+ priority: 0
5229
+ }),
5230
+ i: () => ({
5231
+ conversion: convertTextFormatElement,
5232
+ priority: 0
5233
+ }),
5234
+ mark: () => ({
5235
+ conversion: convertTextFormatElement,
5236
+ priority: 0
5237
+ }),
5238
+ s: () => ({
5239
+ conversion: convertTextFormatElement,
5240
+ priority: 0
5241
+ }),
5242
+ span: () => ({
5243
+ conversion: convertSpanElement,
5244
+ priority: 0
5245
+ }),
5246
+ strong: () => ({
5247
+ conversion: convertTextFormatElement,
5248
+ priority: 0
5249
+ }),
5250
+ sub: () => ({
5251
+ conversion: convertTextFormatElement,
5252
+ priority: 0
5253
+ }),
5254
+ sup: () => ({
5255
+ conversion: convertTextFormatElement,
5256
+ priority: 0
5257
+ }),
5258
+ u: () => ({
5259
+ conversion: convertTextFormatElement,
5260
+ priority: 0
5261
+ })
5262
+ } });
5196
5263
  }
5197
5264
  afterCloneFrom(prevNode) {
5198
5265
  super.afterCloneFrom(prevNode);
@@ -5390,61 +5457,6 @@ var TextNode = class TextNode extends LexicalNode {
5390
5457
  if (prevStyle !== nextStyle) setDOMStyleFromCSS(dom.style, nextStyle, prevStyle);
5391
5458
  return false;
5392
5459
  }
5393
- static importDOM() {
5394
- return {
5395
- "#text": () => ({
5396
- conversion: $convertTextDOMNode,
5397
- priority: 0
5398
- }),
5399
- b: () => ({
5400
- conversion: convertBringAttentionToElement,
5401
- priority: 0
5402
- }),
5403
- code: () => ({
5404
- conversion: convertTextFormatElement,
5405
- priority: 0
5406
- }),
5407
- em: () => ({
5408
- conversion: convertTextFormatElement,
5409
- priority: 0
5410
- }),
5411
- i: () => ({
5412
- conversion: convertTextFormatElement,
5413
- priority: 0
5414
- }),
5415
- mark: () => ({
5416
- conversion: convertTextFormatElement,
5417
- priority: 0
5418
- }),
5419
- s: () => ({
5420
- conversion: convertTextFormatElement,
5421
- priority: 0
5422
- }),
5423
- span: () => ({
5424
- conversion: convertSpanElement,
5425
- priority: 0
5426
- }),
5427
- strong: () => ({
5428
- conversion: convertTextFormatElement,
5429
- priority: 0
5430
- }),
5431
- sub: () => ({
5432
- conversion: convertTextFormatElement,
5433
- priority: 0
5434
- }),
5435
- sup: () => ({
5436
- conversion: convertTextFormatElement,
5437
- priority: 0
5438
- }),
5439
- u: () => ({
5440
- conversion: convertTextFormatElement,
5441
- priority: 0
5442
- })
5443
- };
5444
- }
5445
- static importJSON(serializedNode) {
5446
- return $createTextNode().updateFromJSON(serializedNode);
5447
- }
5448
5460
  updateFromJSON(serializedNode) {
5449
5461
  return super.updateFromJSON(serializedNode).setTextContent(serializedNode.text).setFormat(serializedNode.format).setDetail(serializedNode.detail).setMode(serializedNode.mode).setStyle(serializedNode.style);
5450
5462
  }
@@ -5930,29 +5942,20 @@ function applyTextFormatFromStyle(style, shouldApply) {
5930
5942
  };
5931
5943
  }
5932
5944
  /** @noInheritDoc */
5933
- var TabNode = class TabNode extends TextNode {
5934
- static getType() {
5935
- return "tab";
5936
- }
5937
- static clone(node) {
5938
- return new TabNode(node.__key);
5945
+ var TabNode = class extends TextNode {
5946
+ $config() {
5947
+ return this.config("tab", { extends: TextNode });
5939
5948
  }
5940
- constructor(key) {
5949
+ constructor(key = void 0) {
5941
5950
  super(" ", key);
5942
5951
  this.__detail = IS_UNMERGEABLE;
5943
5952
  }
5944
- static importDOM() {
5945
- return null;
5946
- }
5947
5953
  createDOM(config) {
5948
5954
  const dom = super.createDOM(config);
5949
5955
  const classNames = getCachedClassNameArray(config.theme, "tab");
5950
5956
  if (classNames !== void 0) dom.classList.add(...classNames);
5951
5957
  return dom;
5952
5958
  }
5953
- static importJSON(serializedTabNode) {
5954
- return $createTabNode().updateFromJSON(serializedTabNode);
5955
- }
5956
5959
  /**
5957
5960
  * Always normalizes the stored content to `'\t'` regardless of input — see
5958
5961
  * comment below for the rationale.
@@ -6086,6 +6089,26 @@ function $transferStartingElementPointToTextPoint(start, end, format, style) {
6086
6089
  if (start.is(end)) end.set(textNode.__key, 0, "text");
6087
6090
  start.set(textNode.__key, 0, "text");
6088
6091
  }
6092
+ function $insertTextAtPoint(selection, text, format, style) {
6093
+ const anchorNode = selection.anchor.getNode();
6094
+ if (!$isTextNode(anchorNode)) formatDevErrorMessage(`insertText: anchor is not a text node`);
6095
+ const offset = selection.anchor.offset;
6096
+ const textNode = $createTextNode(text);
6097
+ textNode.setFormat(format);
6098
+ textNode.setStyle(style);
6099
+ const parent = anchorNode.getParentOrThrow();
6100
+ if (offset === 0) if (parent.isInline() && !anchorNode.__prev) parent.insertBefore(textNode);
6101
+ else anchorNode.insertBefore(textNode, false);
6102
+ else if (offset === anchorNode.getTextContentSize()) if (parent.isInline() && !anchorNode.__next) parent.insertAfter(textNode);
6103
+ else anchorNode.insertAfter(textNode, false);
6104
+ else {
6105
+ const [before] = anchorNode.splitText(offset);
6106
+ before.insertAfter(textNode, false);
6107
+ }
6108
+ if (anchorNode.getTextContent() === "" && anchorNode.isAttached()) anchorNode.remove();
6109
+ textNode.selectEnd();
6110
+ if (textNode.isComposing() && selection.anchor.type === "text") selection.anchor.set(selection.anchor.key, selection.anchor.offset - text.length, selection.anchor.type);
6111
+ }
6089
6112
  var NodeSelection = class NodeSelection {
6090
6113
  _nodes;
6091
6114
  _cachedNodes;
@@ -6401,201 +6424,91 @@ var RangeSelection = class RangeSelection {
6401
6424
  * @param text the text to insert into the Selection
6402
6425
  */
6403
6426
  insertText(text) {
6404
- const anchor = this.anchor;
6405
- const focus = this.focus;
6406
- const format = this.format;
6407
- const style = this.style;
6408
- let firstPoint = anchor;
6409
- let endPoint = focus;
6410
- if (!this.isCollapsed() && focus.isBefore(anchor)) {
6411
- firstPoint = focus;
6412
- endPoint = anchor;
6413
- }
6414
- if (firstPoint.type === "element") $transferStartingElementPointToTextPoint(firstPoint, endPoint, format, style);
6415
- if (endPoint.type === "element") $setPointFromCaret(endPoint, $normalizeCaret($caretFromPoint(endPoint, "next")));
6416
- const startOffset = firstPoint.offset;
6417
- let endOffset = endPoint.offset;
6418
- const selectedNodes = this.getNodes();
6419
- const selectedNodesLength = selectedNodes.length;
6420
- let firstNode = selectedNodes[0];
6421
- if (!$isTextNode(firstNode)) formatDevErrorMessage(`insertText: first node is not a text node`);
6422
- const firstNodeTextLength = firstNode.getTextContent().length;
6423
- const firstNodeParent = firstNode.getParentOrThrow();
6424
- let lastNode = selectedNodes[selectedNodesLength - 1];
6425
- if (selectedNodesLength === 1 && endPoint.type === "element") {
6426
- endOffset = firstNodeTextLength;
6427
- endPoint.set(firstPoint.key, endOffset, "text");
6428
- }
6429
- if (this.isCollapsed() && startOffset === firstNodeTextLength && ($isTokenOrSegmented(firstNode) || !firstNode.canInsertTextAfter() || !firstNodeParent.canInsertTextAfter() && firstNode.getNextSibling() === null)) {
6430
- const candidateNextSibling = firstNode.getNextSibling();
6431
- let nextSibling;
6432
- if (!$isTextNode(candidateNextSibling) || !candidateNextSibling.canInsertTextBefore() || $isTokenOrSegmented(candidateNextSibling)) {
6433
- nextSibling = $createTextNode();
6434
- nextSibling.setFormat(format);
6435
- nextSibling.setStyle(style);
6436
- if (!firstNodeParent.canInsertTextAfter()) firstNodeParent.insertAfter(nextSibling);
6437
- else firstNode.insertAfter(nextSibling);
6438
- } else nextSibling = candidateNextSibling;
6439
- nextSibling.select(0, 0);
6440
- firstNode = nextSibling;
6441
- if (text !== "") {
6442
- this.insertText(text);
6443
- return;
6444
- }
6445
- } else if (this.isCollapsed() && startOffset === 0 && ($isTokenOrSegmented(firstNode) || !firstNode.canInsertTextBefore() || !firstNodeParent.canInsertTextBefore() && firstNode.getPreviousSibling() === null)) {
6446
- const candidatePrevSibling = firstNode.getPreviousSibling();
6447
- let prevSibling;
6448
- if (!$isTextNode(candidatePrevSibling) || $isTokenOrSegmented(candidatePrevSibling)) {
6449
- prevSibling = $createTextNode();
6450
- prevSibling.setFormat(format);
6451
- if (!firstNodeParent.canInsertTextBefore()) firstNodeParent.insertBefore(prevSibling);
6452
- else firstNode.insertBefore(prevSibling);
6453
- } else prevSibling = candidatePrevSibling;
6454
- prevSibling.select();
6455
- firstNode = prevSibling;
6456
- if (text !== "") {
6457
- this.insertText(text);
6458
- return;
6459
- }
6460
- } else if (firstNode.isSegmented() && startOffset !== firstNodeTextLength) if ($getCompositionKey() !== null) firstNode = firstNode.setMode("normal").setFormat(format).setStyle(style);
6461
- else {
6462
- const textNode = $createTextNode(firstNode.getTextContent());
6463
- textNode.setFormat(format);
6464
- firstNode.replace(textNode);
6465
- firstNode = textNode;
6466
- }
6467
- else if (!this.isCollapsed() && text !== "") {
6468
- const lastNodeParent = lastNode.getParent();
6469
- if (!firstNodeParent.canInsertTextBefore() || !firstNodeParent.canInsertTextAfter() || $isElementNode(lastNodeParent) && (!lastNodeParent.canInsertTextBefore() || !lastNodeParent.canInsertTextAfter())) {
6470
- this.insertText("");
6471
- $normalizeSelectionPointsForBoundaries(this.anchor, this.focus);
6472
- this.insertText(text);
6427
+ let format = this.format;
6428
+ let style = this.style;
6429
+ if (!this.isCollapsed()) {
6430
+ const firstNode = (this.focus.isBefore(this.anchor) ? this.focus : this.anchor).getNode();
6431
+ if ($isTextNode(firstNode)) {
6432
+ format = firstNode.getFormat();
6433
+ style = firstNode.getStyle();
6434
+ }
6435
+ this.removeText();
6436
+ this.format = format;
6437
+ this.style = style;
6438
+ if (text === "") return;
6439
+ if ($getCompositionKey() === null) {
6440
+ if (this.anchor.type === "element") $transferStartingElementPointToTextPoint(this.anchor, this.focus, format, style);
6441
+ $insertTextAtPoint(this, text, format, style);
6473
6442
  return;
6474
6443
  }
6475
6444
  }
6476
- if (selectedNodesLength === 1) {
6477
- if ($isTokenOrTab(firstNode)) {
6478
- const textNode = $createTextNode(text);
6479
- textNode.select();
6480
- firstNode.replace(textNode);
6481
- return;
6482
- }
6483
- const firstNodeFormat = firstNode.getFormat();
6484
- const firstNodeStyle = firstNode.getStyle();
6485
- if (startOffset === endOffset && (firstNodeFormat !== format || firstNodeStyle !== style)) if (firstNode.getTextContent() === "") {
6486
- firstNode.setFormat(format);
6487
- firstNode.setStyle(style);
6488
- } else {
6489
- const textNode = $createTextNode(text);
6490
- textNode.setFormat(format);
6491
- textNode.setStyle(style);
6492
- textNode.select();
6493
- if (startOffset === 0) firstNode.insertBefore(textNode, false);
6445
+ if (this.anchor.type === "element") $transferStartingElementPointToTextPoint(this.anchor, this.focus, format, style);
6446
+ const anchorNode = this.anchor.getNode();
6447
+ if (!$isTextNode(anchorNode)) formatDevErrorMessage(`insertText: anchor is not a text node`);
6448
+ const offset = this.anchor.offset;
6449
+ const anchorParent = anchorNode.getParentOrThrow();
6450
+ const anchorSize = anchorNode.getTextContentSize();
6451
+ if ($isTokenOrSegmented(anchorNode) || offset === 0 && (!anchorNode.canInsertTextBefore() || !anchorParent.canInsertTextBefore() && !anchorNode.__prev) || offset === anchorSize && (!anchorNode.canInsertTextAfter() || !anchorParent.canInsertTextAfter() && !anchorNode.__next)) {
6452
+ if (anchorNode.isSegmented() && offset !== 0 && offset !== anchorSize) {
6453
+ if ($getCompositionKey() !== null) anchorNode.setMode("normal").setFormat(format).setStyle(style);
6494
6454
  else {
6495
- const [targetNode] = firstNode.splitText(startOffset);
6496
- targetNode.insertAfter(textNode, false);
6497
- }
6498
- if (textNode.isComposing() && this.anchor.type === "text") {
6499
- this.anchor.offset -= text.length;
6500
- this._cachedNodes = null;
6501
- this._cachedIsBackward = null;
6455
+ const replacement = $createTextNode(anchorNode.getTextContent());
6456
+ replacement.setFormat(format);
6457
+ replacement.setStyle(style);
6458
+ anchorNode.replace(replacement);
6459
+ replacement.select(offset, offset);
6502
6460
  }
6461
+ if (text !== "") this.insertText(text);
6503
6462
  return;
6504
6463
  }
6505
- else if ($isTabNode(firstNode)) {
6506
- const textNode = $createTextNode(text);
6507
- textNode.setFormat(format);
6508
- textNode.setStyle(style);
6509
- textNode.select();
6510
- firstNode.replace(textNode);
6464
+ if (text === "") return;
6465
+ if (offset === 0) {
6466
+ const prev = anchorNode.getPreviousSibling();
6467
+ if ($isTextNode(prev) && prev.canInsertTextAfter() && !$isTokenOrSegmented(prev)) prev.select();
6468
+ else {
6469
+ const newNode = $createTextNode();
6470
+ newNode.setFormat(format);
6471
+ newNode.setStyle(style);
6472
+ if (!anchorParent.canInsertTextBefore()) anchorParent.insertBefore(newNode);
6473
+ else anchorNode.insertBefore(newNode);
6474
+ newNode.select();
6475
+ }
6476
+ this.insertText(text);
6511
6477
  return;
6512
- }
6513
- const delCount = endOffset - startOffset;
6514
- firstNode = firstNode.spliceText(startOffset, delCount, text, true);
6515
- if (firstNode.getTextContent() === "") firstNode.remove();
6516
- else if (this.anchor.type === "text") {
6517
- this.format = firstNodeFormat;
6518
- this.style = firstNodeStyle;
6519
- if (firstNode.isComposing()) {
6520
- this.anchor.offset -= text.length;
6521
- this._cachedNodes = null;
6522
- this._cachedIsBackward = null;
6478
+ } else if (offset === anchorSize) {
6479
+ const next = anchorNode.getNextSibling();
6480
+ if ($isTextNode(next) && next.canInsertTextBefore() && !$isTokenOrSegmented(next)) next.select(0, 0);
6481
+ else {
6482
+ const newNode = $createTextNode();
6483
+ newNode.setFormat(format);
6484
+ newNode.setStyle(style);
6485
+ if (!anchorParent.canInsertTextAfter()) anchorParent.insertAfter(newNode);
6486
+ else anchorNode.insertAfter(newNode);
6487
+ newNode.select(0, 0);
6523
6488
  }
6489
+ this.insertText(text);
6490
+ return;
6524
6491
  }
6492
+ const newNode = $createTextNode(text);
6493
+ newNode.setFormat(format);
6494
+ newNode.setStyle(style);
6495
+ anchorNode.replace(newNode);
6496
+ newNode.select();
6497
+ return;
6498
+ }
6499
+ if (text === "") return;
6500
+ const atStartOfInline = anchorParent.isInline() && offset === 0 && !anchorNode.__prev;
6501
+ const atEndOfInline = anchorParent.isInline() && offset === anchorSize && !anchorNode.__next;
6502
+ const formatDiffers = anchorNode.getFormat() !== format || anchorNode.getStyle() !== style;
6503
+ if (atStartOfInline || atEndOfInline || formatDiffers) if (anchorNode.getTextContent() === "" && !atStartOfInline && !atEndOfInline) {
6504
+ anchorNode.setFormat(format);
6505
+ anchorNode.setStyle(style);
6525
6506
  } else {
6526
- const markedNodeKeysForKeep = /* @__PURE__ */ new Set([...firstNode.getParentKeys(), ...lastNode.getParentKeys()]);
6527
- const firstElement = $isElementNode(firstNode) ? firstNode : firstNode.getParentOrThrow();
6528
- let lastElement = $isElementNode(lastNode) ? lastNode : lastNode.getParentOrThrow();
6529
- let lastElementChild = lastNode;
6530
- if (!firstElement.is(lastElement) && lastElement.isInline()) do {
6531
- lastElementChild = lastElement;
6532
- lastElement = lastElement.getParentOrThrow();
6533
- } while (lastElement.isInline());
6534
- if (endPoint.type === "text" && (endOffset !== 0 || lastNode.getTextContent() === "") || endPoint.type === "element" && lastNode.getIndexWithinParent() < endOffset) if ($isTextNode(lastNode) && !$isTokenOrTab(lastNode) && endOffset !== lastNode.getTextContentSize()) {
6535
- if (lastNode.isSegmented()) {
6536
- const textNode = $createTextNode(lastNode.getTextContent());
6537
- lastNode.replace(textNode);
6538
- lastNode = textNode;
6539
- }
6540
- if (!$isRootNode(endPoint.getNode()) && endPoint.type === "text") {
6541
- if (!$isTextNode(lastNode)) formatDevErrorMessage(`insertText: lastNode is not a TextNode`);
6542
- lastNode = lastNode.spliceText(0, endOffset, "");
6543
- }
6544
- markedNodeKeysForKeep.add(lastNode.__key);
6545
- } else {
6546
- const lastNodeParent = lastNode.getParentOrThrow();
6547
- if (!lastNodeParent.canBeEmpty() && lastNodeParent.getChildrenSize() === 1) lastNodeParent.remove();
6548
- else lastNode.remove();
6549
- }
6550
- else markedNodeKeysForKeep.add(lastNode.__key);
6551
- const lastNodeChildren = lastElement.getChildren();
6552
- const selectedNodesSet = new Set(selectedNodes);
6553
- const firstAndLastElementsAreEqual = firstElement.is(lastElement);
6554
- const insertionTarget = firstElement.isInline() && firstNode.getNextSibling() === null ? firstElement : firstNode;
6555
- for (let i = lastNodeChildren.length - 1; i >= 0; i--) {
6556
- const lastNodeChild = lastNodeChildren[i];
6557
- if (lastNodeChild.is(firstNode) || $isElementNode(lastNodeChild) && lastNodeChild.isParentOf(firstNode)) break;
6558
- if (lastNodeChild.isAttached()) if (!selectedNodesSet.has(lastNodeChild) || lastNodeChild.is(lastElementChild)) {
6559
- if (!firstAndLastElementsAreEqual) insertionTarget.insertAfter(lastNodeChild, false);
6560
- } else lastNodeChild.remove();
6561
- }
6562
- if (!firstAndLastElementsAreEqual) {
6563
- let parent = lastElement;
6564
- let lastRemovedParent = null;
6565
- while (parent !== null) {
6566
- const children = parent.getChildren();
6567
- const childrenLength = children.length;
6568
- if (childrenLength === 0 || children[childrenLength - 1].is(lastRemovedParent)) {
6569
- markedNodeKeysForKeep.delete(parent.__key);
6570
- lastRemovedParent = parent;
6571
- }
6572
- parent = parent.getParent();
6573
- }
6574
- }
6575
- if (!$isTokenOrTab(firstNode)) {
6576
- firstNode = firstNode.spliceText(startOffset, firstNodeTextLength - startOffset, text, true);
6577
- if (firstNode.getTextContent() === "") firstNode.remove();
6578
- else if (this.anchor.type === "text") {
6579
- this.format = firstNode.getFormat();
6580
- this.style = firstNode.getStyle();
6581
- if (firstNode.isComposing()) {
6582
- this.anchor.offset -= text.length;
6583
- this._cachedNodes = null;
6584
- this._cachedIsBackward = null;
6585
- }
6586
- }
6587
- } else if (startOffset === firstNodeTextLength) firstNode.select();
6588
- else {
6589
- const textNode = $createTextNode(text);
6590
- textNode.select();
6591
- firstNode.replace(textNode);
6592
- }
6593
- for (let i = 1; i < selectedNodesLength; i++) {
6594
- const selectedNode = selectedNodes[i];
6595
- const key = selectedNode.__key;
6596
- if (!markedNodeKeysForKeep.has(key)) selectedNode.remove();
6597
- }
6507
+ $insertTextAtPoint(this, text, format, style);
6508
+ return;
6598
6509
  }
6510
+ anchorNode.spliceText(offset, 0, text, true);
6511
+ if (anchorNode.isComposing() && this.anchor.type === "text") this.anchor.set(this.anchor.key, this.anchor.offset - text.length, this.anchor.type);
6599
6512
  }
6600
6513
  /**
6601
6514
  * Removes the text in the Selection, adjusting the EditorState accordingly.
@@ -8503,7 +8416,7 @@ function $commitPendingUpdatesImpl(editor, recoveryEditorState) {
8503
8416
  }
8504
8417
  }
8505
8418
  if (mutatedNodes !== null) triggerMutationListeners(editor, mutatedNodes, tags, dirtyLeaves, currentEditorState);
8506
- if (!$isRangeSelection(pendingSelection) && pendingSelection !== null && (currentSelection === null || !currentSelection.is(pendingSelection))) editor.dispatchCommand(SELECTION_CHANGE_COMMAND, void 0);
8419
+ if (!$isRangeSelection(pendingSelection) && pendingSelection !== null && (currentSelection === null || !currentSelection.is(pendingSelection))) editor.dispatchCommand(SELECTION_CHANGE_COMMAND);
8507
8420
  /**
8508
8421
  * Capture pendingDecorators after garbage collecting detached decorators
8509
8422
  */
@@ -8754,7 +8667,10 @@ function $beginUpdate(editor, updateFn, options) {
8754
8667
  * within an update
8755
8668
  */
8756
8669
  function updateEditorSync(editor, updateFn, options) {
8757
- if (activeEditor === editor && options === void 0) updateFn();
8670
+ if (activeEditor === editor && options === void 0) if (isCurrentlyReadOnlyMode()) {
8671
+ console.warn("updateEditorSync: an editor update (e.g. a command listener that mutates the editor) ran while a read-only context was on the stack. This most commonly happens when a command is dispatched from inside editor.read(). The update has been deferred to a fresh writable update so it still applies, but dispatching mutations from a read-only context is an anti-pattern — dispatch after editor.read() returns, or via queueMicrotask.");
8672
+ $beginUpdate(editor, updateFn, options);
8673
+ } else updateFn();
8758
8674
  else $beginUpdate(editor, updateFn, options);
8759
8675
  }
8760
8676
  function updateEditor(editor, updateFn, options) {
@@ -9434,14 +9350,11 @@ function $isDecoratorNode(node) {
9434
9350
  return node instanceof DecoratorNode;
9435
9351
  }
9436
9352
  /** @noInheritDoc */
9437
- var RootNode = class RootNode extends ElementNode {
9353
+ var RootNode = class extends ElementNode {
9438
9354
  /** @internal */
9439
9355
  __cachedText;
9440
- static getType() {
9441
- return "root";
9442
- }
9443
- static clone() {
9444
- return new RootNode();
9356
+ $config() {
9357
+ return this.config("root", { extends: ElementNode });
9445
9358
  }
9446
9359
  constructor() {
9447
9360
  super("root");
@@ -9578,8 +9491,8 @@ var EditorState = class EditorState {
9578
9491
  */
9579
9492
  /** @internal */
9580
9493
  var ArtificialNode__DO_NOT_USE = class extends ElementNode {
9581
- static getType() {
9582
- return "artificial";
9494
+ $config() {
9495
+ return this.config("artificial", { extends: ElementNode });
9583
9496
  }
9584
9497
  createDOM(config) {
9585
9498
  return $getDocument().createElement("div");
@@ -9593,16 +9506,16 @@ var ArtificialNode__DO_NOT_USE = class extends ElementNode {
9593
9506
  *
9594
9507
  */
9595
9508
  /** @noInheritDoc */
9596
- var LineBreakNode = class LineBreakNode extends LexicalNode {
9509
+ var LineBreakNode = class extends LexicalNode {
9597
9510
  /** @internal */
9598
- static getType() {
9599
- return "linebreak";
9600
- }
9601
- static clone(node) {
9602
- return new LineBreakNode(node.__key);
9603
- }
9604
- constructor(key) {
9605
- super(key);
9511
+ $config() {
9512
+ return this.config("linebreak", { importDOM: { br: (node) => {
9513
+ if (isOnlyChildInBlockNode(node) || isLastChildInBlockNode(node)) return null;
9514
+ return {
9515
+ conversion: $convertLineBreakElement,
9516
+ priority: 0
9517
+ };
9518
+ } } });
9606
9519
  }
9607
9520
  getTextContent() {
9608
9521
  return "\n";
@@ -9616,18 +9529,6 @@ var LineBreakNode = class LineBreakNode extends LexicalNode {
9616
9529
  isInline() {
9617
9530
  return true;
9618
9531
  }
9619
- static importDOM() {
9620
- return { br: (node) => {
9621
- if (isOnlyChildInBlockNode(node) || isLastChildInBlockNode(node)) return null;
9622
- return {
9623
- conversion: $convertLineBreakElement,
9624
- priority: 0
9625
- };
9626
- } };
9627
- }
9628
- static importJSON(serializedLineBreakNode) {
9629
- return $createLineBreakNode().updateFromJSON(serializedLineBreakNode);
9630
- }
9631
9532
  };
9632
9533
  function $convertLineBreakElement(node) {
9633
9534
  return { node: $createLineBreakNode() };
@@ -9686,13 +9587,16 @@ function isWhitespaceDomTextNode(node) {
9686
9587
  *
9687
9588
  */
9688
9589
  /** @noInheritDoc */
9689
- var ParagraphNode = class ParagraphNode extends ElementNode {
9590
+ var ParagraphNode = class extends ElementNode {
9690
9591
  /** @internal */
9691
- static getType() {
9692
- return "paragraph";
9693
- }
9694
- static clone(node) {
9695
- return new ParagraphNode(node.__key);
9592
+ $config() {
9593
+ return this.config("paragraph", {
9594
+ extends: ElementNode,
9595
+ importDOM: { p: () => ({
9596
+ conversion: $convertParagraphElement,
9597
+ priority: 0
9598
+ }) }
9599
+ });
9696
9600
  }
9697
9601
  createDOM(config) {
9698
9602
  const dom = $getDocument().createElement("p");
@@ -9703,12 +9607,6 @@ var ParagraphNode = class ParagraphNode extends ElementNode {
9703
9607
  updateDOM(prevNode, dom, config) {
9704
9608
  return false;
9705
9609
  }
9706
- static importDOM() {
9707
- return { p: (node) => ({
9708
- conversion: $convertParagraphElement,
9709
- priority: 0
9710
- }) };
9711
- }
9712
9610
  exportDOM(editor) {
9713
9611
  const { element } = super.exportDOM(editor);
9714
9612
  if (isHTMLElement(element)) {
@@ -9718,9 +9616,6 @@ var ParagraphNode = class ParagraphNode extends ElementNode {
9718
9616
  }
9719
9617
  return { element };
9720
9618
  }
9721
- static importJSON(serializedNode) {
9722
- return $createParagraphNode().updateFromJSON(serializedNode);
9723
- }
9724
9619
  exportJSON() {
9725
9620
  const json = super.exportJSON();
9726
9621
  if (json.textFormat === void 0 || json.textStyle === void 0) {
@@ -10492,8 +10387,8 @@ var LexicalEditor = class {
10492
10387
  * @param type - the type of command listeners to trigger.
10493
10388
  * @param payload - the data to pass as an argument to the command listeners.
10494
10389
  */
10495
- dispatchCommand(type, payload) {
10496
- return dispatchCommand(this, type, payload);
10390
+ dispatchCommand(type, ...args) {
10391
+ return dispatchCommand(this, type, ...args);
10497
10392
  }
10498
10393
  /**
10499
10394
  * Gets a map of all decorators in the editor.
@@ -10728,6 +10623,7 @@ function getPendingNodeToClone() {
10728
10623
  pendingNodeToClone = null;
10729
10624
  return node;
10730
10625
  }
10626
+ const INTERNAL_SKIP_AFTER_CLONE_FROM = Symbol("INTERNAL_SKIP_AFTER_CLONE_FROM");
10731
10627
  let keyCounter = 1;
10732
10628
  function resetRandomKey() {
10733
10629
  keyCounter = 1;
@@ -11480,8 +11376,8 @@ function isFirefoxClipboardEvents(editor) {
11480
11376
  const inputType = event && event.inputType;
11481
11377
  return inputType === "insertFromPaste" || inputType === "insertFromPasteAsQuotation";
11482
11378
  }
11483
- function dispatchCommand(editor, command, payload) {
11484
- return triggerCommandListeners(editor, command, payload, editor);
11379
+ function dispatchCommand(editor, command, ...args) {
11380
+ return triggerCommandListeners(editor, command, args[0], editor);
11485
11381
  }
11486
11382
  function getElementByKeyOrThrow(editor, key) {
11487
11383
  const element = editor._keyToDOMMap.get(key);
@@ -11620,7 +11516,7 @@ function $isRootOrShadowRoot(node) {
11620
11516
  * @returns The copy of the node.
11621
11517
  */
11622
11518
  function $copyNode(node, skipReset = false) {
11623
- const copy = node.constructor.clone(node);
11519
+ const copy = node.constructor.clone(node, INTERNAL_SKIP_AFTER_CLONE_FROM);
11624
11520
  $setNodeKey(copy, null);
11625
11521
  copy.afterCloneFrom(node);
11626
11522
  if (!skipReset) copy.resetOnCopyNodeFrom(node);
@@ -12358,7 +12254,7 @@ function computeTypeToNodeMap(editorState) {
12358
12254
  */
12359
12255
  function $cloneWithProperties(latestNode) {
12360
12256
  const constructor = latestNode.constructor;
12361
- const mutableNode = constructor.clone(latestNode);
12257
+ const mutableNode = constructor.clone(latestNode, INTERNAL_SKIP_AFTER_CLONE_FROM);
12362
12258
  mutableNode.afterCloneFrom(latestNode);
12363
12259
  if (!(mutableNode.__key === latestNode.__key)) formatDevErrorMessage(`$cloneWithProperties: ${constructor.name}.clone(node) (with type '${constructor.getType()}') did not return a node with the same key, make sure to specify node.__key as the last argument to the constructor`);
12364
12260
  if (!(mutableNode.__parent === latestNode.__parent && mutableNode.__next === latestNode.__next && mutableNode.__prev === latestNode.__prev)) formatDevErrorMessage(`$cloneWithProperties: ${constructor.name}.clone(node) (with type '${constructor.getType()}') overrode afterCloneFrom but did not call super.afterCloneFrom(prevNode)`);
@@ -12533,13 +12429,16 @@ function isAbstractNodeClass(klass) {
12533
12429
  return klass === DecoratorNode || klass === ElementNode || klass === LexicalNode;
12534
12430
  }
12535
12431
  const STATIC_NODE_CONFIG_CACHE = /* @__PURE__ */ new WeakMap();
12432
+ const SYNTHESIZED_GET_TYPE = Symbol("lexical.synthesizedGetType");
12433
+ const IS_UNOPTIMIZED_DEV_BUILD = TabNode.length === 0 && TextNode.length === 0 && TextNode.name === "TextNode";
12536
12434
  /** @internal */
12537
12435
  function getStaticNodeConfig(klass) {
12538
12436
  const cache = STATIC_NODE_CONFIG_CACHE.get(klass);
12539
12437
  if (cache) return cache;
12540
12438
  const nodeConfigRecord = klass.prototype != null && PROTOTYPE_CONFIG_METHOD in klass.prototype ? klass.prototype[PROTOTYPE_CONFIG_METHOD]() : void 0;
12541
12439
  const isAbstract = isAbstractNodeClass(klass);
12542
- const nodeType = !isAbstract && hasOwnStaticMethod(klass, "getType") ? klass.getType() : void 0;
12440
+ const ownGetType = !isAbstract && hasOwnStaticMethod(klass, "getType") ? klass.getType : void 0;
12441
+ const nodeType = ownGetType && !(SYNTHESIZED_GET_TYPE in ownGetType) ? ownGetType.call(klass) : void 0;
12543
12442
  let ownNodeConfig;
12544
12443
  let ownNodeType = nodeType;
12545
12444
  if (nodeConfigRecord) if (nodeType) ownNodeConfig = nodeConfigRecord[nodeType];
@@ -12557,18 +12456,28 @@ function getStaticNodeConfig(klass) {
12557
12456
  }
12558
12457
  }
12559
12458
  if (!isAbstract && ownNodeType) {
12560
- if (!hasOwnStaticMethod(klass, "getType")) klass.getType = () => ownNodeType;
12459
+ if (!hasOwnStaticMethod(klass, "getType")) {
12460
+ const synthesizedForKlass = klass;
12461
+ const synthesizedGetType = function() {
12462
+ if (this !== synthesizedForKlass) return LexicalNode.getType.call(this);
12463
+ return ownNodeType;
12464
+ };
12465
+ synthesizedGetType[SYNTHESIZED_GET_TYPE] = true;
12466
+ klass.getType = synthesizedGetType;
12467
+ }
12561
12468
  if (!hasOwnStaticMethod(klass, "clone")) {
12562
- if (TextNode.length === 0) {
12469
+ if (IS_UNOPTIMIZED_DEV_BUILD) {
12563
12470
  if (!(klass.length === 0)) formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static clone method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
12564
12471
  }
12565
- klass.clone = (prevNode) => {
12472
+ klass.clone = (prevNode, internalSkipAfterCloneFrom) => {
12566
12473
  setPendingNodeToClone(prevNode);
12567
- return new klass();
12474
+ const node = new klass();
12475
+ if (internalSkipAfterCloneFrom !== INTERNAL_SKIP_AFTER_CLONE_FROM) node.afterCloneFrom(prevNode);
12476
+ return node;
12568
12477
  };
12569
12478
  }
12570
12479
  if (!hasOwnStaticMethod(klass, "importJSON")) {
12571
- if (TextNode.length === 0) {
12480
+ if (IS_UNOPTIMIZED_DEV_BUILD) {
12572
12481
  if (!(klass.length === 0)) formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static importJSON method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
12573
12482
  }
12574
12483
  klass.importJSON = ownNodeConfig && ownNodeConfig.$importJSON || ((serializedNode) => new klass().updateFromJSON(serializedNode));
@@ -13876,7 +13785,13 @@ function $removeTextFromCaretRange(initialRange, sliceMode = "removeEmptySlices"
13876
13785
  const { origin } = caret;
13877
13786
  if (!$isElementNode(origin) || seenStart.has(origin.getKey())) removedNodes.push(origin);
13878
13787
  }
13879
- for (const node of removedNodes) node.remove();
13788
+ const removedParents = /* @__PURE__ */ new Set();
13789
+ for (const node of removedNodes) {
13790
+ const parent = node.getParent();
13791
+ if (parent !== null && !seenStart.has(parent.getKey())) removedParents.add(parent);
13792
+ $removeFromParent(node);
13793
+ }
13794
+ for (const parent of removedParents) if (!parent.canBeEmpty() && !$isRootOrShadowRoot(parent) && parent.isEmpty() && parent.isAttached()) parent.remove();
13880
13795
  for (const slice of range.getTextSlices()) {
13881
13796
  if (!slice) continue;
13882
13797
  const { origin } = slice.caret;