@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
@@ -1,16 +1,6 @@
1
1
  import { c } from "react-compiler-runtime";
2
2
  import React, { useEffect } from "react";
3
3
  import { useEditor } from "../_chunks-es/use-editor.js";
4
- import { useActorRef } from "@xstate/react";
5
- import isEqual from "lodash/isEqual.js";
6
- import { setup, fromCallback, assign } from "xstate";
7
- import { getFocusTextBlock, getSelectionStartPoint, getPreviousInlineObject, isSelectionCollapsed, getFocusSpan, getFocusBlock, isSelectionExpanded } from "../_chunks-es/selector.get-selection-text.js";
8
- import { getBlockTextBefore } from "../_chunks-es/selector.get-text-before.js";
9
- import { spanSelectionPointToBlockOffset, getTextBlockText } from "../_chunks-es/util.get-text-block-text.js";
10
- import { blockOffsetsToSelection, childSelectionPointToBlockOffset, mergeTextBlocks } from "../_chunks-es/util.merge-text-blocks.js";
11
- import { defineBehavior, execute, effect, forward, raise } from "../behaviors/index.js";
12
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
13
- import { isTextBlock } from "@portabletext/schema";
14
4
  function BehaviorPlugin(props) {
15
5
  const $ = c(4), editor = useEditor();
16
6
  let t0, t1;
@@ -26,315 +16,7 @@ function BehaviorPlugin(props) {
26
16
  function _temp(unregister) {
27
17
  unregister();
28
18
  }
29
- function createPairRegex(char, amount) {
30
- const prePrefix = `(?<!\\${char})`, prefix = `\\${char}`.repeat(Math.max(amount, 1)), postPrefix = "(?!\\s)", content = `([^${char}\\n]+?)`, preSuffix = "(?<!\\s)", suffix = `\\${char}`.repeat(Math.max(amount, 1)), postSuffix = `(?!\\${char})`;
31
- return `${prePrefix}${prefix}${postPrefix}${content}${preSuffix}${suffix}${postSuffix}`;
32
- }
33
- function createDecoratorPairBehavior(config) {
34
- config.pair.amount < 1 && console.warn("The amount of characters in the pair should be greater than 0");
35
- const pairRegex = createPairRegex(config.pair.char, config.pair.amount), regEx = new RegExp(`(${pairRegex})$`);
36
- return defineBehavior({
37
- on: "insert.text",
38
- guard: ({
39
- snapshot,
40
- event
41
- }) => {
42
- if (config.pair.amount < 1)
43
- return !1;
44
- const decorator = config.decorator({
45
- schema: snapshot.context.schema
46
- });
47
- if (decorator === void 0)
48
- return !1;
49
- const focusTextBlock = getFocusTextBlock(snapshot), selectionStartPoint = getSelectionStartPoint(snapshot), selectionStartOffset = selectionStartPoint ? spanSelectionPointToBlockOffset({
50
- context: {
51
- schema: snapshot.context.schema,
52
- value: snapshot.context.value
53
- },
54
- selectionPoint: selectionStartPoint
55
- }) : void 0;
56
- if (!focusTextBlock || !selectionStartOffset)
57
- return !1;
58
- const newText = `${getBlockTextBefore(snapshot)}${event.text}`, textToDecorate = newText.match(regEx)?.at(0);
59
- if (textToDecorate === void 0)
60
- return !1;
61
- const prefixOffsets = {
62
- anchor: {
63
- path: focusTextBlock.path,
64
- // Example: "foo **bar**".length - "**bar**".length = 4
65
- offset: newText.length - textToDecorate.length
66
- },
67
- focus: {
68
- path: focusTextBlock.path,
69
- // Example: "foo **bar**".length - "**bar**".length + "*".length * 2 = 6
70
- offset: newText.length - textToDecorate.length + config.pair.char.length * config.pair.amount
71
- }
72
- }, suffixOffsets = {
73
- anchor: {
74
- path: focusTextBlock.path,
75
- // Example: "foo **bar*|" (10) + "*".length - 2 = 9
76
- offset: selectionStartOffset.offset + event.text.length - config.pair.char.length * config.pair.amount
77
- },
78
- focus: {
79
- path: focusTextBlock.path,
80
- // Example: "foo **bar*|" (10) + "*".length = 11
81
- offset: selectionStartOffset.offset + event.text.length
82
- }
83
- };
84
- if (prefixOffsets.focus.offset - prefixOffsets.anchor.offset > 1) {
85
- const prefixSelection = blockOffsetsToSelection({
86
- context: snapshot.context,
87
- offsets: prefixOffsets
88
- }), inlineObjectBeforePrefixFocus = getPreviousInlineObject({
89
- ...snapshot,
90
- context: {
91
- ...snapshot.context,
92
- selection: prefixSelection ? {
93
- anchor: prefixSelection.focus,
94
- focus: prefixSelection.focus
95
- } : null
96
- }
97
- }), inlineObjectBeforePrefixFocusOffset = inlineObjectBeforePrefixFocus ? childSelectionPointToBlockOffset({
98
- context: {
99
- schema: snapshot.context.schema,
100
- value: snapshot.context.value
101
- },
102
- selectionPoint: {
103
- path: inlineObjectBeforePrefixFocus.path,
104
- offset: 0
105
- }
106
- }) : void 0;
107
- if (inlineObjectBeforePrefixFocusOffset && inlineObjectBeforePrefixFocusOffset.offset > prefixOffsets.anchor.offset && inlineObjectBeforePrefixFocusOffset.offset < prefixOffsets.focus.offset)
108
- return !1;
109
- }
110
- if (suffixOffsets.focus.offset - suffixOffsets.anchor.offset > 1) {
111
- const previousInlineObject = getPreviousInlineObject(snapshot), previousInlineObjectOffset = previousInlineObject ? childSelectionPointToBlockOffset({
112
- context: {
113
- schema: snapshot.context.schema,
114
- value: snapshot.context.value
115
- },
116
- selectionPoint: {
117
- path: previousInlineObject.path,
118
- offset: 0
119
- }
120
- }) : void 0;
121
- if (previousInlineObjectOffset && previousInlineObjectOffset.offset > suffixOffsets.anchor.offset && previousInlineObjectOffset.offset < suffixOffsets.focus.offset)
122
- return !1;
123
- }
124
- return {
125
- prefixOffsets,
126
- suffixOffsets,
127
- decorator
128
- };
129
- },
130
- actions: [
131
- // Insert the text as usual in its own undo step
132
- ({
133
- event
134
- }) => [execute(event)],
135
- (_, {
136
- prefixOffsets,
137
- suffixOffsets,
138
- decorator
139
- }) => [
140
- // Decorate the text between the prefix and suffix
141
- execute({
142
- type: "decorator.add",
143
- decorator,
144
- at: {
145
- anchor: prefixOffsets.focus,
146
- focus: suffixOffsets.anchor
147
- }
148
- }),
149
- // Delete the suffix
150
- execute({
151
- type: "delete.text",
152
- at: suffixOffsets
153
- }),
154
- // Delete the prefix
155
- execute({
156
- type: "delete.text",
157
- at: prefixOffsets
158
- }),
159
- // Toggle the decorator off so the next inserted text isn't emphasized
160
- execute({
161
- type: "decorator.remove",
162
- decorator
163
- }),
164
- effect(() => {
165
- config.onDecorate({
166
- ...suffixOffsets.anchor,
167
- offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
168
- });
169
- })
170
- ]
171
- ]
172
- });
173
- }
174
- function DecoratorShortcutPlugin(config) {
175
- const $ = c(4), editor = useEditor();
176
- let t0;
177
- return $[0] !== config.decorator || $[1] !== config.pair || $[2] !== editor ? (t0 = {
178
- input: {
179
- editor,
180
- decorator: config.decorator,
181
- pair: config.pair
182
- }
183
- }, $[0] = config.decorator, $[1] = config.pair, $[2] = editor, $[3] = t0) : t0 = $[3], useActorRef(decoratorPairMachine, t0), null;
184
- }
185
- const emphasisListener = ({
186
- sendBack,
187
- input
188
- }) => input.editor.registerBehavior({
189
- behavior: createDecoratorPairBehavior({
190
- decorator: input.decorator,
191
- pair: input.pair,
192
- onDecorate: (offset) => {
193
- sendBack({
194
- type: "emphasis.add",
195
- blockOffset: offset
196
- });
197
- }
198
- })
199
- }), selectionListenerCallback = ({
200
- sendBack,
201
- input
202
- }) => input.editor.registerBehavior({
203
- behavior: defineBehavior({
204
- on: "select",
205
- guard: ({
206
- snapshot,
207
- event
208
- }) => {
209
- if (!event.at)
210
- return {
211
- blockOffsets: void 0
212
- };
213
- const anchor = spanSelectionPointToBlockOffset({
214
- context: snapshot.context,
215
- selectionPoint: event.at.anchor
216
- }), focus = spanSelectionPointToBlockOffset({
217
- context: snapshot.context,
218
- selectionPoint: event.at.focus
219
- });
220
- return !anchor || !focus ? {
221
- blockOffsets: void 0
222
- } : {
223
- blockOffsets: {
224
- anchor,
225
- focus
226
- }
227
- };
228
- },
229
- actions: [({
230
- event
231
- }, {
232
- blockOffsets
233
- }) => [{
234
- type: "effect",
235
- effect: () => {
236
- sendBack({
237
- type: "selection",
238
- blockOffsets
239
- });
240
- }
241
- }, forward(event)]]
242
- })
243
- }), deleteBackwardListenerCallback = ({
244
- sendBack,
245
- input
246
- }) => input.editor.registerBehavior({
247
- behavior: defineBehavior({
248
- on: "delete.backward",
249
- actions: [() => [execute({
250
- type: "history.undo"
251
- }), effect(() => {
252
- sendBack({
253
- type: "delete.backward"
254
- });
255
- })]]
256
- })
257
- }), decoratorPairMachine = setup({
258
- types: {
259
- context: {},
260
- input: {},
261
- events: {}
262
- },
263
- actors: {
264
- "emphasis listener": fromCallback(emphasisListener),
265
- "delete.backward listener": fromCallback(deleteBackwardListenerCallback),
266
- "selection listener": fromCallback(selectionListenerCallback)
267
- }
268
- }).createMachine({
269
- id: "decorator pair",
270
- context: ({
271
- input
272
- }) => ({
273
- decorator: input.decorator,
274
- editor: input.editor,
275
- pair: input.pair
276
- }),
277
- initial: "idle",
278
- states: {
279
- idle: {
280
- invoke: [{
281
- src: "emphasis listener",
282
- input: ({
283
- context
284
- }) => ({
285
- decorator: context.decorator,
286
- editor: context.editor,
287
- pair: context.pair
288
- })
289
- }],
290
- on: {
291
- "emphasis.add": {
292
- target: "emphasis added",
293
- actions: assign({
294
- offsetAfterEmphasis: ({
295
- event
296
- }) => event.blockOffset
297
- })
298
- }
299
- }
300
- },
301
- "emphasis added": {
302
- exit: [assign({
303
- offsetAfterEmphasis: void 0
304
- })],
305
- invoke: [{
306
- src: "selection listener",
307
- input: ({
308
- context
309
- }) => ({
310
- editor: context.editor
311
- })
312
- }, {
313
- src: "delete.backward listener",
314
- input: ({
315
- context
316
- }) => ({
317
- editor: context.editor
318
- })
319
- }],
320
- on: {
321
- selection: {
322
- target: "idle",
323
- guard: ({
324
- context,
325
- event
326
- }) => !isEqual({
327
- anchor: context.offsetAfterEmphasis,
328
- focus: context.offsetAfterEmphasis
329
- }, event.blockOffsets)
330
- },
331
- "delete.backward": {
332
- target: "idle"
333
- }
334
- }
335
- }
336
- }
337
- }), EditorRefPlugin = React.forwardRef((_, ref) => {
19
+ const EditorRefPlugin = React.forwardRef((_, ref) => {
338
20
  const $ = c(2), editor = useEditor(), portableTextEditorRef = React.useRef(editor);
339
21
  let t0, t1;
340
22
  return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => portableTextEditorRef.current, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React.useImperativeHandle(ref, t0, t1), null;
@@ -350,485 +32,9 @@ function EventListenerPlugin(props) {
350
32
  };
351
33
  }, t1 = [editor, props.on], $[0] = editor, $[1] = props.on, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1), null;
352
34
  }
353
- function createMarkdownBehaviors(config) {
354
- const automaticBlockquoteOnSpace = defineBehavior({
355
- on: "insert.text",
356
- guard: ({
357
- snapshot,
358
- event
359
- }) => {
360
- if (event.text !== " ")
361
- return !1;
362
- const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
363
- if (!selectionCollapsed || !focusTextBlock || !focusSpan)
364
- return !1;
365
- const previousInlineObject = getPreviousInlineObject(snapshot), blockOffset = spanSelectionPointToBlockOffset({
366
- context: snapshot.context,
367
- selectionPoint: {
368
- path: [{
369
- _key: focusTextBlock.node._key
370
- }, "children", {
371
- _key: focusSpan.node._key
372
- }],
373
- offset: snapshot.context.selection?.focus.offset ?? 0
374
- }
375
- });
376
- if (previousInlineObject || !blockOffset)
377
- return !1;
378
- const blockText = getTextBlockText(focusTextBlock.node), caretAtTheEndOfQuote = blockOffset.offset === 1, looksLikeMarkdownQuote = /^>/.test(blockText), blockquoteStyle = config.blockquoteStyle?.(snapshot.context);
379
- return caretAtTheEndOfQuote && looksLikeMarkdownQuote && blockquoteStyle !== void 0 ? {
380
- focusTextBlock,
381
- style: blockquoteStyle
382
- } : !1;
383
- },
384
- actions: [() => [execute({
385
- type: "insert.text",
386
- text: " "
387
- })], (_, {
388
- focusTextBlock,
389
- style
390
- }) => [execute({
391
- type: "block.unset",
392
- props: ["listItem", "level"],
393
- at: focusTextBlock.path
394
- }), execute({
395
- type: "block.set",
396
- props: {
397
- style
398
- },
399
- at: focusTextBlock.path
400
- }), execute({
401
- type: "delete.text",
402
- at: {
403
- anchor: {
404
- path: focusTextBlock.path,
405
- offset: 0
406
- },
407
- focus: {
408
- path: focusTextBlock.path,
409
- offset: 2
410
- }
411
- }
412
- })]]
413
- }), automaticHr = defineBehavior({
414
- on: "insert.text",
415
- guard: ({
416
- snapshot,
417
- event
418
- }) => {
419
- const hrCharacter = event.text === "-" ? "-" : event.text === "*" ? "*" : event.text === "_" ? "_" : void 0;
420
- if (hrCharacter === void 0)
421
- return !1;
422
- const hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = getFocusTextBlock(snapshot), selectionCollapsed = isSelectionCollapsed(snapshot);
423
- if (!hrObject || !focusBlock || !selectionCollapsed)
424
- return !1;
425
- const previousInlineObject = getPreviousInlineObject(snapshot), textBefore = getBlockTextBefore(snapshot), hrBlockOffsets = {
426
- anchor: {
427
- path: focusBlock.path,
428
- offset: 0
429
- },
430
- focus: {
431
- path: focusBlock.path,
432
- offset: 3
433
- }
434
- };
435
- return !previousInlineObject && textBefore === `${hrCharacter}${hrCharacter}` ? {
436
- hrObject,
437
- focusBlock,
438
- hrCharacter,
439
- hrBlockOffsets
440
- } : !1;
441
- },
442
- actions: [(_, {
443
- hrCharacter
444
- }) => [execute({
445
- type: "insert.text",
446
- text: hrCharacter
447
- })], (_, {
448
- hrObject,
449
- hrBlockOffsets
450
- }) => [execute({
451
- type: "insert.block",
452
- placement: "before",
453
- block: {
454
- _type: hrObject.name,
455
- ...hrObject.value ?? {}
456
- }
457
- }), execute({
458
- type: "delete.text",
459
- at: hrBlockOffsets
460
- })]]
461
- }), automaticHrOnPaste = defineBehavior({
462
- on: "clipboard.paste",
463
- guard: ({
464
- snapshot,
465
- event
466
- }) => {
467
- const text = event.originEvent.dataTransfer.getData("text/plain"), hrRegExp = /^(---)$|(___)$|(\*\*\*)$/, hrCharacters = text.match(hrRegExp)?.[0], hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = getFocusBlock(snapshot);
468
- return !hrCharacters || !hrObject || !focusBlock ? !1 : {
469
- hrCharacters,
470
- hrObject,
471
- focusBlock
472
- };
473
- },
474
- actions: [(_, {
475
- hrCharacters
476
- }) => [execute({
477
- type: "insert.text",
478
- text: hrCharacters
479
- })], ({
480
- snapshot
481
- }, {
482
- hrObject,
483
- focusBlock
484
- }) => isTextBlock(snapshot.context, focusBlock.node) ? [execute({
485
- type: "insert.block",
486
- block: {
487
- _type: snapshot.context.schema.block.name,
488
- children: focusBlock.node.children
489
- },
490
- placement: "after"
491
- }), execute({
492
- type: "insert.block",
493
- block: {
494
- _type: hrObject.name,
495
- ...hrObject.value ?? {}
496
- },
497
- placement: "after"
498
- }), execute({
499
- type: "delete.block",
500
- at: focusBlock.path
501
- })] : [execute({
502
- type: "insert.block",
503
- block: {
504
- _type: hrObject.name,
505
- ...hrObject.value ?? {}
506
- },
507
- placement: "after"
508
- })]]
509
- }), automaticHeadingOnSpace = defineBehavior({
510
- on: "insert.text",
511
- guard: ({
512
- snapshot,
513
- event
514
- }) => {
515
- if (event.text !== " ")
516
- return !1;
517
- const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
518
- if (!selectionCollapsed || !focusTextBlock || !focusSpan)
519
- return !1;
520
- const blockOffset = spanSelectionPointToBlockOffset({
521
- context: snapshot.context,
522
- selectionPoint: {
523
- path: [{
524
- _key: focusTextBlock.node._key
525
- }, "children", {
526
- _key: focusSpan.node._key
527
- }],
528
- offset: snapshot.context.selection?.focus.offset ?? 0
529
- }
530
- });
531
- if (!blockOffset)
532
- return !1;
533
- const previousInlineObject = getPreviousInlineObject(snapshot), blockText = getTextBlockText(focusTextBlock.node), markdownHeadingSearch = /^#+/.exec(blockText), level = markdownHeadingSearch ? markdownHeadingSearch[0].length : void 0, caretAtTheEndOfHeading = blockOffset.offset === level;
534
- if (previousInlineObject || !caretAtTheEndOfHeading)
535
- return !1;
536
- const style = level !== void 0 ? config.headingStyle?.({
537
- schema: snapshot.context.schema,
538
- level
539
- }) : void 0;
540
- return level !== void 0 && style !== void 0 ? {
541
- focusTextBlock,
542
- style,
543
- level
544
- } : !1;
545
- },
546
- actions: [({
547
- event
548
- }) => [execute(event)], (_, {
549
- focusTextBlock,
550
- style,
551
- level
552
- }) => [execute({
553
- type: "block.unset",
554
- props: ["listItem", "level"],
555
- at: focusTextBlock.path
556
- }), execute({
557
- type: "block.set",
558
- props: {
559
- style
560
- },
561
- at: focusTextBlock.path
562
- }), execute({
563
- type: "delete.text",
564
- at: {
565
- anchor: {
566
- path: focusTextBlock.path,
567
- offset: 0
568
- },
569
- focus: {
570
- path: focusTextBlock.path,
571
- offset: level + 1
572
- }
573
- }
574
- })]]
575
- }), clearStyleOnBackspace = defineBehavior({
576
- on: "delete.backward",
577
- guard: ({
578
- snapshot
579
- }) => {
580
- const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
581
- if (!selectionCollapsed || !focusTextBlock || !focusSpan)
582
- return !1;
583
- const atTheBeginningOfBLock = focusTextBlock.node.children[0]._key === focusSpan.node._key && snapshot.context.selection?.focus.offset === 0, defaultStyle = config.defaultStyle?.(snapshot.context);
584
- return atTheBeginningOfBLock && defaultStyle && focusTextBlock.node.style !== defaultStyle ? {
585
- defaultStyle,
586
- focusTextBlock
587
- } : !1;
588
- },
589
- actions: [(_, {
590
- defaultStyle,
591
- focusTextBlock
592
- }) => [execute({
593
- type: "block.set",
594
- props: {
595
- style: defaultStyle
596
- },
597
- at: focusTextBlock.path
598
- })]]
599
- }), automaticListOnSpace = defineBehavior({
600
- on: "insert.text",
601
- guard: ({
602
- snapshot,
603
- event
604
- }) => {
605
- if (event.text !== " ")
606
- return !1;
607
- const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
608
- if (!selectionCollapsed || !focusTextBlock || !focusSpan)
609
- return !1;
610
- const previousInlineObject = getPreviousInlineObject(snapshot), blockOffset = spanSelectionPointToBlockOffset({
611
- context: snapshot.context,
612
- selectionPoint: {
613
- path: [{
614
- _key: focusTextBlock.node._key
615
- }, "children", {
616
- _key: focusSpan.node._key
617
- }],
618
- offset: snapshot.context.selection?.focus.offset ?? 0
619
- }
620
- });
621
- if (previousInlineObject || !blockOffset)
622
- return !1;
623
- const blockText = getTextBlockText(focusTextBlock.node), defaultStyle = config.defaultStyle?.(snapshot.context), looksLikeUnorderedList = /^(-|\*)/.test(blockText), unorderedListStyle = config.unorderedListStyle?.(snapshot.context), caretAtTheEndOfUnorderedList = blockOffset.offset === 1;
624
- if (defaultStyle && caretAtTheEndOfUnorderedList && looksLikeUnorderedList && unorderedListStyle !== void 0)
625
- return {
626
- focusTextBlock,
627
- listItem: unorderedListStyle,
628
- listItemLength: 1,
629
- style: defaultStyle
630
- };
631
- const looksLikeOrderedList = /^1\./.test(blockText), orderedListStyle = config.orderedListStyle?.(snapshot.context), caretAtTheEndOfOrderedList = blockOffset.offset === 2;
632
- return defaultStyle && caretAtTheEndOfOrderedList && looksLikeOrderedList && orderedListStyle !== void 0 ? {
633
- focusTextBlock,
634
- listItem: orderedListStyle,
635
- listItemLength: 2,
636
- style: defaultStyle
637
- } : !1;
638
- },
639
- actions: [({
640
- event
641
- }) => [execute(event)], (_, {
642
- focusTextBlock,
643
- style,
644
- listItem,
645
- listItemLength
646
- }) => [execute({
647
- type: "block.set",
648
- props: {
649
- listItem,
650
- level: 1,
651
- style
652
- },
653
- at: focusTextBlock.path
654
- }), execute({
655
- type: "delete.text",
656
- at: {
657
- anchor: {
658
- path: focusTextBlock.path,
659
- offset: 0
660
- },
661
- focus: {
662
- path: focusTextBlock.path,
663
- offset: listItemLength + 1
664
- }
665
- }
666
- })]]
667
- });
668
- return [automaticBlockquoteOnSpace, automaticHeadingOnSpace, automaticHr, automaticHrOnPaste, clearStyleOnBackspace, automaticListOnSpace];
669
- }
670
- function MarkdownPlugin(props) {
671
- const $ = c(17), editor = useEditor();
672
- let t0, t1;
673
- $[0] !== editor || $[1] !== props.config ? (t0 = () => {
674
- const unregisterBehaviors = createMarkdownBehaviors(props.config).map((behavior) => editor.registerBehavior({
675
- behavior
676
- }));
677
- return () => {
678
- for (const unregisterBehavior of unregisterBehaviors)
679
- unregisterBehavior();
680
- };
681
- }, t1 = [editor, props.config], $[0] = editor, $[1] = props.config, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1);
682
- let t2;
683
- $[4] !== props.config.boldDecorator ? (t2 = props.config.boldDecorator ? /* @__PURE__ */ jsxs(Fragment, { children: [
684
- /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
685
- char: "*",
686
- amount: 2
687
- } }),
688
- /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
689
- char: "_",
690
- amount: 2
691
- } })
692
- ] }) : null, $[4] = props.config.boldDecorator, $[5] = t2) : t2 = $[5];
693
- let t3;
694
- $[6] !== props.config.codeDecorator ? (t3 = props.config.codeDecorator ? /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.codeDecorator, pair: {
695
- char: "`",
696
- amount: 1
697
- } }) : null, $[6] = props.config.codeDecorator, $[7] = t3) : t3 = $[7];
698
- let t4;
699
- $[8] !== props.config.italicDecorator ? (t4 = props.config.italicDecorator ? /* @__PURE__ */ jsxs(Fragment, { children: [
700
- /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
701
- char: "*",
702
- amount: 1
703
- } }),
704
- /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
705
- char: "_",
706
- amount: 1
707
- } })
708
- ] }) : null, $[8] = props.config.italicDecorator, $[9] = t4) : t4 = $[9];
709
- let t5;
710
- $[10] !== props.config.strikeThroughDecorator ? (t5 = props.config.strikeThroughDecorator ? /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.strikeThroughDecorator, pair: {
711
- char: "~",
712
- amount: 2
713
- } }) : null, $[10] = props.config.strikeThroughDecorator, $[11] = t5) : t5 = $[11];
714
- let t6;
715
- return $[12] !== t2 || $[13] !== t3 || $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsxs(Fragment, { children: [
716
- t2,
717
- t3,
718
- t4,
719
- t5
720
- ] }), $[12] = t2, $[13] = t3, $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6;
721
- }
722
- const oneLineBehaviors = [
723
- /**
724
- * Hitting Enter on an expanded selection should just delete that selection
725
- * without causing a line break.
726
- */
727
- defineBehavior({
728
- on: "insert.break",
729
- guard: ({
730
- snapshot
731
- }) => snapshot.context.selection && isSelectionExpanded(snapshot) ? {
732
- selection: snapshot.context.selection
733
- } : !1,
734
- actions: [(_, {
735
- selection
736
- }) => [execute({
737
- type: "delete",
738
- at: selection
739
- })]]
740
- }),
741
- /**
742
- * All other cases of `insert.break` should be aborted.
743
- */
744
- defineBehavior({
745
- on: "insert.break",
746
- actions: []
747
- }),
748
- /**
749
- * `insert.block` `before` or `after` is not allowed in a one-line editor.
750
- */
751
- defineBehavior({
752
- on: "insert.block",
753
- guard: ({
754
- event
755
- }) => event.placement === "before" || event.placement === "after",
756
- actions: []
757
- }),
758
- /**
759
- * An ordinary `insert.block` is acceptable if it's a text block. In that
760
- * case it will get merged into the existing text block.
761
- */
762
- defineBehavior({
763
- on: "insert.block",
764
- guard: ({
765
- snapshot,
766
- event
767
- }) => !(!getFocusTextBlock(snapshot) || !isTextBlock(snapshot.context, event.block)),
768
- actions: [({
769
- event
770
- }) => [execute({
771
- type: "insert.block",
772
- block: event.block,
773
- placement: "auto",
774
- select: "end"
775
- })]]
776
- }),
777
- /**
778
- * Fallback Behavior to avoid `insert.block` in case the Behaviors above all
779
- * end up with a falsy guard.
780
- */
781
- defineBehavior({
782
- on: "insert.block",
783
- actions: []
784
- }),
785
- /**
786
- * If multiple blocks are inserted, then the non-text blocks are filtered out
787
- * and the text blocks are merged into one block
788
- */
789
- defineBehavior({
790
- on: "insert.blocks",
791
- guard: ({
792
- snapshot,
793
- event
794
- }) => {
795
- const textBlocks = event.blocks.filter((block) => isTextBlock(snapshot.context, block));
796
- return textBlocks.length === 0 ? !1 : textBlocks.reduce((targetBlock, incomingBlock) => mergeTextBlocks({
797
- context: snapshot.context,
798
- targetBlock,
799
- incomingBlock
800
- }));
801
- },
802
- actions: [
803
- // `insert.block` is raised so the Behavior above can handle the
804
- // insertion
805
- (_, block) => [raise({
806
- type: "insert.block",
807
- block,
808
- placement: "auto"
809
- })]
810
- ]
811
- }),
812
- /**
813
- * Fallback Behavior to avoid `insert.blocks` in case the Behavior above
814
- * ends up with a falsy guard.
815
- */
816
- defineBehavior({
817
- on: "insert.blocks",
818
- actions: []
819
- })
820
- ];
821
- function OneLinePlugin() {
822
- const $ = c(1);
823
- let t0;
824
- return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx(BehaviorPlugin, { behaviors: oneLineBehaviors }), $[0] = t0) : t0 = $[0], t0;
825
- }
826
35
  export {
827
36
  BehaviorPlugin,
828
- DecoratorShortcutPlugin,
829
37
  EditorRefPlugin,
830
- EventListenerPlugin,
831
- MarkdownPlugin,
832
- OneLinePlugin
38
+ EventListenerPlugin
833
39
  };
834
40
  //# sourceMappingURL=index.js.map