@portabletext/editor 2.21.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) 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} +29 -5
  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 +297 -320
  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 +3 -3
  19. package/lib/utils/index.js +97 -9
  20. package/lib/utils/index.js.map +1 -1
  21. package/package.json +3 -5
  22. package/src/behaviors/behavior.perform-event.ts +7 -7
  23. package/src/editor/PortableTextEditor.tsx +0 -19
  24. package/src/editor/create-editor.ts +0 -3
  25. package/src/editor/editor-machine.ts +0 -10
  26. package/src/editor/event-to-change.tsx +5 -1
  27. package/src/editor/plugins/create-with-event-listeners.ts +0 -4
  28. package/src/editor/plugins/createWithObjectKeys.ts +2 -1
  29. package/src/editor/plugins/createWithPatches.ts +3 -3
  30. package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -1
  31. package/src/editor/plugins/createWithPortableTextMarkModel.ts +2 -1
  32. package/src/editor/plugins/with-plugins.ts +10 -14
  33. package/src/editor/relay-machine.ts +0 -4
  34. package/src/editor/sync-machine.ts +2 -2
  35. package/src/editor.ts +0 -4
  36. package/src/history/behavior.operation.history.redo.ts +67 -0
  37. package/src/history/behavior.operation.history.undo.ts +71 -0
  38. package/src/history/event.history.undo.test.tsx +672 -0
  39. package/src/history/history.preserving-keys.test.tsx +112 -0
  40. package/src/history/remote-patches.ts +20 -0
  41. package/src/history/slate-plugin.history.ts +146 -0
  42. package/src/history/slate-plugin.redoing.ts +21 -0
  43. package/src/history/slate-plugin.undoing.ts +21 -0
  44. package/src/history/slate-plugin.without-history.ts +23 -0
  45. package/src/history/transform-operation.ts +245 -0
  46. package/src/history/undo-redo-collaboration.test.tsx +541 -0
  47. package/src/history/undo-redo.feature +125 -0
  48. package/src/history/undo-redo.test.tsx +195 -0
  49. package/src/history/undo-step.ts +148 -0
  50. package/src/index.ts +0 -1
  51. package/src/operations/behavior.operations.ts +2 -4
  52. package/src/plugins/index.ts +0 -3
  53. package/src/selectors/index.ts +0 -3
  54. package/src/test/vitest/step-definitions.tsx +55 -0
  55. package/src/test/vitest/test-editor.tsx +1 -1
  56. package/lib/_chunks-es/selector.get-selection-text.js +0 -92
  57. package/lib/_chunks-es/selector.get-selection-text.js.map +0 -1
  58. package/lib/_chunks-es/selector.get-text-before.js +0 -36
  59. package/lib/_chunks-es/selector.get-text-before.js.map +0 -1
  60. package/lib/_chunks-es/util.get-text-block-text.js.map +0 -1
  61. package/lib/_chunks-es/util.is-empty-text-block.js +0 -40
  62. package/lib/_chunks-es/util.is-empty-text-block.js.map +0 -1
  63. package/lib/_chunks-es/util.merge-text-blocks.js +0 -101
  64. package/lib/_chunks-es/util.merge-text-blocks.js.map +0 -1
  65. package/src/editor/plugins/createWithMaxBlocks.ts +0 -53
  66. package/src/editor/plugins/createWithUndoRedo.ts +0 -628
  67. package/src/editor/with-undo-step.ts +0 -37
  68. package/src/editor/withUndoRedo.ts +0 -34
  69. package/src/editor-event-listener.tsx +0 -28
  70. package/src/plugins/plugin.decorator-shortcut.ts +0 -238
  71. package/src/plugins/plugin.markdown.test.tsx +0 -42
  72. package/src/plugins/plugin.markdown.tsx +0 -131
  73. package/src/plugins/plugin.one-line.tsx +0 -123
  74. package/src/selectors/selector.get-list-state.test.ts +0 -189
  75. package/src/selectors/selector.get-list-state.ts +0 -96
  76. package/src/selectors/selector.get-selected-slice.ts +0 -13
  77. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -657
  78. 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) {
@@ -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;
@@ -2240,7 +2229,7 @@ const IS_PROCESSING_REMOTE_CHANGES = /* @__PURE__ */ new WeakMap(), KEY_TO_SLATE
2240
2229
  nativeEvent: event_1
2241
2230
  });
2242
2231
  }
2243
- debug$d("No result from custom paste handler, pasting normally");
2232
+ debug$g("No result from custom paste handler, pasting normally");
2244
2233
  }, $[85] = editorActor, $[86] = onPaste, $[87] = portableTextEditor, $[88] = relayActor, $[89] = slateEditor, $[90] = t21) : t21 = $[90];
2245
2234
  const handlePaste = t21;
2246
2235
  let t22;
@@ -2873,6 +2862,183 @@ function createPlaceholderBlock(context) {
2873
2862
  }]
2874
2863
  };
2875
2864
  }
2865
+ function withRemoteChanges(editor, fn) {
2866
+ const prev = isChangingRemotely(editor) || !1;
2867
+ IS_PROCESSING_REMOTE_CHANGES.set(editor, !0), fn(), IS_PROCESSING_REMOTE_CHANGES.set(editor, prev);
2868
+ }
2869
+ function isChangingRemotely(editor) {
2870
+ return IS_PROCESSING_REMOTE_CHANGES.get(editor);
2871
+ }
2872
+ 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();
2873
+ function pluginRedoing(editor, fn) {
2874
+ const prev = isRedoing(editor);
2875
+ IS_REDOING.set(editor, !0), fn(), IS_REDOING.set(editor, prev);
2876
+ }
2877
+ function isRedoing(editor) {
2878
+ return IS_REDOING.get(editor) ?? !1;
2879
+ }
2880
+ function setIsRedoing(editor, isRedoing2) {
2881
+ IS_REDOING.set(editor, isRedoing2);
2882
+ }
2883
+ const IS_UDOING = /* @__PURE__ */ new WeakMap();
2884
+ function pluginUndoing(editor, fn) {
2885
+ const prev = isUndoing(editor);
2886
+ IS_UDOING.set(editor, !0), fn(), IS_UDOING.set(editor, prev);
2887
+ }
2888
+ function isUndoing(editor) {
2889
+ return IS_UDOING.get(editor) ?? !1;
2890
+ }
2891
+ function setIsUndoing(editor, isUndoing2) {
2892
+ IS_UDOING.set(editor, isUndoing2);
2893
+ }
2894
+ const WITH_HISTORY = /* @__PURE__ */ new WeakMap();
2895
+ function isWithHistory(editor) {
2896
+ return WITH_HISTORY.get(editor) ?? !0;
2897
+ }
2898
+ function pluginWithoutHistory(editor, fn) {
2899
+ const withHistory = isWithHistory(editor);
2900
+ WITH_HISTORY.set(editor, !1), fn(), WITH_HISTORY.set(editor, withHistory);
2901
+ }
2902
+ function setWithHistory(editor, withHistory) {
2903
+ WITH_HISTORY.set(editor, withHistory);
2904
+ }
2905
+ const IS_NORMALIZING_NODE = /* @__PURE__ */ new WeakMap();
2906
+ function withNormalizeNode(editor, fn) {
2907
+ const prev = IS_NORMALIZING_NODE.get(editor);
2908
+ IS_NORMALIZING_NODE.set(editor, !0), fn(), IS_NORMALIZING_NODE.set(editor, prev);
2909
+ }
2910
+ function isNormalizingNode(editor) {
2911
+ return IS_NORMALIZING_NODE.get(editor) ?? !1;
2912
+ }
2913
+ const CURRENT_UNDO_STEP_ID = /* @__PURE__ */ new WeakMap();
2914
+ function getCurrentUndoStepId(editor) {
2915
+ return CURRENT_UNDO_STEP_ID.get(editor)?.undoStepId;
2916
+ }
2917
+ function createUndoStepId(editor) {
2918
+ CURRENT_UNDO_STEP_ID.set(editor, {
2919
+ undoStepId: defaultKeyGenerator()
2920
+ });
2921
+ }
2922
+ function clearUndoStepId(editor) {
2923
+ CURRENT_UNDO_STEP_ID.set(editor, void 0);
2924
+ }
2925
+ function createUndoSteps({
2926
+ steps,
2927
+ op,
2928
+ editor,
2929
+ currentUndoStepId,
2930
+ previousUndoStepId
2931
+ }) {
2932
+ const lastStep = steps.at(-1);
2933
+ if (!lastStep)
2934
+ return createNewStep(steps, op, editor);
2935
+ if (editor.operations.length > 0)
2936
+ return currentUndoStepId === previousUndoStepId || isNormalizingNode(editor) ? mergeIntoLastStep(steps, lastStep, op) : createNewStep(steps, op, editor);
2937
+ if (op.type === "set_selection" && currentUndoStepId === void 0 && previousUndoStepId !== void 0 || op.type === "set_selection" && currentUndoStepId !== void 0 && previousUndoStepId !== void 0 && previousUndoStepId !== currentUndoStepId)
2938
+ return mergeIntoLastStep(steps, lastStep, op);
2939
+ if (currentUndoStepId === void 0 && previousUndoStepId === void 0) {
2940
+ if (op.type === "set_selection")
2941
+ return mergeIntoLastStep(steps, lastStep, op);
2942
+ const lastOp = lastStep.operations.at(-1);
2943
+ 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);
2944
+ }
2945
+ return createNewStep(steps, op, editor);
2946
+ }
2947
+ function createNewStep(steps, op, editor) {
2948
+ const operations = editor.selection === null ? [op] : [{
2949
+ type: "set_selection",
2950
+ properties: {
2951
+ ...editor.selection
2952
+ },
2953
+ newProperties: {
2954
+ ...editor.selection
2955
+ }
2956
+ }, op];
2957
+ return [...steps, {
2958
+ operations,
2959
+ timestamp: /* @__PURE__ */ new Date()
2960
+ }];
2961
+ }
2962
+ function mergeIntoLastStep(steps, lastStep, op) {
2963
+ return [...steps.slice(0, -1), {
2964
+ timestamp: lastStep.timestamp,
2965
+ operations: [...lastStep.operations, op]
2966
+ }];
2967
+ }
2968
+ const debug$f = debugWithName("plugin:history"), UNDO_STEP_LIMIT = 1e3;
2969
+ function pluginHistory({
2970
+ editorActor,
2971
+ subscriptions
2972
+ }) {
2973
+ return (editor) => {
2974
+ const remotePatches = getRemotePatches(editor);
2975
+ let previousSnapshot = fromSlateValue(editor.children, editorActor.getSnapshot().context.schema.block.name), previousUndoStepId = getCurrentUndoStepId(editor);
2976
+ subscriptions.push(() => {
2977
+ const subscription = editorActor.on("patches", ({
2978
+ patches,
2979
+ snapshot
2980
+ }) => {
2981
+ let reset = !1;
2982
+ for (const patch of patches)
2983
+ if (!reset && patch.origin !== "local") {
2984
+ if (patch.type === "unset" && patch.path.length === 0) {
2985
+ debug$f("Someone else cleared the content, resetting undo/redo history"), editor.history = {
2986
+ undos: [],
2987
+ redos: []
2988
+ }, remotePatches.splice(0, remotePatches.length), setWithHistory(editor, !0), reset = !0;
2989
+ return;
2990
+ }
2991
+ remotePatches.push({
2992
+ patch,
2993
+ time: /* @__PURE__ */ new Date(),
2994
+ snapshot,
2995
+ previousSnapshot
2996
+ });
2997
+ }
2998
+ previousSnapshot = snapshot;
2999
+ });
3000
+ return () => {
3001
+ subscription.unsubscribe();
3002
+ };
3003
+ }), editor.history = {
3004
+ undos: [],
3005
+ redos: []
3006
+ };
3007
+ const {
3008
+ apply: apply2
3009
+ } = editor;
3010
+ return editor.apply = (op) => {
3011
+ if (editorActor.getSnapshot().matches({
3012
+ "edit mode": "read only"
3013
+ })) {
3014
+ apply2(op);
3015
+ return;
3016
+ }
3017
+ if (isChangingRemotely(editor)) {
3018
+ apply2(op);
3019
+ return;
3020
+ }
3021
+ if (isUndoing(editor) || isRedoing(editor)) {
3022
+ apply2(op);
3023
+ return;
3024
+ }
3025
+ const withHistory = isWithHistory(editor), currentUndoStepId = getCurrentUndoStepId(editor);
3026
+ if (!withHistory) {
3027
+ previousUndoStepId = currentUndoStepId, apply2(op);
3028
+ return;
3029
+ }
3030
+ for (op.type !== "set_selection" && (editor.history.redos = []), editor.history.undos = createUndoSteps({
3031
+ steps: editor.history.undos,
3032
+ op,
3033
+ editor,
3034
+ currentUndoStepId,
3035
+ previousUndoStepId
3036
+ }); editor.history.undos.length > UNDO_STEP_LIMIT; )
3037
+ editor.history.undos.shift();
3038
+ previousUndoStepId = currentUndoStepId, apply2(op);
3039
+ }, editor;
3040
+ };
3041
+ }
2876
3042
  function getPreviousSpan({
2877
3043
  editor,
2878
3044
  blockPath,
@@ -2901,43 +3067,7 @@ function getNextSpan({
2901
3067
  }
2902
3068
  return nextSpan;
2903
3069
  }
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");
3070
+ const debug$e = debugWithName("plugin:withPortableTextMarkModel");
2941
3071
  function createWithPortableTextMarkModel(editorActor) {
2942
3072
  return function(editor) {
2943
3073
  const {
@@ -2951,7 +3081,7 @@ function createWithPortableTextMarkModel(editorActor) {
2951
3081
  for (const [child, childPath] of children) {
2952
3082
  const nextNode = node.children[childPath[1] + 1];
2953
3083
  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, () => {
3084
+ debug$e("Merging spans", JSON.stringify(child, null, 2), JSON.stringify(nextNode, null, 2)), withNormalizeNode(editor, () => {
2955
3085
  Transforms.mergeNodes(editor, {
2956
3086
  at: [childPath[0], childPath[1] + 1],
2957
3087
  voids: !0
@@ -2962,7 +3092,7 @@ function createWithPortableTextMarkModel(editorActor) {
2962
3092
  }
2963
3093
  }
2964
3094
  if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
2965
- debug$c("Adding .markDefs to block node"), withNormalizeNode(editor, () => {
3095
+ debug$e("Adding .markDefs to block node"), withNormalizeNode(editor, () => {
2966
3096
  Transforms.setNodes(editor, {
2967
3097
  markDefs: []
2968
3098
  }, {
@@ -2972,7 +3102,7 @@ function createWithPortableTextMarkModel(editorActor) {
2972
3102
  return;
2973
3103
  }
2974
3104
  if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
2975
- debug$c("Adding .marks to span node"), withNormalizeNode(editor, () => {
3105
+ debug$e("Adding .marks to span node"), withNormalizeNode(editor, () => {
2976
3106
  Transforms.setNodes(editor, {
2977
3107
  marks: []
2978
3108
  }, {
@@ -2984,7 +3114,7 @@ function createWithPortableTextMarkModel(editorActor) {
2984
3114
  if (editor.isTextSpan(node)) {
2985
3115
  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
3116
  if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
2987
- debug$c("Removing annotations from empty span node"), withNormalizeNode(editor, () => {
3117
+ debug$e("Removing annotations from empty span node"), withNormalizeNode(editor, () => {
2988
3118
  Transforms.setNodes(editor, {
2989
3119
  marks: node.marks?.filter((mark) => decorators2.includes(mark))
2990
3120
  }, {
@@ -3000,7 +3130,7 @@ function createWithPortableTextMarkModel(editorActor) {
3000
3130
  if (editor.isTextSpan(child)) {
3001
3131
  const marks = child.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !node.markDefs?.find((def) => def._key === mark));
3002
3132
  if (orphanedAnnotations.length > 0) {
3003
- debug$c("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3133
+ debug$e("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3004
3134
  Transforms.setNodes(editor, {
3005
3135
  marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))
3006
3136
  }, {
@@ -3016,7 +3146,7 @@ function createWithPortableTextMarkModel(editorActor) {
3016
3146
  if (editor.isTextBlock(block)) {
3017
3147
  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
3148
  if (orphanedAnnotations.length > 0) {
3019
- debug$c("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3149
+ debug$e("Removing orphaned annotations from span node"), withNormalizeNode(editor, () => {
3020
3150
  Transforms.setNodes(editor, {
3021
3151
  marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))
3022
3152
  }, {
@@ -3032,7 +3162,7 @@ function createWithPortableTextMarkModel(editorActor) {
3032
3162
  for (const markDef of markDefs)
3033
3163
  markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
3034
3164
  if (markDefs.length !== newMarkDefs.length) {
3035
- debug$c("Removing duplicate markDefs"), withNormalizeNode(editor, () => {
3165
+ debug$e("Removing duplicate markDefs"), withNormalizeNode(editor, () => {
3036
3166
  Transforms.setNodes(editor, {
3037
3167
  markDefs: newMarkDefs
3038
3168
  }, {
@@ -3045,7 +3175,7 @@ function createWithPortableTextMarkModel(editorActor) {
3045
3175
  if (editor.isTextBlock(node) && !editor.operations.some((op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1)) {
3046
3176
  const newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
3047
3177
  if (node.markDefs && !isEqual(newMarkDefs, node.markDefs)) {
3048
- debug$c("Removing markDef not in use"), withNormalizeNode(editor, () => {
3178
+ debug$e("Removing markDef not in use"), withNormalizeNode(editor, () => {
3049
3179
  Transforms.setNodes(editor, {
3050
3180
  markDefs: newMarkDefs
3051
3181
  }, {
@@ -3137,7 +3267,7 @@ function createWithPortableTextMarkModel(editorActor) {
3137
3267
  const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
3138
3268
  if (editor.isTextBlock(targetBlock)) {
3139
3269
  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, {
3270
+ debug$e("Copying markDefs over to merged block", op), Transforms.setNodes(editor, {
3141
3271
  markDefs: newMarkDefs
3142
3272
  }, {
3143
3273
  at: targetPath,
@@ -3833,174 +3963,7 @@ function parse(textline) {
3833
3963
  function toInt(num) {
3834
3964
  return parseInt(num, 10);
3835
3965
  }
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
- };
3966
+ const debug$d = debugWithName("transformOperation");
4004
3967
  function transformOperation(editor, patch, operation, snapshot, previousSnapshot) {
4005
3968
  const transformedOperation = {
4006
3969
  ...operation
@@ -4009,16 +3972,16 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
4009
3972
  const insertBlockIndex = (snapshot || []).findIndex((blk) => isEqual({
4010
3973
  _key: blk._key
4011
3974
  }, 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)];
3975
+ return debug$d(`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`), [adjustBlockPath(transformedOperation, patch.items.length, insertBlockIndex)];
4013
3976
  }
4014
3977
  if (patch.type === "unset" && patch.path.length === 1) {
4015
3978
  const unsetBlockIndex = (previousSnapshot || []).findIndex((blk) => isEqual({
4016
3979
  _key: blk._key
4017
3980
  }, 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)];
3981
+ 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
3982
  }
4020
3983
  if (patch.type === "unset" && patch.path.length === 0)
4021
- return debug$b(`Adjusting selection for unset everything patch and ${operation.type} operation`), [];
3984
+ return debug$d(`Adjusting selection for unset everything patch and ${operation.type} operation`), [];
4022
3985
  if (patch.type === "diffMatchPatch") {
4023
3986
  const operationTargetBlock = findOperationTargetBlock(editor, transformedOperation);
4024
3987
  return !operationTargetBlock || !isEqual({
@@ -4085,27 +4048,80 @@ function adjustBlockPath(operation, level, blockIndex) {
4085
4048
  }
4086
4049
  return transformedOperation;
4087
4050
  }
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
4051
  function findOperationTargetBlock(editor, operation) {
4105
4052
  let block;
4106
4053
  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
4054
  }
4108
- const addAnnotationOperationImplementation = ({
4055
+ const debug$c = debugWithName("behavior.operation.history.redo"), historyRedoOperationImplementation = ({
4056
+ operation
4057
+ }) => {
4058
+ const editor = operation.editor, {
4059
+ redos
4060
+ } = editor.history, remotePatches = getRemotePatches(editor);
4061
+ if (redos.length > 0) {
4062
+ const step = redos[redos.length - 1];
4063
+ if (debug$c("Redoing", step), step.operations.length > 0) {
4064
+ const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
4065
+ let transformedOperations = step.operations;
4066
+ otherPatches.forEach((item) => {
4067
+ transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
4068
+ });
4069
+ try {
4070
+ Editor.withoutNormalizing(editor, () => {
4071
+ pluginRedoing(editor, () => {
4072
+ pluginWithoutHistory(editor, () => {
4073
+ transformedOperations.forEach((op) => {
4074
+ editor.apply(op);
4075
+ });
4076
+ });
4077
+ });
4078
+ });
4079
+ } catch (err) {
4080
+ debug$c("Could not perform redo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
4081
+ undos: [],
4082
+ redos: []
4083
+ }, setWithHistory(editor, !0), setIsRedoing(editor, !1), editor.onChange();
4084
+ return;
4085
+ }
4086
+ editor.history.undos.push(step), editor.history.redos.pop();
4087
+ }
4088
+ }
4089
+ }, debug$b = debugWithName("behavior.operation.history.undo"), historyUndoOperationImplementation = ({
4090
+ operation
4091
+ }) => {
4092
+ const editor = operation.editor, {
4093
+ undos
4094
+ } = editor.history, remotePatches = getRemotePatches(editor);
4095
+ if (undos.length > 0) {
4096
+ const step = undos[undos.length - 1];
4097
+ if (debug$b("Undoing", step), step.operations.length > 0) {
4098
+ const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
4099
+ let transformedOperations = step.operations;
4100
+ otherPatches.forEach((item) => {
4101
+ transformedOperations = flatten(transformedOperations.map((op) => transformOperation(editor, item.patch, op, item.snapshot, item.previousSnapshot)));
4102
+ });
4103
+ const reversedOperations = transformedOperations.map(Operation.inverse).reverse();
4104
+ try {
4105
+ Editor.withoutNormalizing(editor, () => {
4106
+ pluginUndoing(editor, () => {
4107
+ pluginWithoutHistory(editor, () => {
4108
+ reversedOperations.forEach((op) => {
4109
+ editor.apply(op);
4110
+ });
4111
+ });
4112
+ });
4113
+ });
4114
+ } catch (err) {
4115
+ debug$b("Could not perform undo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = {
4116
+ undos: [],
4117
+ redos: []
4118
+ }, setWithHistory(editor, !0), setIsUndoing(editor, !1), editor.onChange();
4119
+ return;
4120
+ }
4121
+ editor.history.redos.push(step), editor.history.undos.pop();
4122
+ }
4123
+ }
4124
+ }, addAnnotationOperationImplementation = ({
4109
4125
  context,
4110
4126
  operation
4111
4127
  }) => {
@@ -5182,8 +5198,6 @@ function isPerformingBehaviorOperation(editor) {
5182
5198
  }
5183
5199
  function createWithEventListeners(editorActor) {
5184
5200
  return function(editor) {
5185
- if (editorActor.getSnapshot().context.maxBlocks !== void 0)
5186
- return editor;
5187
5201
  const {
5188
5202
  delete: editorDelete,
5189
5203
  select
@@ -5380,31 +5394,6 @@ function createWithEventListeners(editorActor) {
5380
5394
  }, editor;
5381
5395
  };
5382
5396
  }
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
5397
  function createWithObjectKeys(editorActor) {
5409
5398
  return function(editor) {
5410
5399
  const {
@@ -6249,7 +6238,7 @@ function createWithPatches({
6249
6238
  withRemoteChanges(editor, () => {
6250
6239
  Editor.withoutNormalizing(editor, () => {
6251
6240
  withoutPatching(editor, () => {
6252
- withoutSaving(editor, () => {
6241
+ pluginWithoutHistory(editor, () => {
6253
6242
  for (const patch of patches) {
6254
6243
  debug$a.enabled && debug$a(`Handling remote patch ${JSON.stringify(patch)}`);
6255
6244
  try {
@@ -6765,16 +6754,16 @@ const withPlugins = (editor, options) => {
6765
6754
  editorActor,
6766
6755
  relayActor,
6767
6756
  subscriptions: options.subscriptions
6768
- }), withMaxBlocks = createWithMaxBlocks(editorActor), withUndoRedo = createWithUndoRedo({
6757
+ }), withUndoRedo = pluginHistory({
6769
6758
  editorActor,
6770
6759
  subscriptions: options.subscriptions
6771
6760
  }), withPortableTextMarkModel = createWithPortableTextMarkModel(editorActor), withPlaceholderBlock = createWithPlaceholderBlock(editorActor), withUtils = createWithUtils({
6772
6761
  editorActor
6773
6762
  });
6774
- return createWithEventListeners(editorActor)(withSchemaTypes(withObjectKeys(withPortableTextMarkModel(withPlaceholderBlock(withUtils(withMaxBlocks(withUndoRedo(withPatches(pluginUpdateValue(editorActor.getSnapshot().context, pluginUpdateSelection({
6763
+ return createWithEventListeners(editorActor)(withSchemaTypes(withObjectKeys(withPortableTextMarkModel(withPlaceholderBlock(withUtils(withUndoRedo(withPatches(pluginUpdateValue(editorActor.getSnapshot().context, pluginUpdateSelection({
6775
6764
  editorActor,
6776
6765
  editor: e
6777
- })))))))))));
6766
+ }))))))))));
6778
6767
  }, debug$7 = debugWithName("setup");
6779
6768
  function createSlateEditor(config) {
6780
6769
  debug$7("Creating new Slate editor instance");
@@ -9868,7 +9857,7 @@ function performEvent({
9868
9857
  nativeEvent,
9869
9858
  sendBack
9870
9859
  }) {
9871
- mode === "send" && !isNativeBehaviorEvent(event) && createUndoStep(editor), debug$6(`(${mode}:${eventCategory(event)})`, JSON.stringify(event, null, 2));
9860
+ mode === "send" && !isNativeBehaviorEvent(event) && createUndoStepId(editor), debug$6(`(${mode}:${eventCategory(event)})`, JSON.stringify(event, null, 2));
9872
9861
  const eventBehaviors = [...remainingEventBehaviors, ...abstractBehaviors].filter((behavior) => {
9873
9862
  if (behavior.on === "*")
9874
9863
  return !0;
@@ -9876,7 +9865,7 @@ function performEvent({
9876
9865
  return listenedNamespace !== void 0 && eventNamespace !== void 0 && listenedNamespace === eventNamespace || listenedNamespace !== void 0 && eventNamespace === void 0 && listenedNamespace === event.type ? !0 : behavior.on === event.type;
9877
9866
  });
9878
9867
  if (eventBehaviors.length === 0 && isSyntheticBehaviorEvent(event)) {
9879
- nativeEvent?.preventDefault(), mode === "send" && clearUndoStep(editor), withPerformingBehaviorOperation(editor, () => {
9868
+ nativeEvent?.preventDefault(), mode === "send" && clearUndoStepId(editor), withPerformingBehaviorOperation(editor, () => {
9880
9869
  debug$6(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2)), performOperation({
9881
9870
  context: {
9882
9871
  keyGenerator,
@@ -9925,7 +9914,7 @@ function performEvent({
9925
9914
  continue;
9926
9915
  nativeEventPrevented = actions.some((action) => action.type === "raise" || action.type === "execute") || !actions.some((action) => action.type === "forward");
9927
9916
  let undoStepCreated = !1;
9928
- actionSetIndex > 0 && (createUndoStep(editor), undoStepCreated = !0), !undoStepCreated && actions.some((action) => action.type === "execute") && (createUndoStep(editor), undoStepCreated = !0);
9917
+ actionSetIndex > 0 && (createUndoStepId(editor), undoStepCreated = !0), !undoStepCreated && actions.some((action) => action.type === "execute") && (createUndoStepId(editor), undoStepCreated = !0);
9929
9918
  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
9919
  withoutNormalizingConditional(editor, () => raiseGroup || executeGroup, () => {
9931
9920
  for (const action of actions) {
@@ -9983,11 +9972,11 @@ function performEvent({
9983
9972
  sendBack
9984
9973
  });
9985
9974
  }
9986
- }), undoStepCreated && clearUndoStep(editor);
9975
+ }), undoStepCreated && clearUndoStepId(editor);
9987
9976
  }
9988
9977
  break;
9989
9978
  }
9990
- !defaultBehaviorOverwritten && isSyntheticBehaviorEvent(event) ? (nativeEvent?.preventDefault(), mode === "send" && clearUndoStep(editor), withPerformingBehaviorOperation(editor, () => {
9979
+ !defaultBehaviorOverwritten && isSyntheticBehaviorEvent(event) ? (nativeEvent?.preventDefault(), mode === "send" && clearUndoStepId(editor), withPerformingBehaviorOperation(editor, () => {
9991
9980
  debug$6(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2)), performOperation({
9992
9981
  context: {
9993
9982
  keyGenerator,
@@ -10275,7 +10264,6 @@ const editorMachine = setup({
10275
10264
  schema: input.schema,
10276
10265
  selection: null,
10277
10266
  initialReadOnly: input.readOnly ?? !1,
10278
- maxBlocks: input.maxBlocks,
10279
10267
  initialValue: input.initialValue
10280
10268
  }),
10281
10269
  on: {
@@ -10285,13 +10273,6 @@ const editorMachine = setup({
10285
10273
  "remove behavior": {
10286
10274
  actions: "remove behavior from context"
10287
10275
  },
10288
- "update maxBlocks": {
10289
- actions: assign({
10290
- maxBlocks: ({
10291
- event
10292
- }) => event.maxBlocks
10293
- })
10294
- },
10295
10276
  "add slate editor": {
10296
10277
  actions: "add slate editor to context"
10297
10278
  },
@@ -11955,7 +11936,7 @@ function clearEditor({
11955
11936
  hadSelection
11956
11937
  }) {
11957
11938
  Editor.withoutNormalizing(slateEditor, () => {
11958
- withoutSaving(slateEditor, () => {
11939
+ pluginWithoutHistory(slateEditor, () => {
11959
11940
  withRemoteChanges(slateEditor, () => {
11960
11941
  withoutPatching(slateEditor, () => {
11961
11942
  if (doneSyncing)
@@ -12205,7 +12186,6 @@ function createInternalEditor(config) {
12205
12186
  break;
12206
12187
  case "update readOnly":
12207
12188
  case "patches":
12208
- case "update maxBlocks":
12209
12189
  editorActor.send(event);
12210
12190
  break;
12211
12191
  default:
@@ -12259,7 +12239,6 @@ function editorConfigToMachineInput(config) {
12259
12239
  converters: createCoreConverters(legacySchema),
12260
12240
  getLegacySchema: () => legacySchema,
12261
12241
  keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
12262
- maxBlocks: config.maxBlocks,
12263
12242
  readOnly: config.readOnly,
12264
12243
  schema,
12265
12244
  initialValue: config.initialValue
@@ -12302,7 +12281,6 @@ function createActors(config) {
12302
12281
  }), config.editorActor.send({
12303
12282
  type: "mutation",
12304
12283
  patches: event.patches,
12305
- snapshot: event.snapshot,
12306
12284
  value: event.snapshot
12307
12285
  })), event.type === "patch" && config.relayActor.send(event);
12308
12286
  });
@@ -12415,7 +12393,11 @@ function eventToChange(event) {
12415
12393
  value: event.value
12416
12394
  };
12417
12395
  case "mutation":
12418
- return event;
12396
+ return {
12397
+ type: "mutation",
12398
+ patches: event.patches,
12399
+ snapshot: event.value
12400
+ };
12419
12401
  case "ready":
12420
12402
  return event;
12421
12403
  case "selection":
@@ -12453,7 +12435,6 @@ class PortableTextEditor extends Component {
12453
12435
  } = createInternalEditor({
12454
12436
  initialValue: props.value,
12455
12437
  keyGenerator: props.keyGenerator,
12456
- maxBlocks: props.maxBlocks === void 0 ? void 0 : Number.parseInt(props.maxBlocks.toString(), 10),
12457
12438
  readOnly: props.readOnly,
12458
12439
  schema: props.schemaType
12459
12440
  });
@@ -12476,9 +12457,6 @@ class PortableTextEditor extends Component {
12476
12457
  !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
12458
  type: "update readOnly",
12478
12459
  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
12460
  }), this.props.value !== prevProps.value && this.editor.send({
12483
12461
  type: "update value",
12484
12462
  value: this.props.value
@@ -12927,7 +12905,6 @@ const usePortableTextEditorSelection = () => {
12927
12905
  }, t1 = [editorActor], $[0] = editorActor, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), useEffect(t0, t1), selection;
12928
12906
  };
12929
12907
  export {
12930
- EditorEventListener,
12931
12908
  EditorProvider,
12932
12909
  PortableTextEditable,
12933
12910
  PortableTextEditor,