@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,657 +0,0 @@
1
- import {compileSchema, defineSchema} from '@portabletext/schema'
2
- import {createTestKeyGenerator} from '@portabletext/test'
3
- import type {PortableTextBlock} from '@sanity/types'
4
- import {describe, expect, test} from 'vitest'
5
- import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
6
- import type {EditorSelection} from '../types/editor'
7
- import {parseBlock} from '../utils/parse-blocks'
8
- import {getTrimmedSelection} from './selector.get-trimmed-selection'
9
-
10
- const keyGenerator = createTestKeyGenerator()
11
-
12
- function snapshot(
13
- value: Array<Partial<PortableTextBlock>>,
14
- selection: EditorSelection,
15
- ) {
16
- const schema = compileSchema(
17
- defineSchema({
18
- blockObjects: [{name: 'image'}],
19
- inlineObjects: [{name: 'stock-ticker'}],
20
- }),
21
- )
22
-
23
- return createTestSnapshot({
24
- context: {
25
- keyGenerator,
26
- schema,
27
- selection,
28
- value: value.flatMap((block) => {
29
- const parsedBlock = parseBlock({
30
- context: {
31
- keyGenerator,
32
- schema,
33
- },
34
- block,
35
- options: {
36
- removeUnusedMarkDefs: true,
37
- validateFields: false,
38
- },
39
- })
40
-
41
- return parsedBlock ? [parsedBlock] : []
42
- }),
43
- },
44
- })
45
- }
46
-
47
- function createSpan(text: string, marks: Array<string> = []) {
48
- return {
49
- _key: keyGenerator(),
50
- _type: 'span',
51
- text,
52
- marks,
53
- }
54
- }
55
-
56
- function createBlock(children: PortableTextBlock['children']) {
57
- return {
58
- _key: keyGenerator(),
59
- _type: 'block',
60
- children,
61
- }
62
- }
63
-
64
- function createStockTicker(symbol: string) {
65
- return {
66
- _key: keyGenerator(),
67
- _type: 'stock-ticker',
68
- symbol,
69
- }
70
- }
71
-
72
- function createImage(src: string) {
73
- return {
74
- _key: keyGenerator(),
75
- _type: 'image',
76
- src,
77
- }
78
- }
79
-
80
- describe(getTrimmedSelection.name, () => {
81
- test('Sensible defaults', () => {
82
- expect(getTrimmedSelection(snapshot([], null))).toBe(null)
83
- expect(
84
- getTrimmedSelection(snapshot([createBlock([createSpan('foo')])], null)),
85
- ).toBe(null)
86
- })
87
-
88
- test('does not trim spans that have selected text', () => {
89
- const foo = createSpan('foo')
90
- const bar = createSpan('bar', ['strong'])
91
- const baz = createSpan('baz')
92
- const block = createBlock([foo, bar, baz])
93
-
94
- expect(
95
- getTrimmedSelection(
96
- snapshot([block], {
97
- anchor: {
98
- path: [{_key: block._key}, 'children', {_key: bar._key}],
99
- offset: 0,
100
- },
101
- focus: {
102
- path: [{_key: block._key}, 'children', {_key: bar._key}],
103
- offset: 3,
104
- },
105
- }),
106
- ),
107
- ).toEqual({
108
- anchor: {
109
- path: [{_key: block._key}, 'children', {_key: bar._key}],
110
- offset: 0,
111
- },
112
- focus: {
113
- path: [{_key: block._key}, 'children', {_key: bar._key}],
114
- offset: 3,
115
- },
116
- })
117
-
118
- expect(
119
- getTrimmedSelection(
120
- snapshot([block], {
121
- anchor: {
122
- path: [{_key: block._key}, 'children', {_key: foo._key}],
123
- offset: 2,
124
- },
125
- focus: {
126
- path: [{_key: block._key}, 'children', {_key: baz._key}],
127
- offset: 2,
128
- },
129
- }),
130
- ),
131
- ).toEqual({
132
- anchor: {
133
- path: [{_key: block._key}, 'children', {_key: foo._key}],
134
- offset: 2,
135
- },
136
- focus: {
137
- path: [{_key: block._key}, 'children', {_key: baz._key}],
138
- offset: 2,
139
- },
140
- })
141
- })
142
-
143
- test('trims spans that have no selected text', () => {
144
- const foo = createSpan('foo')
145
- const bar = createSpan('bar', ['strong'])
146
- const baz = createSpan('baz')
147
- const block = createBlock([foo, bar, baz])
148
-
149
- expect(
150
- getTrimmedSelection(
151
- snapshot([block], {
152
- anchor: {
153
- path: [{_key: block._key}, 'children', {_key: foo._key}],
154
- offset: 3,
155
- },
156
- focus: {
157
- path: [{_key: block._key}, 'children', {_key: baz._key}],
158
- offset: 0,
159
- },
160
- }),
161
- ),
162
- ).toEqual({
163
- anchor: {
164
- path: [{_key: block._key}, 'children', {_key: bar._key}],
165
- offset: 0,
166
- },
167
- focus: {
168
- path: [{_key: block._key}, 'children', {_key: bar._key}],
169
- offset: 3,
170
- },
171
- })
172
- })
173
-
174
- test('trims inline objects at the start edge', () => {
175
- const aapl = createStockTicker('AAPL')
176
- const foo = createSpan('foo')
177
- const block = createBlock([aapl, foo])
178
-
179
- expect(
180
- getTrimmedSelection(
181
- snapshot([block], {
182
- anchor: {
183
- path: [{_key: block._key}, 'children', {_key: aapl._key}],
184
- offset: 0,
185
- },
186
- focus: {
187
- path: [{_key: block._key}, 'children', {_key: foo._key}],
188
- offset: 3,
189
- },
190
- }),
191
- ),
192
- ).toEqual({
193
- anchor: {
194
- path: [{_key: block._key}, 'children', {_key: foo._key}],
195
- offset: 0,
196
- },
197
- focus: {
198
- path: [{_key: block._key}, 'children', {_key: foo._key}],
199
- offset: 3,
200
- },
201
- })
202
- })
203
-
204
- test('trims inline objects at the end edge', () => {
205
- const foo = createSpan('foo')
206
- const aapl = createStockTicker('AAPL')
207
- const block = createBlock([foo, aapl])
208
-
209
- expect(
210
- getTrimmedSelection(
211
- snapshot([block], {
212
- anchor: {
213
- path: [{_key: block._key}, 'children', {_key: foo._key}],
214
- offset: 0,
215
- },
216
- focus: {
217
- path: [{_key: block._key}, 'children', {_key: aapl._key}],
218
- offset: 0,
219
- },
220
- }),
221
- ),
222
- ).toEqual({
223
- anchor: {
224
- path: [{_key: block._key}, 'children', {_key: foo._key}],
225
- offset: 0,
226
- },
227
- focus: {
228
- path: [{_key: block._key}, 'children', {_key: foo._key}],
229
- offset: 3,
230
- },
231
- })
232
- })
233
-
234
- test('trims empty spans', () => {
235
- const empty1 = createSpan('')
236
- const aapl = createStockTicker('AAPL')
237
- const foo = createSpan('foo')
238
- const nvda = createStockTicker('NVDA')
239
- const empty2 = createSpan('')
240
- const block = createBlock([empty1, aapl, foo, nvda, empty2])
241
-
242
- expect(
243
- getTrimmedSelection(
244
- snapshot([block], {
245
- anchor: {
246
- path: [{_key: block._key}, 'children', {_key: empty1._key}],
247
- offset: 0,
248
- },
249
- focus: {
250
- path: [{_key: block._key}, 'children', {_key: empty2._key}],
251
- offset: 0,
252
- },
253
- }),
254
- ),
255
- ).toEqual({
256
- anchor: {
257
- path: [{_key: block._key}, 'children', {_key: foo._key}],
258
- offset: 0,
259
- },
260
- focus: {
261
- path: [{_key: block._key}, 'children', {_key: foo._key}],
262
- offset: 3,
263
- },
264
- })
265
- })
266
-
267
- test('trims off block at the start edge', () => {
268
- const empty1 = createSpan('')
269
- const aapl = createStockTicker('AAPL')
270
- const foo = createSpan('foo')
271
- const empty2 = createSpan('')
272
- const nvda = createStockTicker('NVDA')
273
- const bar = createSpan('bar')
274
- const block1 = createBlock([foo, aapl, empty1])
275
- const block2 = createBlock([empty2, nvda, bar])
276
-
277
- expect(
278
- getTrimmedSelection(
279
- snapshot([block1, block2], {
280
- anchor: {
281
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
282
- offset: 3,
283
- },
284
- focus: {
285
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
286
- offset: 3,
287
- },
288
- }),
289
- ),
290
- ).toEqual({
291
- anchor: {
292
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
293
- offset: 0,
294
- },
295
- focus: {
296
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
297
- offset: 3,
298
- },
299
- })
300
- })
301
-
302
- test('trims off block at the end edge', () => {
303
- const empty1 = createSpan('')
304
- const aapl = createStockTicker('AAPL')
305
- const foo = createSpan('foo')
306
- const empty2 = createSpan('')
307
- const nvda = createStockTicker('NVDA')
308
- const bar = createSpan('bar')
309
- const block1 = createBlock([foo, aapl, empty1])
310
- const block2 = createBlock([empty2, nvda, bar])
311
-
312
- expect(
313
- getTrimmedSelection(
314
- snapshot([block1, block2], {
315
- anchor: {
316
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
317
- offset: 0,
318
- },
319
- focus: {
320
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
321
- offset: 0,
322
- },
323
- }),
324
- ),
325
- ).toEqual({
326
- anchor: {
327
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
328
- offset: 0,
329
- },
330
- focus: {
331
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
332
- offset: 3,
333
- },
334
- })
335
- })
336
-
337
- test('ignores empty text block on start edge', () => {
338
- const empty = createSpan('')
339
- const block1 = createBlock([empty])
340
- const foo = createSpan('foo')
341
- const block2 = createBlock([foo])
342
-
343
- expect(
344
- getTrimmedSelection(
345
- snapshot([block1, block2], {
346
- anchor: {
347
- path: [{_key: block1._key}, 'children', {_key: empty._key}],
348
- offset: 0,
349
- },
350
- focus: {
351
- path: [{_key: block2._key}, 'children', {_key: foo._key}],
352
- offset: 3,
353
- },
354
- }),
355
- ),
356
- ).toEqual({
357
- anchor: {
358
- path: [{_key: block1._key}, 'children', {_key: empty._key}],
359
- offset: 0,
360
- },
361
- focus: {
362
- path: [{_key: block2._key}, 'children', {_key: foo._key}],
363
- offset: 3,
364
- },
365
- })
366
- })
367
-
368
- test('ignores empty text block on end edge', () => {
369
- const foo = createSpan('foo')
370
- const block1 = createBlock([foo])
371
- const empty = createSpan('')
372
- const block2 = createBlock([empty])
373
-
374
- expect(
375
- getTrimmedSelection(
376
- snapshot([block1, block2], {
377
- anchor: {
378
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
379
- offset: 0,
380
- },
381
- focus: {
382
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
383
- offset: 0,
384
- },
385
- }),
386
- ),
387
- ).toEqual({
388
- anchor: {
389
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
390
- offset: 0,
391
- },
392
- focus: {
393
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
394
- offset: 0,
395
- },
396
- })
397
- })
398
-
399
- test('ignores block object on start edge', () => {
400
- const image1 = createImage('image1')
401
- const empty1 = createSpan('')
402
- const aapl = createStockTicker('AAPL')
403
- const foo = createSpan('foo')
404
- const nvda = createStockTicker('NVDA')
405
- const empty2 = createSpan('')
406
- const block = createBlock([empty1, aapl, foo, nvda, empty2])
407
- const image2 = createImage('image2')
408
-
409
- expect(
410
- getTrimmedSelection(
411
- snapshot([image1, block, image2], {
412
- anchor: {
413
- path: [{_key: image1._key}],
414
- offset: 0,
415
- },
416
- focus: {
417
- path: [{_key: block._key}, 'children', {_key: empty2._key}],
418
- offset: 0,
419
- },
420
- }),
421
- ),
422
- ).toEqual({
423
- anchor: {
424
- path: [{_key: image1._key}],
425
- offset: 0,
426
- },
427
- focus: {
428
- path: [{_key: block._key}, 'children', {_key: foo._key}],
429
- offset: 3,
430
- },
431
- })
432
- })
433
-
434
- test('ignores block object on end edge', () => {
435
- const image1 = createImage('image1')
436
- const empty1 = createSpan('')
437
- const aapl = createStockTicker('AAPL')
438
- const foo = createSpan('foo')
439
- const nvda = createStockTicker('NVDA')
440
- const empty2 = createSpan('')
441
- const block = createBlock([empty1, aapl, foo, nvda, empty2])
442
- const image2 = createImage('image2')
443
-
444
- expect(
445
- getTrimmedSelection(
446
- snapshot([image1, block, image2], {
447
- anchor: {
448
- path: [{_key: block._key}, 'children', {_key: empty1._key}],
449
- offset: 0,
450
- },
451
- focus: {
452
- path: [{_key: image2._key}],
453
- offset: 0,
454
- },
455
- }),
456
- ),
457
- ).toEqual({
458
- anchor: {
459
- path: [{_key: block._key}, 'children', {_key: foo._key}],
460
- offset: 0,
461
- },
462
- focus: {
463
- path: [{_key: image2._key}],
464
- offset: 0,
465
- },
466
- })
467
- })
468
-
469
- test('ignores block objects on start and end edge', () => {
470
- const image1 = createImage('image1')
471
- const empty1 = createSpan('')
472
- const aapl = createStockTicker('AAPL')
473
- const foo = createSpan('foo')
474
- const nvda = createStockTicker('NVDA')
475
- const empty2 = createSpan('')
476
- const block = createBlock([empty1, aapl, foo, nvda, empty2])
477
- const image2 = createImage('image2')
478
-
479
- expect(
480
- getTrimmedSelection(
481
- snapshot([image1, block, image2], {
482
- anchor: {
483
- path: [{_key: image1._key}],
484
- offset: 0,
485
- },
486
- focus: {
487
- path: [{_key: image2._key}],
488
- offset: 0,
489
- },
490
- }),
491
- ),
492
- ).toEqual({
493
- anchor: {
494
- path: [{_key: image1._key}],
495
- offset: 0,
496
- },
497
- focus: {
498
- path: [{_key: image2._key}],
499
- offset: 0,
500
- },
501
- })
502
- })
503
-
504
- test('edge case', () => {
505
- expect(
506
- getTrimmedSelection(
507
- snapshot(
508
- [
509
- {
510
- _key: 'b0',
511
- _type: 'block',
512
- children: [
513
- {
514
- _key: 's0',
515
- _type: 'span',
516
- text: 'foo',
517
- },
518
- {
519
- _key: 's1',
520
- _type: 'span',
521
- text: '',
522
- },
523
- ],
524
- },
525
- {
526
- _key: 'b1',
527
- _type: 'block',
528
- children: [
529
- {
530
- _key: 's2',
531
- _type: 'span',
532
- text: '',
533
- },
534
- {
535
- _key: 's3',
536
- _type: 'span',
537
- text: 'bar',
538
- },
539
- ],
540
- },
541
- ],
542
- {
543
- anchor: {
544
- path: [{_key: 'b0'}, 'children', {_key: 's0'}],
545
- offset: 3,
546
- },
547
- focus: {
548
- path: [{_key: 'b1'}, 'children', {_key: 's2'}],
549
- offset: 0,
550
- },
551
- },
552
- ),
553
- ),
554
- ).toEqual(null)
555
- })
556
-
557
- test('edge case #2', () => {
558
- const foo = createSpan('foo')
559
- const block1 = createBlock([foo])
560
- const empty = createSpan('')
561
- const block2 = createBlock([empty])
562
- const bar = createSpan('bar')
563
- const block3 = createBlock([bar])
564
-
565
- expect(
566
- getTrimmedSelection(
567
- snapshot([block1, block2, block3], {
568
- anchor: {
569
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
570
- offset: 3,
571
- },
572
- focus: {
573
- path: [{_key: block3._key}, 'children', {_key: bar._key}],
574
- offset: 0,
575
- },
576
- }),
577
- ),
578
- ).toEqual({
579
- anchor: {
580
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
581
- offset: 0,
582
- },
583
- focus: {
584
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
585
- offset: 0,
586
- },
587
- })
588
- })
589
-
590
- test('edge case #3', () => {
591
- const foo = createSpan('foo')
592
- const block1 = createBlock([foo])
593
- const empty = createSpan('')
594
- const block2 = createBlock([empty])
595
- const bar = createSpan('bar')
596
- const block3 = createBlock([bar])
597
-
598
- expect(
599
- getTrimmedSelection(
600
- snapshot([block1, block2, block3], {
601
- anchor: {
602
- path: [{_key: block3._key}, 'children', {_key: bar._key}],
603
- offset: 0,
604
- },
605
- focus: {
606
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
607
- offset: 3,
608
- },
609
- backward: true,
610
- }),
611
- ),
612
- ).toEqual({
613
- anchor: {
614
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
615
- offset: 0,
616
- },
617
- focus: {
618
- path: [{_key: block2._key}, 'children', {_key: empty._key}],
619
- offset: 0,
620
- },
621
- backward: true,
622
- })
623
- })
624
-
625
- test('backwards selection', () => {
626
- const foo = createSpan('foo')
627
- const block1 = createBlock([foo])
628
- const bar = createSpan('bar')
629
- const block2 = createBlock([bar])
630
-
631
- expect(
632
- getTrimmedSelection(
633
- snapshot([block1, block2], {
634
- anchor: {
635
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
636
- offset: 3,
637
- },
638
- focus: {
639
- path: [{_key: block1._key}, 'children', {_key: foo._key}],
640
- offset: 3,
641
- },
642
- backward: true,
643
- }),
644
- ),
645
- ).toEqual({
646
- anchor: {
647
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
648
- offset: 3,
649
- },
650
- focus: {
651
- path: [{_key: block2._key}, 'children', {_key: bar._key}],
652
- offset: 0,
653
- },
654
- backward: true,
655
- })
656
- })
657
- })