@portabletext/editor 6.1.2 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react/compiler-runtime";
3
3
  import { useSelector, useActorRef } from "@xstate/react";
4
- import React, { useRef, useEffect, useLayoutEffect, useState, createContext, useContext, Fragment, useReducer, useCallback, useMemo, memo, forwardRef, Component, startTransition } from "react";
4
+ import React, { useRef, useEffect, useLayoutEffect, useState, createContext, useContext, useReducer, useCallback, useMemo, memo, forwardRef, Component, startTransition } from "react";
5
5
  import rawDebug from "debug";
6
6
  import { createKeyboardShortcut, code, underline, italic as italic$1, bold as bold$1, undo as undo$1, redo as redo$1 } from "@portabletext/keyboard-shortcuts";
7
7
  import { getBlockEndPoint, getBlockStartPoint, getBlockKeyFromSelectionPoint, isSelectionCollapsed, isKeyedSegment, isEqualSelectionPoints, getChildKeyFromSelectionPoint, blockOffsetToSpanSelectionPoint, defaultKeyGenerator, parseBlocks, parseBlock, isListBlock, getSelectionStartPoint as getSelectionStartPoint$1, getSelectionEndPoint as getSelectionEndPoint$1, parseAnnotation, parseMarkDefs, parseSpan, parseInlineObject, isEqualPathSegments } from "./_chunks-es/util.slice-blocks.js";
@@ -16,7 +16,7 @@ import { defineBehavior, forward, raise, effect } from "./behaviors/index.js";
16
16
  import { htmlToPortableText } from "@portabletext/html";
17
17
  import { toHTML } from "@portabletext/to-html";
18
18
  import { markdownToPortableText, portableTextToMarkdown } from "@portabletext/markdown";
19
- import { applyAll, unset, insert, setIfMissing, set, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
19
+ import { applyAll, set, unset, insert, setIfMissing, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
20
20
  import { EditorContext as EditorContext$1 } from "./_chunks-es/use-editor.js";
21
21
  import { useEditor } from "./_chunks-es/use-editor.js";
22
22
  const rootName = "pte:";
@@ -44,10 +44,6 @@ const debug$1 = {
44
44
  return Path.isPath(value.path) && isObject(value.node);
45
45
  case "insert_text":
46
46
  return typeof value.offset == "number" && typeof value.text == "string" && Path.isPath(value.path);
47
- case "merge_node":
48
- return typeof value.position == "number" && Path.isPath(value.path) && isObject(value.properties);
49
- case "move_node":
50
- return Path.isPath(value.path) && Path.isPath(value.newPath);
51
47
  case "remove_node":
52
48
  return Path.isPath(value.path) && isObject(value.node);
53
49
  case "remove_text":
@@ -56,8 +52,6 @@ const debug$1 = {
56
52
  return Path.isPath(value.path) && isObject(value.properties) && isObject(value.newProperties);
57
53
  case "set_selection":
58
54
  return value.properties === null && Range.isRange(value.newProperties) || value.newProperties === null && Range.isRange(value.properties) || isObject(value.properties) && isObject(value.newProperties);
59
- case "split_node":
60
- return Path.isPath(value.path) && typeof value.position == "number" && isObject(value.properties);
61
55
  default:
62
56
  return !1;
63
57
  }
@@ -77,32 +71,6 @@ const debug$1 = {
77
71
  ...op,
78
72
  type: "remove_text"
79
73
  };
80
- case "merge_node":
81
- return {
82
- ...op,
83
- type: "split_node",
84
- path: Path.previous(op.path)
85
- };
86
- case "move_node": {
87
- const {
88
- newPath,
89
- path: path2
90
- } = op;
91
- if (Path.equals(newPath, path2))
92
- return op;
93
- if (Path.isSibling(path2, newPath))
94
- return {
95
- ...op,
96
- path: newPath,
97
- newPath: path2
98
- };
99
- const inversePath = Path.transform(path2, op), inverseNewPath = Path.transform(Path.next(path2), op);
100
- return {
101
- ...op,
102
- path: inversePath,
103
- newPath: inverseNewPath
104
- };
105
- }
106
74
  case "remove_node":
107
75
  return {
108
76
  ...op,
@@ -143,12 +111,6 @@ const debug$1 = {
143
111
  newProperties: properties
144
112
  };
145
113
  }
146
- case "split_node":
147
- return {
148
- ...op,
149
- type: "merge_node",
150
- path: Path.next(op.path)
151
- };
152
114
  }
153
115
  }
154
116
  }, Range = {
@@ -505,14 +467,11 @@ const debug$1 = {
505
467
  }, PathRef = {
506
468
  transform(ref, op) {
507
469
  const {
508
- current,
509
- affinity
470
+ current
510
471
  } = ref;
511
472
  if (current == null)
512
473
  return;
513
- const path2 = Path.transform(current, op, {
514
- affinity
515
- });
474
+ const path2 = Path.transform(current, op);
516
475
  ref.current = path2, path2 == null && ref.unref();
517
476
  }
518
477
  }, Path = {
@@ -595,9 +554,6 @@ const debug$1 = {
595
554
  switch (operation.type) {
596
555
  case "insert_node":
597
556
  case "remove_node":
598
- case "merge_node":
599
- case "split_node":
600
- case "move_node":
601
557
  return !0;
602
558
  default:
603
559
  return !1;
@@ -616,12 +572,10 @@ const debug$1 = {
616
572
  throw new Error(`Cannot get the previous path of a first child path [${path2}] because it would result in a negative index.`);
617
573
  return path2.slice(0, -1).concat(last - 1);
618
574
  },
619
- transform(path2, operation, options = {}) {
575
+ transform(path2, operation) {
620
576
  if (!path2)
621
577
  return null;
622
- const p = [...path2], {
623
- affinity = "forward"
624
- } = options;
578
+ const p = [...path2];
625
579
  if (path2.length === 0)
626
580
  return p;
627
581
  switch (operation.type) {
@@ -641,40 +595,6 @@ const debug$1 = {
641
595
  Path.endsBefore(op, p) && (p[op.length - 1] = p[op.length - 1] - 1);
642
596
  break;
643
597
  }
644
- case "merge_node": {
645
- const {
646
- path: op,
647
- position
648
- } = operation;
649
- Path.equals(op, p) || Path.endsBefore(op, p) ? p[op.length - 1] = p[op.length - 1] - 1 : Path.isAncestor(op, p) && (p[op.length - 1] = p[op.length - 1] - 1, p[op.length] = p[op.length] + position);
650
- break;
651
- }
652
- case "split_node": {
653
- const {
654
- path: op,
655
- position
656
- } = operation;
657
- if (Path.equals(op, p)) {
658
- if (affinity === "forward")
659
- p[p.length - 1] = p[p.length - 1] + 1;
660
- else if (affinity !== "backward")
661
- return null;
662
- } else Path.endsBefore(op, p) ? p[op.length - 1] = p[op.length - 1] + 1 : Path.isAncestor(op, p) && path2[op.length] >= position && (p[op.length - 1] = p[op.length - 1] + 1, p[op.length] = p[op.length] - position);
663
- break;
664
- }
665
- case "move_node": {
666
- const {
667
- path: op,
668
- newPath: onp
669
- } = operation;
670
- if (Path.equals(op, onp))
671
- return p;
672
- if (Path.isAncestor(op, p) || Path.equals(op, p)) {
673
- const copy = onp.slice();
674
- return Path.endsBefore(op, onp) && op.length < onp.length && (copy[op.length - 1] = copy[op.length - 1] - 1), copy.concat(p.slice(op.length));
675
- } else Path.isSibling(op, onp) && (Path.isAncestor(onp, p) || Path.equals(onp, p)) ? Path.endsBefore(op, p) ? p[op.length - 1] = p[op.length - 1] - 1 : p[op.length - 1] = p[op.length - 1] + 1 : Path.endsBefore(onp, p) || Path.equals(onp, p) || Path.isAncestor(onp, p) ? (Path.endsBefore(op, p) && (p[op.length - 1] = p[op.length - 1] - 1), p[onp.length - 1] = p[onp.length - 1] + 1) : Path.endsBefore(op, p) && (Path.equals(onp, p) && (p[onp.length - 1] = p[onp.length - 1] + 1), p[op.length - 1] = p[op.length - 1] - 1);
676
- break;
677
- }
678
598
  }
679
599
  return p;
680
600
  }
@@ -719,19 +639,14 @@ const debug$1 = {
719
639
  offset
720
640
  } = point2;
721
641
  switch (op.type) {
722
- case "insert_node":
723
- case "move_node": {
724
- path2 = Path.transform(path2, op, options);
642
+ case "insert_node": {
643
+ path2 = Path.transform(path2, op);
725
644
  break;
726
645
  }
727
646
  case "insert_text": {
728
647
  Path.equals(op.path, path2) && (op.offset < offset || op.offset === offset && affinity === "forward") && (offset += op.text.length);
729
648
  break;
730
649
  }
731
- case "merge_node": {
732
- Path.equals(op.path, path2) && (offset += op.position), path2 = Path.transform(path2, op, options);
733
- break;
734
- }
735
650
  case "remove_text": {
736
651
  Path.equals(op.path, path2) && op.offset <= offset && (offset -= Math.min(offset - op.offset, op.text.length));
737
652
  break;
@@ -739,19 +654,7 @@ const debug$1 = {
739
654
  case "remove_node": {
740
655
  if (Path.equals(op.path, path2) || Path.isAncestor(op.path, path2))
741
656
  return null;
742
- path2 = Path.transform(path2, op, options);
743
- break;
744
- }
745
- case "split_node": {
746
- if (Path.equals(op.path, path2)) {
747
- if (op.position === offset && affinity == null)
748
- return null;
749
- (op.position < offset || op.position === offset && affinity === "forward") && (offset -= op.position, path2 = Path.transform(path2, op, {
750
- ...options,
751
- affinity: "forward"
752
- }));
753
- } else
754
- path2 = Path.transform(path2, op, options);
657
+ path2 = Path.transform(path2, op);
755
658
  break;
756
659
  }
757
660
  default:
@@ -906,42 +809,6 @@ const debug$1 = {
906
809
  }), transformSelection = !0;
907
810
  break;
908
811
  }
909
- case "merge_node": {
910
- const {
911
- path: path2
912
- } = op, index = path2[path2.length - 1], prevPath = Path.previous(path2), prevIndex = prevPath[prevPath.length - 1];
913
- modifyChildren(editor, Path.parent(path2), editor.schema, (children) => {
914
- const node2 = children[index], prev = children[prevIndex];
915
- let newNode;
916
- if (Text$1.isText(node2, editor.schema) && Text$1.isText(prev, editor.schema))
917
- newNode = {
918
- ...prev,
919
- text: prev.text + node2.text
920
- };
921
- else if (!Text$1.isText(node2, editor.schema) && !Text$1.isText(prev, editor.schema))
922
- newNode = {
923
- ...prev,
924
- children: prev.children.concat(node2.children)
925
- };
926
- else
927
- throw new Error(`Cannot apply a "merge_node" operation at path [${path2}] to nodes of different interfaces: ${Scrubber.stringify(node2)} ${Scrubber.stringify(prev)}`);
928
- return replaceChildren(children, prevIndex, 2, newNode);
929
- }), transformSelection = !0;
930
- break;
931
- }
932
- case "move_node": {
933
- const {
934
- path: path2,
935
- newPath
936
- } = op, index = path2[path2.length - 1];
937
- if (Path.isAncestor(path2, newPath))
938
- throw new Error(`Cannot move a path [${path2}] to new path [${newPath}] because the destination is inside itself.`);
939
- const node2 = Node$1.get(editor, path2, editor.schema);
940
- modifyChildren(editor, Path.parent(path2), editor.schema, (children) => removeChildren(children, index, 1));
941
- const truePath = Path.transform(path2, op), newIndex = truePath[truePath.length - 1];
942
- modifyChildren(editor, Path.parent(truePath), editor.schema, (children) => insertChildren(children, newIndex, node2)), transformSelection = !0;
943
- break;
944
- }
945
812
  case "remove_node": {
946
813
  const {
947
814
  path: path2
@@ -1051,40 +918,6 @@ const debug$1 = {
1051
918
  editor.selection = selection;
1052
919
  break;
1053
920
  }
1054
- case "split_node": {
1055
- const {
1056
- path: path2,
1057
- position,
1058
- properties
1059
- } = op, index = path2[path2.length - 1];
1060
- if (path2.length === 0)
1061
- throw new Error(`Cannot apply a "split_node" operation at path [${path2}] because the root node cannot be split.`);
1062
- modifyChildren(editor, Path.parent(path2), editor.schema, (children) => {
1063
- const node2 = children[index];
1064
- let newNode, nextNode;
1065
- if (Text$1.isText(node2, editor.schema)) {
1066
- const before2 = node2.text.slice(0, position), after2 = node2.text.slice(position);
1067
- newNode = {
1068
- ...node2,
1069
- text: before2
1070
- }, nextNode = {
1071
- ...properties,
1072
- text: after2
1073
- };
1074
- } else {
1075
- const before2 = node2.children.slice(0, position), after2 = node2.children.slice(position);
1076
- newNode = {
1077
- ...node2,
1078
- children: before2
1079
- }, nextNode = {
1080
- ...properties,
1081
- children: after2
1082
- };
1083
- }
1084
- return replaceChildren(children, index, 1, newNode, nextNode);
1085
- }), transformSelection = !0;
1086
- break;
1087
- }
1088
921
  }
1089
922
  if (transformSelection && editor.selection) {
1090
923
  const selection = {
@@ -1099,17 +932,8 @@ const debug$1 = {
1099
932
  insertNodes(editor, nodes2, options) {
1100
933
  editor.insertNodes(nodes2, options);
1101
934
  },
1102
- mergeNodes(editor, options) {
1103
- editor.mergeNodes(options);
1104
- },
1105
- moveNodes(editor, options) {
1106
- editor.moveNodes(options);
1107
- },
1108
935
  removeNodes(editor, options) {
1109
936
  editor.removeNodes(options);
1110
- },
1111
- splitNodes(editor, options) {
1112
- editor.splitNodes(options);
1113
937
  }
1114
938
  }, SelectionTransforms = {
1115
939
  collapse(editor, options) {
@@ -1477,43 +1301,12 @@ const apply$1 = (editor, op) => {
1477
1301
  } = op, levels2 = Path.levels(path2), descendants = Text$1.isText(node2, _editor.schema) ? [] : Array.from(Node$1.nodes(node2, _editor.schema), ([, p]) => path2.concat(p));
1478
1302
  return [...levels2, ...descendants];
1479
1303
  }
1480
- case "merge_node": {
1481
- const {
1482
- path: path2
1483
- } = op, ancestors = Path.ancestors(path2), previousPath = Path.previous(path2);
1484
- return [...ancestors, previousPath];
1485
- }
1486
- case "move_node": {
1487
- const {
1488
- path: path2,
1489
- newPath
1490
- } = op;
1491
- if (Path.equals(path2, newPath))
1492
- return [];
1493
- const oldAncestors = [], newAncestors = [];
1494
- for (const ancestor of Path.ancestors(path2)) {
1495
- const p = Path.transform(ancestor, op);
1496
- oldAncestors.push(p);
1497
- }
1498
- for (const ancestor of Path.ancestors(newPath)) {
1499
- const p = Path.transform(ancestor, op);
1500
- newAncestors.push(p);
1501
- }
1502
- const newParent = newAncestors[newAncestors.length - 1], newIndex = newPath[newPath.length - 1], resultPath = newParent.concat(newIndex);
1503
- return [...oldAncestors, ...newAncestors, resultPath];
1504
- }
1505
1304
  case "remove_node": {
1506
1305
  const {
1507
1306
  path: path2
1508
1307
  } = op;
1509
1308
  return [...Path.ancestors(path2)];
1510
1309
  }
1511
- case "split_node": {
1512
- const {
1513
- path: path2
1514
- } = op, levels2 = Path.levels(path2), nextPath = Path.next(path2);
1515
- return [...levels2, nextPath];
1516
- }
1517
1310
  default:
1518
1311
  return [];
1519
1312
  }
@@ -1522,7 +1315,143 @@ const apply$1 = (editor, op) => {
1522
1315
  selection
1523
1316
  } = editor;
1524
1317
  return selection ? Node$1.fragment(editor, selection, editor.schema) : [];
1525
- }, normalizeNode = (editor, entry) => {
1318
+ };
1319
+ function applyMergeNode(editor, path2, position) {
1320
+ const node2 = Node$1.get(editor, path2, editor.schema), prevPath = Path.previous(path2);
1321
+ for (const ref of Editor.pathRefs(editor)) {
1322
+ const current = ref.current;
1323
+ current && (ref.current = transformPathForMerge(current, path2, position));
1324
+ }
1325
+ for (const ref of Editor.pointRefs(editor)) {
1326
+ const current = ref.current;
1327
+ current && (ref.current = transformPointForMerge(current, path2, position));
1328
+ }
1329
+ for (const ref of Editor.rangeRefs(editor)) {
1330
+ const current = ref.current;
1331
+ if (current) {
1332
+ const anchor = transformPointForMerge(current.anchor, path2, position), focus = transformPointForMerge(current.focus, path2, position);
1333
+ anchor && focus ? ref.current = {
1334
+ anchor,
1335
+ focus
1336
+ } : (ref.current = null, ref.unref());
1337
+ }
1338
+ }
1339
+ if (editor.selection) {
1340
+ const anchor = transformPointForMerge(editor.selection.anchor, path2, position), focus = transformPointForMerge(editor.selection.focus, path2, position);
1341
+ anchor && focus && (editor.selection = {
1342
+ anchor,
1343
+ focus
1344
+ });
1345
+ }
1346
+ const pathRefs = new Set(Editor.pathRefs(editor)), pointRefs = new Set(Editor.pointRefs(editor)), rangeRefs = new Set(Editor.rangeRefs(editor));
1347
+ Editor.pathRefs(editor).clear(), Editor.pointRefs(editor).clear(), Editor.rangeRefs(editor).clear();
1348
+ const savedSelection = editor.selection, editorAny = editor, savedPendingDiffs = editorAny.pendingDiffs, savedPendingSelection = editorAny.pendingSelection, savedPendingAction = editorAny.pendingAction;
1349
+ if (Array.isArray(savedPendingDiffs) && savedPendingDiffs.length > 0 && (editorAny.pendingDiffs = savedPendingDiffs.map((textDiff) => transformTextDiffForMerge(textDiff, path2, position)).filter(Boolean)), savedPendingSelection && typeof savedPendingSelection == "object" && "anchor" in savedPendingSelection && "focus" in savedPendingSelection) {
1350
+ const sel = savedPendingSelection, anchor = transformPointForMerge(sel.anchor, path2, position), focus = transformPointForMerge(sel.focus, path2, position);
1351
+ editorAny.pendingSelection = anchor && focus ? {
1352
+ anchor,
1353
+ focus
1354
+ } : null;
1355
+ }
1356
+ if (savedPendingAction && typeof savedPendingAction == "object" && "at" in savedPendingAction) {
1357
+ const action = savedPendingAction;
1358
+ if ("offset" in action.at && typeof action.at.offset == "number") {
1359
+ const at = transformPointForMerge(action.at, path2, position);
1360
+ editorAny.pendingAction = at ? {
1361
+ ...action,
1362
+ at
1363
+ } : null;
1364
+ } else if (Range.isRange(action.at)) {
1365
+ const anchor = transformPointForMerge(action.at.anchor, path2, position), focus = transformPointForMerge(action.at.focus, path2, position);
1366
+ editorAny.pendingAction = anchor && focus ? {
1367
+ ...action,
1368
+ at: {
1369
+ anchor,
1370
+ focus
1371
+ }
1372
+ } : null;
1373
+ }
1374
+ }
1375
+ const preTransformedPendingDiffs = editorAny.pendingDiffs, preTransformedPendingSelection = editorAny.pendingSelection, preTransformedPendingAction = editorAny.pendingAction;
1376
+ editorAny.pendingDiffs = [], editorAny.pendingSelection = null, editorAny.pendingAction = null;
1377
+ try {
1378
+ Editor.withoutNormalizing(editor, () => {
1379
+ if (Text$1.isText(node2, editor.schema))
1380
+ node2.text.length > 0 && editor.apply({
1381
+ type: "insert_text",
1382
+ path: prevPath,
1383
+ offset: position,
1384
+ text: node2.text
1385
+ }), editor.apply({
1386
+ type: "remove_node",
1387
+ path: path2,
1388
+ node: node2
1389
+ });
1390
+ else if (Element$2.isElement(node2, editor.schema)) {
1391
+ const children = node2.children;
1392
+ for (let i = 0; i < children.length; i++)
1393
+ editor.apply({
1394
+ type: "insert_node",
1395
+ path: [...prevPath, position + i],
1396
+ node: children[i]
1397
+ });
1398
+ editor.apply({
1399
+ type: "remove_node",
1400
+ path: path2,
1401
+ node: node2
1402
+ });
1403
+ }
1404
+ });
1405
+ } finally {
1406
+ editor.selection = savedSelection;
1407
+ for (const ref of pathRefs)
1408
+ Editor.pathRefs(editor).add(ref);
1409
+ for (const ref of pointRefs)
1410
+ Editor.pointRefs(editor).add(ref);
1411
+ for (const ref of rangeRefs)
1412
+ Editor.rangeRefs(editor).add(ref);
1413
+ editorAny.pendingDiffs = preTransformedPendingDiffs, editorAny.pendingSelection = preTransformedPendingSelection, editorAny.pendingAction = preTransformedPendingAction;
1414
+ }
1415
+ }
1416
+ function transformTextDiffForMerge(textDiff, mergePath, position) {
1417
+ const {
1418
+ path: path2,
1419
+ diff: diff2,
1420
+ id
1421
+ } = textDiff;
1422
+ if (!Path.equals(mergePath, path2)) {
1423
+ const newPath = transformPathForMerge(path2, mergePath, position);
1424
+ return newPath ? {
1425
+ diff: diff2,
1426
+ id,
1427
+ path: newPath
1428
+ } : null;
1429
+ }
1430
+ return {
1431
+ diff: {
1432
+ start: diff2.start + position,
1433
+ end: diff2.end + position,
1434
+ text: diff2.text
1435
+ },
1436
+ id,
1437
+ path: transformPathForMerge(path2, mergePath, position)
1438
+ };
1439
+ }
1440
+ function transformPathForMerge(path2, mergePath, position) {
1441
+ const p = [...path2];
1442
+ return Path.equals(mergePath, p) || Path.endsBefore(mergePath, p) ? p[mergePath.length - 1] = p[mergePath.length - 1] - 1 : Path.isAncestor(mergePath, p) && (p[mergePath.length - 1] = p[mergePath.length - 1] - 1, p[mergePath.length] = p[mergePath.length] + position), p;
1443
+ }
1444
+ function transformPointForMerge(point2, mergePath, position) {
1445
+ let {
1446
+ path: path2,
1447
+ offset
1448
+ } = point2;
1449
+ return Path.equals(mergePath, path2) && (offset += position), path2 = transformPathForMerge(path2, mergePath, position), {
1450
+ path: path2,
1451
+ offset
1452
+ };
1453
+ }
1454
+ const normalizeNode = (editor, entry) => {
1526
1455
  const [node2, path2] = entry;
1527
1456
  if (Text$1.isText(node2, editor.schema) || editor.isObjectNode(node2))
1528
1457
  return;
@@ -1539,20 +1468,26 @@ const apply$1 = (editor, op) => {
1539
1468
  if (element !== editor && (editor.isInline(element) || Text$1.isText(firstChild, editor.schema) || editor.isObjectNode(firstChild) || Element$2.isElement(firstChild, editor.schema) && editor.isInline(firstChild)))
1540
1469
  for (let n2 = 0; n2 < element.children.length; n2++) {
1541
1470
  const child = element.children[n2], prev = element.children[n2 - 1];
1542
- if (Text$1.isText(child, editor.schema))
1543
- prev != null && Text$1.isText(prev, editor.schema) && (child.text === "" ? (Transforms.removeNodes(editor, {
1544
- at: path2.concat(n2),
1545
- voids: !0
1546
- }), element = Node$1.get(editor, path2, editor.schema), n2--) : prev.text === "" ? (Transforms.removeNodes(editor, {
1547
- at: path2.concat(n2 - 1),
1548
- voids: !0
1549
- }), element = Node$1.get(editor, path2, editor.schema), n2--) : Text$1.equals(child, prev, {
1550
- loose: !0
1551
- }) && (Transforms.mergeNodes(editor, {
1552
- at: path2.concat(n2),
1553
- voids: !0
1554
- }), element = Node$1.get(editor, path2, editor.schema), n2--));
1555
- else if (Element$2.isElement(child, editor.schema))
1471
+ if (Text$1.isText(child, editor.schema)) {
1472
+ if (prev != null && Text$1.isText(prev, editor.schema)) {
1473
+ if (child.text === "")
1474
+ Transforms.removeNodes(editor, {
1475
+ at: path2.concat(n2),
1476
+ voids: !0
1477
+ }), element = Node$1.get(editor, path2, editor.schema), n2--;
1478
+ else if (prev.text === "")
1479
+ Transforms.removeNodes(editor, {
1480
+ at: path2.concat(n2 - 1),
1481
+ voids: !0
1482
+ }), element = Node$1.get(editor, path2, editor.schema), n2--;
1483
+ else if (Text$1.equals(child, prev, {
1484
+ loose: !0
1485
+ })) {
1486
+ const mergePath = path2.concat(n2);
1487
+ applyMergeNode(editor, mergePath, prev.text.length), element = Node$1.get(editor, path2, editor.schema), n2--;
1488
+ }
1489
+ }
1490
+ } else if (Element$2.isElement(child, editor.schema))
1556
1491
  if (editor.isInline(child)) {
1557
1492
  if (prev == null || !Text$1.isText(prev, editor.schema)) {
1558
1493
  const newChild = editor.createSpan();
@@ -2147,7 +2082,109 @@ const previous = (editor, options = {}) => {
2147
2082
  Editor.setNormalizing(editor, value);
2148
2083
  }
2149
2084
  Editor.normalize(editor);
2150
- }, shouldMergeNodesRemovePrevNode = (_editor, [prevNode, prevPath], [_curNode, _curNodePath]) => Element$2.isElement(prevNode, _editor.schema) && (prevNode.children.length === 0 || prevNode.children.length === 1 && Text$1.isText(prevNode.children[0], _editor.schema) && prevNode.children[0].text === "") || Text$1.isText(prevNode, _editor.schema) && prevNode.text === "" && prevPath[prevPath.length - 1] !== 0, insertNodes = (editor, nodes2, options = {}) => {
2085
+ }, shouldMergeNodesRemovePrevNode = (_editor, [prevNode, prevPath], [_curNode, _curNodePath]) => Element$2.isElement(prevNode, _editor.schema) && (prevNode.children.length === 0 || prevNode.children.length === 1 && Text$1.isText(prevNode.children[0], _editor.schema) && prevNode.children[0].text === "") || Text$1.isText(prevNode, _editor.schema) && prevNode.text === "" && prevPath[prevPath.length - 1] !== 0;
2086
+ function rangeRefAffinities(range2, affinity) {
2087
+ if (affinity === "inward") {
2088
+ const isCollapsed = Range.isCollapsed(range2);
2089
+ if (Range.isForward(range2)) {
2090
+ const anchorAffinity = "forward";
2091
+ return [anchorAffinity, isCollapsed ? anchorAffinity : "backward"];
2092
+ } else {
2093
+ const anchorAffinity = "backward";
2094
+ return [anchorAffinity, isCollapsed ? anchorAffinity : "forward"];
2095
+ }
2096
+ } else return affinity === "outward" ? Range.isForward(range2) ? ["backward", "forward"] : ["forward", "backward"] : [affinity, affinity];
2097
+ }
2098
+ function applySplitNode(editor, path2, position, properties) {
2099
+ const node2 = Node$1.get(editor, path2, editor.schema);
2100
+ for (const ref of Editor.pathRefs(editor)) {
2101
+ const current = ref.current;
2102
+ current && (ref.current = transformPathForSplit(current, path2, position, ref.affinity ?? "forward"));
2103
+ }
2104
+ for (const ref of Editor.pointRefs(editor)) {
2105
+ const current = ref.current;
2106
+ current && (ref.current = transformPointForSplit(current, path2, position, ref.affinity ?? "forward"));
2107
+ }
2108
+ for (const ref of Editor.rangeRefs(editor)) {
2109
+ const current = ref.current;
2110
+ if (current) {
2111
+ const [anchorAffinity, focusAffinity] = rangeRefAffinities(current, ref.affinity), anchor = transformPointForSplit(current.anchor, path2, position, anchorAffinity ?? "forward"), focus = transformPointForSplit(current.focus, path2, position, focusAffinity ?? "forward");
2112
+ anchor && focus ? ref.current = {
2113
+ anchor,
2114
+ focus
2115
+ } : (ref.current = null, ref.unref());
2116
+ }
2117
+ }
2118
+ if (editor.selection) {
2119
+ const anchor = transformPointForSplit(editor.selection.anchor, path2, position, "forward"), focus = transformPointForSplit(editor.selection.focus, path2, position, "forward");
2120
+ anchor && focus && (editor.selection = {
2121
+ anchor,
2122
+ focus
2123
+ });
2124
+ }
2125
+ const pathRefs = new Set(Editor.pathRefs(editor)), pointRefs = new Set(Editor.pointRefs(editor)), rangeRefs = new Set(Editor.rangeRefs(editor));
2126
+ Editor.pathRefs(editor).clear(), Editor.pointRefs(editor).clear(), Editor.rangeRefs(editor).clear();
2127
+ const savedSelection = editor.selection;
2128
+ try {
2129
+ Editor.withoutNormalizing(editor, () => {
2130
+ if (Text$1.isText(node2, editor.schema)) {
2131
+ const afterText = node2.text.slice(position), newNode = {
2132
+ ...properties,
2133
+ text: afterText
2134
+ };
2135
+ editor.apply({
2136
+ type: "remove_text",
2137
+ path: path2,
2138
+ offset: position,
2139
+ text: afterText
2140
+ }), editor.apply({
2141
+ type: "insert_node",
2142
+ path: Path.next(path2),
2143
+ node: newNode
2144
+ });
2145
+ } else if (Element$2.isElement(node2, editor.schema)) {
2146
+ const afterChildren = node2.children.slice(position), newNode = {
2147
+ ...properties,
2148
+ children: afterChildren
2149
+ };
2150
+ for (let i = node2.children.length - 1; i >= position; i--)
2151
+ editor.apply({
2152
+ type: "remove_node",
2153
+ path: [...path2, i],
2154
+ node: node2.children[i]
2155
+ });
2156
+ editor.apply({
2157
+ type: "insert_node",
2158
+ path: Path.next(path2),
2159
+ node: newNode
2160
+ });
2161
+ }
2162
+ });
2163
+ } finally {
2164
+ editor.selection = savedSelection;
2165
+ for (const ref of pathRefs)
2166
+ Editor.pathRefs(editor).add(ref);
2167
+ for (const ref of pointRefs)
2168
+ Editor.pointRefs(editor).add(ref);
2169
+ for (const ref of rangeRefs)
2170
+ Editor.rangeRefs(editor).add(ref);
2171
+ }
2172
+ }
2173
+ function transformPathForSplit(path2, splitPath, position, affinity = "forward") {
2174
+ const p = [...path2];
2175
+ return Path.equals(splitPath, p) ? affinity === "forward" && (p[p.length - 1] = p[p.length - 1] + 1) : Path.endsBefore(splitPath, p) ? p[splitPath.length - 1] = p[splitPath.length - 1] + 1 : Path.isAncestor(splitPath, p) && path2[splitPath.length] >= position && (p[splitPath.length - 1] = p[splitPath.length - 1] + 1, p[splitPath.length] = p[splitPath.length] - position), p;
2176
+ }
2177
+ function transformPointForSplit(point2, splitPath, position, affinity = "forward") {
2178
+ let {
2179
+ path: path2,
2180
+ offset
2181
+ } = point2;
2182
+ return Path.equals(splitPath, path2) ? (position < offset || position === offset && affinity === "forward") && (offset -= position, path2 = transformPathForSplit(path2, splitPath, position, "forward")) : path2 = transformPathForSplit(path2, splitPath, position, affinity), {
2183
+ path: path2,
2184
+ offset
2185
+ };
2186
+ }
2187
+ const insertNodes = (editor, nodes2, options = {}) => {
2151
2188
  Editor.withoutNormalizing(editor, () => {
2152
2189
  const {
2153
2190
  hanging = !1,
@@ -2184,12 +2221,43 @@ const previous = (editor, options = {}) => {
2184
2221
  });
2185
2222
  if (entry) {
2186
2223
  const [, matchPath2] = entry, pathRef2 = Editor.pathRef(editor, matchPath2), isAtEnd = Editor.isEnd(editor, at, matchPath2);
2187
- Transforms.splitNodes(editor, {
2188
- at,
2189
- match: match2,
2190
- mode,
2191
- voids
2192
- });
2224
+ {
2225
+ const splitAt = at, beforeRef = Editor.pointRef(editor, splitAt, {
2226
+ affinity: "backward"
2227
+ });
2228
+ let afterRef;
2229
+ try {
2230
+ const [highest] = Editor.nodes(editor, {
2231
+ at: splitAt,
2232
+ match: match2,
2233
+ mode,
2234
+ voids
2235
+ });
2236
+ if (highest) {
2237
+ afterRef = Editor.pointRef(editor, splitAt);
2238
+ const depth = splitAt.path.length, [, highestPath] = highest, lowestPath = splitAt.path.slice(0, depth);
2239
+ let position = splitAt.offset;
2240
+ for (const [node22, nodePath] of Editor.levels(editor, {
2241
+ at: lowestPath,
2242
+ reverse: !0,
2243
+ voids
2244
+ })) {
2245
+ let split = !1;
2246
+ if (nodePath.length < highestPath.length || nodePath.length === 0)
2247
+ break;
2248
+ const point2 = beforeRef.current, isEndOfNode = Editor.isEnd(editor, point2, nodePath);
2249
+ if (!Editor.isEdge(editor, point2, nodePath)) {
2250
+ split = !0;
2251
+ const properties = Node$1.extractProps(node22, editor.schema);
2252
+ applySplitNode(editor, nodePath, position, properties);
2253
+ }
2254
+ position = nodePath[nodePath.length - 1] + (split || isEndOfNode ? 1 : 0);
2255
+ }
2256
+ }
2257
+ } finally {
2258
+ beforeRef.unref(), afterRef?.unref();
2259
+ }
2260
+ }
2193
2261
  const path2 = pathRef2.unref();
2194
2262
  at = isAtEnd ? Path.next(path2) : path2;
2195
2263
  } else
@@ -2237,126 +2305,6 @@ const previous = (editor, options = {}) => {
2237
2305
  }
2238
2306
  }
2239
2307
  });
2240
- }, hasSingleChildNest = (editor, node2) => {
2241
- if (Element$2.isElement(node2, editor.schema)) {
2242
- const element = node2;
2243
- return element.children.length === 1 ? hasSingleChildNest(editor, element.children[0]) : !1;
2244
- } else return !Editor.isEditor(node2);
2245
- }, mergeNodes = (editor, options = {}) => {
2246
- Editor.withoutNormalizing(editor, () => {
2247
- let {
2248
- match: match2,
2249
- at = editor.selection
2250
- } = options;
2251
- const {
2252
- hanging = !1,
2253
- voids = !1,
2254
- mode = "lowest"
2255
- } = options;
2256
- if (!at)
2257
- return;
2258
- if (match2 == null)
2259
- if (Path.isPath(at)) {
2260
- const [parent2] = Editor.parent(editor, at);
2261
- match2 = (n2) => parent2.children.includes(n2);
2262
- } else
2263
- match2 = (n2) => Element$2.isElement(n2, editor.schema) && Editor.isBlock(editor, n2);
2264
- if (!hanging && Range.isRange(at) && (at = Editor.unhangRange(editor, at, {
2265
- voids
2266
- })), Range.isRange(at))
2267
- if (Range.isCollapsed(at))
2268
- at = at.anchor;
2269
- else {
2270
- const [, end2] = Range.edges(at), pointRef2 = Editor.pointRef(editor, end2);
2271
- Transforms.delete(editor, {
2272
- at
2273
- }), at = pointRef2.unref(), options.at == null && Transforms.select(editor, at);
2274
- }
2275
- const [current] = Editor.nodes(editor, {
2276
- at,
2277
- match: match2,
2278
- voids,
2279
- mode
2280
- }), prev = Editor.previous(editor, {
2281
- at,
2282
- match: match2,
2283
- voids,
2284
- mode
2285
- });
2286
- if (!current || !prev)
2287
- return;
2288
- const [node2, path2] = current, [prevNode, prevPath] = prev;
2289
- if (path2.length === 0 || prevPath.length === 0)
2290
- return;
2291
- const newPath = Path.next(prevPath), commonPath = Path.common(path2, prevPath), isPreviousSibling = Path.isSibling(path2, prevPath), levels2 = Array.from(Editor.levels(editor, {
2292
- at: path2
2293
- }), ([n2]) => n2).slice(commonPath.length).slice(0, -1), emptyAncestor = Editor.above(editor, {
2294
- at: path2,
2295
- mode: "highest",
2296
- match: (n2) => levels2.includes(n2) && hasSingleChildNest(editor, n2)
2297
- }), emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1]);
2298
- let properties, position;
2299
- if (Text$1.isText(node2, editor.schema) && Text$1.isText(prevNode, editor.schema)) {
2300
- const {
2301
- text: _text,
2302
- ...rest
2303
- } = node2;
2304
- position = prevNode.text.length, properties = rest;
2305
- } else if (Element$2.isElement(node2, editor.schema) && Element$2.isElement(prevNode, editor.schema)) {
2306
- const {
2307
- children: _children,
2308
- ...rest
2309
- } = node2;
2310
- position = prevNode.children.length, properties = rest;
2311
- } else
2312
- throw new Error(`Cannot merge the node at path [${path2}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(node2)} ${Scrubber.stringify(prevNode)}`);
2313
- isPreviousSibling || Transforms.moveNodes(editor, {
2314
- at: path2,
2315
- to: newPath,
2316
- voids
2317
- }), emptyRef && Transforms.removeNodes(editor, {
2318
- at: emptyRef.current,
2319
- voids
2320
- }), Editor.shouldMergeNodesRemovePrevNode(editor, prev, current) ? Transforms.removeNodes(editor, {
2321
- at: prevPath,
2322
- voids
2323
- }) : editor.apply({
2324
- type: "merge_node",
2325
- path: newPath,
2326
- position,
2327
- properties
2328
- }), emptyRef && emptyRef.unref();
2329
- });
2330
- }, moveNodes = (editor, options) => {
2331
- Editor.withoutNormalizing(editor, () => {
2332
- const {
2333
- to,
2334
- at = editor.selection,
2335
- mode = "lowest",
2336
- voids = !1
2337
- } = options;
2338
- let {
2339
- match: match2
2340
- } = options;
2341
- if (!at)
2342
- return;
2343
- match2 == null && (match2 = Path.isPath(at) ? matchPath(editor, at) : (n2) => Element$2.isElement(n2, editor.schema) && Editor.isBlock(editor, n2));
2344
- const toRef = Editor.pathRef(editor, to), targets = Editor.nodes(editor, {
2345
- at,
2346
- match: match2,
2347
- mode,
2348
- voids
2349
- }), pathRefs = Array.from(targets, ([, p]) => Editor.pathRef(editor, p));
2350
- for (const pathRef2 of pathRefs) {
2351
- const path2 = pathRef2.unref(), newPath = toRef.current;
2352
- path2.length !== 0 && editor.apply({
2353
- type: "move_node",
2354
- path: path2,
2355
- newPath
2356
- }), toRef.current && Path.isSibling(newPath, path2) && Path.isAfter(newPath, path2) && (toRef.current = Path.next(toRef.current));
2357
- }
2358
- toRef.unref();
2359
- });
2360
2308
  }, removeNodes = (editor, options = {}) => {
2361
2309
  Editor.withoutNormalizing(editor, () => {
2362
2310
  const {
@@ -2377,109 +2325,18 @@ const previous = (editor, options = {}) => {
2377
2325
  at,
2378
2326
  match: match2,
2379
2327
  mode,
2380
- voids
2381
- }), pathRefs = Array.from(depths, ([, p]) => Editor.pathRef(editor, p));
2382
- for (const pathRef2 of pathRefs) {
2383
- const path2 = pathRef2.unref();
2384
- if (path2) {
2385
- const [node2] = Editor.node(editor, path2);
2386
- editor.apply({
2387
- type: "remove_node",
2388
- path: path2,
2389
- node: node2
2390
- });
2391
- }
2392
- }
2393
- });
2394
- }, deleteRange = (editor, range2) => {
2395
- if (Range.isCollapsed(range2))
2396
- return range2.anchor;
2397
- {
2398
- const [, end2] = Range.edges(range2), pointRef2 = Editor.pointRef(editor, end2);
2399
- return Transforms.delete(editor, {
2400
- at: range2
2401
- }), pointRef2.unref();
2402
- }
2403
- }, splitNodes = (editor, options = {}) => {
2404
- Editor.withoutNormalizing(editor, () => {
2405
- const {
2406
- mode = "lowest",
2407
- voids = !1
2408
- } = options;
2409
- let {
2410
- match: match2,
2411
- at = editor.selection,
2412
- height = 0,
2413
- always = !1
2414
- } = options;
2415
- if (match2 == null && (match2 = (n2) => Element$2.isElement(n2, editor.schema) && Editor.isBlock(editor, n2)), Range.isRange(at) && (at = deleteRange(editor, at)), Path.isPath(at)) {
2416
- const path2 = at, point2 = Editor.point(editor, path2), [parent2] = Editor.parent(editor, path2);
2417
- match2 = (n2) => n2 === parent2, height = point2.path.length - path2.length + 1, at = point2, always = !0;
2418
- }
2419
- if (!at)
2420
- return;
2421
- const beforeRef = Editor.pointRef(editor, at, {
2422
- affinity: "backward"
2423
- });
2424
- let afterRef;
2425
- try {
2426
- const [highest] = Editor.nodes(editor, {
2427
- at,
2428
- match: match2,
2429
- mode,
2430
- voids
2431
- });
2432
- if (!highest)
2433
- return;
2434
- const voidMatch = Editor.void(editor, {
2435
- at,
2436
- mode: "highest"
2437
- }), nudge = 0;
2438
- if (!voids && voidMatch) {
2439
- const [voidNode, voidPath] = voidMatch;
2440
- if (Element$2.isElement(voidNode, editor.schema) && editor.isInline(voidNode)) {
2441
- let after2 = Editor.after(editor, voidPath);
2442
- if (!after2) {
2443
- const text = editor.createSpan(), afterPath = Path.next(voidPath);
2444
- Transforms.insertNodes(editor, text, {
2445
- at: afterPath,
2446
- voids
2447
- }), after2 = Editor.point(editor, afterPath);
2448
- }
2449
- at = after2, always = !0;
2450
- }
2451
- height = at.path.length - voidPath.length + 1, always = !0;
2452
- }
2453
- afterRef = Editor.pointRef(editor, at);
2454
- const depth = at.path.length - height, [, highestPath] = highest, lowestPath = at.path.slice(0, depth);
2455
- let position = height === 0 ? at.offset : at.path[depth] + nudge;
2456
- for (const [node2, path2] of Editor.levels(editor, {
2457
- at: lowestPath,
2458
- reverse: !0,
2459
- voids
2460
- })) {
2461
- let split = !1;
2462
- if (path2.length < highestPath.length || path2.length === 0)
2463
- break;
2464
- const point2 = beforeRef.current, isEnd2 = Editor.isEnd(editor, point2, path2);
2465
- if (always || !beforeRef || !Editor.isEdge(editor, point2, path2)) {
2466
- split = !0;
2467
- const properties = Node$1.extractProps(node2, editor.schema);
2468
- editor.apply({
2469
- type: "split_node",
2470
- path: path2,
2471
- position,
2472
- properties
2473
- });
2474
- }
2475
- position = path2[path2.length - 1] + (split || isEnd2 ? 1 : 0);
2476
- }
2477
- if (options.at == null) {
2478
- const point2 = afterRef.current || Editor.end(editor, []);
2479
- Transforms.select(editor, point2);
2328
+ voids
2329
+ }), pathRefs = Array.from(depths, ([, p]) => Editor.pathRef(editor, p));
2330
+ for (const pathRef2 of pathRefs) {
2331
+ const path2 = pathRef2.unref();
2332
+ if (path2) {
2333
+ const [node2] = Editor.node(editor, path2);
2334
+ editor.apply({
2335
+ type: "remove_node",
2336
+ path: path2,
2337
+ node: node2
2338
+ });
2480
2339
  }
2481
- } finally {
2482
- beforeRef.unref(), afterRef?.unref();
2483
2340
  }
2484
2341
  });
2485
2342
  }, collapse = (editor, options = {}) => {
@@ -2568,7 +2425,19 @@ const previous = (editor, options = {}) => {
2568
2425
  newProperties: newProps
2569
2426
  });
2570
2427
  }
2571
- }, deleteText = (editor, options = {}) => {
2428
+ };
2429
+ function applySetNode(editor, props, path2) {
2430
+ const node2 = Node$1.get(editor, path2, editor.schema), propsRecord = props, properties = {}, newProperties = {};
2431
+ for (const key of Object.keys(propsRecord))
2432
+ key !== "children" && (key === "text" && !Element$2.isElement(node2, editor.schema) && !editor.isObjectNode(node2) || propsRecord[key] !== node2[key] && (node2.hasOwnProperty(key) && (properties[key] = node2[key]), propsRecord[key] != null && (newProperties[key] = propsRecord[key])));
2433
+ (Object.keys(newProperties).length > 0 || Object.keys(properties).length > 0) && editor.apply({
2434
+ type: "set_node",
2435
+ path: path2,
2436
+ properties,
2437
+ newProperties
2438
+ });
2439
+ }
2440
+ const deleteText = (editor, options = {}) => {
2572
2441
  Editor.withoutNormalizing(editor, () => {
2573
2442
  const {
2574
2443
  reverse = !1,
@@ -2693,11 +2562,75 @@ const previous = (editor, options = {}) => {
2693
2562
  }), removedText = text);
2694
2563
  }
2695
2564
  }
2696
- !isSingleText && isAcrossBlocks && endRef.current && startRef.current && Transforms.mergeNodes(editor, {
2697
- at: endRef.current,
2698
- hanging: !0,
2699
- voids
2700
- }), isCollapsed && reverse && unit === "character" && removedText.length > 1 && removedText.match(/[\u0980-\u09FF\u0E00-\u0E7F\u1000-\u109F\u0900-\u097F\u1780-\u17FF\u0D00-\u0D7F\u0B00-\u0B7F\u0A00-\u0A7F\u0B80-\u0BFF\u0C00-\u0C7F]+/) && Transforms.insertText(editor, removedText.slice(0, removedText.length - distance));
2565
+ if (!isSingleText && isAcrossBlocks && endRef.current && startRef.current) {
2566
+ const mergeAt = endRef.current, mergeMatch = (n2) => Element$2.isElement(n2, editor.schema) && Editor.isBlock(editor, n2), [current] = Editor.nodes(editor, {
2567
+ at: mergeAt,
2568
+ match: mergeMatch,
2569
+ voids,
2570
+ mode: "lowest"
2571
+ }), prev = Editor.previous(editor, {
2572
+ at: mergeAt,
2573
+ match: mergeMatch,
2574
+ voids,
2575
+ mode: "lowest"
2576
+ });
2577
+ if (current && prev) {
2578
+ const [mergeNode, mergePath] = current, [prevNode, prevPath] = prev;
2579
+ if (mergePath.length !== 0 && prevPath.length !== 0) {
2580
+ const newPath = Path.next(prevPath), commonPath = Path.common(mergePath, prevPath), isPreviousSibling = Path.isSibling(mergePath, prevPath), levels2 = Array.from(Editor.levels(editor, {
2581
+ at: mergePath
2582
+ }), ([n2]) => n2).slice(commonPath.length).slice(0, -1), hasSingleChildNest = (node2) => {
2583
+ if (Element$2.isElement(node2, editor.schema)) {
2584
+ const element = node2;
2585
+ return element.children.length === 1 ? hasSingleChildNest(element.children[0]) : !1;
2586
+ } else return !Editor.isEditor(node2);
2587
+ }, emptyAncestor = Editor.above(editor, {
2588
+ at: mergePath,
2589
+ mode: "highest",
2590
+ match: (n2) => levels2.includes(n2) && hasSingleChildNest(n2)
2591
+ }), emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1]);
2592
+ let position;
2593
+ if (Text$1.isText(mergeNode, editor.schema) && Text$1.isText(prevNode, editor.schema))
2594
+ position = prevNode.text.length;
2595
+ else if (Element$2.isElement(mergeNode, editor.schema) && Element$2.isElement(prevNode, editor.schema))
2596
+ position = prevNode.children.length;
2597
+ else
2598
+ throw new Error(`Cannot merge the node at path [${mergePath}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(mergeNode)} ${Scrubber.stringify(prevNode)}`);
2599
+ if (!isPreviousSibling) {
2600
+ const moveNode = Node$1.get(editor, mergePath, editor.schema);
2601
+ editor.apply({
2602
+ type: "remove_node",
2603
+ path: mergePath,
2604
+ node: moveNode
2605
+ }), editor.apply({
2606
+ type: "insert_node",
2607
+ path: newPath,
2608
+ node: moveNode
2609
+ });
2610
+ }
2611
+ if (emptyRef && Transforms.removeNodes(editor, {
2612
+ at: emptyRef.current,
2613
+ voids
2614
+ }), Editor.shouldMergeNodesRemovePrevNode(editor, prev, current))
2615
+ Transforms.removeNodes(editor, {
2616
+ at: prevPath,
2617
+ voids
2618
+ });
2619
+ else {
2620
+ const pteEditor = editor;
2621
+ if (pteEditor.isTextBlock(mergeNode) && pteEditor.isTextBlock(prevNode) && Array.isArray(mergeNode.markDefs) && mergeNode.markDefs.length > 0) {
2622
+ const targetPath = isPreviousSibling ? prevPath : Path.previous(newPath), oldDefs = Array.isArray(prevNode.markDefs) && prevNode.markDefs || [], newMarkDefs = [...new Map([...oldDefs, ...mergeNode.markDefs].map((def) => [def._key, def])).values()];
2623
+ applySetNode(pteEditor, {
2624
+ markDefs: newMarkDefs
2625
+ }, targetPath);
2626
+ }
2627
+ applyMergeNode(pteEditor, newPath, position);
2628
+ }
2629
+ emptyRef && emptyRef.unref();
2630
+ }
2631
+ }
2632
+ }
2633
+ isCollapsed && reverse && unit === "character" && removedText.length > 1 && removedText.match(/[\u0980-\u09FF\u0E00-\u0E7F\u1000-\u109F\u0900-\u097F\u1780-\u17FF\u0D00-\u0D7F\u0B00-\u0B7F\u0A00-\u0A7F\u0B80-\u0BFF\u0C00-\u0C7F]+/) && Transforms.insertText(editor, removedText.slice(0, removedText.length - distance));
2701
2634
  const startUnref = startRef.unref(), endUnref = endRef.unref(), point2 = reverse ? startUnref || endUnref : endUnref || startUnref;
2702
2635
  options.at == null && point2 && Transforms.select(editor, point2);
2703
2636
  });
@@ -2753,9 +2686,7 @@ const previous = (editor, options = {}) => {
2753
2686
  isStart: (...args) => isStart(e, ...args),
2754
2687
  leaf: (...args) => leaf(e, ...args),
2755
2688
  levels: (...args) => levels(e, ...args),
2756
- mergeNodes: (...args) => mergeNodes(e, ...args),
2757
2689
  move: (...args) => move(e, ...args),
2758
- moveNodes: (...args) => moveNodes(e, ...args),
2759
2690
  next: (...args) => next(e, ...args),
2760
2691
  node: (...args) => node(e, ...args),
2761
2692
  nodes: (...args) => nodes(e, ...args),
@@ -2773,7 +2704,6 @@ const previous = (editor, options = {}) => {
2773
2704
  select: (...args) => select(e, ...args),
2774
2705
  setNormalizing: (...args) => setNormalizing(e, ...args),
2775
2706
  setSelection: (...args) => setSelection$1(e, ...args),
2776
- splitNodes: (...args) => splitNodes(e, ...args),
2777
2707
  start: (...args) => start(e, ...args),
2778
2708
  string: (...args) => string(e, ...args),
2779
2709
  unhangRange: (...args) => unhangRange(e, ...args),
@@ -3462,7 +3392,7 @@ function transformPendingPoint(editor, point2, op) {
3462
3392
  }, transformed = Point.transform(anchor, op, {
3463
3393
  affinity: "backward"
3464
3394
  });
3465
- return transformed ? op.type === "split_node" && Path.equals(op.path, point2.path) && anchor.offset < op.position && diff2.start < op.position ? transformed : {
3395
+ return transformed ? {
3466
3396
  path: transformed.path,
3467
3397
  offset: transformed.offset + diff2.text.length - diff2.end + diff2.start
3468
3398
  } : null;
@@ -3525,46 +3455,6 @@ function transformTextDiff(textDiff, op) {
3525
3455
  id,
3526
3456
  path: path2
3527
3457
  };
3528
- case "split_node":
3529
- return !Path.equals(op.path, path2) || op.position >= diff2.end ? {
3530
- diff: diff2,
3531
- id,
3532
- path: Path.transform(path2, op, {
3533
- affinity: "backward"
3534
- })
3535
- } : op.position > diff2.start ? {
3536
- diff: {
3537
- start: diff2.start,
3538
- end: Math.min(op.position, diff2.end),
3539
- text: diff2.text
3540
- },
3541
- id,
3542
- path: path2
3543
- } : {
3544
- diff: {
3545
- start: diff2.start - op.position,
3546
- end: diff2.end - op.position,
3547
- text: diff2.text
3548
- },
3549
- id,
3550
- path: Path.transform(path2, op, {
3551
- affinity: "forward"
3552
- })
3553
- };
3554
- case "merge_node":
3555
- return Path.equals(op.path, path2) ? {
3556
- diff: {
3557
- start: diff2.start + op.position,
3558
- end: diff2.end + op.position,
3559
- text: diff2.text
3560
- },
3561
- id,
3562
- path: Path.transform(path2, op)
3563
- } : {
3564
- diff: diff2,
3565
- id,
3566
- path: Path.transform(path2, op)
3567
- };
3568
3458
  }
3569
3459
  const newPath = Path.transform(path2, op);
3570
3460
  return newPath ? {
@@ -3579,7 +3469,7 @@ const withDOM = (editor) => {
3579
3469
  onChange
3580
3470
  } = e;
3581
3471
  return e.isNodeMapDirty = !1, e.domWindow = null, e.domElement = null, e.domPlaceholder = "", e.domPlaceholderElement = null, e.keyToElement = /* @__PURE__ */ new WeakMap(), e.nodeToIndex = /* @__PURE__ */ new WeakMap(), e.nodeToParent = /* @__PURE__ */ new WeakMap(), e.elementToNode = /* @__PURE__ */ new WeakMap(), e.nodeToElement = /* @__PURE__ */ new WeakMap(), e.nodeToKey = /* @__PURE__ */ new WeakMap(), e.readOnly = !1, e.focused = !1, e.composing = !1, e.userSelection = null, e.onContextChange = null, e.scheduleFlush = null, e.pendingInsertionMarks = null, e.userMarks = null, e.pendingDiffs = [], e.pendingAction = null, e.pendingSelection = null, e.forceRender = null, e.apply = (op) => {
3582
- const matches = [], pathRefMatches = [], pendingDiffs = e.pendingDiffs;
3472
+ const matches = [], pendingDiffs = e.pendingDiffs;
3583
3473
  if (pendingDiffs?.length) {
3584
3474
  const transformed = pendingDiffs.map((textDiff) => transformTextDiff(textDiff, op)).filter(Boolean);
3585
3475
  e.pendingDiffs = transformed;
@@ -3597,8 +3487,7 @@ const withDOM = (editor) => {
3597
3487
  switch (op.type) {
3598
3488
  case "insert_text":
3599
3489
  case "remove_text":
3600
- case "set_node":
3601
- case "split_node": {
3490
+ case "set_node": {
3602
3491
  matches.push(...getMatches(e, op.path));
3603
3492
  break;
3604
3493
  }
@@ -3611,27 +3500,10 @@ const withDOM = (editor) => {
3611
3500
  matches.push(...getMatches(e, Path.parent(op.path)));
3612
3501
  break;
3613
3502
  }
3614
- case "merge_node": {
3615
- const prevPath = Path.previous(op.path);
3616
- matches.push(...getMatches(e, prevPath));
3617
- break;
3618
- }
3619
- case "move_node": {
3620
- const commonPath = Path.common(Path.parent(op.path), Path.parent(op.newPath));
3621
- matches.push(...getMatches(e, commonPath));
3622
- let changedPath;
3623
- Path.isBefore(op.path, op.newPath) ? (matches.push(...getMatches(e, Path.parent(op.path))), changedPath = op.newPath) : (matches.push(...getMatches(e, Path.parent(op.newPath))), changedPath = op.path);
3624
- const changedNode = Node$1.get(editor, Path.parent(changedPath), editor.schema), changedNodeKey = DOMEditor.findKey(e, changedNode), changedPathRef = Editor.pathRef(e, Path.parent(changedPath));
3625
- pathRefMatches.push([changedPathRef, changedNodeKey]);
3626
- break;
3627
- }
3628
3503
  }
3629
3504
  switch (apply2(op), op.type) {
3630
3505
  case "insert_node":
3631
3506
  case "remove_node":
3632
- case "merge_node":
3633
- case "move_node":
3634
- case "split_node":
3635
3507
  case "insert_text":
3636
3508
  case "remove_text":
3637
3509
  case "set_selection":
@@ -3641,13 +3513,6 @@ const withDOM = (editor) => {
3641
3513
  const [node2] = Editor.node(e, path2);
3642
3514
  e.nodeToKey.set(node2, key);
3643
3515
  }
3644
- for (const [pathRef2, key] of pathRefMatches) {
3645
- if (pathRef2.current) {
3646
- const [node2] = Editor.node(e, pathRef2.current);
3647
- e.nodeToKey.set(node2, key);
3648
- }
3649
- pathRef2.unref();
3650
- }
3651
3516
  }, e.setFragmentData = (data) => {
3652
3517
  const {
3653
3518
  selection
@@ -3689,8 +3554,53 @@ const withDOM = (editor) => {
3689
3554
  const lines = text.split(/\r\n|\r|\n/);
3690
3555
  let split = !1;
3691
3556
  for (const line of lines)
3692
- split && Transforms.splitNodes(e, {
3693
- always: !0
3557
+ split && Editor.withoutNormalizing(e, () => {
3558
+ let splitAt = null;
3559
+ if (e.selection)
3560
+ if (Range.isCollapsed(e.selection))
3561
+ splitAt = e.selection.anchor;
3562
+ else {
3563
+ const [, end2] = Range.edges(e.selection), pointRef2 = Editor.pointRef(e, end2);
3564
+ Transforms.delete(e, {
3565
+ at: e.selection
3566
+ }), splitAt = pointRef2.unref();
3567
+ }
3568
+ if (!splitAt)
3569
+ return;
3570
+ const splitMatch = (n2) => Element$2.isElement(n2, e.schema) && Editor.isBlock(e, n2), beforeRef = Editor.pointRef(e, splitAt, {
3571
+ affinity: "backward"
3572
+ });
3573
+ let afterRef;
3574
+ try {
3575
+ const [highest] = Editor.nodes(e, {
3576
+ at: splitAt,
3577
+ match: splitMatch,
3578
+ mode: "lowest",
3579
+ voids: !1
3580
+ });
3581
+ if (!highest)
3582
+ return;
3583
+ afterRef = Editor.pointRef(e, splitAt);
3584
+ const depth = splitAt.path.length, [, highestPath] = highest, lowestPath = splitAt.path.slice(0, depth);
3585
+ let position = splitAt.offset;
3586
+ for (const [node2, nodePath] of Editor.levels(e, {
3587
+ at: lowestPath,
3588
+ reverse: !0,
3589
+ voids: !1
3590
+ })) {
3591
+ let didSplit = !1;
3592
+ if (nodePath.length < highestPath.length || nodePath.length === 0)
3593
+ break;
3594
+ const point22 = beforeRef.current, isEndOfNode = Editor.isEnd(e, point22, nodePath);
3595
+ didSplit = !0;
3596
+ const properties = Node$1.extractProps(node2, e.schema);
3597
+ applySplitNode(e, nodePath, position, properties), position = nodePath[nodePath.length - 1] + (didSplit || isEndOfNode ? 1 : 0);
3598
+ }
3599
+ const point2 = afterRef.current || Editor.end(e, []);
3600
+ Transforms.select(e, point2);
3601
+ } finally {
3602
+ beforeRef.unref(), afterRef?.unref();
3603
+ }
3694
3604
  }), e.insertText(line), split = !0;
3695
3605
  return !0;
3696
3606
  }
@@ -5130,537 +5040,61 @@ function createAndroidInputManager({
5130
5040
  editor
5131
5041
  }), {
5132
5042
  at: targetRange2
5133
- });
5134
- }
5135
- }
5136
- }, hasPendingAction = () => !!editor.pendingAction, hasPendingDiffs = () => !!editor.pendingDiffs?.length, hasPendingChanges = () => hasPendingAction() || hasPendingDiffs(), isFlushing = () => flushing, handleUserSelect = (range2) => {
5137
- editor.pendingSelection = range2, flushTimeoutId && (clearTimeout(flushTimeoutId), flushTimeoutId = null);
5138
- const {
5139
- selection
5140
- } = editor;
5141
- if (!range2)
5142
- return;
5143
- const pathChanged = !selection || !Path.equals(selection.anchor.path, range2.anchor.path), parentPathChanged = !selection || !Path.equals(selection.anchor.path.slice(0, -1), range2.anchor.path.slice(0, -1));
5144
- (pathChanged && insertPositionHint || parentPathChanged) && (insertPositionHint = !1), (pathChanged || hasPendingDiffs()) && (flushTimeoutId = setTimeout(flush, FLUSH_DELAY));
5145
- }, handleInput = () => {
5146
- (hasPendingAction() || !hasPendingDiffs()) && flush();
5147
- }, handleKeyDown = (_) => {
5148
- hasPendingDiffs() || (updatePlaceholderVisibility(!0), setTimeout(updatePlaceholderVisibility));
5149
- }, scheduleFlush = () => {
5150
- hasPendingAction() || (actionTimeoutId = setTimeout(flush));
5151
- };
5152
- return {
5153
- flush,
5154
- scheduleFlush,
5155
- hasPendingDiffs,
5156
- hasPendingAction,
5157
- hasPendingChanges,
5158
- isFlushing,
5159
- handleUserSelect,
5160
- handleCompositionEnd,
5161
- handleCompositionStart,
5162
- handleDOMBeforeInput,
5163
- handleKeyDown,
5164
- handleDomMutations: (mutations) => {
5165
- hasPendingDiffs() || hasPendingAction() || mutations.some((mutation) => isTrackedMutation(editor, mutation, mutations)) && editor.forceRender?.();
5166
- },
5167
- handleInput
5168
- };
5169
- }
5170
- const MUTATION_OBSERVER_CONFIG$1 = {
5171
- subtree: !0,
5172
- childList: !0,
5173
- characterData: !0
5174
- }, useAndroidInputManager = IS_ANDROID ? ({
5175
- editorActor,
5176
- node: node2,
5177
- ...options
5178
- }) => {
5179
- if (!IS_ANDROID)
5180
- return null;
5181
- const editor = useSlateStatic(), isMounted = useIsMounted(), [inputManager] = useState(() => createAndroidInputManager({
5182
- editor,
5183
- editorActor,
5184
- ...options
5185
- }));
5186
- return useMutationObserver(node2, inputManager.handleDomMutations, MUTATION_OBSERVER_CONFIG$1), editor.scheduleFlush = inputManager.scheduleFlush, isMounted && inputManager.flush(), inputManager;
5187
- } : () => null;
5188
- class ChildrenHelper {
5189
- /**
5190
- * Sparse array of Slate node keys, each index corresponding to an index in
5191
- * the children array
5192
- *
5193
- * Fetching the key for a Slate node is expensive, so we cache them here.
5194
- */
5195
- /**
5196
- * The index of the next node to be read in the children array
5197
- */
5198
- constructor(editor, children) {
5199
- this.editor = editor, this.children = children, this.cachedKeys = new Array(children.length), this.pointerIndex = 0;
5200
- }
5201
- /**
5202
- * Read a given number of nodes, advancing the pointer by that amount
5203
- */
5204
- read(n2) {
5205
- if (n2 === 1)
5206
- return [this.children[this.pointerIndex++]];
5207
- const slicedChildren = this.remaining(n2);
5208
- return this.pointerIndex += n2, slicedChildren;
5209
- }
5210
- /**
5211
- * Get the remaining children without advancing the pointer
5212
- *
5213
- * @param [maxChildren] Limit the number of children returned.
5214
- */
5215
- remaining(maxChildren) {
5216
- return maxChildren === void 0 ? this.children.slice(this.pointerIndex) : this.children.slice(this.pointerIndex, this.pointerIndex + maxChildren);
5217
- }
5218
- /**
5219
- * Whether all children have been read
5220
- */
5221
- get reachedEnd() {
5222
- return this.pointerIndex >= this.children.length;
5223
- }
5224
- /**
5225
- * Determine whether a node with a given key appears in the unread part of the
5226
- * children array, and return its index relative to the current pointer if so
5227
- *
5228
- * Searching for the node object itself using indexOf is most efficient, but
5229
- * will fail to locate nodes that have been modified. In this case, nodes
5230
- * should be identified by their keys instead.
5231
- *
5232
- * Searching an array of keys using indexOf is very inefficient since fetching
5233
- * the keys for all children in advance is very slow. Insead, if the node
5234
- * search fails to return a value, fetch the keys of each remaining child one
5235
- * by one and compare it to the known key.
5236
- */
5237
- lookAhead(node2, key) {
5238
- const elementResult = this.children.indexOf(node2, this.pointerIndex);
5239
- if (elementResult > -1)
5240
- return elementResult - this.pointerIndex;
5241
- for (let i = this.pointerIndex; i < this.children.length; i++) {
5242
- const candidateNode = this.children[i];
5243
- if (this.findKey(candidateNode, i) === key)
5244
- return i - this.pointerIndex;
5245
- }
5246
- return -1;
5247
- }
5248
- /**
5249
- * Convert an array of Slate nodes to an array of chunk leaves, each
5250
- * containing the node and its key
5251
- */
5252
- toChunkLeaves(nodes2, startIndex) {
5253
- return nodes2.map((node2, i) => ({
5254
- type: "leaf",
5255
- node: node2,
5256
- key: this.findKey(node2, startIndex + i),
5257
- index: startIndex + i
5258
- }));
5259
- }
5260
- /**
5261
- * Get the key for a Slate node, cached using the node's index
5262
- */
5263
- findKey(node2, index) {
5264
- const cachedKey = this.cachedKeys[index];
5265
- if (cachedKey)
5266
- return cachedKey;
5267
- const key = ReactEditor.findKey(this.editor, node2);
5268
- return this.cachedKeys[index] = key, key;
5269
- }
5270
- }
5271
- class ChunkTreeHelper {
5272
- /**
5273
- * The root of the chunk tree
5274
- */
5275
- /**
5276
- * The ideal size of a chunk
5277
- */
5278
- /**
5279
- * Whether debug mode is enabled
5280
- *
5281
- * If enabled, the pointer state will be checked for internal consistency
5282
- * after each mutating operation.
5283
- */
5284
- /**
5285
- * Whether the traversal has reached the end of the chunk tree
5286
- *
5287
- * When this is true, the pointerChunk and pointerIndex point to the last
5288
- * top-level node in the chunk tree, although pointerNode returns null.
5289
- */
5290
- /**
5291
- * The chunk containing the current node
5292
- */
5293
- /**
5294
- * The index of the current node within pointerChunk
5295
- *
5296
- * Can be -1 to indicate that the pointer is before the start of the tree.
5297
- */
5298
- /**
5299
- * Similar to a Slate path; tracks the path of pointerChunk relative to the
5300
- * root.
5301
- *
5302
- * Used to move the pointer from the current chunk to the parent chunk more
5303
- * efficiently.
5304
- */
5305
- /**
5306
- * Indexing the current chunk's children has a slight time cost, which adds up
5307
- * when traversing very large trees, so the current node is cached.
5308
- *
5309
- * A value of undefined means that the current node is not cached. This
5310
- * property must be set to undefined whenever the pointer is moved, unless
5311
- * the pointer is guaranteed to point to the same node that it did previously.
5312
- */
5313
- constructor(chunkTree, {
5314
- chunkSize,
5315
- debug: debug2
5316
- }) {
5317
- this.root = chunkTree, this.chunkSize = chunkSize, this.debug = debug2 ?? !1, this.pointerChunk = chunkTree, this.pointerIndex = -1, this.pointerIndexStack = [], this.reachedEnd = !1, this.validateState();
5318
- }
5319
- /**
5320
- * Move the pointer to the next leaf in the chunk tree
5321
- */
5322
- readLeaf() {
5323
- if (this.reachedEnd)
5324
- return null;
5325
- for (; ; )
5326
- if (this.pointerIndex + 1 < this.pointerSiblings.length) {
5327
- this.pointerIndex++, this.cachedPointerNode = void 0;
5328
- break;
5329
- } else {
5330
- if (this.pointerChunk.type === "root")
5331
- return this.reachedEnd = !0, null;
5332
- this.exitChunk();
5333
- }
5334
- return this.validateState(), this.enterChunkUntilLeaf(!1), this.pointerNode;
5335
- }
5336
- /**
5337
- * Move the pointer to the previous leaf in the chunk tree
5338
- */
5339
- returnToPreviousLeaf() {
5340
- if (this.reachedEnd) {
5341
- this.reachedEnd = !1, this.enterChunkUntilLeaf(!0);
5342
- return;
5343
- }
5344
- for (; ; )
5345
- if (this.pointerIndex >= 1) {
5346
- this.pointerIndex--, this.cachedPointerNode = void 0;
5347
- break;
5348
- } else if (this.pointerChunk.type === "root") {
5349
- this.pointerIndex = -1;
5350
- return;
5351
- } else
5352
- this.exitChunk();
5353
- this.validateState(), this.enterChunkUntilLeaf(!0);
5354
- }
5355
- /**
5356
- * Insert leaves before the current leaf, leaving the pointer unchanged
5357
- */
5358
- insertBefore(leaves) {
5359
- this.returnToPreviousLeaf(), this.insertAfter(leaves), this.readLeaf();
5360
- }
5361
- /**
5362
- * Insert leaves after the current leaf, leaving the pointer on the last
5363
- * inserted leaf
5364
- *
5365
- * The insertion algorithm first checks for any chunk we're currently at the
5366
- * end of that can receive additional leaves. Next, it tries to insert leaves
5367
- * at the starts of any subsequent chunks.
5368
- *
5369
- * Any remaining leaves are passed to rawInsertAfter to be chunked and
5370
- * inserted at the highest possible level.
5371
- */
5372
- insertAfter(leaves) {
5373
- if (leaves.length === 0)
5374
- return;
5375
- let beforeDepth = 0, afterDepth = 0;
5376
- for (; this.pointerChunk.type === "chunk" && this.pointerIndex === this.pointerSiblings.length - 1; ) {
5377
- const remainingCapacity = this.chunkSize - this.pointerSiblings.length, toInsertCount = Math.min(remainingCapacity, leaves.length);
5378
- if (toInsertCount > 0) {
5379
- const leavesToInsert = leaves.splice(0, toInsertCount);
5380
- this.rawInsertAfter(leavesToInsert, beforeDepth);
5381
- }
5382
- this.exitChunk(), beforeDepth++;
5383
- }
5384
- if (leaves.length === 0)
5385
- return;
5386
- const rawInsertPointer = this.savePointer();
5387
- let finalPointer = null;
5388
- if (this.readLeaf())
5389
- for (; this.pointerChunk.type === "chunk" && this.pointerIndex === 0; ) {
5390
- const remainingCapacity = this.chunkSize - this.pointerSiblings.length, toInsertCount = Math.min(remainingCapacity, leaves.length);
5391
- if (toInsertCount > 0) {
5392
- const leavesToInsert = leaves.splice(-toInsertCount, toInsertCount);
5393
- this.pointerIndex = -1, this.cachedPointerNode = void 0, this.rawInsertAfter(leavesToInsert, afterDepth), finalPointer || (finalPointer = this.savePointer());
5394
- }
5395
- this.exitChunk(), afterDepth++;
5396
- }
5397
- this.restorePointer(rawInsertPointer);
5398
- const minDepth = Math.max(beforeDepth, afterDepth);
5399
- this.rawInsertAfter(leaves, minDepth), finalPointer && this.restorePointer(finalPointer), this.validateState();
5400
- }
5401
- /**
5402
- * Remove the current node and decrement the pointer, deleting any ancestor
5403
- * chunk that becomes empty as a result
5404
- */
5405
- remove() {
5406
- this.pointerSiblings.splice(this.pointerIndex--, 1), this.cachedPointerNode = void 0, this.pointerSiblings.length === 0 && this.pointerChunk.type === "chunk" ? (this.exitChunk(), this.remove()) : this.invalidateChunk(), this.validateState();
5407
- }
5408
- /**
5409
- * Add the current chunk and all ancestor chunks to the list of modified
5410
- * chunks
5411
- */
5412
- invalidateChunk() {
5413
- for (let c2 = this.pointerChunk; c2.type === "chunk"; c2 = c2.parent)
5414
- this.root.modifiedChunks.add(c2);
5415
- }
5416
- /**
5417
- * Whether the pointer is at the start of the tree
5418
- */
5419
- get atStart() {
5420
- return this.pointerChunk.type === "root" && this.pointerIndex === -1;
5421
- }
5422
- /**
5423
- * The siblings of the current node
5424
- */
5425
- get pointerSiblings() {
5426
- return this.pointerChunk.children;
5427
- }
5428
- /**
5429
- * Get the current node (uncached)
5430
- *
5431
- * If the pointer is at the start or end of the document, returns null.
5432
- *
5433
- * Usually, the current node is a chunk leaf, although it can be a chunk
5434
- * while insertions are in progress.
5435
- */
5436
- getPointerNode() {
5437
- return this.reachedEnd || this.pointerIndex === -1 ? null : this.pointerSiblings[this.pointerIndex] ?? null;
5438
- }
5439
- /**
5440
- * Cached getter for the current node
5441
- */
5442
- get pointerNode() {
5443
- if (this.cachedPointerNode !== void 0)
5444
- return this.cachedPointerNode;
5445
- const pointerNode = this.getPointerNode();
5446
- return this.cachedPointerNode = pointerNode, pointerNode;
5447
- }
5448
- /**
5449
- * Get the path of a chunk relative to the root, returning null if the chunk
5450
- * is not connected to the root
5451
- */
5452
- getChunkPath(chunk) {
5453
- const path2 = [];
5454
- for (let c2 = chunk; c2.type === "chunk"; c2 = c2.parent) {
5455
- const index = c2.parent.children.indexOf(c2);
5456
- if (index === -1)
5457
- return null;
5458
- path2.unshift(index);
5459
- }
5460
- return path2;
5461
- }
5462
- /**
5463
- * Save the current pointer to be restored later
5464
- */
5465
- savePointer() {
5466
- if (this.atStart)
5467
- return "start";
5468
- if (!this.pointerNode)
5469
- throw new Error("Cannot save pointer when pointerNode is null");
5470
- return {
5471
- chunk: this.pointerChunk,
5472
- node: this.pointerNode
5473
- };
5474
- }
5475
- /**
5476
- * Restore the pointer to a previous state
5477
- */
5478
- restorePointer(savedPointer) {
5479
- if (savedPointer === "start") {
5480
- this.pointerChunk = this.root, this.pointerIndex = -1, this.pointerIndexStack = [], this.reachedEnd = !1, this.cachedPointerNode = void 0;
5481
- return;
5043
+ });
5044
+ }
5482
5045
  }
5046
+ }, hasPendingAction = () => !!editor.pendingAction, hasPendingDiffs = () => !!editor.pendingDiffs?.length, hasPendingChanges = () => hasPendingAction() || hasPendingDiffs(), isFlushing = () => flushing, handleUserSelect = (range2) => {
5047
+ editor.pendingSelection = range2, flushTimeoutId && (clearTimeout(flushTimeoutId), flushTimeoutId = null);
5483
5048
  const {
5484
- chunk,
5485
- node: node2
5486
- } = savedPointer, index = chunk.children.indexOf(node2);
5487
- if (index === -1)
5488
- throw new Error("Cannot restore point because saved node is no longer in saved chunk");
5489
- const indexStack = this.getChunkPath(chunk);
5490
- if (!indexStack)
5491
- throw new Error("Cannot restore point because saved chunk is no longer connected to root");
5492
- this.pointerChunk = chunk, this.pointerIndex = index, this.pointerIndexStack = indexStack, this.reachedEnd = !1, this.cachedPointerNode = node2, this.validateState();
5493
- }
5494
- /**
5495
- * Assuming the current node is a chunk, move the pointer into that chunk
5496
- *
5497
- * @param end If true, place the pointer on the last node of the chunk.
5498
- * Otherwise, place the pointer on the first node.
5499
- */
5500
- enterChunk(end2) {
5501
- if (this.pointerNode?.type !== "chunk")
5502
- throw new Error("Cannot enter non-chunk");
5503
- if (this.pointerIndexStack.push(this.pointerIndex), this.pointerChunk = this.pointerNode, this.pointerIndex = end2 ? this.pointerSiblings.length - 1 : 0, this.cachedPointerNode = void 0, this.validateState(), this.pointerChunk.children.length === 0)
5504
- throw new Error("Cannot enter empty chunk");
5505
- }
5506
- /**
5507
- * Assuming the current node is a chunk, move the pointer into that chunk
5508
- * repeatedly until the current node is a leaf
5509
- *
5510
- * @param end If true, place the pointer on the last node of the chunk.
5511
- * Otherwise, place the pointer on the first node.
5512
- */
5513
- enterChunkUntilLeaf(end2) {
5514
- for (; this.pointerNode?.type === "chunk"; )
5515
- this.enterChunk(end2);
5516
- }
5517
- /**
5518
- * Move the pointer to the parent chunk
5519
- */
5520
- exitChunk() {
5521
- if (this.pointerChunk.type === "root")
5522
- throw new Error("Cannot exit root");
5523
- const previousPointerChunk = this.pointerChunk;
5524
- this.pointerChunk = previousPointerChunk.parent, this.pointerIndex = this.pointerIndexStack.pop(), this.cachedPointerNode = void 0, this.validateState();
5525
- }
5526
- /**
5527
- * Insert leaves immediately after the current node, leaving the pointer on
5528
- * the last inserted leaf
5529
- *
5530
- * Leaves are chunked according to the number of nodes already in the parent
5531
- * plus the number of nodes being inserted, or the minimum depth if larger
5532
- */
5533
- rawInsertAfter(leaves, minDepth) {
5534
- if (leaves.length === 0)
5535
- return;
5536
- const groupIntoChunks = (leaves2, parent2, perChunk) => {
5537
- if (perChunk === 1)
5538
- return leaves2;
5539
- const chunks2 = [];
5540
- for (let i = 0; i < this.chunkSize; i++) {
5541
- const chunkNodes = leaves2.slice(i * perChunk, (i + 1) * perChunk);
5542
- if (chunkNodes.length === 0)
5543
- break;
5544
- const chunk = {
5545
- type: "chunk",
5546
- key: new Key(),
5547
- parent: parent2,
5548
- children: []
5549
- };
5550
- chunk.children = groupIntoChunks(chunkNodes, chunk, perChunk / this.chunkSize), chunks2.push(chunk);
5551
- }
5552
- return chunks2;
5553
- }, newTotal = this.pointerSiblings.length + leaves.length;
5554
- let depthForTotal = 0;
5555
- for (let i = this.chunkSize; i < newTotal; i *= this.chunkSize)
5556
- depthForTotal++;
5557
- const depth = Math.max(depthForTotal, minDepth), perTopLevelChunk = this.chunkSize ** depth, chunks = groupIntoChunks(leaves, this.pointerChunk, perTopLevelChunk);
5558
- this.pointerSiblings.splice(this.pointerIndex + 1, 0, ...chunks), this.pointerIndex += chunks.length, this.cachedPointerNode = void 0, this.invalidateChunk(), this.validateState();
5559
- }
5560
- /**
5561
- * If debug mode is enabled, ensure that the state is internally consistent
5562
- */
5563
- // istanbul ignore next
5564
- validateState() {
5565
- if (!this.debug)
5049
+ selection
5050
+ } = editor;
5051
+ if (!range2)
5566
5052
  return;
5567
- const validateDescendant = (node2) => {
5568
- if (node2.type === "chunk") {
5569
- const {
5570
- parent: parent2,
5571
- children
5572
- } = node2;
5573
- if (!parent2.children.includes(node2))
5574
- throw new Error(`Debug: Chunk ${node2.key.id} has an incorrect parent property`);
5575
- children.forEach(validateDescendant);
5576
- }
5577
- };
5578
- if (this.root.children.forEach(validateDescendant), this.cachedPointerNode !== void 0 && this.cachedPointerNode !== this.getPointerNode())
5579
- throw new Error("Debug: The cached pointer is incorrect and has not been invalidated");
5580
- const actualIndexStack = this.getChunkPath(this.pointerChunk);
5581
- if (!actualIndexStack)
5582
- throw new Error("Debug: The pointer chunk is not connected to the root");
5583
- if (!Path.equals(this.pointerIndexStack, actualIndexStack))
5584
- throw new Error(`Debug: The cached index stack [${this.pointerIndexStack.join(", ")}] does not match the path of the pointer chunk [${actualIndexStack.join(", ")}]`);
5585
- }
5053
+ const pathChanged = !selection || !Path.equals(selection.anchor.path, range2.anchor.path), parentPathChanged = !selection || !Path.equals(selection.anchor.path.slice(0, -1), range2.anchor.path.slice(0, -1));
5054
+ (pathChanged && insertPositionHint || parentPathChanged) && (insertPositionHint = !1), (pathChanged || hasPendingDiffs()) && (flushTimeoutId = setTimeout(flush, FLUSH_DELAY));
5055
+ }, handleInput = () => {
5056
+ (hasPendingAction() || !hasPendingDiffs()) && flush();
5057
+ }, handleKeyDown = (_) => {
5058
+ hasPendingDiffs() || (updatePlaceholderVisibility(!0), setTimeout(updatePlaceholderVisibility));
5059
+ }, scheduleFlush = () => {
5060
+ hasPendingAction() || (actionTimeoutId = setTimeout(flush));
5061
+ };
5062
+ return {
5063
+ flush,
5064
+ scheduleFlush,
5065
+ hasPendingDiffs,
5066
+ hasPendingAction,
5067
+ hasPendingChanges,
5068
+ isFlushing,
5069
+ handleUserSelect,
5070
+ handleCompositionEnd,
5071
+ handleCompositionStart,
5072
+ handleDOMBeforeInput,
5073
+ handleKeyDown,
5074
+ handleDomMutations: (mutations) => {
5075
+ hasPendingDiffs() || hasPendingAction() || mutations.some((mutation) => isTrackedMutation(editor, mutation, mutations)) && editor.forceRender?.();
5076
+ },
5077
+ handleInput
5078
+ };
5586
5079
  }
5587
- const reconcileChildren = (editor, {
5588
- chunkTree,
5589
- children,
5590
- chunkSize,
5591
- rerenderChildren = [],
5592
- onInsert,
5593
- onUpdate,
5594
- onIndexChange,
5595
- debug: debug2
5080
+ const MUTATION_OBSERVER_CONFIG$1 = {
5081
+ subtree: !0,
5082
+ childList: !0,
5083
+ characterData: !0
5084
+ }, useAndroidInputManager = IS_ANDROID ? ({
5085
+ editorActor,
5086
+ node: node2,
5087
+ ...options
5596
5088
  }) => {
5597
- chunkTree.modifiedChunks.clear();
5598
- const chunkTreeHelper = new ChunkTreeHelper(chunkTree, {
5599
- chunkSize,
5600
- debug: debug2
5601
- }), childrenHelper = new ChildrenHelper(editor, children);
5602
- let treeLeaf;
5603
- for (; treeLeaf = chunkTreeHelper.readLeaf(); ) {
5604
- const lookAhead = childrenHelper.lookAhead(treeLeaf.node, treeLeaf.key), wasMoved = lookAhead > 0 && chunkTree.movedNodeKeys.has(treeLeaf.key);
5605
- if (lookAhead === -1 || wasMoved) {
5606
- chunkTreeHelper.remove();
5607
- continue;
5608
- }
5609
- const insertedChildrenStartIndex = childrenHelper.pointerIndex, insertedChildren = childrenHelper.read(lookAhead + 1), matchingChild = insertedChildren.pop();
5610
- if (insertedChildren.length) {
5611
- const leavesToInsert = childrenHelper.toChunkLeaves(insertedChildren, insertedChildrenStartIndex);
5612
- chunkTreeHelper.insertBefore(leavesToInsert), insertedChildren.forEach((node2, relativeIndex) => {
5613
- onInsert?.(node2, insertedChildrenStartIndex + relativeIndex);
5614
- });
5615
- }
5616
- const matchingChildIndex = childrenHelper.pointerIndex - 1;
5617
- treeLeaf.node !== matchingChild && (treeLeaf.node = matchingChild, chunkTreeHelper.invalidateChunk(), onUpdate?.(matchingChild, matchingChildIndex)), treeLeaf.index !== matchingChildIndex && (treeLeaf.index = matchingChildIndex, onIndexChange?.(matchingChild, matchingChildIndex)), rerenderChildren.includes(matchingChildIndex) && chunkTreeHelper.invalidateChunk();
5618
- }
5619
- if (!childrenHelper.reachedEnd) {
5620
- const remainingChildren = childrenHelper.remaining(), leavesToInsert = childrenHelper.toChunkLeaves(remainingChildren, childrenHelper.pointerIndex);
5621
- chunkTreeHelper.returnToPreviousLeaf(), chunkTreeHelper.insertAfter(leavesToInsert), remainingChildren.forEach((node2, relativeIndex) => {
5622
- onInsert?.(node2, childrenHelper.pointerIndex + relativeIndex);
5623
- });
5624
- }
5625
- chunkTree.movedNodeKeys.clear();
5626
- }, getChunkTreeForNode = (editor, node2, options = {}) => {
5627
- const key = ReactEditor.findKey(editor, node2);
5628
- let chunkTree = editor.keyToChunkTree.get(key);
5629
- return chunkTree || (chunkTree = {
5630
- type: "root",
5631
- movedNodeKeys: /* @__PURE__ */ new Set(),
5632
- modifiedChunks: /* @__PURE__ */ new Set(),
5633
- children: []
5634
- }, editor.keyToChunkTree.set(key, chunkTree)), options.reconcile && reconcileChildren(editor, {
5635
- chunkTree,
5636
- children: node2.children,
5637
- ...options.reconcile
5638
- }), chunkTree;
5639
- }, defaultRenderChunk = ({
5640
- children
5641
- }) => children, ChunkAncestor = (props) => {
5642
- const {
5643
- root,
5644
- ancestor,
5645
- renderElement,
5646
- renderChunk = defaultRenderChunk
5647
- } = props;
5648
- return ancestor.children.map((chunkNode) => {
5649
- if (chunkNode.type === "chunk") {
5650
- const key = chunkNode.key.id, renderedChunk = renderChunk({
5651
- highest: ancestor === root,
5652
- lowest: chunkNode.children.some((c2) => c2.type === "leaf"),
5653
- attributes: {
5654
- "data-slate-chunk": !0
5655
- },
5656
- children: /* @__PURE__ */ jsx(MemoizedChunk, { root, ancestor: chunkNode, renderElement, renderChunk })
5657
- });
5658
- return /* @__PURE__ */ jsx(Fragment, { children: renderedChunk }, key);
5659
- }
5660
- const element = chunkNode.node;
5661
- return renderElement(element, chunkNode.index, chunkNode.key);
5662
- });
5663
- }, ChunkTree = ChunkAncestor, MemoizedChunk = React.memo(ChunkAncestor, (prev, next2) => prev.root === next2.root && prev.renderElement === next2.renderElement && prev.renderChunk === next2.renderChunk && !next2.root.modifiedChunks.has(next2.ancestor));
5089
+ if (!IS_ANDROID)
5090
+ return null;
5091
+ const editor = useSlateStatic(), isMounted = useIsMounted(), [inputManager] = useState(() => createAndroidInputManager({
5092
+ editor,
5093
+ editorActor,
5094
+ ...options
5095
+ }));
5096
+ return useMutationObserver(node2, inputManager.handleDomMutations, MUTATION_OBSERVER_CONFIG$1), editor.scheduleFlush = inputManager.scheduleFlush, isMounted && inputManager.flush(), inputManager;
5097
+ } : () => null;
5664
5098
  function useGenericSelector(selector, equalityFn) {
5665
5099
  const [, forceRender] = useReducer((s) => s + 1, 0), latestSubscriptionCallbackError = useRef(void 0), latestSelector = useRef(() => null), latestSelectedState = useRef(null);
5666
5100
  let selectedState;
@@ -5730,7 +5164,6 @@ const defaultRenderElement$1 = (props) => /* @__PURE__ */ jsx(DefaultElement, {
5730
5164
  decorations: parentDecorations,
5731
5165
  element,
5732
5166
  renderElement = defaultRenderElement$1,
5733
- renderChunk,
5734
5167
  renderPlaceholder,
5735
5168
  renderLeaf,
5736
5169
  renderText
@@ -5740,7 +5173,6 @@ const defaultRenderElement$1 = (props) => /* @__PURE__ */ jsx(DefaultElement, {
5740
5173
  decorations,
5741
5174
  node: element,
5742
5175
  renderElement,
5743
- renderChunk,
5744
5176
  renderPlaceholder,
5745
5177
  renderLeaf,
5746
5178
  renderText
@@ -5757,7 +5189,7 @@ const defaultRenderElement$1 = (props) => /* @__PURE__ */ jsx(DefaultElement, {
5757
5189
  children,
5758
5190
  element
5759
5191
  });
5760
- }, MemoizedElement = React.memo(Element$1, (prev, next2) => prev.element === next2.element && prev.renderElement === next2.renderElement && prev.renderChunk === next2.renderChunk && prev.renderText === next2.renderText && prev.renderLeaf === next2.renderLeaf && prev.renderPlaceholder === next2.renderPlaceholder && isElementDecorationsEqual(prev.decorations, next2.decorations)), DefaultElement = (props) => {
5192
+ }, MemoizedElement = React.memo(Element$1, (prev, next2) => prev.element === next2.element && prev.renderElement === next2.renderElement && prev.renderText === next2.renderText && prev.renderLeaf === next2.renderLeaf && prev.renderPlaceholder === next2.renderPlaceholder && isElementDecorationsEqual(prev.decorations, next2.decorations)), DefaultElement = (props) => {
5761
5193
  const {
5762
5194
  attributes,
5763
5195
  children,
@@ -5953,58 +5385,34 @@ const defaultRenderLeaf = (props) => /* @__PURE__ */ jsx(DefaultLeaf, { ...props
5953
5385
  decorations,
5954
5386
  node: node2,
5955
5387
  renderElement,
5956
- renderChunk,
5957
5388
  renderPlaceholder,
5958
5389
  renderText,
5959
5390
  renderLeaf
5960
5391
  } = props, editor = useSlateStatic();
5961
5392
  editor.isNodeMapDirty = !1;
5962
- const isEditor2 = Editor.isEditor(node2), chunkSize = !isEditor2 && Element$2.isElement(node2, editor.schema) && !editor.isInline(node2) && Editor.hasInlines(editor, node2) ? null : editor.getChunkSize(node2), chunking = !!chunkSize, {
5963
- decorationsByChild,
5964
- childrenToRedecorate
5965
- } = useDecorationsByChild(editor, node2, decorations);
5966
- chunking || node2.children.forEach((n2, i) => {
5393
+ const isEditor2 = Editor.isEditor(node2), decorationsByChild = useDecorationsByChild(editor, node2, decorations);
5394
+ node2.children.forEach((n2, i) => {
5967
5395
  editor.nodeToIndex.set(n2, i), editor.nodeToParent.set(n2, node2);
5968
5396
  });
5969
5397
  const renderElementComponent = useCallback((n2, i, cachedKey) => {
5970
5398
  const key = cachedKey ?? ReactEditor.findKey(editor, n2);
5971
- return /* @__PURE__ */ jsx(ElementContext.Provider, { value: n2, children: /* @__PURE__ */ jsx(MemoizedElement, { decorations: decorationsByChild[i] ?? [], element: n2, renderElement, renderChunk, renderPlaceholder, renderLeaf, renderText }, key.id) }, `provider-${key.id}`);
5972
- }, [editor, decorationsByChild, renderElement, renderChunk, renderPlaceholder, renderLeaf, renderText]), renderTextComponent = (n2, i) => {
5399
+ return /* @__PURE__ */ jsx(ElementContext.Provider, { value: n2, children: /* @__PURE__ */ jsx(MemoizedElement, { decorations: decorationsByChild[i] ?? [], element: n2, renderElement, renderPlaceholder, renderLeaf, renderText }, key.id) }, `provider-${key.id}`);
5400
+ }, [editor, decorationsByChild, renderElement, renderPlaceholder, renderLeaf, renderText]), renderTextComponent = (n2, i) => {
5973
5401
  const key = ReactEditor.findKey(editor, n2);
5974
5402
  return /* @__PURE__ */ jsx(MemoizedText, { decorations: decorationsByChild[i] ?? [], isLast: i === node2.children.length - 1, parent: node2, renderPlaceholder, renderLeaf, renderText, text: n2 }, key.id);
5975
5403
  }, renderObjectNodeComponent = (n2, i) => {
5976
5404
  const key = ReactEditor.findKey(editor, n2);
5977
5405
  return /* @__PURE__ */ jsx(MemoizedObjectNode, { decorations: decorationsByChild[i] ?? [], isInline: !isEditor2, objectNode: n2, renderElement }, key.id);
5978
5406
  };
5979
- if (!chunking)
5980
- return node2.children.map((n2, i) => Element$2.isElement(n2, editor.schema) ? renderElementComponent(n2, i) : Node$1.isObjectNode(n2, editor.schema) ? renderObjectNodeComponent(n2, i) : renderTextComponent(n2, i));
5981
- const chunkTree = getChunkTreeForNode(editor, node2, {
5982
- reconcile: {
5983
- chunkSize,
5984
- rerenderChildren: childrenToRedecorate,
5985
- onInsert: (n2, i) => {
5986
- editor.nodeToIndex.set(n2, i), editor.nodeToParent.set(n2, node2);
5987
- },
5988
- onUpdate: (n2, i) => {
5989
- editor.nodeToIndex.set(n2, i), editor.nodeToParent.set(n2, node2);
5990
- },
5991
- onIndexChange: (n2, i) => {
5992
- editor.nodeToIndex.set(n2, i);
5993
- }
5994
- }
5995
- });
5996
- return /* @__PURE__ */ jsx(ChunkTree, { root: chunkTree, ancestor: chunkTree, renderElement: renderElementComponent, renderChunk });
5407
+ return node2.children.map((n2, i) => Element$2.isElement(n2, editor.schema) ? renderElementComponent(n2, i) : Node$1.isObjectNode(n2, editor.schema) ? renderObjectNodeComponent(n2, i) : renderTextComponent(n2, i));
5997
5408
  }, useDecorationsByChild = (editor, node2, decorations) => {
5998
- const decorationsByChild = splitDecorationsByChild(editor, node2, decorations), mutableDecorationsByChild = useRef(decorationsByChild).current, childrenToRedecorate = [];
5409
+ const decorationsByChild = splitDecorationsByChild(editor, node2, decorations), mutableDecorationsByChild = useRef(decorationsByChild).current;
5999
5410
  mutableDecorationsByChild.length = decorationsByChild.length;
6000
5411
  for (let i = 0; i < decorationsByChild.length; i++) {
6001
5412
  const decorations2 = decorationsByChild[i], previousDecorations = mutableDecorationsByChild[i] ?? null;
6002
- isElementDecorationsEqual(previousDecorations, decorations2) || (mutableDecorationsByChild[i] = decorations2, childrenToRedecorate.push(i));
5413
+ isElementDecorationsEqual(previousDecorations, decorations2) || (mutableDecorationsByChild[i] = decorations2);
6003
5414
  }
6004
- return {
6005
- decorationsByChild: mutableDecorationsByChild,
6006
- childrenToRedecorate
6007
- };
5415
+ return mutableDecorationsByChild;
6008
5416
  }, ComposingContext = createContext(!1), ReadOnlyContext = createContext(!1), useReadOnly = () => useContext(ReadOnlyContext), SlateSelectorContext = createContext({}), refEquality = (a, b) => a === b;
6009
5417
  function useSlateSelector(selector, equalityFn = refEquality, {
6010
5418
  deferred
@@ -6184,7 +5592,7 @@ class RestoreDOMComponent extends Component {
6184
5592
  }
6185
5593
  const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({
6186
5594
  children
6187
- }) => /* @__PURE__ */ jsx(Fragment$1, { children }), Children = (props) => /* @__PURE__ */ jsx(React.Fragment, { children: useChildren(props) }), Editable = forwardRef((props, forwardedRef) => {
5595
+ }) => /* @__PURE__ */ jsx(Fragment, { children }), Children = (props) => /* @__PURE__ */ jsx(React.Fragment, { children: useChildren(props) }), Editable = forwardRef((props, forwardedRef) => {
6188
5596
  const defaultRenderPlaceholder = useCallback((props2) => /* @__PURE__ */ jsx(DefaultPlaceholder, { ...props2 }), []), {
6189
5597
  autoFocus,
6190
5598
  decorate = defaultDecorate,
@@ -6193,7 +5601,6 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({
6193
5601
  placeholder,
6194
5602
  readOnly = !1,
6195
5603
  renderElement,
6196
- renderChunk,
6197
5604
  renderLeaf,
6198
5605
  renderText,
6199
5606
  renderPlaceholder = defaultRenderPlaceholder,
@@ -7134,7 +6541,7 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({
7134
6541
  editor
7135
6542
  }));
7136
6543
  }, [readOnly, editor, editorActor, attributes.onPaste]),
7137
- children: /* @__PURE__ */ jsx(Children, { decorations, node: editor, renderElement, renderChunk, renderPlaceholder, renderLeaf, renderText })
6544
+ children: /* @__PURE__ */ jsx(Children, { decorations, node: editor, renderElement, renderPlaceholder, renderLeaf, renderText })
7138
6545
  }
7139
6546
  ) }) }) }) });
7140
6547
  }), DefaultPlaceholder = ({
@@ -7533,18 +6940,11 @@ const withReact = (editor) => {
7533
6940
  apply: apply2,
7534
6941
  insertText: insertText2
7535
6942
  } = e;
7536
- return e.getChunkSize = () => null, e.keyToChunkTree = /* @__PURE__ */ new WeakMap(), IS_ANDROID && (e.insertText = (text, options) => (e.pendingSelection = null, insertText2(text, options))), e.onChange = (options) => {
6943
+ return IS_ANDROID && (e.insertText = (text, options) => (e.pendingSelection = null, insertText2(text, options))), e.onChange = (options) => {
7537
6944
  (REACT_MAJOR_VERSION < 18 ? ReactDOM.unstable_batchedUpdates : (callback) => callback())(() => {
7538
6945
  onChange(options);
7539
6946
  });
7540
6947
  }, e.apply = (operation) => {
7541
- if (operation.type === "move_node") {
7542
- const parent2 = Node$1.parent(e, operation.path, e.schema);
7543
- if (e.getChunkSize(parent2)) {
7544
- const node2 = Node$1.get(e, operation.path, e.schema), chunkTree = getChunkTreeForNode(e, parent2), key = ReactEditor.findKey(e, node2);
7545
- chunkTree.movedNodeKeys.add(key);
7546
- }
7547
- }
7548
6948
  apply2(operation);
7549
6949
  }, e;
7550
6950
  }, EditorActorContext = createContext({}), IS_MAC = typeof window < "u" && /Mac|iPod|iPhone|iPad/.test(window.navigator.userAgent), modifiers = {
@@ -8763,7 +8163,7 @@ function RenderLeaf(props) {
8763
8163
  let t2;
8764
8164
  $[4] !== t1 ? (t2 = /* @__PURE__ */ jsx("span", { style: PLACEHOLDER_STYLE, contentEditable: !1, children: t1 }), $[4] = t1, $[5] = t2) : t2 = $[5];
8765
8165
  let t3;
8766
- return $[6] !== renderedSpan || $[7] !== t2 ? (t3 = /* @__PURE__ */ jsxs(Fragment$1, { children: [
8166
+ return $[6] !== renderedSpan || $[7] !== t2 ? (t3 = /* @__PURE__ */ jsxs(Fragment, { children: [
8767
8167
  t2,
8768
8168
  renderedSpan
8769
8169
  ] }), $[6] = renderedSpan, $[7] = t2, $[8] = t3) : t3 = $[8], t3;
@@ -10668,21 +10068,18 @@ function createHistoryPlugin({
10668
10068
  }, editor;
10669
10069
  };
10670
10070
  }
10671
- function applyInsertNodeAtPath(editor, node2, path2, options = {}) {
10672
- if (editor.apply({
10071
+ function applyInsertNodeAtPath(editor, node2, path2) {
10072
+ editor.apply({
10673
10073
  type: "insert_node",
10674
10074
  path: path2,
10675
10075
  node: node2
10676
- }), options.select) {
10677
- const point2 = Editor.end(editor, path2);
10678
- point2 && applySelect(editor, point2);
10679
- }
10076
+ });
10077
+ const point2 = Editor.end(editor, path2);
10078
+ point2 && applySelect(editor, point2);
10680
10079
  }
10681
- function applyInsertNodeAtPoint(editor, node2, at, options = {}) {
10080
+ function applyInsertNodeAtPoint(editor, node2, at) {
10682
10081
  Editor.withoutNormalizing(editor, () => {
10683
- let match2;
10684
- Text$1.isText(node2, editor.schema) ? match2 = (n2) => Text$1.isText(n2, editor.schema) : Element$2.isElement(node2, editor.schema) && editor.isInline(node2) ? match2 = (n2) => Text$1.isText(n2, editor.schema) || Element$2.isElement(n2, editor.schema) && Editor.isInline(editor, n2) : editor.isObjectNode(node2) ? match2 = (n2) => Text$1.isText(n2, editor.schema) || editor.isObjectNode(n2) || Element$2.isElement(n2, editor.schema) && Editor.isInline(editor, n2) : match2 = (n2) => Element$2.isElement(n2, editor.schema) && Editor.isBlock(editor, n2) || editor.isObjectNode(n2);
10685
- const [entry] = Editor.nodes(editor, {
10082
+ const match2 = Text$1.isText(node2, editor.schema) ? (n2) => Text$1.isText(n2, editor.schema) : (n2) => Text$1.isText(n2, editor.schema) || editor.isObjectNode(n2), [entry] = Editor.nodes(editor, {
10686
10083
  at: at.path,
10687
10084
  match: match2,
10688
10085
  mode: "lowest",
@@ -10693,33 +10090,16 @@ function applyInsertNodeAtPoint(editor, node2, at, options = {}) {
10693
10090
  const [, matchPath2] = entry, pathRef2 = Editor.pathRef(editor, matchPath2), isAtEnd = Editor.isEnd(editor, at, matchPath2);
10694
10091
  if (!Editor.isEdge(editor, at, matchPath2)) {
10695
10092
  const textNode = Node$1.get(editor, at.path, editor.schema), properties = Node$1.extractProps(textNode, editor.schema);
10696
- editor.apply({
10697
- type: "split_node",
10698
- path: at.path,
10699
- position: at.offset,
10700
- properties
10701
- });
10093
+ applySplitNode(editor, at.path, at.offset, properties);
10702
10094
  }
10703
10095
  const path2 = pathRef2.unref(), insertPath = isAtEnd ? Path.next(path2) : path2;
10704
- if (editor.apply({
10096
+ editor.apply({
10705
10097
  type: "insert_node",
10706
10098
  path: insertPath,
10707
10099
  node: node2
10708
- }), options.select) {
10709
- const point2 = Editor.end(editor, insertPath);
10710
- point2 && applySelect(editor, point2);
10711
- }
10712
- });
10713
- }
10714
- function applySetNode(editor, props, path2) {
10715
- const node2 = Node$1.get(editor, path2, editor.schema), propsRecord = props, properties = {}, newProperties = {};
10716
- for (const key of Object.keys(propsRecord))
10717
- key !== "children" && (key === "text" && !Element$2.isElement(node2, editor.schema) && !editor.isObjectNode(node2) || propsRecord[key] !== node2[key] && (node2.hasOwnProperty(key) && (properties[key] = node2[key]), propsRecord[key] != null && (newProperties[key] = propsRecord[key])));
10718
- (Object.keys(newProperties).length > 0 || Object.keys(properties).length > 0) && editor.apply({
10719
- type: "set_node",
10720
- path: path2,
10721
- properties,
10722
- newProperties
10100
+ });
10101
+ const point2 = Editor.end(editor, insertPath);
10102
+ point2 && applySelect(editor, point2);
10723
10103
  });
10724
10104
  }
10725
10105
  function withNormalizeNode(editor, fn) {
@@ -10740,9 +10120,7 @@ function createNormalizationPlugin(editorActor) {
10740
10120
  const [node2, path2] = nodeEntry;
10741
10121
  if (Editor.isEditor(node2) && node2.children.length === 0 && withoutPatching(editor, () => {
10742
10122
  withNormalizeNode(editor, () => {
10743
- applyInsertNodeAtPath(editor, createPlaceholderBlock(editorActor.getSnapshot().context), [0], {
10744
- select: !0
10745
- });
10123
+ applyInsertNodeAtPath(editor, createPlaceholderBlock(editorActor.getSnapshot().context), [0]);
10746
10124
  });
10747
10125
  }), editor.isTextBlock(node2)) {
10748
10126
  const children = Node$1.children(editor, path2, editor.schema);
@@ -10750,16 +10128,8 @@ function createNormalizationPlugin(editorActor) {
10750
10128
  const nextNode = node2.children[childPath[1] + 1];
10751
10129
  if (editor.isTextSpan(child) && editor.isTextSpan(nextNode) && child.marks?.every((mark) => nextNode.marks?.includes(mark)) && nextNode.marks?.every((mark) => child.marks?.includes(mark))) {
10752
10130
  debug$1.normalization("merging spans with same marks"), withNormalizeNode(editor, () => {
10753
- const mergePath = [childPath[0], childPath[1] + 1], {
10754
- text: _text,
10755
- ...properties
10756
- } = nextNode;
10757
- editor.apply({
10758
- type: "merge_node",
10759
- path: mergePath,
10760
- position: child.text.length,
10761
- properties
10762
- });
10131
+ const mergePath = [childPath[0], childPath[1] + 1];
10132
+ applyMergeNode(editor, mergePath, child.text.length);
10763
10133
  });
10764
10134
  return;
10765
10135
  }
@@ -10842,7 +10212,7 @@ function createNormalizationPlugin(editorActor) {
10842
10212
  return;
10843
10213
  }
10844
10214
  }
10845
- if (editor.isTextBlock(node2) && !editor.operations.some((op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1)) {
10215
+ if (editor.isTextBlock(node2)) {
10846
10216
  const newMarkDefs = (node2.markDefs || []).filter((def) => node2.children.find((child) => Text$1.isText(child, editor.schema) && Array.isArray(child.marks) && child.marks.includes(def._key)));
10847
10217
  if (node2.markDefs && !isEqualMarkDefs(newMarkDefs, node2.markDefs)) {
10848
10218
  debug$1.normalization("removing markDef not in use"), withNormalizeNode(editor, () => {
@@ -10890,16 +10260,6 @@ function createNormalizationPlugin(editorActor) {
10890
10260
  }
10891
10261
  } else
10892
10262
  editor.decoratorState = {};
10893
- if (op.type === "merge_node" && op.path.length === 1 && "markDefs" in op.properties && op.properties._type === editorActor.getSnapshot().context.schema.block.name && Array.isArray(op.properties.markDefs) && op.properties.markDefs.length > 0 && op.path[0] - 1 >= 0) {
10894
- const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
10895
- if (editor.isTextBlock(targetBlock)) {
10896
- const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [], newMarkDefs = [...new Map([...oldDefs, ...op.properties.markDefs].map((def) => [def._key, def])).values()];
10897
- debug$1.normalization("copying markDefs over to merged block", op), applySetNode(editor, {
10898
- markDefs: newMarkDefs
10899
- }, targetPath), apply2(op);
10900
- return;
10901
- }
10902
- }
10903
10263
  apply2(op);
10904
10264
  }, editor;
10905
10265
  };
@@ -12090,58 +11450,6 @@ function insertNodePatch(schema, children, operation, beforeValue) {
12090
11450
  }
12091
11451
  return [];
12092
11452
  }
12093
- function splitNodePatch(schema, children, operation, beforeValue) {
12094
- const patches = [], splitBlock2 = children[operation.path[0]];
12095
- if (!isTextBlock({
12096
- schema
12097
- }, splitBlock2))
12098
- throw new Error(`Block with path ${JSON.stringify(operation.path[0])} is not a text block and can't be split`);
12099
- if (operation.path.length === 1) {
12100
- const oldBlock = beforeValue[operation.path[0]];
12101
- if (isTextBlock({
12102
- schema
12103
- }, oldBlock)) {
12104
- const nextBlock = children[operation.path[0] + 1];
12105
- if (!nextBlock)
12106
- return patches;
12107
- const targetValue = nextBlock;
12108
- targetValue && (patches.push(insert([targetValue], "after", [{
12109
- _key: splitBlock2._key
12110
- }])), oldBlock.children.slice(operation.position).forEach((span) => {
12111
- const path2 = [{
12112
- _key: oldBlock._key
12113
- }, "children", {
12114
- _key: span._key
12115
- }];
12116
- patches.push(unset(path2));
12117
- }));
12118
- }
12119
- return patches;
12120
- }
12121
- if (operation.path.length === 2) {
12122
- const splitSpan = splitBlock2.children[operation.path[1]];
12123
- if (isSpan({
12124
- schema
12125
- }, splitSpan)) {
12126
- const targetSpans = {
12127
- children: splitBlock2.children.slice(operation.path[1] + 1, operation.path[1] + 2)
12128
- }.children;
12129
- patches.push(setIfMissing([], [{
12130
- _key: splitBlock2._key
12131
- }, "children"])), patches.push(insert(targetSpans, "after", [{
12132
- _key: splitBlock2._key
12133
- }, "children", {
12134
- _key: splitSpan._key
12135
- }])), patches.push(set(splitSpan.text, [{
12136
- _key: splitBlock2._key
12137
- }, "children", {
12138
- _key: splitSpan._key
12139
- }, "text"]));
12140
- }
12141
- return patches;
12142
- }
12143
- return patches;
12144
- }
12145
11453
  function removeNodePatch(schema, beforeValue, operation) {
12146
11454
  const block = beforeValue[operation.path[0]];
12147
11455
  if (operation.path.length === 1) {
@@ -12162,86 +11470,6 @@ function removeNodePatch(schema, beforeValue, operation) {
12162
11470
  } else
12163
11471
  return [];
12164
11472
  }
12165
- function mergeNodePatch(schema, children, operation, beforeValue) {
12166
- const patches = [], block = beforeValue[operation.path[0]], updatedBlock = children[operation.path[0]];
12167
- if (operation.path.length === 1)
12168
- if (block?._key) {
12169
- const prevBlock = children[operation.path[0] - 1];
12170
- if (!prevBlock)
12171
- throw new Error("Previous block not found!");
12172
- const newBlock = prevBlock;
12173
- patches.push(set(newBlock, [{
12174
- _key: newBlock._key
12175
- }])), patches.push(unset([{
12176
- _key: block._key
12177
- }]));
12178
- } else
12179
- throw new Error("Target key not found!");
12180
- else if (isTextBlock({
12181
- schema
12182
- }, block) && isTextBlock({
12183
- schema
12184
- }, updatedBlock) && operation.path.length === 2) {
12185
- const updatedSpan = updatedBlock.children[operation.path[1] - 1] && isSpan({
12186
- schema
12187
- }, updatedBlock.children[operation.path[1] - 1]) ? updatedBlock.children[operation.path[1] - 1] : void 0, removedSpan = block.children[operation.path[1]] && isSpan({
12188
- schema
12189
- }, block.children[operation.path[1]]) ? block.children[operation.path[1]] : void 0;
12190
- if (updatedSpan) {
12191
- const spansMatchingKey = block.children.filter((span) => span._key === updatedSpan._key);
12192
- if (spansMatchingKey.length === 1) {
12193
- const prevSpan = spansMatchingKey[0];
12194
- isSpan({
12195
- schema
12196
- }, prevSpan) && prevSpan.text !== updatedSpan.text && patches.push(set(updatedSpan.text, [{
12197
- _key: block._key
12198
- }, "children", {
12199
- _key: updatedSpan._key
12200
- }, "text"]));
12201
- } else
12202
- console.warn(`Multiple spans have \`_key\` ${updatedSpan._key}. It's ambiguous which one to update.`, JSON.stringify(block, null, 2));
12203
- }
12204
- removedSpan && (block.children.filter((span) => span._key === removedSpan._key).length === 1 ? patches.push(unset([{
12205
- _key: block._key
12206
- }, "children", {
12207
- _key: removedSpan._key
12208
- }])) : console.warn(`Multiple spans have \`_key\` ${removedSpan._key}. It's ambiguous which one to remove.`, JSON.stringify(block, null, 2)));
12209
- }
12210
- return patches;
12211
- }
12212
- function moveNodePatch(schema, beforeValue, operation) {
12213
- const patches = [], block = beforeValue[operation.path[0]], targetBlock = beforeValue[operation.newPath[0]];
12214
- if (!targetBlock || !block)
12215
- return patches;
12216
- if (operation.path.length === 1) {
12217
- const position = operation.path[0] > operation.newPath[0] ? "before" : "after";
12218
- patches.push(unset([{
12219
- _key: block._key
12220
- }])), patches.push(insert([block], position, [{
12221
- _key: targetBlock._key
12222
- }]));
12223
- } else if (operation.path.length === 2 && isTextBlock({
12224
- schema
12225
- }, block) && isTextBlock({
12226
- schema
12227
- }, targetBlock)) {
12228
- const child = block.children[operation.path[1]], targetChild = targetBlock.children[operation.newPath[1]], position = operation.newPath[1] === targetBlock.children.length ? "after" : "before", childToInsert = block.children[operation.path[1]];
12229
- if (!child || !targetChild || !childToInsert)
12230
- return patches;
12231
- patches.push(unset([{
12232
- _key: block._key
12233
- }, "children", {
12234
- _key: child._key
12235
- }])), patches.push(setIfMissing([], [{
12236
- _key: targetBlock._key
12237
- }, "children"])), patches.push(insert([childToInsert], position, [{
12238
- _key: targetBlock._key
12239
- }, "children", {
12240
- _key: targetChild._key
12241
- }]));
12242
- }
12243
- return patches;
12244
- }
12245
11473
  function withRemoteChanges(editor, fn) {
12246
11474
  const prev = editor.isProcessingRemoteChanges;
12247
11475
  editor.isProcessingRemoteChanges = !0, fn(), editor.isProcessingRemoteChanges = prev;
@@ -12313,23 +11541,14 @@ function createPatchesPlugin({
12313
11541
  case "remove_node":
12314
11542
  patches = [...patches, ...removeNodePatch(editorActor.getSnapshot().context.schema, previousValue, operation)];
12315
11543
  break;
12316
- case "split_node":
12317
- patches = [...patches, ...splitNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousValue)];
12318
- break;
12319
11544
  case "insert_node":
12320
11545
  patches = [...patches, ...insertNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousValue)];
12321
11546
  break;
12322
11547
  case "set_node":
12323
11548
  patches = [...patches, ...setNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation)];
12324
11549
  break;
12325
- case "merge_node":
12326
- patches = [...patches, ...mergeNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousValue)];
12327
- break;
12328
- case "move_node":
12329
- patches = [...patches, ...moveNodePatch(editorActor.getSnapshot().context.schema, previousValue, operation)];
12330
- break;
12331
11550
  }
12332
- if (!editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(operation.type) && (patches = [...patches, unset([])], relayActor.send({
11551
+ if (!editorWasEmpty && editorIsEmpty && ["set_node", "remove_text", "remove_node"].includes(operation.type) && (patches = [...patches, unset([])], relayActor.send({
12333
11552
  type: "unset",
12334
11553
  previousValue
12335
11554
  })), editorWasEmpty && patches.length > 0 && (patches = [setIfMissing([], []), ...patches]), patches.length > 0)
@@ -12418,23 +11637,6 @@ function createUniqueKeysPlugin(editorActor) {
12418
11637
  apply2(operation);
12419
11638
  return;
12420
11639
  }
12421
- if (operation.type === "split_node") {
12422
- const _key = operation.properties._key && keyExistsAtPath({
12423
- blockIndexMap: editor.blockIndexMap,
12424
- context: {
12425
- schema: context.schema,
12426
- value: editor.children
12427
- }
12428
- }, operation.path, operation.properties._key) ? void 0 : operation.properties._key;
12429
- apply2({
12430
- ...operation,
12431
- properties: {
12432
- ...operation.properties,
12433
- _key: _key === void 0 ? editorActor.getSnapshot().context.keyGenerator() : _key
12434
- }
12435
- });
12436
- return;
12437
- }
12438
11640
  if (operation.type === "insert_node" && !Editor.isEditor(operation.node)) {
12439
11641
  const _key = operation.node._key && keyExistsAtPath({
12440
11642
  blockIndexMap: editor.blockIndexMap,
@@ -12452,54 +11654,6 @@ function createUniqueKeysPlugin(editorActor) {
12452
11654
  });
12453
11655
  return;
12454
11656
  }
12455
- if (operation.type === "merge_node") {
12456
- const index = operation.path[operation.path.length - 1], prevPath = Path.previous(operation.path), prevIndex = prevPath[prevPath.length - 1];
12457
- if (operation.path.length !== 1 || prevPath.length !== 1) {
12458
- apply2(operation);
12459
- return;
12460
- }
12461
- const block = editor.children.at(index), previousBlock = editor.children.at(prevIndex);
12462
- if (!block || !previousBlock) {
12463
- apply2(operation);
12464
- return;
12465
- }
12466
- if (!isTextBlock(editorActor.getSnapshot().context, block) || !isTextBlock(editorActor.getSnapshot().context, previousBlock)) {
12467
- apply2(operation);
12468
- return;
12469
- }
12470
- const previousBlockChildKeys = previousBlock.children.map((child) => child._key), previousBlockMarkDefKeys = previousBlock.markDefs?.map((markDef) => markDef._key) ?? [], markDefKeyMap = /* @__PURE__ */ new Map(), adjustedMarkDefs = block.markDefs?.map((markDef) => {
12471
- if (previousBlockMarkDefKeys.includes(markDef._key)) {
12472
- const newKey = editorActor.getSnapshot().context.keyGenerator();
12473
- return markDefKeyMap.set(markDef._key, newKey), {
12474
- ...markDef,
12475
- _key: newKey
12476
- };
12477
- }
12478
- return markDef;
12479
- });
12480
- let childIndex = 0;
12481
- for (const child of block.children) {
12482
- if (isSpan(editorActor.getSnapshot().context, child)) {
12483
- const marks = child.marks?.map((mark) => markDefKeyMap.get(mark) || mark) ?? [];
12484
- isEqualMarks(child.marks, marks) || applySetNode(editor, {
12485
- marks
12486
- }, [index, childIndex]);
12487
- }
12488
- previousBlockChildKeys.includes(child._key) && applySetNode(editor, {
12489
- _key: editorActor.getSnapshot().context.keyGenerator()
12490
- }, [index, childIndex]), childIndex++;
12491
- }
12492
- apply2({
12493
- ...operation,
12494
- properties: {
12495
- ...operation.properties,
12496
- // Make sure the adjusted markDefs are carried along for the merge
12497
- // operation
12498
- markDefs: adjustedMarkDefs
12499
- }
12500
- });
12501
- return;
12502
- }
12503
11657
  apply2(operation);
12504
11658
  }, editor.normalizeNode = (entry) => {
12505
11659
  const [node2, path2] = entry;
@@ -14213,21 +13367,11 @@ const addAnnotationOperationImplementation = ({
14213
13367
  }), [splitStart, splitEnd] = Range.edges(splitRange);
14214
13368
  if (!Editor.isEnd(editor, splitEnd, splitEnd.path) || !Editor.isEdge(editor, splitEnd, splitEnd.path)) {
14215
13369
  const [endNode] = Editor.node(editor, splitEnd.path);
14216
- editor.apply({
14217
- type: "split_node",
14218
- path: splitEnd.path,
14219
- position: splitEnd.offset,
14220
- properties: Node$1.extractProps(endNode, editor.schema)
14221
- });
13370
+ applySplitNode(editor, splitEnd.path, splitEnd.offset, Node$1.extractProps(endNode, editor.schema));
14222
13371
  }
14223
13372
  if (!Editor.isStart(editor, splitStart, splitStart.path) || !Editor.isEdge(editor, splitStart, splitStart.path)) {
14224
13373
  const [startNode] = Editor.node(editor, splitStart.path);
14225
- editor.apply({
14226
- type: "split_node",
14227
- path: splitStart.path,
14228
- position: splitStart.offset,
14229
- properties: Node$1.extractProps(startNode, editor.schema)
14230
- });
13374
+ applySplitNode(editor, splitStart.path, splitStart.offset, Node$1.extractProps(startNode, editor.schema));
14231
13375
  }
14232
13376
  const updatedSplitRange = splitRangeRef.unref();
14233
13377
  !at && updatedSplitRange && applySelect(editor, updatedSplitRange);
@@ -14304,21 +13448,11 @@ const addAnnotationOperationImplementation = ({
14304
13448
  }), [splitStart, splitEnd] = Range.edges(splitRange);
14305
13449
  if (!Editor.isEnd(editor, splitEnd, splitEnd.path) || !Editor.isEdge(editor, splitEnd, splitEnd.path)) {
14306
13450
  const [endNode] = Editor.node(editor, splitEnd.path);
14307
- editor.apply({
14308
- type: "split_node",
14309
- path: splitEnd.path,
14310
- position: splitEnd.offset,
14311
- properties: Node$1.extractProps(endNode, editor.schema)
14312
- });
13451
+ applySplitNode(editor, splitEnd.path, splitEnd.offset, Node$1.extractProps(endNode, editor.schema));
14313
13452
  }
14314
13453
  if (!Editor.isStart(editor, splitStart, splitStart.path) || !Editor.isEdge(editor, splitStart, splitStart.path)) {
14315
13454
  const [startNode] = Editor.node(editor, splitStart.path);
14316
- editor.apply({
14317
- type: "split_node",
14318
- path: splitStart.path,
14319
- position: splitStart.offset,
14320
- properties: Node$1.extractProps(startNode, editor.schema)
14321
- });
13455
+ applySplitNode(editor, splitStart.path, splitStart.offset, Node$1.extractProps(startNode, editor.schema));
14322
13456
  }
14323
13457
  const updatedSplitRange = splitRangeRef.unref();
14324
13458
  !at && updatedSplitRange && applySelect(editor, updatedSplitRange);
@@ -14557,21 +13691,11 @@ const addAnnotationOperationImplementation = ({
14557
13691
  }), [start2, end2] = Range.edges(at);
14558
13692
  if (!Editor.isEnd(editor, end2, end2.path) || !Editor.isEdge(editor, end2, end2.path)) {
14559
13693
  const [endNode] = Editor.node(editor, end2.path);
14560
- editor.apply({
14561
- type: "split_node",
14562
- path: end2.path,
14563
- position: end2.offset,
14564
- properties: Node$1.extractProps(endNode, editor.schema)
14565
- });
13694
+ applySplitNode(editor, end2.path, end2.offset, Node$1.extractProps(endNode, editor.schema));
14566
13695
  }
14567
13696
  if (!Editor.isStart(editor, start2, start2.path) || !Editor.isEdge(editor, start2, start2.path)) {
14568
13697
  const [startNode] = Editor.node(editor, start2.path);
14569
- editor.apply({
14570
- type: "split_node",
14571
- path: start2.path,
14572
- position: start2.offset,
14573
- properties: Node$1.extractProps(startNode, editor.schema)
14574
- });
13698
+ applySplitNode(editor, start2.path, start2.offset, Node$1.extractProps(startNode, editor.schema));
14575
13699
  }
14576
13700
  if (at = rangeRef2.unref(), !at)
14577
13701
  throw new Error("Unable to add decorator without a selection");
@@ -14635,21 +13759,11 @@ const addAnnotationOperationImplementation = ({
14635
13759
  const [start2, end2] = Range.edges(at);
14636
13760
  if (!Editor.isEnd(editor, end2, end2.path) || !Editor.isEdge(editor, end2, end2.path)) {
14637
13761
  const [endNode] = Editor.node(editor, end2.path);
14638
- editor.apply({
14639
- type: "split_node",
14640
- path: end2.path,
14641
- position: end2.offset,
14642
- properties: Node$1.extractProps(endNode, editor.schema)
14643
- });
13762
+ applySplitNode(editor, end2.path, end2.offset, Node$1.extractProps(endNode, editor.schema));
14644
13763
  }
14645
13764
  if (!Editor.isStart(editor, start2, start2.path) || !Editor.isEdge(editor, start2, start2.path)) {
14646
13765
  const [startNode] = Editor.node(editor, start2.path);
14647
- editor.apply({
14648
- type: "split_node",
14649
- path: start2.path,
14650
- position: start2.offset,
14651
- properties: Node$1.extractProps(startNode, editor.schema)
14652
- });
13766
+ applySplitNode(editor, start2.path, start2.offset, Node$1.extractProps(startNode, editor.schema));
14653
13767
  }
14654
13768
  }
14655
13769
  const updatedAt = rangeRef2.unref();
@@ -15267,24 +14381,14 @@ function insertBlock(options) {
15267
14381
  text: _2,
15268
14382
  ...properties
15269
14383
  } = textNode;
15270
- editor.apply({
15271
- type: "split_node",
15272
- path: selectionPoint.path,
15273
- position: childOffset,
15274
- properties
15275
- });
14384
+ applySplitNode(editor, selectionPoint.path, childOffset, properties);
15276
14385
  }
15277
14386
  }
15278
14387
  const splitAtIndex = childOffset > 0 ? childIndex + 1 : childIndex, {
15279
14388
  children: _,
15280
14389
  ...blockProperties
15281
14390
  } = currentBlock;
15282
- editor.apply({
15283
- type: "split_node",
15284
- path: blockPath,
15285
- position: splitAtIndex,
15286
- properties: blockProperties
15287
- });
14391
+ applySplitNode(editor, blockPath, splitAtIndex, blockProperties);
15288
14392
  const insertPath = [blockPath[0] + 1];
15289
14393
  if (editor.apply({
15290
14394
  type: "insert_node",
@@ -15476,12 +14580,7 @@ function insertBlock(options) {
15476
14580
  text: _,
15477
14581
  ...properties
15478
14582
  } = nodeToSplit;
15479
- editor.apply({
15480
- type: "split_node",
15481
- path: startPoint.path,
15482
- position: startPoint.offset,
15483
- properties
15484
- });
14583
+ applySplitNode(editor, startPoint.path, startPoint.offset, properties);
15485
14584
  }
15486
14585
  insertTextBlockFragment(editor, block, startPoint), select2 === "none" ? setSelectionToRange(editor, at) : setSelection(editor, [endBlockPath[0] + 1], "start");
15487
14586
  } else {
@@ -15494,12 +14593,7 @@ function insertBlock(options) {
15494
14593
  text: _,
15495
14594
  ...properties
15496
14595
  } = textNode;
15497
- editor.apply({
15498
- type: "split_node",
15499
- path: currentPath,
15500
- position: currentOffset,
15501
- properties
15502
- }), currentPath = Path.next(currentPath), currentOffset = 0;
14596
+ applySplitNode(editor, currentPath, currentOffset, properties), currentPath = Path.next(currentPath), currentOffset = 0;
15503
14597
  }
15504
14598
  const splitAtIndex = currentOffset > 0 ? currentPath[1] + 1 : currentPath[1], blockToSplit = Node$1.get(editor, blockPath, editor.schema);
15505
14599
  if (splitAtIndex < blockToSplit.children.length && Element$2.isElement(blockToSplit, editor.schema)) {
@@ -15507,12 +14601,7 @@ function insertBlock(options) {
15507
14601
  children: _,
15508
14602
  ...blockProperties
15509
14603
  } = blockToSplit;
15510
- editor.apply({
15511
- type: "split_node",
15512
- path: blockPath,
15513
- position: splitAtIndex,
15514
- properties: blockProperties
15515
- });
14604
+ applySplitNode(editor, blockPath, splitAtIndex, blockProperties);
15516
14605
  }
15517
14606
  const currentFirstBlockPath = firstBlockPathRef.unref(), insertPath = currentFirstBlockPath ? [currentFirstBlockPath[0] + 1] : [blockPath[0] + 1];
15518
14607
  if (editor.apply({
@@ -15654,18 +14743,7 @@ function deleteSameBlockRange(editor, start2, end2) {
15654
14743
  });
15655
14744
  }
15656
14745
  const startNodeAfter = Node$1.get(editor, start2.path, editor.schema), endNodeAfter = Node$1.get(editor, newEndPath, editor.schema);
15657
- if (Text$1.isText(startNodeAfter, editor.schema) && Text$1.isText(endNodeAfter, editor.schema)) {
15658
- const {
15659
- text: _,
15660
- ...properties
15661
- } = endNodeAfter;
15662
- editor.apply({
15663
- type: "merge_node",
15664
- path: newEndPath,
15665
- position: startNodeAfter.text.length,
15666
- properties
15667
- });
15668
- }
14746
+ Text$1.isText(startNodeAfter, editor.schema) && Text$1.isText(endNodeAfter, editor.schema) && applyMergeNode(editor, newEndPath, startNodeAfter.text.length);
15669
14747
  }
15670
14748
  function deleteCrossBlockRange(editor, start2, end2) {
15671
14749
  const startBlockPath = [start2.path[0]];
@@ -15702,18 +14780,15 @@ function deleteCrossBlockRange(editor, start2, end2) {
15702
14780
  }
15703
14781
  }
15704
14782
  const startBlock = Node$1.get(editor, startBlockPath, editor.schema), endBlock = Node$1.get(editor, adjustedEndBlockPath, editor.schema);
15705
- if (editor.isTextBlock(startBlock) && editor.isTextBlock(endBlock)) {
15706
- const {
15707
- children: _,
15708
- ...properties
15709
- } = endBlock;
15710
- editor.apply({
15711
- type: "merge_node",
15712
- path: adjustedEndBlockPath,
15713
- position: startBlock.children.length,
15714
- properties
15715
- });
15716
- }
14783
+ editor.isTextBlock(startBlock) && editor.isTextBlock(endBlock) && Editor.withoutNormalizing(editor, () => {
14784
+ if (Array.isArray(endBlock.markDefs) && endBlock.markDefs.length > 0) {
14785
+ const oldDefs = Array.isArray(startBlock.markDefs) && startBlock.markDefs || [], newMarkDefs = [...new Map([...oldDefs, ...endBlock.markDefs].map((def) => [def._key, def])).values()];
14786
+ applySetNode(editor, {
14787
+ markDefs: newMarkDefs
14788
+ }, startBlockPath);
14789
+ }
14790
+ applyMergeNode(editor, adjustedEndBlockPath, startBlock.children.length);
14791
+ });
15717
14792
  }
15718
14793
  function deleteExpandedRange(editor, range2) {
15719
14794
  const [start2, end2] = Range.edges(range2);
@@ -15729,12 +14804,7 @@ function insertTextBlockFragment(editor, block, at) {
15729
14804
  text: _,
15730
14805
  ...properties
15731
14806
  } = textNode;
15732
- editor.apply({
15733
- type: "split_node",
15734
- path: at.path,
15735
- position: at.offset,
15736
- properties
15737
- });
14807
+ applySplitNode(editor, at.path, at.offset, properties);
15738
14808
  }
15739
14809
  }
15740
14810
  const parentPath = Path.parent(at.path);
@@ -15777,11 +14847,7 @@ const insertChildOperationImplementation = ({
15777
14847
  const [focusSpan] = getFocusSpan({
15778
14848
  editor: operation.editor
15779
14849
  });
15780
- focusSpan ? applyInsertNodeAtPoint(operation.editor, span, focus, {
15781
- select: !0
15782
- }) : applyInsertNodeAtPath(operation.editor, span, [focusBlockIndex, focusChildIndex + 1], {
15783
- select: !0
15784
- }), operation.editor.pendingSelection = operation.editor.selection;
14850
+ focusSpan ? applyInsertNodeAtPoint(operation.editor, span, focus) : applyInsertNodeAtPath(operation.editor, span, [focusBlockIndex, focusChildIndex + 1]), operation.editor.pendingSelection = operation.editor.selection;
15785
14851
  return;
15786
14852
  }
15787
14853
  const inlineObject = parseInlineObject({
@@ -15803,11 +14869,7 @@ const insertChildOperationImplementation = ({
15803
14869
  }, [focusSpan] = getFocusSpan({
15804
14870
  editor: operation.editor
15805
14871
  });
15806
- focusSpan ? applyInsertNodeAtPoint(operation.editor, inlineNode, focus, {
15807
- select: !0
15808
- }) : applyInsertNodeAtPath(operation.editor, inlineNode, [focusBlockIndex, focusChildIndex + 1], {
15809
- select: !0
15810
- });
14872
+ focusSpan ? applyInsertNodeAtPoint(operation.editor, inlineNode, focus) : applyInsertNodeAtPath(operation.editor, inlineNode, [focusBlockIndex, focusChildIndex + 1]);
15811
14873
  return;
15812
14874
  }
15813
14875
  throw new Error("Unable to parse child");
@@ -15901,11 +14963,34 @@ const moveBackwardOperationImplementation = ({
15901
14963
  const destinationBlockIndex = operation.editor.blockIndexMap.get(destinationKey);
15902
14964
  if (destinationBlockIndex === void 0)
15903
14965
  throw new Error("Failed to get block index from block key");
15904
- operation.editor.apply({
15905
- type: "move_node",
15906
- path: [originBlockIndex],
15907
- newPath: [destinationBlockIndex]
15908
- });
14966
+ const editor = operation.editor, node2 = Node$1.get(editor, [originBlockIndex], editor.schema), savedSelection = editor.selection ? {
14967
+ anchor: {
14968
+ ...editor.selection.anchor
14969
+ },
14970
+ focus: {
14971
+ ...editor.selection.focus
14972
+ }
14973
+ } : null;
14974
+ if (Editor.withoutNormalizing(editor, () => {
14975
+ editor.apply({
14976
+ type: "remove_node",
14977
+ path: [originBlockIndex],
14978
+ node: node2
14979
+ }), editor.apply({
14980
+ type: "insert_node",
14981
+ path: [destinationBlockIndex],
14982
+ node: node2
14983
+ });
14984
+ }), savedSelection) {
14985
+ const fixPoint = (point2) => point2.path[0] === originBlockIndex ? {
14986
+ ...point2,
14987
+ path: [destinationBlockIndex, ...point2.path.slice(1)]
14988
+ } : point2;
14989
+ editor.selection = {
14990
+ anchor: fixPoint(savedSelection.anchor),
14991
+ focus: fixPoint(savedSelection.focus)
14992
+ };
14993
+ }
15909
14994
  }, moveForwardOperationImplementation = ({
15910
14995
  operation
15911
14996
  }) => {