@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
@@ -1,15 +1,104 @@
1
- import { getBlockKeyFromSelectionPoint } from "../_chunks-es/util.get-text-block-text.js";
2
- import { blockOffsetToSpanSelectionPoint, getBlockStartPoint, getSelectionEndPoint, getSelectionStartPoint, getTextBlockText, isKeyedSegment, sliceBlocks, spanSelectionPointToBlockOffset } from "../_chunks-es/util.get-text-block-text.js";
3
- import { childSelectionPointToBlockOffset } from "../_chunks-es/util.merge-text-blocks.js";
4
- import { blockOffsetToBlockSelectionPoint, blockOffsetToSelectionPoint, blockOffsetsToSelection, mergeTextBlocks } from "../_chunks-es/util.merge-text-blocks.js";
5
- import { isEqualSelectionPoints } from "../_chunks-es/util.is-empty-text-block.js";
6
- import { getBlockEndPoint, isEmptyTextBlock, isSelectionCollapsed } from "../_chunks-es/util.is-empty-text-block.js";
7
- import { isSpan } from "@portabletext/schema";
8
- import { isSpan as isSpan2, isTextBlock } from "@portabletext/schema";
1
+ import { blockOffsetToSpanSelectionPoint, getBlockKeyFromSelectionPoint, getChildKeyFromSelectionPoint, isEqualSelectionPoints, parseBlock } from "../_chunks-es/util.slice-blocks.js";
2
+ import { getBlockEndPoint, getBlockStartPoint, getSelectionEndPoint, getSelectionStartPoint, isKeyedSegment, isSelectionCollapsed, sliceBlocks, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
3
+ import { isTextBlock, isSpan } from "@portabletext/schema";
4
+ import { isSpan as isSpan2, isTextBlock as isTextBlock2 } from "@portabletext/schema";
9
5
  import { sliceTextBlock } from "../_chunks-es/util.slice-text-block.js";
6
+ import { getTextBlockText, isEmptyTextBlock } from "../_chunks-es/util.slice-text-block.js";
7
+ function blockOffsetToBlockSelectionPoint({
8
+ context,
9
+ blockOffset
10
+ }) {
11
+ let selectionPoint;
12
+ for (const block of context.value)
13
+ if (block._key === blockOffset.path[0]._key) {
14
+ selectionPoint = {
15
+ path: [{
16
+ _key: block._key
17
+ }],
18
+ offset: blockOffset.offset
19
+ };
20
+ break;
21
+ }
22
+ return selectionPoint;
23
+ }
24
+ function blockOffsetToSelectionPoint({
25
+ context,
26
+ blockOffset,
27
+ direction
28
+ }) {
29
+ return blockOffsetToSpanSelectionPoint({
30
+ context,
31
+ blockOffset,
32
+ direction
33
+ }) || blockOffsetToBlockSelectionPoint({
34
+ context,
35
+ blockOffset
36
+ });
37
+ }
38
+ function blockOffsetsToSelection({
39
+ context,
40
+ offsets,
41
+ backward
42
+ }) {
43
+ const anchor = blockOffsetToSelectionPoint({
44
+ context,
45
+ blockOffset: offsets.anchor,
46
+ direction: backward ? "backward" : "forward"
47
+ }), focus = blockOffsetToSelectionPoint({
48
+ context,
49
+ blockOffset: offsets.focus,
50
+ direction: backward ? "forward" : "backward"
51
+ });
52
+ return !anchor || !focus ? null : {
53
+ anchor,
54
+ focus,
55
+ backward
56
+ };
57
+ }
58
+ function childSelectionPointToBlockOffset({
59
+ context,
60
+ selectionPoint
61
+ }) {
62
+ let offset = 0;
63
+ const blockKey = getBlockKeyFromSelectionPoint(selectionPoint), childKey = getChildKeyFromSelectionPoint(selectionPoint);
64
+ if (!(!blockKey || !childKey)) {
65
+ for (const block of context.value)
66
+ if (block._key === blockKey && isTextBlock(context, block))
67
+ for (const child of block.children) {
68
+ if (child._key === childKey)
69
+ return {
70
+ path: [{
71
+ _key: block._key
72
+ }],
73
+ offset: offset + selectionPoint.offset
74
+ };
75
+ isSpan(context, child) && (offset += child.text.length);
76
+ }
77
+ }
78
+ }
10
79
  function isEqualSelections(a, b) {
11
80
  return !a && !b ? !0 : !a || !b ? !1 : isEqualSelectionPoints(a.anchor, b.anchor) && isEqualSelectionPoints(a.focus, b.focus);
12
81
  }
82
+ function mergeTextBlocks({
83
+ context,
84
+ targetBlock,
85
+ incomingBlock
86
+ }) {
87
+ const parsedIncomingBlock = parseBlock({
88
+ context,
89
+ block: incomingBlock,
90
+ options: {
91
+ normalize: !1,
92
+ removeUnusedMarkDefs: !0,
93
+ validateFields: !1
94
+ }
95
+ });
96
+ return !parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock) ? targetBlock : {
97
+ ...targetBlock,
98
+ children: [...targetBlock.children, ...parsedIncomingBlock.children],
99
+ markDefs: [...targetBlock.markDefs ?? [], ...parsedIncomingBlock.markDefs ?? []]
100
+ };
101
+ }
13
102
  function reverseSelection(selection) {
14
103
  return selection && (selection.backward ? {
15
104
  anchor: selection.focus,
@@ -99,7 +188,7 @@ export {
99
188
  isKeyedSegment,
100
189
  isSelectionCollapsed,
101
190
  isSpan2 as isSpan,
102
- isTextBlock,
191
+ isTextBlock2 as isTextBlock,
103
192
  mergeTextBlocks,
104
193
  reverseSelection,
105
194
  selectionPointToBlockOffset,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.selection-point-to-block-offset.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'\nimport {getBlockKeyFromSelectionPoint} from './util.selection-point'\n\n/**\n * @public\n */\nexport function selectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n\n if (selectionPoint.path.length === 1 && blockKey !== undefined) {\n return {\n path: [{_key: blockKey}],\n offset: selectionPoint.offset,\n }\n }\n\n return childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n })\n}\n","import {isSpan} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {sliceTextBlock} from './util.slice-text-block'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n block,\n })\n const after = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n block,\n })\n\n return {before, after}\n}\n"],"names":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","reverseSelection","selection","backward","selectionPointToBlockOffset","context","selectionPoint","blockKey","getBlockKeyFromSelectionPoint","path","length","undefined","_key","offset","childSelectionPointToBlockOffset","splitTextBlock","block","point","firstChild","children","at","lastChild","before","sliceTextBlock","schema","after","isSpan","text"],"mappings":";;;;;;;;;AAMO,SAASA,kBAAkBC,GAAoBC,GAAoB;AACxE,SAAI,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACdO,SAASC,iBAEdC,WAA+C;AAC/C,SAAKA,cAIDA,UAAUC,WACL;AAAA,IACLJ,QAAQG,UAAUF;AAAAA,IAClBA,OAAOE,UAAUH;AAAAA,IACjBI,UAAU;AAAA,EAAA,IAIP;AAAA,IACLJ,QAAQG,UAAUF;AAAAA,IAClBA,OAAOE,UAAUH;AAAAA,IACjBI,UAAU;AAAA,EAAA;AAEd;AChBO,SAASC,4BAA4B;AAAA,EAC1CC;AAAAA,EACAC;AAIF,GAA4B;AAC1B,QAAMC,WAAWC,8BAA8BF,cAAc;AAE7D,SAAIA,eAAeG,KAAKC,WAAW,KAAKH,aAAaI,SAC5C;AAAA,IACLF,MAAM,CAAC;AAAA,MAACG,MAAML;AAAAA,IAAAA,CAAS;AAAA,IACvBM,QAAQP,eAAeO;AAAAA,EAAAA,IAIpBC,iCAAiC;AAAA,IACtCT;AAAAA,IACAC;AAAAA,EAAAA,CACD;AACH;ACpBO,SAASS,eAAe;AAAA,EAC7BV;AAAAA,EACAW;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAAST,SAAS,CAAC;AAE7D,MAAI,CAACQ,cAAc,CAACG;AAClB;AAGF,QAAMC,SAASC,eAAe;AAAA,IAC5BlB,SAAS;AAAA,MACPmB,QAAQnB,QAAQmB;AAAAA,MAChBtB,WAAW;AAAA,QACTH,QAAQ;AAAA,UACNU,MAAM,CAAC;AAAA,YAACG,MAAMI,MAAMJ;AAAAA,UAAAA,GAAO,YAAY;AAAA,YAACA,MAAMM,WAAWN;AAAAA,UAAAA,CAAK;AAAA,UAC9DC,QAAQ;AAAA,QAAA;AAAA,QAEVb,OAAOiB;AAAAA,MAAAA;AAAAA,IACT;AAAA,IAEFD;AAAAA,EAAAA,CACD,GACKS,QAAQF,eAAe;AAAA,IAC3BlB,SAAS;AAAA,MACPmB,QAAQnB,QAAQmB;AAAAA,MAChBtB,WAAW;AAAA,QACTH,QAAQkB;AAAAA,QACRjB,OAAO;AAAA,UACLS,MAAM,CAAC;AAAA,YAACG,MAAMI,MAAMJ;AAAAA,UAAAA,GAAO,YAAY;AAAA,YAACA,MAAMS,UAAUT;AAAAA,UAAAA,CAAK;AAAA,UAC7DC,QAAQa,OAAOrB,SAASgB,SAAS,IAAIA,UAAUM,KAAKjB,SAAS;AAAA,QAAA;AAAA,MAC/D;AAAA,IACF;AAAA,IAEFM;AAAAA,EAAAA,CACD;AAED,SAAO;AAAA,IAACM;AAAAA,IAAQG;AAAAA,EAAAA;AAClB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/utils/util.block-offset-to-block-selection-point.ts","../../src/utils/util.block-offset-to-selection-point.ts","../../src/utils/util.block-offsets-to-selection.ts","../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/utils/util.is-equal-selections.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.selection-point-to-block-offset.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n}: {\n context: Pick<EditorContext, 'value'>\n blockOffset: BlockOffset\n}): EditorSelectionPoint | undefined {\n let selectionPoint: EditorSelectionPoint | undefined\n\n for (const block of context.value) {\n if (block._key === blockOffset.path[0]._key) {\n selectionPoint = {\n path: [{_key: block._key}],\n offset: blockOffset.offset,\n }\n break\n }\n }\n\n return selectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {blockOffsetToSpanSelectionPoint} from './util.block-offset'\nimport {blockOffsetToBlockSelectionPoint} from './util.block-offset-to-block-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetToSelectionPoint({\n context,\n blockOffset,\n direction,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}): EditorSelectionPoint | undefined {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n context,\n blockOffset,\n direction,\n })\n\n if (!spanSelectionPoint) {\n return blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n })\n }\n\n return spanSelectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelection} from '../types/editor'\nimport {blockOffsetToSelectionPoint} from './util.block-offset-to-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetsToSelection({\n context,\n offsets,\n backward,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n offsets: {anchor: BlockOffset; focus: BlockOffset}\n backward?: boolean\n}): EditorSelection {\n const anchor = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.anchor,\n direction: backward ? 'backward' : 'forward',\n })\n const focus = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.focus,\n direction: backward ? 'forward' : 'backward',\n })\n\n if (!anchor || !focus) {\n return null\n }\n\n return {\n anchor,\n focus,\n backward,\n }\n}\n","import {isSpan, isTextBlock} from '@portabletext/schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {\n getBlockKeyFromSelectionPoint,\n getChildKeyFromSelectionPoint,\n} from './util.selection-point'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n const childKey = getChildKeyFromSelectionPoint(selectionPoint)\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of context.value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isTextBlock(context, block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isSpan(context, child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import {isTextBlock} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {parseBlock} from './parse-blocks'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {\n normalize: false,\n removeUnusedMarkDefs: true,\n validateFields: false,\n },\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'\nimport {getBlockKeyFromSelectionPoint} from './util.selection-point'\n\n/**\n * @public\n */\nexport function selectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n\n if (selectionPoint.path.length === 1 && blockKey !== undefined) {\n return {\n path: [{_key: blockKey}],\n offset: selectionPoint.offset,\n }\n }\n\n return childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n })\n}\n","import {isSpan} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {sliceTextBlock} from './util.slice-text-block'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n block,\n })\n const after = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n block,\n })\n\n return {before, after}\n}\n"],"names":["blockOffsetToBlockSelectionPoint","context","blockOffset","selectionPoint","block","value","_key","path","offset","blockOffsetToSelectionPoint","direction","blockOffsetToSpanSelectionPoint","blockOffsetsToSelection","offsets","backward","anchor","focus","childSelectionPointToBlockOffset","blockKey","getBlockKeyFromSelectionPoint","childKey","getChildKeyFromSelectionPoint","isTextBlock","child","children","isSpan","text","length","isEqualSelections","a","b","isEqualSelectionPoints","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","normalize","removeUnusedMarkDefs","validateFields","markDefs","reverseSelection","selection","selectionPointToBlockOffset","undefined","splitTextBlock","point","firstChild","at","lastChild","before","sliceTextBlock","schema","after"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "2.21.3",
3
+ "version": "3.0.1",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -141,8 +141,6 @@
141
141
  "test:browser:watch": "vitest --project browser",
142
142
  "test:browser:webkit": "vitest --run --project \"browser (webkit)\"",
143
143
  "test:browser:webkit:watch": "vitest --project \"browser (webkit)\"",
144
- "test:e2e:chromium": "vitest --run --project \"browser.bak (chromium)\"",
145
- "test:e2e:chromium:watch": "vitest --project \"browser.bak (chromium)\"",
146
144
  "test:unit": "vitest --run --project unit",
147
145
  "test:unit:watch": "vitest --project unit",
148
146
  "test:watch": "vitest"
@@ -130,6 +130,7 @@ export const abstractSplitBehaviors = [
130
130
  }),
131
131
  context: snapshot.context,
132
132
  options: {
133
+ normalize: false,
133
134
  removeUnusedMarkDefs: true,
134
135
  validateFields: false,
135
136
  },
@@ -2,8 +2,8 @@ import {createEditorDom} from '../editor/editor-dom'
2
2
  import type {EditorSchema} from '../editor/editor-schema'
3
3
  import type {EditorSnapshot} from '../editor/editor-snapshot'
4
4
  import {withPerformingBehaviorOperation} from '../editor/with-performing-behavior-operation'
5
- import {clearUndoStep, createUndoStep} from '../editor/with-undo-step'
6
5
  import {withoutNormalizingConditional} from '../editor/without-normalizing-conditional'
6
+ import {clearUndoStepId, createUndoStepId} from '../history/undo-step'
7
7
  import {debugWithName} from '../internal-utils/debug'
8
8
  import {performOperation} from '../operations/behavior.operations'
9
9
  import type {PortableTextSlateEditor} from '../types/editor'
@@ -61,7 +61,7 @@ export function performEvent({
61
61
  ) => void
62
62
  }) {
63
63
  if (mode === 'send' && !isNativeBehaviorEvent(event)) {
64
- createUndoStep(editor)
64
+ createUndoStepId(editor)
65
65
  }
66
66
 
67
67
  debug(`(${mode}:${eventCategory(event)})`, JSON.stringify(event, null, 2))
@@ -110,7 +110,7 @@ export function performEvent({
110
110
  nativeEvent?.preventDefault()
111
111
 
112
112
  if (mode === 'send') {
113
- clearUndoStep(editor)
113
+ clearUndoStepId(editor)
114
114
  }
115
115
 
116
116
  withPerformingBehaviorOperation(editor, () => {
@@ -211,7 +211,7 @@ export function performEvent({
211
211
 
212
212
  if (actionSetIndex > 0) {
213
213
  // Since there are multiple action sets
214
- createUndoStep(editor)
214
+ createUndoStepId(editor)
215
215
 
216
216
  undoStepCreated = true
217
217
  }
@@ -224,7 +224,7 @@ export function performEvent({
224
224
  // we set up a new undo step.
225
225
  // All actions performed recursively from now will be squashed into this
226
226
  // undo step
227
- createUndoStep(editor)
227
+ createUndoStepId(editor)
228
228
 
229
229
  undoStepCreated = true
230
230
  }
@@ -321,7 +321,7 @@ export function performEvent({
321
321
  )
322
322
 
323
323
  if (undoStepCreated) {
324
- clearUndoStep(editor)
324
+ clearUndoStepId(editor)
325
325
  }
326
326
  }
327
327
 
@@ -332,7 +332,7 @@ export function performEvent({
332
332
  nativeEvent?.preventDefault()
333
333
 
334
334
  if (mode === 'send') {
335
- clearUndoStep(editor)
335
+ clearUndoStepId(editor)
336
336
  }
337
337
 
338
338
  withPerformingBehaviorOperation(editor, () => {
@@ -50,6 +50,7 @@ export const converterPortableText = defineConverter({
50
50
  context: snapshot.context,
51
51
  block,
52
52
  options: {
53
+ normalize: false,
53
54
  removeUnusedMarkDefs: true,
54
55
  validateFields: false,
55
56
  },
@@ -61,6 +61,7 @@ export function createConverterTextHtml(
61
61
  context: snapshot.context,
62
62
  block,
63
63
  options: {
64
+ normalize: false,
64
65
  removeUnusedMarkDefs: true,
65
66
  validateFields: false,
66
67
  },
@@ -85,6 +85,7 @@ export function createConverterTextPlain(
85
85
  context: snapshot.context,
86
86
  block,
87
87
  options: {
88
+ normalize: false,
88
89
  removeUnusedMarkDefs: true,
89
90
  validateFields: false,
90
91
  },
@@ -467,6 +467,7 @@ export const PortableTextEditable = forwardRef<
467
467
  },
468
468
  blocks: result.insert,
469
469
  options: {
470
+ normalize: false,
470
471
  removeUnusedMarkDefs: true,
471
472
  validateFields: false,
472
473
  },
@@ -67,11 +67,6 @@ export type PortableTextEditorProps<
67
67
  */
68
68
  schemaType: ArraySchemaType<PortableTextBlock> | ArrayDefinition
69
69
 
70
- /**
71
- * Maximum number of blocks to allow within the editor
72
- */
73
- maxBlocks?: number | string
74
-
75
70
  /**
76
71
  * Function used to generate keys for array items (`_key`)
77
72
  */
@@ -152,10 +147,6 @@ export class PortableTextEditor extends Component<
152
147
  const {actors, editor, subscriptions} = createInternalEditor({
153
148
  initialValue: props.value,
154
149
  keyGenerator: props.keyGenerator,
155
- maxBlocks:
156
- props.maxBlocks === undefined
157
- ? undefined
158
- : Number.parseInt(props.maxBlocks.toString(), 10),
159
150
  readOnly: props.readOnly,
160
151
  schema: props.schemaType,
161
152
  })
@@ -221,16 +212,6 @@ export class PortableTextEditor extends Component<
221
212
  })
222
213
  }
223
214
 
224
- if (this.props.maxBlocks !== prevProps.maxBlocks) {
225
- this.editor._internal.editorActor.send({
226
- type: 'update maxBlocks',
227
- maxBlocks:
228
- this.props.maxBlocks === undefined
229
- ? undefined
230
- : Number.parseInt(this.props.maxBlocks.toString(), 10),
231
- })
232
- }
233
-
234
215
  if (this.props.value !== prevProps.value) {
235
216
  this.editor.send({
236
217
  type: 'update value',
@@ -108,7 +108,6 @@ export function createInternalEditor(config: EditorConfig): {
108
108
 
109
109
  case 'update readOnly':
110
110
  case 'patches':
111
- case 'update maxBlocks':
112
111
  editorActor.send(event)
113
112
  break
114
113
 
@@ -169,7 +168,6 @@ function editorConfigToMachineInput(config: EditorConfig) {
169
168
  converters: createCoreConverters(legacySchema),
170
169
  getLegacySchema: () => legacySchema,
171
170
  keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
172
- maxBlocks: config.maxBlocks,
173
171
  readOnly: config.readOnly,
174
172
  schema,
175
173
  initialValue: config.initialValue,
@@ -239,7 +237,6 @@ function createActors(config: {
239
237
  config.editorActor.send({
240
238
  type: 'mutation',
241
239
  patches: event.patches,
242
- snapshot: event.snapshot,
243
240
  value: event.snapshot,
244
241
  })
245
242
  }
@@ -57,10 +57,6 @@ export type ExternalEditorEvent =
57
57
  type: 'update readOnly'
58
58
  readOnly: boolean
59
59
  }
60
- | {
61
- type: 'update maxBlocks'
62
- maxBlocks: number | undefined
63
- }
64
60
  | PatchesEvent
65
61
 
66
62
  type InternalPatchEvent = NamespaceEvent<PatchEvent, 'internal'> & {
@@ -191,7 +187,6 @@ export const editorMachine = setup({
191
187
  pendingIncomingPatchesEvents: Array<PatchesEvent>
192
188
  schema: EditorSchema
193
189
  initialReadOnly: boolean
194
- maxBlocks: number | undefined
195
190
  selection: EditorSelection
196
191
  initialValue: Array<PortableTextBlock> | undefined
197
192
  internalDrag?: {
@@ -206,7 +201,6 @@ export const editorMachine = setup({
206
201
  converters?: Array<Converter>
207
202
  getLegacySchema: () => PortableTextMemberSchemaTypes
208
203
  keyGenerator: () => string
209
- maxBlocks?: number
210
204
  readOnly?: boolean
211
205
  schema: EditorSchema
212
206
  initialValue?: Array<PortableTextBlock>
@@ -387,15 +381,11 @@ export const editorMachine = setup({
387
381
  schema: input.schema,
388
382
  selection: null,
389
383
  initialReadOnly: input.readOnly ?? false,
390
- maxBlocks: input.maxBlocks,
391
384
  initialValue: input.initialValue,
392
385
  }),
393
386
  on: {
394
387
  'add behavior': {actions: 'add behavior to context'},
395
388
  'remove behavior': {actions: 'remove behavior from context'},
396
- 'update maxBlocks': {
397
- actions: assign({maxBlocks: ({event}) => event.maxBlocks}),
398
- },
399
389
  'add slate editor': {actions: 'add slate editor to context'},
400
390
  'update selection': {
401
391
  actions: [
@@ -30,7 +30,11 @@ export function eventToChange(
30
30
  }
31
31
  }
32
32
  case 'mutation': {
33
- return event
33
+ return {
34
+ type: 'mutation',
35
+ patches: event.patches,
36
+ snapshot: event.value,
37
+ }
34
38
  }
35
39
  case 'ready': {
36
40
  return event
@@ -1,16 +1,13 @@
1
- import {Editor} from 'slate'
1
+ import {Editor, Node, Text} from 'slate'
2
2
  import {slateRangeToSelection} from '../../internal-utils/slate-utils'
3
3
  import {performOperation} from '../../operations/behavior.operations'
4
4
  import type {EditorActor} from '../editor-machine'
5
+ import {isNormalizingNode} from '../with-normalizing-node'
5
6
  import {isPerformingBehaviorOperation} from '../with-performing-behavior-operation'
6
7
 
7
8
  export function createWithEventListeners(editorActor: EditorActor) {
8
9
  return function withEventListeners(editor: Editor) {
9
- if (editorActor.getSnapshot().context.maxBlocks !== undefined) {
10
- return editor
11
- }
12
-
13
- const {delete: editorDelete, select} = editor
10
+ const {delete: editorDelete, insertNodes, select} = editor
14
11
 
15
12
  editor.delete = (options) => {
16
13
  if (isPerformingBehaviorOperation(editor)) {
@@ -119,6 +116,33 @@ export function createWithEventListeners(editorActor: EditorActor) {
119
116
  })
120
117
  }
121
118
 
119
+ editor.insertNodes = (nodes, options) => {
120
+ if (isNormalizingNode(editor)) {
121
+ const normalizedNodes = (Node.isNode(nodes) ? [nodes] : nodes).map(
122
+ (node) => {
123
+ if (!Text.isText(node)) {
124
+ return node
125
+ }
126
+
127
+ if (typeof node._type !== 'string') {
128
+ return {
129
+ ...(node as Node),
130
+ _type: editorActor.getSnapshot().context.schema.span.name,
131
+ }
132
+ }
133
+
134
+ return node
135
+ },
136
+ ) as Array<Node>
137
+
138
+ insertNodes(normalizedNodes, options)
139
+
140
+ return
141
+ }
142
+
143
+ insertNodes(nodes, options)
144
+ }
145
+
122
146
  editor.insertSoftBreak = () => {
123
147
  if (isPerformingBehaviorOperation(editor)) {
124
148
  performOperation({
@@ -1,11 +1,12 @@
1
1
  import {isSpan, isTextBlock} from '@portabletext/schema'
2
2
  import {isEqual} from 'lodash'
3
3
  import {Editor, Element, Node, Path, Transforms} from 'slate'
4
+ import {isRedoing} from '../../history/slate-plugin.redoing'
5
+ import {isUndoing} from '../../history/slate-plugin.undoing'
4
6
  import type {PortableTextSlateEditor} from '../../types/editor'
5
7
  import type {EditorActor} from '../editor-machine'
6
8
  import {withNormalizeNode} from '../with-normalizing-node'
7
9
  import {isChangingRemotely} from '../withChanges'
8
- import {isRedoing, isUndoing} from '../withUndoRedo'
9
10
 
10
11
  /**
11
12
  * This plugin makes sure that every new node in the editor get a new _key prop when created
@@ -1,5 +1,7 @@
1
1
  import {insert, setIfMissing, unset, type Patch} from '@portabletext/patches'
2
2
  import {Editor, type Descendant, type Operation} from 'slate'
3
+ import {pluginWithoutHistory} from '../../history/slate-plugin.without-history'
4
+ import {getCurrentUndoStepId} from '../../history/undo-step'
3
5
  import {createApplyPatch} from '../../internal-utils/applyPatch'
4
6
  import {debugWithName} from '../../internal-utils/debug'
5
7
  import {
@@ -17,10 +19,8 @@ import type {PortableTextSlateEditor} from '../../types/editor'
17
19
  import type {EditorActor} from '../editor-machine'
18
20
  import type {RelayActor} from '../relay-machine'
19
21
  import {IS_PROCESSING_REMOTE_CHANGES, KEY_TO_VALUE_ELEMENT} from '../weakMaps'
20
- import {getCurrentUndoStepId} from '../with-undo-step'
21
22
  import {withRemoteChanges} from '../withChanges'
22
23
  import {isPatching, PATCHING, withoutPatching} from '../withoutPatching'
23
- import {withoutSaving} from './createWithUndoRedo'
24
24
 
25
25
  const debug = debugWithName('plugin:withPatches')
26
26
  const debugVerbose = false
@@ -61,7 +61,7 @@ export function createWithPatches({
61
61
  withRemoteChanges(editor, () => {
62
62
  Editor.withoutNormalizing(editor, () => {
63
63
  withoutPatching(editor, () => {
64
- withoutSaving(editor, () => {
64
+ pluginWithoutHistory(editor, () => {
65
65
  for (const patch of patches) {
66
66
  if (debug.enabled)
67
67
  debug(`Handling remote patch ${JSON.stringify(patch)}`)
@@ -1,9 +1,10 @@
1
1
  import {Editor} from 'slate'
2
+ import {isRedoing} from '../../history/slate-plugin.redoing'
3
+ import {isUndoing} from '../../history/slate-plugin.undoing'
2
4
  import {debugWithName} from '../../internal-utils/debug'
3
5
  import type {PortableTextSlateEditor} from '../../types/editor'
4
6
  import type {EditorActor} from '../editor-machine'
5
7
  import {isChangingRemotely} from '../withChanges'
6
- import {isRedoing, isUndoing} from '../withUndoRedo'
7
8
 
8
9
  const debug = debugWithName('plugin:withPlaceholderBlock')
9
10
 
@@ -8,6 +8,8 @@ import {isTextBlock} from '@portabletext/schema'
8
8
  import type {PortableTextObject, PortableTextSpan} from '@sanity/types'
9
9
  import {isEqual, uniq} from 'lodash'
10
10
  import {Editor, Element, Node, Path, Range, Text, Transforms} from 'slate'
11
+ import {isRedoing} from '../../history/slate-plugin.redoing'
12
+ import {isUndoing} from '../../history/slate-plugin.undoing'
11
13
  import {debugWithName} from '../../internal-utils/debug'
12
14
  import {getNextSpan, getPreviousSpan} from '../../internal-utils/sibling-utils'
13
15
  import type {BehaviorOperationImplementation} from '../../operations/behavior.operations'
@@ -17,7 +19,6 @@ import type {EditorActor} from '../editor-machine'
17
19
  import {getEditorSnapshot} from '../editor-selector'
18
20
  import {withNormalizeNode} from '../with-normalizing-node'
19
21
  import {isChangingRemotely} from '../withChanges'
20
- import {isRedoing, isUndoing} from '../withUndoRedo'
21
22
 
22
23
  const debug = debugWithName('plugin:withPortableTextMarkModel')
23
24
 
@@ -1,15 +1,14 @@
1
1
  import type {BaseOperation, Editor, Node, NodeEntry} from 'slate'
2
+ import {pluginHistory} from '../../history/slate-plugin.history'
2
3
  import type {PortableTextSlateEditor} from '../../types/editor'
3
4
  import type {EditorActor} from '../editor-machine'
4
5
  import type {RelayActor} from '../relay-machine'
5
6
  import {createWithEventListeners} from './create-with-event-listeners'
6
- import {createWithMaxBlocks} from './createWithMaxBlocks'
7
7
  import {createWithObjectKeys} from './createWithObjectKeys'
8
8
  import {createWithPatches} from './createWithPatches'
9
9
  import {createWithPlaceholderBlock} from './createWithPlaceholderBlock'
10
10
  import {createWithPortableTextMarkModel} from './createWithPortableTextMarkModel'
11
11
  import {createWithSchemaTypes} from './createWithSchemaTypes'
12
- import {createWithUndoRedo} from './createWithUndoRedo'
13
12
  import {createWithUtils} from './createWithUtils'
14
13
  import {pluginUpdateSelection} from './slate-plugin.update-selection'
15
14
  import {pluginUpdateValue} from './slate-plugin.update-value'
@@ -41,8 +40,7 @@ export const withPlugins = <T extends Editor>(
41
40
  relayActor,
42
41
  subscriptions: options.subscriptions,
43
42
  })
44
- const withMaxBlocks = createWithMaxBlocks(editorActor)
45
- const withUndoRedo = createWithUndoRedo({
43
+ const withUndoRedo = pluginHistory({
46
44
  editorActor,
47
45
  subscriptions: options.subscriptions,
48
46
  })
@@ -62,16 +60,14 @@ export const withPlugins = <T extends Editor>(
62
60
  withPortableTextMarkModel(
63
61
  withPlaceholderBlock(
64
62
  withUtils(
65
- withMaxBlocks(
66
- withUndoRedo(
67
- withPatches(
68
- pluginUpdateValue(
69
- editorActor.getSnapshot().context,
70
- pluginUpdateSelection({
71
- editorActor,
72
- editor: e,
73
- }),
74
- ),
63
+ withUndoRedo(
64
+ withPatches(
65
+ pluginUpdateValue(
66
+ editorActor.getSnapshot().context,
67
+ pluginUpdateSelection({
68
+ editorActor,
69
+ editor: e,
70
+ }),
75
71
  ),
76
72
  ),
77
73
  ),
@@ -72,10 +72,6 @@ export type InternalEditorEmittedEvent = EditorEmittedEvent | UnsetEvent
72
72
  export type MutationEvent = {
73
73
  type: 'mutation'
74
74
  patches: Array<Patch>
75
- /**
76
- * @deprecated Use `value` instead
77
- */
78
- snapshot: Array<PortableTextBlock> | undefined
79
75
  value: Array<PortableTextBlock> | undefined
80
76
  }
81
77
 
@@ -16,6 +16,7 @@ import {
16
16
  type AnyEventObject,
17
17
  type CallbackLogicFunction,
18
18
  } from 'xstate'
19
+ import {pluginWithoutHistory} from '../history/slate-plugin.without-history'
19
20
  import {debugWithName} from '../internal-utils/debug'
20
21
  import {validateValue} from '../internal-utils/validateValue'
21
22
  import {toSlateBlock, VOID_CHILD_KEY} from '../internal-utils/values'
@@ -25,7 +26,6 @@ import type {
25
26
  PortableTextSlateEditor,
26
27
  } from '../types/editor'
27
28
  import type {EditorSchema} from './editor-schema'
28
- import {withoutSaving} from './plugins/createWithUndoRedo'
29
29
  import {isChangingRemotely, withRemoteChanges} from './withChanges'
30
30
  import {withoutPatching} from './withoutPatching'
31
31
 
@@ -582,7 +582,7 @@ function clearEditor({
582
582
  hadSelection: boolean
583
583
  }) {
584
584
  Editor.withoutNormalizing(slateEditor, () => {
585
- withoutSaving(slateEditor, () => {
585
+ pluginWithoutHistory(slateEditor, () => {
586
586
  withRemoteChanges(slateEditor, () => {
587
587
  withoutPatching(slateEditor, () => {
588
588
  if (doneSyncing) {
package/src/editor.ts CHANGED
@@ -20,10 +20,6 @@ export type EditorConfig = {
20
20
  * @beta
21
21
  */
22
22
  keyGenerator?: () => string
23
- /**
24
- * @deprecated Will be removed in the next major version
25
- */
26
- maxBlocks?: number
27
23
  readOnly?: boolean
28
24
  initialValue?: Array<PortableTextBlock>
29
25
  } & (