@portabletext/editor 2.21.3 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/lib/_chunks-dts/index.d.ts +49 -209
  2. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +103 -20
  3. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
  4. package/lib/_chunks-es/{util.get-text-block-text.js → util.slice-blocks.js} +73 -24
  5. package/lib/_chunks-es/util.slice-blocks.js.map +1 -0
  6. package/lib/_chunks-es/util.slice-text-block.js +13 -2
  7. package/lib/_chunks-es/util.slice-text-block.js.map +1 -1
  8. package/lib/behaviors/index.d.ts +1 -1
  9. package/lib/index.d.ts +2 -2
  10. package/lib/index.js +339 -341
  11. package/lib/index.js.map +1 -1
  12. package/lib/plugins/index.d.ts +2 -133
  13. package/lib/plugins/index.js +2 -796
  14. package/lib/plugins/index.js.map +1 -1
  15. package/lib/selectors/index.d.ts +2 -24
  16. package/lib/selectors/index.js +28 -130
  17. package/lib/selectors/index.js.map +1 -1
  18. package/lib/utils/index.d.ts +6 -4
  19. package/lib/utils/index.js +98 -9
  20. package/lib/utils/index.js.map +1 -1
  21. package/package.json +1 -3
  22. package/src/behaviors/behavior.abstract.split.ts +1 -0
  23. package/src/behaviors/behavior.perform-event.ts +7 -7
  24. package/src/converters/converter.portable-text.ts +1 -0
  25. package/src/converters/converter.text-html.ts +1 -0
  26. package/src/converters/converter.text-plain.ts +1 -0
  27. package/src/editor/Editable.tsx +1 -0
  28. package/src/editor/PortableTextEditor.tsx +0 -19
  29. package/src/editor/create-editor.ts +0 -3
  30. package/src/editor/editor-machine.ts +0 -10
  31. package/src/editor/event-to-change.tsx +5 -1
  32. package/src/editor/plugins/create-with-event-listeners.ts +30 -6
  33. package/src/editor/plugins/createWithObjectKeys.ts +2 -1
  34. package/src/editor/plugins/createWithPatches.ts +3 -3
  35. package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -1
  36. package/src/editor/plugins/createWithPortableTextMarkModel.ts +2 -1
  37. package/src/editor/plugins/with-plugins.ts +10 -14
  38. package/src/editor/relay-machine.ts +0 -4
  39. package/src/editor/sync-machine.ts +2 -2
  40. package/src/editor.ts +0 -4
  41. package/src/history/behavior.operation.history.redo.ts +67 -0
  42. package/src/history/behavior.operation.history.undo.ts +71 -0
  43. package/src/history/event.history.undo.test.tsx +672 -0
  44. package/src/history/history.preserving-keys.test.tsx +112 -0
  45. package/src/history/remote-patches.ts +20 -0
  46. package/src/history/slate-plugin.history.ts +146 -0
  47. package/src/history/slate-plugin.redoing.ts +21 -0
  48. package/src/history/slate-plugin.undoing.ts +21 -0
  49. package/src/history/slate-plugin.without-history.ts +23 -0
  50. package/src/history/transform-operation.ts +245 -0
  51. package/src/history/undo-redo-collaboration.test.tsx +541 -0
  52. package/src/history/undo-redo.feature +125 -0
  53. package/src/history/undo-redo.test.tsx +195 -0
  54. package/src/history/undo-step.ts +148 -0
  55. package/src/index.ts +0 -1
  56. package/src/internal-utils/operation-to-patches.test.ts +23 -25
  57. package/src/internal-utils/operation-to-patches.ts +31 -22
  58. package/src/internal-utils/selection-text.test.ts +3 -0
  59. package/src/internal-utils/selection-text.ts +5 -2
  60. package/src/internal-utils/values.ts +23 -11
  61. package/src/operations/behavior.operation.block.set.ts +1 -0
  62. package/src/operations/behavior.operation.block.unset.ts +2 -0
  63. package/src/operations/behavior.operation.insert.block.ts +1 -0
  64. package/src/operations/behavior.operations.ts +2 -4
  65. package/src/plugins/index.ts +0 -3
  66. package/src/selectors/index.ts +0 -3
  67. package/src/test/vitest/step-definitions.tsx +57 -0
  68. package/src/test/vitest/test-editor.tsx +1 -1
  69. package/src/utils/parse-blocks.test.ts +296 -16
  70. package/src/utils/parse-blocks.ts +81 -22
  71. package/src/utils/util.merge-text-blocks.ts +5 -1
  72. package/src/utils/util.slice-blocks.ts +24 -10
  73. package/lib/_chunks-es/selector.get-selection-text.js +0 -92
  74. package/lib/_chunks-es/selector.get-selection-text.js.map +0 -1
  75. package/lib/_chunks-es/selector.get-text-before.js +0 -36
  76. package/lib/_chunks-es/selector.get-text-before.js.map +0 -1
  77. package/lib/_chunks-es/util.get-text-block-text.js.map +0 -1
  78. package/lib/_chunks-es/util.is-empty-text-block.js +0 -40
  79. package/lib/_chunks-es/util.is-empty-text-block.js.map +0 -1
  80. package/lib/_chunks-es/util.merge-text-blocks.js +0 -101
  81. package/lib/_chunks-es/util.merge-text-blocks.js.map +0 -1
  82. package/src/editor/plugins/createWithMaxBlocks.ts +0 -53
  83. package/src/editor/plugins/createWithUndoRedo.ts +0 -628
  84. package/src/editor/with-undo-step.ts +0 -37
  85. package/src/editor/withUndoRedo.ts +0 -34
  86. package/src/editor-event-listener.tsx +0 -28
  87. package/src/plugins/plugin.decorator-shortcut.ts +0 -238
  88. package/src/plugins/plugin.markdown.test.tsx +0 -42
  89. package/src/plugins/plugin.markdown.tsx +0 -131
  90. package/src/plugins/plugin.one-line.tsx +0 -123
  91. package/src/selectors/selector.get-list-state.test.ts +0 -189
  92. package/src/selectors/selector.get-list-state.ts +0 -96
  93. package/src/selectors/selector.get-selected-slice.ts +0 -13
  94. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -657
  95. package/src/selectors/selector.get-trimmed-selection.ts +0 -189
package/lib/index.js CHANGED
@@ -1,20 +1,17 @@
1
- import { c } from "react-compiler-runtime";
2
- import { useEffect, createContext, useContext, useState, useRef, forwardRef, Component, startTransition } from "react";
3
- import { useEditor, EditorContext } from "./_chunks-es/use-editor.js";
4
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { c } from "react-compiler-runtime";
5
3
  import { useSelector, useActorRef } from "@xstate/react";
6
4
  import noop from "lodash/noop.js";
5
+ import { createContext, useContext, useEffect, useState, useRef, forwardRef, Component, startTransition } from "react";
7
6
  import { Element as Element$1, Text, Range, Editor, Node, Point, Path, Transforms, Operation, deleteText, createEditor } from "slate";
8
7
  import { useSelected, useSlateSelector, useSlateStatic, ReactEditor, useSlate, Editable, withReact, Slate } from "slate-react";
9
- import debug$g from "debug";
8
+ import debug$j from "debug";
10
9
  import { DOMEditor, isDOMNode, EDITOR_TO_PENDING_SELECTION, IS_FOCUSED, IS_READ_ONLY } from "slate-dom";
11
- import { getBlockEndPoint, isSelectionCollapsed, isEqualSelectionPoints, isEmptyTextBlock } from "./_chunks-es/util.is-empty-text-block.js";
12
- import { getBlockStartPoint, getBlockKeyFromSelectionPoint, getChildKeyFromSelectionPoint, blockOffsetToSpanSelectionPoint, defaultKeyGenerator, parseBlocks, parseBlock, parseAnnotation, parseSpan, parseInlineObject, isKeyedSegment, isListBlock, isTypedObject, getSelectionStartPoint, getSelectionEndPoint, getTextBlockText } from "./_chunks-es/util.get-text-block-text.js";
10
+ import { getBlockEndPoint, getBlockStartPoint, getBlockKeyFromSelectionPoint, isSelectionCollapsed, isEqualSelectionPoints, getChildKeyFromSelectionPoint, blockOffsetToSpanSelectionPoint, defaultKeyGenerator, parseBlocks, parseBlock, parseAnnotation, parseSpan, parseInlineObject, isKeyedSegment, isListBlock, isTypedObject, getSelectionStartPoint, getSelectionEndPoint } from "./_chunks-es/util.slice-blocks.js";
13
11
  import isEqual from "lodash/isEqual.js";
14
12
  import { isTextBlock, isSpan, compileSchema } from "@portabletext/schema";
15
13
  import { defineSchema } from "@portabletext/schema";
16
- import { getFocusInlineObject, getSelectedBlocks, getSelectionStartBlock, getSelectionEndBlock, isOverlappingSelection, isSelectingEntireBlocks, getActiveDecorators, isActiveAnnotation, getCaretWordSelection, getFocusBlockObject, getPreviousBlock, getNextBlock, getMarkState, getActiveAnnotationsMarks, isAtTheEndOfBlock, isAtTheStartOfBlock, getFirstBlock as getFirstBlock$1, getLastBlock as getLastBlock$1, getFocusListBlock, getSelectionEndPoint as getSelectionEndPoint$1, isActiveDecorator, getActiveAnnotations, getSelectedTextBlocks, isActiveListItem, isActiveStyle } from "./_chunks-es/selector.is-at-the-start-of-block.js";
17
- import { isSelectionCollapsed as isSelectionCollapsed$1, getFocusTextBlock, getFocusSpan as getFocusSpan$1, isSelectionExpanded, getFocusBlock as getFocusBlock$1, getSelectedValue, getSelectionStartPoint as getSelectionStartPoint$1, getFocusChild as getFocusChild$1 } from "./_chunks-es/selector.get-selection-text.js";
14
+ import { getFocusInlineObject, isSelectionCollapsed as isSelectionCollapsed$1, getFocusTextBlock, getFocusSpan as getFocusSpan$1, getSelectedBlocks, isSelectionExpanded, getSelectionStartBlock, getSelectionEndBlock, isOverlappingSelection, getFocusBlock as getFocusBlock$1, isSelectingEntireBlocks, getSelectedValue, getActiveDecorators, isActiveAnnotation, getCaretWordSelection, getFocusBlockObject, getPreviousBlock, getNextBlock, getMarkState, getActiveAnnotationsMarks, isAtTheEndOfBlock, isAtTheStartOfBlock, getFirstBlock as getFirstBlock$1, getLastBlock as getLastBlock$1, getFocusListBlock, getSelectionStartPoint as getSelectionStartPoint$1, getSelectionEndPoint as getSelectionEndPoint$1, isActiveDecorator, getFocusChild as getFocusChild$1, getActiveAnnotations, getSelectedTextBlocks, isActiveListItem, isActiveStyle } from "./_chunks-es/selector.is-at-the-start-of-block.js";
18
15
  import { defineBehavior, forward, raise, effect } from "./behaviors/index.js";
19
16
  import uniq from "lodash/uniq.js";
20
17
  import { setup, fromCallback, assign, and, enqueueActions, emit, assertEvent, raise as raise$1, not, createActor } from "xstate";
@@ -25,26 +22,18 @@ import { Schema } from "@sanity/schema";
25
22
  import flatten from "lodash/flatten.js";
26
23
  import omit from "lodash/omit.js";
27
24
  import { applyAll, unset, insert, set, setIfMissing, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
25
+ import { isEmptyTextBlock, sliceTextBlock, getTextBlockText } from "./_chunks-es/util.slice-text-block.js";
28
26
  import { createDraft, finishDraft } from "immer";
29
27
  import { createKeyboardShortcut, code, underline, italic, bold, undo, redo } from "@portabletext/keyboard-shortcuts";
30
- import { sliceTextBlock } from "./_chunks-es/util.slice-text-block.js";
31
28
  import isPlainObject from "lodash/isPlainObject.js";
29
+ import { EditorContext } from "./_chunks-es/use-editor.js";
30
+ import { useEditor } from "./_chunks-es/use-editor.js";
32
31
  import { Subject } from "rxjs";
33
- function EditorEventListener(props) {
34
- const $ = c(4), editor = useEditor();
35
- let t0, t1;
36
- return $[0] !== editor || $[1] !== props.on ? (t0 = () => {
37
- const subscription = editor.on("*", props.on);
38
- return () => {
39
- subscription.unsubscribe();
40
- };
41
- }, t1 = [editor, props.on], $[0] = editor, $[1] = props.on, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1), null;
42
- }
43
32
  const rootName = "sanity-pte:";
44
- debug$g(rootName);
33
+ debug$j(rootName);
45
34
  function debugWithName(name) {
46
35
  const namespace = `${rootName}${name}`;
47
- return debug$g && debug$g.enabled(namespace) ? debug$g(namespace) : debug$g(rootName);
36
+ return debug$j && debug$j.enabled(namespace) ? debug$j(namespace) : debug$j(rootName);
48
37
  }
49
38
  const VOID_CHILD_KEY = "void-child";
50
39
  function keepObjectEquality(object, keyMap) {
@@ -71,20 +60,20 @@ function toSlateBlock(block, {
71
60
  let hasInlines = !1;
72
61
  const hasMissingStyle = typeof textBlock.style > "u", hasMissingMarkDefs = typeof textBlock.markDefs > "u", hasMissingChildren = typeof textBlock.children > "u", children = (textBlock.children || []).map((child) => {
73
62
  const {
74
- _type: cType,
75
- _key: cKey,
76
- ...cRest
77
- } = child;
78
- return cType !== "span" ? (hasInlines = !0, keepObjectEquality({
79
- _type: cType,
80
- _key: cKey,
63
+ _type: childType,
64
+ _key: childKey,
65
+ ...childProps
66
+ } = child, propKeys = Object.keys(childProps);
67
+ return childType !== schemaTypes.span.name ? propKeys.length === 1 && propKeys.at(0) === "text" ? child : (hasInlines = !0, keepObjectEquality({
68
+ _type: childType,
69
+ _key: childKey,
81
70
  children: [{
82
71
  _key: VOID_CHILD_KEY,
83
- _type: "span",
72
+ _type: schemaTypes.span.name,
84
73
  text: "",
85
74
  marks: []
86
75
  }],
87
- value: cRest,
76
+ value: childProps,
88
77
  __inline: !0
89
78
  }, keyMap)) : child;
90
79
  });
@@ -1547,7 +1536,7 @@ function toKeyName(name) {
1547
1536
  const keyName = name.toLowerCase();
1548
1537
  return aliases[keyName] ?? keyName;
1549
1538
  }
1550
- const debug$f = debugWithName("plugin:withHotKeys");
1539
+ const debug$i = debugWithName("plugin:withHotKeys");
1551
1540
  function createWithHotkeys(editorActor, portableTextEditor, hotkeysFromOptions) {
1552
1541
  const reservedHotkeys = ["enter", "tab", "shift", "delete", "end"], activeHotkeys = hotkeysFromOptions ?? {};
1553
1542
  return function(editor) {
@@ -1562,7 +1551,7 @@ function createWithHotkeys(editorActor, portableTextEditor, hotkeysFromOptions)
1562
1551
  const possibleMark = activeHotkeys[cat];
1563
1552
  if (possibleMark) {
1564
1553
  const mark = possibleMark[hotkey];
1565
- debug$f(`HotKey ${hotkey} to toggle ${mark}`), editorActor.send({
1554
+ debug$i(`HotKey ${hotkey} to toggle ${mark}`), editorActor.send({
1566
1555
  type: "behavior event",
1567
1556
  behaviorEvent: {
1568
1557
  type: "decorator.toggle",
@@ -1891,7 +1880,7 @@ function createDecorate(schema, slateEditor) {
1891
1880
  }) || Range.includes(decoratedRange, path));
1892
1881
  };
1893
1882
  }
1894
- const RelayActorContext = createContext({}), debug$e = debugWithName("validate selection machine"), validateSelectionSetup = setup({
1883
+ const RelayActorContext = createContext({}), debug$h = debugWithName("validate selection machine"), validateSelectionSetup = setup({
1895
1884
  types: {
1896
1885
  context: {},
1897
1886
  input: {},
@@ -1963,12 +1952,12 @@ function validateSelection(slateEditor, editorElement) {
1963
1952
  const existingDOMRange = domSelection.getRangeAt(0);
1964
1953
  try {
1965
1954
  const newDOMRange = ReactEditor.toDOMRange(slateEditor, slateEditor.selection);
1966
- (newDOMRange.startOffset !== existingDOMRange.startOffset || newDOMRange.endOffset !== existingDOMRange.endOffset) && (debug$e("DOM range out of sync, validating selection"), domSelection?.removeAllRanges(), domSelection.addRange(newDOMRange));
1955
+ (newDOMRange.startOffset !== existingDOMRange.startOffset || newDOMRange.endOffset !== existingDOMRange.endOffset) && (debug$h("DOM range out of sync, validating selection"), domSelection?.removeAllRanges(), domSelection.addRange(newDOMRange));
1967
1956
  } catch {
1968
- debug$e("Could not resolve selection, selecting top document"), Transforms.deselect(slateEditor), slateEditor.children.length > 0 && Transforms.select(slateEditor, Editor.start(slateEditor, [])), slateEditor.onChange();
1957
+ debug$h("Could not resolve selection, selecting top document"), Transforms.deselect(slateEditor), slateEditor.children.length > 0 && Transforms.select(slateEditor, Editor.start(slateEditor, [])), slateEditor.onChange();
1969
1958
  }
1970
1959
  }
1971
- const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE_ELEMENT = /* @__PURE__ */ new WeakMap(), KEY_TO_VALUE_ELEMENT = /* @__PURE__ */ new WeakMap(), SLATE_TO_PORTABLE_TEXT_RANGE = /* @__PURE__ */ new WeakMap(), debug$d = debugWithName("component:Editable"), PortableTextEditable = forwardRef(function(props, forwardedRef) {
1960
+ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE_ELEMENT = /* @__PURE__ */ new WeakMap(), KEY_TO_VALUE_ELEMENT = /* @__PURE__ */ new WeakMap(), SLATE_TO_PORTABLE_TEXT_RANGE = /* @__PURE__ */ new WeakMap(), debug$g = debugWithName("component:Editable"), PortableTextEditable = forwardRef(function(props, forwardedRef) {
1972
1961
  const $ = c(176);
1973
1962
  let hotkeys, onBeforeInput, onBlur, onClick, onCopy, onCut, onDrag, onDragEnd, onDragEnter, onDragLeave, onDragOver, onDragStart, onDrop, onFocus, onPaste, propsSelection, rangeDecorations, renderAnnotation, renderBlock, renderChild, renderDecorator, renderListItem, renderPlaceholder, renderStyle, restProps, scrollSelectionIntoView, spellCheck;
1974
1963
  $[0] !== props ? ({
@@ -2057,10 +2046,10 @@ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE
2057
2046
  let t14;
2058
2047
  $[63] !== editorActor || $[64] !== propsSelection || $[65] !== slateEditor ? (t14 = () => {
2059
2048
  if (propsSelection) {
2060
- debug$d(`Selection from props ${JSON.stringify(propsSelection)}`);
2049
+ debug$g(`Selection from props ${JSON.stringify(propsSelection)}`);
2061
2050
  const normalizedSelection = normalizeSelection(propsSelection, fromSlateValue(slateEditor.children, editorActor.getSnapshot().context.schema.block.name));
2062
2051
  if (normalizedSelection !== null) {
2063
- debug$d(`Normalized selection from props ${JSON.stringify(normalizedSelection)}`);
2052
+ debug$g(`Normalized selection from props ${JSON.stringify(normalizedSelection)}`);
2064
2053
  const slateRange = toSlateRange({
2065
2054
  context: {
2066
2055
  schema: editorActor.getSnapshot().context.schema,
@@ -2172,8 +2161,8 @@ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE
2172
2161
  event_1.preventDefault(), relayActor.send({
2173
2162
  type: "loading"
2174
2163
  }), Promise.resolve(onPasteResult).then((result_1) => {
2175
- if (debug$d("Custom paste function from client resolved", result_1), !result_1 || !result_1.insert) {
2176
- debug$d("No result from custom paste handler, pasting normally");
2164
+ if (debug$g("Custom paste function from client resolved", result_1), !result_1 || !result_1.insert) {
2165
+ debug$g("No result from custom paste handler, pasting normally");
2177
2166
  const selection_1 = editorActor.getSnapshot().context.selection, position_1 = selection_1 ? {
2178
2167
  selection: selection_1
2179
2168
  } : void 0;
@@ -2205,6 +2194,7 @@ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE
2205
2194
  },
2206
2195
  blocks: result_1.insert,
2207
2196
  options: {
2197
+ normalize: !1,
2208
2198
  removeUnusedMarkDefs: !0,
2209
2199
  validateFields: !1
2210
2200
  }
@@ -2240,7 +2230,7 @@ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE
2240
2230
  nativeEvent: event_1
2241
2231
  });
2242
2232
  }
2243
- debug$d("No result from custom paste handler, pasting normally");
2233
+ debug$g("No result from custom paste handler, pasting normally");
2244
2234
  }, $[85] = editorActor, $[86] = onPaste, $[87] = portableTextEditor, $[88] = relayActor, $[89] = slateEditor, $[90] = t21) : t21 = $[90];
2245
2235
  const handlePaste = t21;
2246
2236
  let t22;
@@ -2656,6 +2646,7 @@ const converterJson = {
2656
2646
  context: snapshot.context,
2657
2647
  block,
2658
2648
  options: {
2649
+ normalize: !1,
2659
2650
  removeUnusedMarkDefs: !0,
2660
2651
  validateFields: !1
2661
2652
  }
@@ -2719,6 +2710,7 @@ function createConverterTextHtml(legacySchema) {
2719
2710
  context: snapshot.context,
2720
2711
  block,
2721
2712
  options: {
2713
+ normalize: !1,
2722
2714
  removeUnusedMarkDefs: !0,
2723
2715
  validateFields: !1
2724
2716
  }
@@ -2767,6 +2759,7 @@ function createConverterTextPlain(legacySchema) {
2767
2759
  context: snapshot.context,
2768
2760
  block,
2769
2761
  options: {
2762
+ normalize: !1,
2770
2763
  removeUnusedMarkDefs: !0,
2771
2764
  validateFields: !1
2772
2765
  }
@@ -2873,6 +2866,183 @@ function createPlaceholderBlock(context) {
2873
2866
  }]
2874
2867
  };
2875
2868
  }
2869
+ function withRemoteChanges(editor, fn) {
2870
+ const prev = isChangingRemotely(editor) || !1;
2871
+ IS_PROCESSING_REMOTE_CHANGES.set(editor, !0), fn(), IS_PROCESSING_REMOTE_CHANGES.set(editor, prev);
2872
+ }
2873
+ function isChangingRemotely(editor) {
2874
+ return IS_PROCESSING_REMOTE_CHANGES.get(editor);
2875
+ }
2876
+ const REMOTE_PATCHES = /* @__PURE__ */ new WeakMap(), getRemotePatches = (editor) => (REMOTE_PATCHES.get(editor) || REMOTE_PATCHES.set(editor, []), REMOTE_PATCHES.get(editor) ?? []), IS_REDOING = /* @__PURE__ */ new WeakMap();
2877
+ function pluginRedoing(editor, fn) {
2878
+ const prev = isRedoing(editor);
2879
+ IS_REDOING.set(editor, !0), fn(), IS_REDOING.set(editor, prev);
2880
+ }
2881
+ function isRedoing(editor) {
2882
+ return IS_REDOING.get(editor) ?? !1;
2883
+ }
2884
+ function setIsRedoing(editor, isRedoing2) {
2885
+ IS_REDOING.set(editor, isRedoing2);
2886
+ }
2887
+ const IS_UDOING = /* @__PURE__ */ new WeakMap();
2888
+ function pluginUndoing(editor, fn) {
2889
+ const prev = isUndoing(editor);
2890
+ IS_UDOING.set(editor, !0), fn(), IS_UDOING.set(editor, prev);
2891
+ }
2892
+ function isUndoing(editor) {
2893
+ return IS_UDOING.get(editor) ?? !1;
2894
+ }
2895
+ function setIsUndoing(editor, isUndoing2) {
2896
+ IS_UDOING.set(editor, isUndoing2);
2897
+ }
2898
+ const WITH_HISTORY = /* @__PURE__ */ new WeakMap();
2899
+ function isWithHistory(editor) {
2900
+ return WITH_HISTORY.get(editor) ?? !0;
2901
+ }
2902
+ function pluginWithoutHistory(editor, fn) {
2903
+ const withHistory = isWithHistory(editor);
2904
+ WITH_HISTORY.set(editor, !1), fn(), WITH_HISTORY.set(editor, withHistory);
2905
+ }
2906
+ function setWithHistory(editor, withHistory) {
2907
+ WITH_HISTORY.set(editor, withHistory);
2908
+ }
2909
+ const IS_NORMALIZING_NODE = /* @__PURE__ */ new WeakMap();
2910
+ function withNormalizeNode(editor, fn) {
2911
+ const prev = IS_NORMALIZING_NODE.get(editor);
2912
+ IS_NORMALIZING_NODE.set(editor, !0), fn(), IS_NORMALIZING_NODE.set(editor, prev);
2913
+ }
2914
+ function isNormalizingNode(editor) {
2915
+ return IS_NORMALIZING_NODE.get(editor) ?? !1;
2916
+ }
2917
+ const CURRENT_UNDO_STEP_ID = /* @__PURE__ */ new WeakMap();
2918
+ function getCurrentUndoStepId(editor) {
2919
+ return CURRENT_UNDO_STEP_ID.get(editor)?.undoStepId;
2920
+ }
2921
+ function createUndoStepId(editor) {
2922
+ CURRENT_UNDO_STEP_ID.set(editor, {
2923
+ undoStepId: defaultKeyGenerator()
2924
+ });
2925
+ }
2926
+ function clearUndoStepId(editor) {
2927
+ CURRENT_UNDO_STEP_ID.set(editor, void 0);
2928
+ }
2929
+ function createUndoSteps({
2930
+ steps,
2931
+ op,
2932
+ editor,
2933
+ currentUndoStepId,
2934
+ previousUndoStepId
2935
+ }) {
2936
+ const lastStep = steps.at(-1);
2937
+ if (!lastStep)
2938
+ return createNewStep(steps, op, editor);
2939
+ if (editor.operations.length > 0)
2940
+ return currentUndoStepId === previousUndoStepId || isNormalizingNode(editor) ? mergeIntoLastStep(steps, lastStep, op) : createNewStep(steps, op, editor);
2941
+ if (op.type === "set_selection" && currentUndoStepId === void 0 && previousUndoStepId !== void 0 || op.type === "set_selection" && currentUndoStepId !== void 0 && previousUndoStepId !== void 0 && previousUndoStepId !== currentUndoStepId)
2942
+ return mergeIntoLastStep(steps, lastStep, op);
2943
+ if (currentUndoStepId === void 0 && previousUndoStepId === void 0) {
2944
+ if (op.type === "set_selection")
2945
+ return mergeIntoLastStep(steps, lastStep, op);
2946
+ const lastOp = lastStep.operations.at(-1);
2947
+ return lastOp && op.type === "insert_text" && lastOp.type === "insert_text" && op.offset === lastOp.offset + lastOp.text.length && Path.equals(op.path, lastOp.path) && op.text !== " " || lastOp && op.type === "remove_text" && lastOp.type === "remove_text" && op.offset + op.text.length === lastOp.offset && Path.equals(op.path, lastOp.path) ? mergeIntoLastStep(steps, lastStep, op) : createNewStep(steps, op, editor);
2948
+ }
2949
+ return createNewStep(steps, op, editor);
2950
+ }
2951
+ function createNewStep(steps, op, editor) {
2952
+ const operations = editor.selection === null ? [op] : [{
2953
+ type: "set_selection",
2954
+ properties: {
2955
+ ...editor.selection
2956
+ },
2957
+ newProperties: {
2958
+ ...editor.selection
2959
+ }
2960
+ }, op];
2961
+ return [...steps, {
2962
+ operations,
2963
+ timestamp: /* @__PURE__ */ new Date()
2964
+ }];
2965
+ }
2966
+ function mergeIntoLastStep(steps, lastStep, op) {
2967
+ return [...steps.slice(0, -1), {
2968
+ timestamp: lastStep.timestamp,
2969
+ operations: [...lastStep.operations, op]
2970
+ }];
2971
+ }
2972
+ const debug$f = debugWithName("plugin:history"), UNDO_STEP_LIMIT = 1e3;
2973
+ function pluginHistory({
2974
+ editorActor,
2975
+ subscriptions
2976
+ }) {
2977
+ return (editor) => {
2978
+ const remotePatches = getRemotePatches(editor);
2979
+ let previousSnapshot = fromSlateValue(editor.children, editorActor.getSnapshot().context.schema.block.name), previousUndoStepId = getCurrentUndoStepId(editor);
2980
+ subscriptions.push(() => {
2981
+ const subscription = editorActor.on("patches", ({
2982
+ patches,
2983
+ snapshot
2984
+ }) => {
2985
+ let reset = !1;
2986
+ for (const patch of patches)
2987
+ if (!reset && patch.origin !== "local") {
2988
+ if (patch.type === "unset" && patch.path.length === 0) {
2989
+ debug$f("Someone else cleared the content, resetting undo/redo history"), editor.history = {
2990
+ undos: [],
2991
+ redos: []
2992
+ }, remotePatches.splice(0, remotePatches.length), setWithHistory(editor, !0), reset = !0;
2993
+ return;
2994
+ }
2995
+ remotePatches.push({
2996
+ patch,
2997
+ time: /* @__PURE__ */ new Date(),
2998
+ snapshot,
2999
+ previousSnapshot
3000
+ });
3001
+ }
3002
+ previousSnapshot = snapshot;
3003
+ });
3004
+ return () => {
3005
+ subscription.unsubscribe();
3006
+ };
3007
+ }), editor.history = {
3008
+ undos: [],
3009
+ redos: []
3010
+ };
3011
+ const {
3012
+ apply: apply2
3013
+ } = editor;
3014
+ return editor.apply = (op) => {
3015
+ if (editorActor.getSnapshot().matches({
3016
+ "edit mode": "read only"
3017
+ })) {
3018
+ apply2(op);
3019
+ return;
3020
+ }
3021
+ if (isChangingRemotely(editor)) {
3022
+ apply2(op);
3023
+ return;
3024
+ }
3025
+ if (isUndoing(editor) || isRedoing(editor)) {
3026
+ apply2(op);
3027
+ return;
3028
+ }
3029
+ const withHistory = isWithHistory(editor), currentUndoStepId = getCurrentUndoStepId(editor);
3030
+ if (!withHistory) {
3031
+ previousUndoStepId = currentUndoStepId, apply2(op);
3032
+ return;
3033
+ }
3034
+ for (op.type !== "set_selection" && (editor.history.redos = []), editor.history.undos = createUndoSteps({
3035
+ steps: editor.history.undos,
3036
+ op,
3037
+ editor,
3038
+ currentUndoStepId,
3039
+ previousUndoStepId
3040
+ }); editor.history.undos.length > UNDO_STEP_LIMIT; )
3041
+ editor.history.undos.shift();
3042
+ previousUndoStepId = currentUndoStepId, apply2(op);
3043
+ }, editor;
3044
+ };
3045
+ }
2876
3046
  function getPreviousSpan({
2877
3047
  editor,
2878
3048
  blockPath,
@@ -2901,43 +3071,7 @@ function getNextSpan({
2901
3071
  }
2902
3072
  return nextSpan;
2903
3073
  }
2904
- const IS_NORMALIZING_NODE = /* @__PURE__ */ new WeakMap();
2905
- function withNormalizeNode(editor, fn) {
2906
- const prev = IS_NORMALIZING_NODE.get(editor);
2907
- IS_NORMALIZING_NODE.set(editor, !0), fn(), IS_NORMALIZING_NODE.set(editor, prev);
2908
- }
2909
- function isNormalizingNode(editor) {
2910
- return IS_NORMALIZING_NODE.get(editor) ?? !1;
2911
- }
2912
- function withRemoteChanges(editor, fn) {
2913
- const prev = isChangingRemotely(editor) || !1;
2914
- IS_PROCESSING_REMOTE_CHANGES.set(editor, !0), fn(), IS_PROCESSING_REMOTE_CHANGES.set(editor, prev);
2915
- }
2916
- function isChangingRemotely(editor) {
2917
- return IS_PROCESSING_REMOTE_CHANGES.get(editor);
2918
- }
2919
- const IS_UDOING = /* @__PURE__ */ new WeakMap(), IS_REDOING = /* @__PURE__ */ new WeakMap();
2920
- function withUndoing(editor, fn) {
2921
- const prev = isUndoing(editor);
2922
- IS_UDOING.set(editor, !0), fn(), IS_UDOING.set(editor, prev);
2923
- }
2924
- function isUndoing(editor) {
2925
- return IS_UDOING.get(editor) ?? !1;
2926
- }
2927
- function setIsUndoing(editor, isUndoing2) {
2928
- IS_UDOING.set(editor, isUndoing2);
2929
- }
2930
- function withRedoing(editor, fn) {
2931
- const prev = isRedoing(editor);
2932
- IS_REDOING.set(editor, !0), fn(), IS_REDOING.set(editor, prev);
2933
- }
2934
- function isRedoing(editor) {
2935
- return IS_REDOING.get(editor) ?? !1;
2936
- }
2937
- function setIsRedoing(editor, isRedoing2) {
2938
- IS_REDOING.set(editor, isRedoing2);
2939
- }
2940
- const debug$c = debugWithName("plugin:withPortableTextMarkModel");
3074
+ const debug$e = debugWithName("plugin:withPortableTextMarkModel");
2941
3075
  function createWithPortableTextMarkModel(editorActor) {
2942
3076
  return function(editor) {
2943
3077
  const {
@@ -2951,7 +3085,7 @@ function createWithPortableTextMarkModel(editorActor) {
2951
3085
  for (const [child, childPath] of children) {
2952
3086
  const nextNode = node.children[childPath[1] + 1];
2953
3087
  if (editor.isTextSpan(child) && editor.isTextSpan(nextNode) && child.marks?.every((mark) => nextNode.marks?.includes(mark)) && nextNode.marks?.every((mark) => child.marks?.includes(mark))) {
2954
- debug$c("Merging spans", JSON.stringify(child, null, 2), JSON.stringify(nextNode, null, 2)), withNormalizeNode(editor, () => {
3088
+ debug$e("Merging spans", JSON.stringify(child, null, 2), JSON.stringify(nextNode, null, 2)), withNormalizeNode(editor, () => {
2955
3089
  Transforms.mergeNodes(editor, {
2956
3090
  at: [childPath[0], childPath[1] + 1],
2957
3091
  voids: !0
@@ -2962,7 +3096,7 @@ function createWithPortableTextMarkModel(editorActor) {
2962
3096
  }
2963
3097
  }
2964
3098
  if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
2965
- debug$c("Adding .markDefs to block node"), withNormalizeNode(editor, () => {
3099
+ debug$e("Adding .markDefs to block node"), withNormalizeNode(editor, () => {
2966
3100
  Transforms.setNodes(editor, {
2967
3101
  markDefs: []
2968
3102
  }, {
@@ -2972,7 +3106,7 @@ function createWithPortableTextMarkModel(editorActor) {
2972
3106
  return;
2973
3107
  }
2974
3108
  if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
2975
- debug$c("Adding .marks to span node"), withNormalizeNode(editor, () => {
3109
+ debug$e("Adding .marks to span node"), withNormalizeNode(editor, () => {
2976
3110
  Transforms.setNodes(editor, {
2977
3111
  marks: []
2978
3112
  }, {
@@ -2984,7 +3118,7 @@ function createWithPortableTextMarkModel(editorActor) {
2984
3118
  if (editor.isTextSpan(node)) {
2985
3119
  const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath), decorators2 = editorActor.getSnapshot().context.schema.decorators.map((decorator) => decorator.name), annotations = node.marks?.filter((mark) => !decorators2.includes(mark));
2986
3120
  if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
2987
- debug$c("Removing annotations from empty span node"), withNormalizeNode(editor, () => {
3121
+ debug$e("Removing annotations from empty span node"), withNormalizeNode(editor, () => {
2988
3122
  Transforms.setNodes(editor, {
2989
3123
  marks: node.marks?.filter((mark) => decorators2.includes(mark))
2990
3124
  }, {
@@ -3000,7 +3134,7 @@ function createWithPortableTextMarkModel(editorActor) {
3000
3134
  if (editor.isTextSpan(child)) {
3001
3135
  const marks = child.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !node.markDefs?.find((def) => def._key === mark));
3002
3136
  if (orphanedAnnotations.length > 0) {
3003
- debug$c("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3137
+ debug$e("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3004
3138
  Transforms.setNodes(editor, {
3005
3139
  marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))
3006
3140
  }, {
@@ -3016,7 +3150,7 @@ function createWithPortableTextMarkModel(editorActor) {
3016
3150
  if (editor.isTextBlock(block)) {
3017
3151
  const decorators2 = editorActor.getSnapshot().context.schema.decorators.map((decorator) => decorator.name), marks = node.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !block.markDefs?.find((def) => def._key === mark));
3018
3152
  if (orphanedAnnotations.length > 0) {
3019
- debug$c("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3153
+ debug$e("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3020
3154
  Transforms.setNodes(editor, {
3021
3155
  marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))
3022
3156
  }, {
@@ -3032,7 +3166,7 @@ function createWithPortableTextMarkModel(editorActor) {
3032
3166
  for (const markDef of markDefs)
3033
3167
  markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
3034
3168
  if (markDefs.length !== newMarkDefs.length) {
3035
- debug$c("Removing duplicate markDefs"), withNormalizeNode(editor, () => {
3169
+ debug$e("Removing duplicate markDefs"), withNormalizeNode(editor, () => {
3036
3170
  Transforms.setNodes(editor, {
3037
3171
  markDefs: newMarkDefs
3038
3172
  }, {
@@ -3045,7 +3179,7 @@ function createWithPortableTextMarkModel(editorActor) {
3045
3179
  if (editor.isTextBlock(node) && !editor.operations.some((op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1)) {
3046
3180
  const newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
3047
3181
  if (node.markDefs && !isEqual(newMarkDefs, node.markDefs)) {
3048
- debug$c("Removing markDef not in use"), withNormalizeNode(editor, () => {
3182
+ debug$e("Removing markDef not in use"), withNormalizeNode(editor, () => {
3049
3183
  Transforms.setNodes(editor, {
3050
3184
  markDefs: newMarkDefs
3051
3185
  }, {
@@ -3137,7 +3271,7 @@ function createWithPortableTextMarkModel(editorActor) {
3137
3271
  const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
3138
3272
  if (editor.isTextBlock(targetBlock)) {
3139
3273
  const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [], newMarkDefs = uniq([...oldDefs, ...op.properties.markDefs]);
3140
- debug$c("Copying markDefs over to merged block", op), Transforms.setNodes(editor, {
3274
+ debug$e("Copying markDefs over to merged block", op), Transforms.setNodes(editor, {
3141
3275
  markDefs: newMarkDefs
3142
3276
  }, {
3143
3277
  at: targetPath,
@@ -3833,174 +3967,7 @@ function parse(textline) {
3833
3967
  function toInt(num) {
3834
3968
  return parseInt(num, 10);
3835
3969
  }
3836
- const CURRENT_UNDO_STEP = /* @__PURE__ */ new WeakMap();
3837
- function getCurrentUndoStepId(editor) {
3838
- return CURRENT_UNDO_STEP.get(editor)?.undoStepId;
3839
- }
3840
- function createUndoStep(editor) {
3841
- CURRENT_UNDO_STEP.set(editor, {
3842
- undoStepId: defaultKeyGenerator()
3843
- });
3844
- }
3845
- function clearUndoStep(editor) {
3846
- CURRENT_UNDO_STEP.set(editor, void 0);
3847
- }
3848
- const debug$b = debugWithName("plugin:withUndoRedo"), SAVING = /* @__PURE__ */ new WeakMap(), REMOTE_PATCHES = /* @__PURE__ */ new WeakMap(), UNDO_STEP_LIMIT = 1e3, isSaving = (editor) => {
3849
- const state = SAVING.get(editor);
3850
- return state === void 0 ? !0 : state;
3851
- }, getRemotePatches = (editor) => (REMOTE_PATCHES.get(editor) || REMOTE_PATCHES.set(editor, []), REMOTE_PATCHES.get(editor) || []);
3852
- function createWithUndoRedo(options) {
3853
- const {
3854
- editorActor
3855
- } = options;
3856
- return (editor) => {
3857
- let previousSnapshot = fromSlateValue(editor.children, editorActor.getSnapshot().context.schema.block.name);
3858
- const remotePatches = getRemotePatches(editor);
3859
- let previousUndoStepId = getCurrentUndoStepId(editor);
3860
- options.subscriptions.push(() => {
3861
- debug$b("Subscribing to patches");
3862
- const sub = editorActor.on("patches", ({
3863
- patches,
3864
- snapshot
3865
- }) => {
3866
- let reset = !1;
3867
- patches.forEach((patch) => {
3868
- if (!reset && patch.origin !== "local" && remotePatches) {
3869
- if (patch.type === "unset" && patch.path.length === 0) {
3870
- debug$b("Someone else cleared the content, resetting undo/redo history"), editor.history = {
3871
- undos: [],
3872
- redos: []
3873
- }, remotePatches.splice(0, remotePatches.length), SAVING.set(editor, !0), reset = !0;
3874
- return;
3875
- }
3876
- remotePatches.push({
3877
- patch,
3878
- time: /* @__PURE__ */ new Date(),
3879
- snapshot,
3880
- previousSnapshot
3881
- });
3882
- }
3883
- }), previousSnapshot = snapshot;
3884
- });
3885
- return () => {
3886
- debug$b("Unsubscribing to patches"), sub.unsubscribe();
3887
- };
3888
- }), editor.history = {
3889
- undos: [],
3890
- redos: []
3891
- };
3892
- const {
3893
- apply: apply2
3894
- } = editor;
3895
- return editor.apply = (op) => {
3896
- if (editorActor.getSnapshot().matches({
3897
- "edit mode": "read only"
3898
- })) {
3899
- apply2(op);
3900
- return;
3901
- }
3902
- if (isChangingRemotely(editor)) {
3903
- apply2(op);
3904
- return;
3905
- }
3906
- if (isUndoing(editor) || isRedoing(editor)) {
3907
- apply2(op);
3908
- return;
3909
- }
3910
- const savingUndoSteps = isSaving(editor), currentUndoStepId = getCurrentUndoStepId(editor);
3911
- if (!savingUndoSteps) {
3912
- previousUndoStepId = currentUndoStepId, apply2(op);
3913
- return;
3914
- }
3915
- op.type !== "set_selection" && (editor.history.redos = []);
3916
- const step = editor.history.undos.at(editor.history.undos.length - 1);
3917
- if (!step) {
3918
- editor.history.undos.push({
3919
- operations: [...editor.selection === null ? [] : [createSelectOperation(editor)], op],
3920
- timestamp: /* @__PURE__ */ new Date()
3921
- }), apply2(op), previousUndoStepId = currentUndoStepId;
3922
- return;
3923
- }
3924
- const selectingWithoutUndoStepId = op.type === "set_selection" && currentUndoStepId === void 0 && previousUndoStepId !== void 0, selectingWithDifferentUndoStepId = op.type === "set_selection" && currentUndoStepId !== void 0 && previousUndoStepId !== void 0 && previousUndoStepId !== currentUndoStepId, lastOp = step.operations.at(-1);
3925
- for ((editor.operations.length > 0 ? currentUndoStepId === previousUndoStepId || isNormalizingNode(editor) : selectingWithoutUndoStepId || selectingWithDifferentUndoStepId || currentUndoStepId === void 0 && previousUndoStepId === void 0 ? shouldMerge(op, lastOp) || lastOp?.type === "set_selection" && op.type === "set_selection" : currentUndoStepId === previousUndoStepId || isNormalizingNode(editor)) ? step.operations.push(op) : editor.history.undos.push({
3926
- operations: [...editor.selection === null ? [] : [createSelectOperation(editor)], op],
3927
- timestamp: /* @__PURE__ */ new Date()
3928
- }); editor.history.undos.length > UNDO_STEP_LIMIT; )
3929
- editor.history.undos.shift();
3930
- previousUndoStepId = currentUndoStepId, apply2(op);
3931
- }, editor;
3932
- };
3933
- }
3934
- const historyUndoOperationImplementation = ({
3935
- operation
3936
- }) => {
3937
- const editor = operation.editor, {
3938
- undos
3939
- } = editor.history, remotePatches = getRemotePatches(editor);
3940
- if (undos.length > 0) {
3941
- const step = undos[undos.length - 1];
3942
- if (debug$b("Undoing", step), step.operations.length > 0) {
3943
- const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
3944
- let transformedOperations = step.operations;
3945
- otherPatches.forEach((item) => {
3946
- transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
3947
- });
3948
- const reversedOperations = transformedOperations.map(Operation.inverse).reverse();
3949
- try {
3950
- Editor.withoutNormalizing(editor, () => {
3951
- withUndoing(editor, () => {
3952
- withoutSaving(editor, () => {
3953
- reversedOperations.forEach((op) => {
3954
- editor.apply(op);
3955
- });
3956
- });
3957
- });
3958
- });
3959
- } catch (err) {
3960
- debug$b("Could not perform undo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
3961
- undos: [],
3962
- redos: []
3963
- }, SAVING.set(editor, !0), setIsUndoing(editor, !1), editor.onChange();
3964
- return;
3965
- }
3966
- editor.history.redos.push(step), editor.history.undos.pop();
3967
- }
3968
- }
3969
- }, historyRedoOperationImplementation = ({
3970
- operation
3971
- }) => {
3972
- const editor = operation.editor, {
3973
- redos
3974
- } = editor.history, remotePatches = getRemotePatches(editor);
3975
- if (redos.length > 0) {
3976
- const step = redos[redos.length - 1];
3977
- if (debug$b("Redoing", step), step.operations.length > 0) {
3978
- const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
3979
- let transformedOperations = step.operations;
3980
- otherPatches.forEach((item) => {
3981
- transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
3982
- });
3983
- try {
3984
- Editor.withoutNormalizing(editor, () => {
3985
- withRedoing(editor, () => {
3986
- withoutSaving(editor, () => {
3987
- transformedOperations.forEach((op) => {
3988
- editor.apply(op);
3989
- });
3990
- });
3991
- });
3992
- });
3993
- } catch (err) {
3994
- debug$b("Could not perform redo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
3995
- undos: [],
3996
- redos: []
3997
- }, SAVING.set(editor, !0), setIsRedoing(editor, !1), editor.onChange();
3998
- return;
3999
- }
4000
- editor.history.undos.push(step), editor.history.redos.pop();
4001
- }
4002
- }
4003
- };
3970
+ const debug$d = debugWithName("transformOperation");
4004
3971
  function transformOperation(editor, patch, operation, snapshot, previousSnapshot) {
4005
3972
  const transformedOperation = {
4006
3973
  ...operation
@@ -4009,16 +3976,16 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
4009
3976
  const insertBlockIndex = (snapshot || []).findIndex((blk) => isEqual({
4010
3977
  _key: blk._key
4011
3978
  }, patch.path[0]));
4012
- return debug$b(`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`), [adjustBlockPath(transformedOperation, patch.items.length, insertBlockIndex)];
3979
+ return debug$d(`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`), [adjustBlockPath(transformedOperation, patch.items.length, insertBlockIndex)];
4013
3980
  }
4014
3981
  if (patch.type === "unset" && patch.path.length === 1) {
4015
3982
  const unsetBlockIndex = (previousSnapshot || []).findIndex((blk) => isEqual({
4016
3983
  _key: blk._key
4017
3984
  }, patch.path[0]));
4018
- return "path" in transformedOperation && Array.isArray(transformedOperation.path) && transformedOperation.path[0] === unsetBlockIndex ? (debug$b("Skipping transformation that targeted removed block"), []) : [adjustBlockPath(transformedOperation, -1, unsetBlockIndex)];
3985
+ return "path" in transformedOperation && Array.isArray(transformedOperation.path) && transformedOperation.path[0] === unsetBlockIndex ? (debug$d("Skipping transformation that targeted removed block"), []) : [adjustBlockPath(transformedOperation, -1, unsetBlockIndex)];
4019
3986
  }
4020
3987
  if (patch.type === "unset" && patch.path.length === 0)
4021
- return debug$b(`Adjusting selection for unset everything patch and ${operation.type} operation`), [];
3988
+ return debug$d(`Adjusting selection for unset everything patch and ${operation.type} operation`), [];
4022
3989
  if (patch.type === "diffMatchPatch") {
4023
3990
  const operationTargetBlock = findOperationTargetBlock(editor, transformedOperation);
4024
3991
  return !operationTargetBlock || !isEqual({
@@ -4085,27 +4052,80 @@ function adjustBlockPath(operation, level, blockIndex) {
4085
4052
  }
4086
4053
  return transformedOperation;
4087
4054
  }
4088
- const shouldMerge = (op, prev) => !!(op.type === "set_selection" || prev && op.type === "insert_text" && prev.type === "insert_text" && op.offset === prev.offset + prev.text.length && Path.equals(op.path, prev.path) && op.text !== " " || prev && op.type === "remove_text" && prev.type === "remove_text" && op.offset + op.text.length === prev.offset && Path.equals(op.path, prev.path));
4089
- function withoutSaving(editor, fn) {
4090
- const prev = isSaving(editor);
4091
- SAVING.set(editor, !1), fn(), SAVING.set(editor, prev);
4092
- }
4093
- function createSelectOperation(editor) {
4094
- return {
4095
- type: "set_selection",
4096
- properties: {
4097
- ...editor.selection
4098
- },
4099
- newProperties: {
4100
- ...editor.selection
4101
- }
4102
- };
4103
- }
4104
4055
  function findOperationTargetBlock(editor, operation) {
4105
4056
  let block;
4106
4057
  return operation.type === "set_selection" && editor.selection ? block = editor.children[editor.selection.focus.path[0]] : "path" in operation && (block = editor.children[operation.path[0]]), block;
4107
4058
  }
4108
- const addAnnotationOperationImplementation = ({
4059
+ const debug$c = debugWithName("behavior.operation.history.redo"), historyRedoOperationImplementation = ({
4060
+ operation
4061
+ }) => {
4062
+ const editor = operation.editor, {
4063
+ redos
4064
+ } = editor.history, remotePatches = getRemotePatches(editor);
4065
+ if (redos.length > 0) {
4066
+ const step = redos[redos.length - 1];
4067
+ if (debug$c("Redoing", step), step.operations.length > 0) {
4068
+ const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
4069
+ let transformedOperations = step.operations;
4070
+ otherPatches.forEach((item) => {
4071
+ transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
4072
+ });
4073
+ try {
4074
+ Editor.withoutNormalizing(editor, () => {
4075
+ pluginRedoing(editor, () => {
4076
+ pluginWithoutHistory(editor, () => {
4077
+ transformedOperations.forEach((op) => {
4078
+ editor.apply(op);
4079
+ });
4080
+ });
4081
+ });
4082
+ });
4083
+ } catch (err) {
4084
+ debug$c("Could not perform redo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
4085
+ undos: [],
4086
+ redos: []
4087
+ }, setWithHistory(editor, !0), setIsRedoing(editor, !1), editor.onChange();
4088
+ return;
4089
+ }
4090
+ editor.history.undos.push(step), editor.history.redos.pop();
4091
+ }
4092
+ }
4093
+ }, debug$b = debugWithName("behavior.operation.history.undo"), historyUndoOperationImplementation = ({
4094
+ operation
4095
+ }) => {
4096
+ const editor = operation.editor, {
4097
+ undos
4098
+ } = editor.history, remotePatches = getRemotePatches(editor);
4099
+ if (undos.length > 0) {
4100
+ const step = undos[undos.length - 1];
4101
+ if (debug$b("Undoing", step), step.operations.length > 0) {
4102
+ const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
4103
+ let transformedOperations = step.operations;
4104
+ otherPatches.forEach((item) => {
4105
+ transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
4106
+ });
4107
+ const reversedOperations = transformedOperations.map(Operation.inverse).reverse();
4108
+ try {
4109
+ Editor.withoutNormalizing(editor, () => {
4110
+ pluginUndoing(editor, () => {
4111
+ pluginWithoutHistory(editor, () => {
4112
+ reversedOperations.forEach((op) => {
4113
+ editor.apply(op);
4114
+ });
4115
+ });
4116
+ });
4117
+ });
4118
+ } catch (err) {
4119
+ debug$b("Could not perform undo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
4120
+ undos: [],
4121
+ redos: []
4122
+ }, setWithHistory(editor, !0), setIsUndoing(editor, !1), editor.onChange();
4123
+ return;
4124
+ }
4125
+ editor.history.redos.push(step), editor.history.undos.pop();
4126
+ }
4127
+ }
4128
+ }, addAnnotationOperationImplementation = ({
4109
4129
  context,
4110
4130
  operation
4111
4131
  }) => {
@@ -4244,6 +4264,7 @@ const addAnnotationOperationImplementation = ({
4244
4264
  context,
4245
4265
  block: updatedBlock,
4246
4266
  options: {
4267
+ normalize: !1,
4247
4268
  removeUnusedMarkDefs: !1,
4248
4269
  validateFields: !0
4249
4270
  }
@@ -4292,6 +4313,7 @@ const addAnnotationOperationImplementation = ({
4292
4313
  context,
4293
4314
  block: omit(parsedBlock, propsToRemove),
4294
4315
  options: {
4316
+ normalize: !1,
4295
4317
  removeUnusedMarkDefs: !0,
4296
4318
  validateFields: !0
4297
4319
  }
@@ -4310,6 +4332,7 @@ const addAnnotationOperationImplementation = ({
4310
4332
  context,
4311
4333
  block: omit(parsedBlock, operation.props.filter((prop) => prop !== "_type")),
4312
4334
  options: {
4335
+ normalize: !1,
4313
4336
  removeUnusedMarkDefs: !0,
4314
4337
  validateFields: !0
4315
4338
  }
@@ -4648,6 +4671,7 @@ const insertBlockOperationImplementation = ({
4648
4671
  block: operation.block,
4649
4672
  context,
4650
4673
  options: {
4674
+ normalize: !0,
4651
4675
  removeUnusedMarkDefs: !0,
4652
4676
  validateFields: !0
4653
4677
  }
@@ -5182,10 +5206,9 @@ function isPerformingBehaviorOperation(editor) {
5182
5206
  }
5183
5207
  function createWithEventListeners(editorActor) {
5184
5208
  return function(editor) {
5185
- if (editorActor.getSnapshot().context.maxBlocks !== void 0)
5186
- return editor;
5187
5209
  const {
5188
5210
  delete: editorDelete,
5211
+ insertNodes,
5189
5212
  select
5190
5213
  } = editor;
5191
5214
  return editor.delete = (options) => {
@@ -5269,6 +5292,16 @@ function createWithEventListeners(editorActor) {
5269
5292
  },
5270
5293
  editor
5271
5294
  });
5295
+ }, editor.insertNodes = (nodes, options) => {
5296
+ if (isNormalizingNode(editor)) {
5297
+ const normalizedNodes = (Node.isNode(nodes) ? [nodes] : nodes).map((node) => Text.isText(node) && typeof node._type != "string" ? {
5298
+ ...node,
5299
+ _type: editorActor.getSnapshot().context.schema.span.name
5300
+ } : node);
5301
+ insertNodes(normalizedNodes, options);
5302
+ return;
5303
+ }
5304
+ insertNodes(nodes, options);
5272
5305
  }, editor.insertSoftBreak = () => {
5273
5306
  if (isPerformingBehaviorOperation(editor)) {
5274
5307
  performOperation({
@@ -5380,31 +5413,6 @@ function createWithEventListeners(editorActor) {
5380
5413
  }, editor;
5381
5414
  };
5382
5415
  }
5383
- function createWithMaxBlocks(editorActor) {
5384
- return function(editor) {
5385
- const {
5386
- apply: apply2
5387
- } = editor;
5388
- return editor.apply = (operation) => {
5389
- if (editorActor.getSnapshot().matches({
5390
- "edit mode": "read only"
5391
- })) {
5392
- apply2(operation);
5393
- return;
5394
- }
5395
- if (isChangingRemotely(editor)) {
5396
- apply2(operation);
5397
- return;
5398
- }
5399
- if (isUndoing(editor) || isRedoing(editor)) {
5400
- apply2(operation);
5401
- return;
5402
- }
5403
- const rows = editorActor.getSnapshot().context.maxBlocks ?? -1;
5404
- rows > 0 && editor.children.length >= rows && (operation.type === "insert_node" || operation.type === "split_node") && operation.path.length === 1 || apply2(operation);
5405
- }, editor;
5406
- };
5407
- }
5408
5416
  function createWithObjectKeys(editorActor) {
5409
5417
  return function(editor) {
5410
5418
  const {
@@ -6070,20 +6078,21 @@ function insertNodePatch(schema, children, operation, beforeValue) {
6070
6078
  } else if (isTextBlock({
6071
6079
  schema
6072
6080
  }, block) && operation.path.length === 2 && children[operation.path[0]]) {
6073
- const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", node = {
6074
- ...operation.node
6075
- };
6076
- !node._type && Text.isText(node) && (node._type = "span", node.marks = []);
6077
- const child = fromSlateValue([{
6078
- _key: "bogus",
6079
- _type: schema.block.name,
6080
- children: [node]
6081
- }], schema.block.name)[0].children[0];
6082
- return [insert([child], position, [{
6081
+ const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", path = block.children.length <= 1 || !block.children[operation.path[1] - 1] ? [{
6082
+ _key: block._key
6083
+ }, "children", 0] : [{
6083
6084
  _key: block._key
6084
- }, "children", block.children.length <= 1 || !block.children[operation.path[1] - 1] ? 0 : {
6085
+ }, "children", {
6085
6086
  _key: block.children[operation.path[1] - 1]._key
6086
- }])];
6087
+ }];
6088
+ if (Text.isText(operation.node))
6089
+ return [insert([operation.node], position, path)];
6090
+ const _type = operation.node._type, _key = operation.node._key, value = "value" in operation.node && typeof operation.node.value == "object" ? operation.node.value : {};
6091
+ return [insert([{
6092
+ _type,
6093
+ _key,
6094
+ ...value
6095
+ }], position, path)];
6087
6096
  }
6088
6097
  return [];
6089
6098
  }
@@ -6249,7 +6258,7 @@ function createWithPatches({
6249
6258
  withRemoteChanges(editor, () => {
6250
6259
  Editor.withoutNormalizing(editor, () => {
6251
6260
  withoutPatching(editor, () => {
6252
- withoutSaving(editor, () => {
6261
+ pluginWithoutHistory(editor, () => {
6253
6262
  for (const patch of patches) {
6254
6263
  debug$a.enabled && debug$a(`Handling remote patch ${JSON.stringify(patch)}`);
6255
6264
  try {
@@ -6765,16 +6774,16 @@ const withPlugins = (editor, options) => {
6765
6774
  editorActor,
6766
6775
  relayActor,
6767
6776
  subscriptions: options.subscriptions
6768
- }), withMaxBlocks = createWithMaxBlocks(editorActor), withUndoRedo = createWithUndoRedo({
6777
+ }), withUndoRedo = pluginHistory({
6769
6778
  editorActor,
6770
6779
  subscriptions: options.subscriptions
6771
6780
  }), withPortableTextMarkModel = createWithPortableTextMarkModel(editorActor), withPlaceholderBlock = createWithPlaceholderBlock(editorActor), withUtils = createWithUtils({
6772
6781
  editorActor
6773
6782
  });
6774
- return createWithEventListeners(editorActor)(withSchemaTypes(withObjectKeys(withPortableTextMarkModel(withPlaceholderBlock(withUtils(withMaxBlocks(withUndoRedo(withPatches(pluginUpdateValue(editorActor.getSnapshot().context, pluginUpdateSelection({
6783
+ return createWithEventListeners(editorActor)(withSchemaTypes(withObjectKeys(withPortableTextMarkModel(withPlaceholderBlock(withUtils(withUndoRedo(withPatches(pluginUpdateValue(editorActor.getSnapshot().context, pluginUpdateSelection({
6775
6784
  editorActor,
6776
6785
  editor: e
6777
- })))))))))));
6786
+ }))))))))));
6778
6787
  }, debug$7 = debugWithName("setup");
6779
6788
  function createSlateEditor(config) {
6780
6789
  debug$7("Creating new Slate editor instance");
@@ -9668,6 +9677,7 @@ const abstractAnnotationBehaviors = [defineBehavior({
9668
9677
  }),
9669
9678
  context: snapshot.context,
9670
9679
  options: {
9680
+ normalize: !1,
9671
9681
  removeUnusedMarkDefs: !0,
9672
9682
  validateFields: !1
9673
9683
  }
@@ -9868,7 +9878,7 @@ function performEvent({
9868
9878
  nativeEvent,
9869
9879
  sendBack
9870
9880
  }) {
9871
- mode === "send" && !isNativeBehaviorEvent(event) && createUndoStep(editor), debug$6(`(${mode}:${eventCategory(event)})`, JSON.stringify(event, null, 2));
9881
+ mode === "send" && !isNativeBehaviorEvent(event) && createUndoStepId(editor), debug$6(`(${mode}:${eventCategory(event)})`, JSON.stringify(event, null, 2));
9872
9882
  const eventBehaviors = [...remainingEventBehaviors, ...abstractBehaviors].filter((behavior) => {
9873
9883
  if (behavior.on === "*")
9874
9884
  return !0;
@@ -9876,7 +9886,7 @@ function performEvent({
9876
9886
  return listenedNamespace !== void 0 && eventNamespace !== void 0 && listenedNamespace === eventNamespace || listenedNamespace !== void 0 && eventNamespace === void 0 && listenedNamespace === event.type ? !0 : behavior.on === event.type;
9877
9887
  });
9878
9888
  if (eventBehaviors.length === 0 && isSyntheticBehaviorEvent(event)) {
9879
- nativeEvent?.preventDefault(), mode === "send" && clearUndoStep(editor), withPerformingBehaviorOperation(editor, () => {
9889
+ nativeEvent?.preventDefault(), mode === "send" && clearUndoStepId(editor), withPerformingBehaviorOperation(editor, () => {
9880
9890
  debug$6(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2)), performOperation({
9881
9891
  context: {
9882
9892
  keyGenerator,
@@ -9925,7 +9935,7 @@ function performEvent({
9925
9935
  continue;
9926
9936
  nativeEventPrevented = actions.some((action) => action.type === "raise" || action.type === "execute") || !actions.some((action) => action.type === "forward");
9927
9937
  let undoStepCreated = !1;
9928
- actionSetIndex > 0 && (createUndoStep(editor), undoStepCreated = !0), !undoStepCreated && actions.some((action) => action.type === "execute") && (createUndoStep(editor), undoStepCreated = !0);
9938
+ actionSetIndex > 0 && (createUndoStepId(editor), undoStepCreated = !0), !undoStepCreated && actions.some((action) => action.type === "execute") && (createUndoStepId(editor), undoStepCreated = !0);
9929
9939
  const actionTypes = actions.map((action) => action.type), uniqueActionTypes = new Set(actionTypes), raiseGroup = actionTypes.length > 1 && uniqueActionTypes.size === 1 && uniqueActionTypes.has("raise"), executeGroup = actionTypes.length > 1 && uniqueActionTypes.size === 1 && uniqueActionTypes.has("execute");
9930
9940
  withoutNormalizingConditional(editor, () => raiseGroup || executeGroup, () => {
9931
9941
  for (const action of actions) {
@@ -9983,11 +9993,11 @@ function performEvent({
9983
9993
  sendBack
9984
9994
  });
9985
9995
  }
9986
- }), undoStepCreated && clearUndoStep(editor);
9996
+ }), undoStepCreated && clearUndoStepId(editor);
9987
9997
  }
9988
9998
  break;
9989
9999
  }
9990
- !defaultBehaviorOverwritten && isSyntheticBehaviorEvent(event) ? (nativeEvent?.preventDefault(), mode === "send" && clearUndoStep(editor), withPerformingBehaviorOperation(editor, () => {
10000
+ !defaultBehaviorOverwritten && isSyntheticBehaviorEvent(event) ? (nativeEvent?.preventDefault(), mode === "send" && clearUndoStepId(editor), withPerformingBehaviorOperation(editor, () => {
9991
10001
  debug$6(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2)), performOperation({
9992
10002
  context: {
9993
10003
  keyGenerator,
@@ -10275,7 +10285,6 @@ const editorMachine = setup({
10275
10285
  schema: input.schema,
10276
10286
  selection: null,
10277
10287
  initialReadOnly: input.readOnly ?? !1,
10278
- maxBlocks: input.maxBlocks,
10279
10288
  initialValue: input.initialValue
10280
10289
  }),
10281
10290
  on: {
@@ -10285,13 +10294,6 @@ const editorMachine = setup({
10285
10294
  "remove behavior": {
10286
10295
  actions: "remove behavior from context"
10287
10296
  },
10288
- "update maxBlocks": {
10289
- actions: assign({
10290
- maxBlocks: ({
10291
- event
10292
- }) => event.maxBlocks
10293
- })
10294
- },
10295
10297
  "add slate editor": {
10296
10298
  actions: "add slate editor to context"
10297
10299
  },
@@ -11955,7 +11957,7 @@ function clearEditor({
11955
11957
  hadSelection
11956
11958
  }) {
11957
11959
  Editor.withoutNormalizing(slateEditor, () => {
11958
- withoutSaving(slateEditor, () => {
11960
+ pluginWithoutHistory(slateEditor, () => {
11959
11961
  withRemoteChanges(slateEditor, () => {
11960
11962
  withoutPatching(slateEditor, () => {
11961
11963
  if (doneSyncing)
@@ -12205,7 +12207,6 @@ function createInternalEditor(config) {
12205
12207
  break;
12206
12208
  case "update readOnly":
12207
12209
  case "patches":
12208
- case "update maxBlocks":
12209
12210
  editorActor.send(event);
12210
12211
  break;
12211
12212
  default:
@@ -12259,7 +12260,6 @@ function editorConfigToMachineInput(config) {
12259
12260
  converters: createCoreConverters(legacySchema),
12260
12261
  getLegacySchema: () => legacySchema,
12261
12262
  keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
12262
- maxBlocks: config.maxBlocks,
12263
12263
  readOnly: config.readOnly,
12264
12264
  schema,
12265
12265
  initialValue: config.initialValue
@@ -12302,7 +12302,6 @@ function createActors(config) {
12302
12302
  }), config.editorActor.send({
12303
12303
  type: "mutation",
12304
12304
  patches: event.patches,
12305
- snapshot: event.snapshot,
12306
12305
  value: event.snapshot
12307
12306
  })), event.type === "patch" && config.relayActor.send(event);
12308
12307
  });
@@ -12415,7 +12414,11 @@ function eventToChange(event) {
12415
12414
  value: event.value
12416
12415
  };
12417
12416
  case "mutation":
12418
- return event;
12417
+ return {
12418
+ type: "mutation",
12419
+ patches: event.patches,
12420
+ snapshot: event.value
12421
+ };
12419
12422
  case "ready":
12420
12423
  return event;
12421
12424
  case "selection":
@@ -12453,7 +12456,6 @@ class PortableTextEditor extends Component {
12453
12456
  } = createInternalEditor({
12454
12457
  initialValue: props.value,
12455
12458
  keyGenerator: props.keyGenerator,
12456
- maxBlocks: props.maxBlocks === void 0 ? void 0 : Number.parseInt(props.maxBlocks.toString(), 10),
12457
12459
  readOnly: props.readOnly,
12458
12460
  schema: props.schemaType
12459
12461
  });
@@ -12476,9 +12478,6 @@ class PortableTextEditor extends Component {
12476
12478
  !this.props.editor && !prevProps.editor && this.props.schemaType !== prevProps.schemaType && console.warn("Updating schema type is no longer supported"), !this.props.editor && !prevProps.editor && (this.props.readOnly !== prevProps.readOnly && this.editor._internal.editorActor.send({
12477
12479
  type: "update readOnly",
12478
12480
  readOnly: this.props.readOnly ?? !1
12479
- }), this.props.maxBlocks !== prevProps.maxBlocks && this.editor._internal.editorActor.send({
12480
- type: "update maxBlocks",
12481
- maxBlocks: this.props.maxBlocks === void 0 ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10)
12482
12481
  }), this.props.value !== prevProps.value && this.editor.send({
12483
12482
  type: "update value",
12484
12483
  value: this.props.value
@@ -12927,7 +12926,6 @@ const usePortableTextEditorSelection = () => {
12927
12926
  }, t1 = [editorActor], $[0] = editorActor, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), useEffect(t0, t1), selection;
12928
12927
  };
12929
12928
  export {
12930
- EditorEventListener,
12931
12929
  EditorProvider,
12932
12930
  PortableTextEditable,
12933
12931
  PortableTextEditor,