@portabletext/editor 2.19.3 → 2.21.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.
@@ -1,16 +1,19 @@
1
1
  import {isSpan} from '@portabletext/schema'
2
2
  import {isEqual} from 'lodash'
3
- import {Editor, Path, Point, Range, Transforms, type Descendant} from 'slate'
4
- import {DOMEditor} from 'slate-dom'
5
3
  import {
6
- getFocusBlock,
7
- getFocusChild,
8
- getLastBlock,
9
- getSelectionEndBlock,
10
- getSelectionStartBlock,
11
- } from '../internal-utils/slate-utils'
12
- import {isEqualToEmptyEditor, toSlateValue} from '../internal-utils/values'
13
- import type {PortableTextSlateEditor} from '../types/editor'
4
+ Editor,
5
+ Element,
6
+ Path,
7
+ Point,
8
+ Range,
9
+ Transforms,
10
+ type Descendant,
11
+ } from 'slate'
12
+ import {DOMEditor} from 'slate-dom'
13
+ import {getFocusBlock, getFocusChild} from '../internal-utils/slate-utils'
14
+ import {toSlateRange} from '../internal-utils/to-slate-range'
15
+ import {isEqualToEmptyEditor, toSlateBlock} from '../internal-utils/values'
16
+ import type {EditorSelection, PortableTextSlateEditor} from '../types/editor'
14
17
  import {parseBlock} from '../utils/parse-blocks'
15
18
  import {isEmptyTextBlock} from '../utils/util.is-empty-text-block'
16
19
  import type {
@@ -34,52 +37,69 @@ export const insertBlockOperationImplementation: BehaviorOperationImplementation
34
37
  throw new Error(`Failed to parse block ${JSON.stringify(operation.block)}`)
35
38
  }
36
39
 
37
- const fragment = toSlateValue([parsedBlock], {schemaTypes: context.schema})[0]
38
-
39
- if (!fragment) {
40
- throw new Error(
41
- `Failed to convert block to Slate fragment ${JSON.stringify(parsedBlock)}`,
42
- )
43
- }
40
+ const block = toSlateBlock(parsedBlock, {schemaTypes: context.schema})
44
41
 
45
42
  insertBlock({
46
43
  context,
47
- block: fragment,
44
+ block,
48
45
  placement: operation.placement,
49
46
  select: operation.select ?? 'start',
47
+ at: operation.at,
50
48
  editor: operation.editor,
51
49
  })
52
50
  }
53
51
 
54
- export function insertBlock({
55
- context,
56
- block,
57
- placement,
58
- select,
59
- editor,
60
- }: {
52
+ export function insertBlock(options: {
61
53
  context: BehaviorOperationImplementationContext
62
54
  block: Descendant
63
55
  placement: 'auto' | 'after' | 'before'
64
56
  select: 'start' | 'end' | 'none'
57
+ at?: NonNullable<EditorSelection>
65
58
  editor: PortableTextSlateEditor
66
59
  }) {
67
- const [startBlock, startBlockPath] = getSelectionStartBlock({editor})
68
- const [endBlock, endBlockPath] = getSelectionEndBlock({editor})
69
-
70
- if (
71
- !editor.selection ||
72
- !startBlock ||
73
- !startBlockPath ||
74
- !endBlock ||
75
- !endBlockPath
76
- ) {
77
- if (select !== 'none') {
78
- DOMEditor.focus(editor)
79
- }
60
+ const {context, block, placement, select, editor} = options
61
+ const at = options.at
62
+ ? toSlateRange({
63
+ context: {
64
+ schema: context.schema,
65
+ value: editor.value,
66
+ selection: options.at,
67
+ },
68
+ blockIndexMap: editor.blockIndexMap,
69
+ })
70
+ : editor.selection
71
+
72
+ // Fall back to the start and end of the editor if neither an editor
73
+ // selection nor an `at` range is provided
74
+ const start = at ? Range.start(at) : Editor.start(editor, [])
75
+ const end = at ? Range.end(at) : Editor.end(editor, [])
76
+
77
+ const [startBlock, startBlockPath] = Array.from(
78
+ Editor.nodes(editor, {
79
+ at: start,
80
+ mode: 'lowest',
81
+ match: (node, path) =>
82
+ Element.isElement(node) && path.length <= start.path.length,
83
+ }),
84
+ ).at(0) ?? [undefined, undefined]
85
+ const [endBlock, endBlockPath] = Array.from(
86
+ Editor.nodes(editor, {
87
+ at: end,
88
+ mode: 'lowest',
89
+ match: (node, path) =>
90
+ Element.isElement(node) && path.length <= end.path.length,
91
+ }),
92
+ ).at(0) ?? [undefined, undefined]
93
+
94
+ if (!startBlock || !startBlockPath || !endBlock || !endBlockPath) {
95
+ throw new Error('Unable to insert block without a start and end block')
96
+ }
80
97
 
81
- const [lastBlock, lastBlockPath] = getLastBlock({editor})
98
+ if (!editor.selection && select !== 'none') {
99
+ DOMEditor.focus(editor)
100
+ }
82
101
 
102
+ if (!at) {
83
103
  if (placement === 'before') {
84
104
  Transforms.insertNodes(editor, [block], {at: [0]})
85
105
 
@@ -89,7 +109,7 @@ export function insertBlock({
89
109
  Transforms.select(editor, Editor.end(editor, [0]))
90
110
  }
91
111
  } else if (placement === 'after') {
92
- const nextPath = lastBlockPath ? [lastBlockPath[0] + 1] : [0]
112
+ const nextPath = Path.next(endBlockPath)
93
113
  Transforms.insertNodes(editor, [block], {at: nextPath})
94
114
 
95
115
  if (select === 'start') {
@@ -100,22 +120,22 @@ export function insertBlock({
100
120
  } else {
101
121
  // placement === 'auto'
102
122
 
103
- if (lastBlock && isEqualToEmptyEditor([lastBlock], context.schema)) {
123
+ if (endBlock && isEqualToEmptyEditor([endBlock], context.schema)) {
104
124
  // And if the last block was an empty text block, let's remove
105
125
  // that too
106
- Transforms.removeNodes(editor, {at: lastBlockPath})
126
+ Transforms.removeNodes(editor, {at: endBlockPath})
107
127
 
108
128
  Transforms.insertNodes(editor, [block], {
109
- at: lastBlockPath,
129
+ at: endBlockPath,
110
130
  select: false,
111
131
  })
112
132
 
113
133
  Transforms.deselect(editor)
114
134
 
115
135
  if (select === 'start') {
116
- Transforms.select(editor, Editor.start(editor, lastBlockPath))
136
+ Transforms.select(editor, Editor.start(editor, endBlockPath))
117
137
  } else if (select === 'end') {
118
- Transforms.select(editor, Editor.end(editor, lastBlockPath))
138
+ Transforms.select(editor, Editor.end(editor, endBlockPath))
119
139
  }
120
140
 
121
141
  return
@@ -123,13 +143,13 @@ export function insertBlock({
123
143
 
124
144
  if (
125
145
  editor.isTextBlock(block) &&
126
- lastBlock &&
127
- editor.isTextBlock(lastBlock)
146
+ endBlock &&
147
+ editor.isTextBlock(endBlock)
128
148
  ) {
129
- const selectionBefore = Editor.end(editor, lastBlockPath)
149
+ const selectionBefore = Editor.end(editor, endBlockPath)
130
150
 
131
151
  Transforms.insertFragment(editor, [block], {
132
- at: Editor.end(editor, lastBlockPath),
152
+ at: Editor.end(editor, endBlockPath),
133
153
  })
134
154
 
135
155
  if (select === 'start') {
@@ -141,7 +161,7 @@ export function insertBlock({
141
161
  return
142
162
  }
143
163
 
144
- const nextPath = lastBlockPath ? [lastBlockPath[0] + 1] : [0]
164
+ const nextPath = Path.next(endBlockPath)
145
165
 
146
166
  Transforms.insertNodes(editor, [block], {at: nextPath, select: false})
147
167
 
@@ -151,326 +171,314 @@ export function insertBlock({
151
171
  Transforms.select(editor, Editor.end(editor, nextPath))
152
172
  }
153
173
  }
174
+
175
+ return
176
+ }
177
+
178
+ if (!at) {
179
+ throw new Error('Unable to insert block without a selection')
180
+ }
181
+
182
+ if (placement === 'before') {
183
+ Transforms.insertNodes(editor, [block], {
184
+ at: startBlockPath,
185
+ select: false,
186
+ })
187
+
188
+ if (select === 'start') {
189
+ Transforms.select(editor, Editor.start(editor, startBlockPath))
190
+ } else if (select === 'end') {
191
+ Transforms.select(editor, Editor.end(editor, startBlockPath))
192
+ }
193
+ } else if (placement === 'after') {
194
+ const nextPath = Path.next(endBlockPath)
195
+
196
+ Transforms.insertNodes(editor, [block], {
197
+ at: nextPath,
198
+ select: false,
199
+ })
200
+
201
+ if (select === 'start') {
202
+ Transforms.select(editor, Editor.start(editor, nextPath))
203
+ } else if (select === 'end') {
204
+ Transforms.select(editor, Editor.end(editor, nextPath))
205
+ }
154
206
  } else {
155
- if (placement === 'before') {
156
- const currentSelection = editor.selection
157
- const selectionStartPoint = Range.start(currentSelection)
207
+ // placement === 'auto'
158
208
 
159
- Transforms.insertNodes(editor, [block], {
160
- at: [selectionStartPoint.path[0]],
161
- select: false,
162
- })
209
+ const endBlockEndPoint = Editor.start(editor, endBlockPath)
163
210
 
164
- if (select === 'start') {
165
- Transforms.select(
166
- editor,
167
- Editor.start(editor, [selectionStartPoint.path[0]]),
168
- )
169
- } else if (select === 'end') {
170
- Transforms.select(
171
- editor,
172
- Editor.end(editor, [selectionStartPoint.path[0]]),
173
- )
174
- }
175
- } else if (placement === 'after') {
176
- const currentSelection = editor.selection
177
- const selectionEndPoint = Range.end(currentSelection)
211
+ if (Range.isExpanded(at) && !editor.isTextBlock(block)) {
212
+ const atBeforeDelete = Editor.rangeRef(editor, at, {affinity: 'inward'})
213
+
214
+ Transforms.delete(editor, {at})
215
+
216
+ const [focusBlock, focusBlockPath] = getFocusBlock({editor})
178
217
 
179
- const nextPath = [selectionEndPoint.path[0] + 1]
218
+ const atAfterDelete = atBeforeDelete.unref() ?? editor.selection
219
+
220
+ const atBeforeInsert = atAfterDelete
221
+ ? Editor.rangeRef(editor, atAfterDelete, {affinity: 'inward'})
222
+ : undefined
180
223
 
181
224
  Transforms.insertNodes(editor, [block], {
182
- at: nextPath,
183
- select: false,
225
+ voids: true,
226
+ at: atAfterDelete ?? undefined,
227
+ select: select !== 'none',
184
228
  })
185
229
 
186
- if (select === 'start') {
187
- Transforms.select(editor, Editor.start(editor, nextPath))
188
- } else if (select === 'end') {
189
- Transforms.select(editor, Editor.end(editor, nextPath))
190
- }
191
- } else {
192
- // placement === 'auto'
230
+ const atAfterInsert = atBeforeInsert?.unref() ?? editor.selection
193
231
 
194
- const currentSelection = editor.selection
195
- const endBlockEndPoint = Editor.start(editor, endBlockPath)
232
+ if (select === 'none' && atAfterInsert) {
233
+ Transforms.select(editor, atAfterInsert)
234
+ }
196
235
 
197
- if (Range.isExpanded(currentSelection) && !editor.isTextBlock(block)) {
198
- Transforms.delete(editor, {at: currentSelection})
236
+ if (focusBlock && isEqualToEmptyEditor([focusBlock], context.schema)) {
237
+ Transforms.removeNodes(editor, {at: focusBlockPath})
238
+ }
199
239
 
200
- const newSelection = editor.selection
240
+ return
241
+ }
201
242
 
202
- const [focusBlock, focusBlockPath] = getFocusBlock({editor})
243
+ if (editor.isTextBlock(endBlock) && editor.isTextBlock(block)) {
244
+ const selectionStartPoint = Range.start(at)
203
245
 
246
+ if (isEqualToEmptyEditor([endBlock], context.schema)) {
204
247
  Transforms.insertNodes(editor, [block], {
205
- voids: true,
248
+ at: endBlockPath,
249
+ select: false,
206
250
  })
251
+ Transforms.removeNodes(editor, {at: Path.next(endBlockPath)})
207
252
 
208
- const adjustedSelection =
209
- newSelection.anchor.offset === 0
210
- ? Range.transform(newSelection, {
211
- type: 'insert_node',
212
- node: block,
213
- path: [newSelection.anchor.path[0]],
214
- })
215
- : newSelection
216
-
217
- if (select === 'none' && adjustedSelection) {
218
- Transforms.select(editor, adjustedSelection)
219
- }
220
-
221
- if (focusBlock && isEqualToEmptyEditor([focusBlock], context.schema)) {
222
- Transforms.removeNodes(editor, {at: focusBlockPath})
253
+ if (select === 'start') {
254
+ Transforms.select(editor, selectionStartPoint)
255
+ } else if (select === 'end') {
256
+ Transforms.select(editor, Editor.end(editor, endBlockPath))
257
+ } else {
258
+ Transforms.select(editor, at)
223
259
  }
224
260
 
225
261
  return
226
262
  }
227
263
 
228
- if (editor.isTextBlock(endBlock) && editor.isTextBlock(block)) {
229
- const selectionStartPoint = Range.start(currentSelection)
264
+ const endBlockChildKeys = endBlock.children.map((child) => child._key)
265
+ const endBlockMarkDefsKeys =
266
+ endBlock.markDefs?.map((markDef) => markDef._key) ?? []
267
+
268
+ // Assign new keys to markDefs with duplicate keys and keep track of
269
+ // the mapping between the old and new keys
270
+ const markDefKeyMap = new Map<string, string>()
271
+ const adjustedMarkDefs = block.markDefs?.map((markDef) => {
272
+ if (endBlockMarkDefsKeys.includes(markDef._key)) {
273
+ const newKey = context.keyGenerator()
274
+ markDefKeyMap.set(markDef._key, newKey)
275
+ return {
276
+ ...markDef,
277
+ _key: newKey,
278
+ }
279
+ }
230
280
 
231
- if (isEqualToEmptyEditor([endBlock], context.schema)) {
232
- const currentSelection = editor.selection
281
+ return markDef
282
+ })
233
283
 
234
- Transforms.insertNodes(editor, [block], {
235
- at: endBlockPath,
236
- select: false,
237
- })
238
- Transforms.removeNodes(editor, {at: Path.next(endBlockPath)})
284
+ // Assign new keys to spans with duplicate keys and update any markDef
285
+ // key if needed
286
+ const adjustedChildren = block.children.map((child) => {
287
+ if (isSpan(context, child)) {
288
+ const marks =
289
+ child.marks?.map((mark) => {
290
+ const markDefKey = markDefKeyMap.get(mark)
239
291
 
240
- if (select === 'start') {
241
- Transforms.select(editor, selectionStartPoint)
242
- } else if (select === 'end') {
243
- Transforms.select(editor, Editor.end(editor, endBlockPath))
244
- } else {
245
- Transforms.select(editor, currentSelection)
246
- }
292
+ if (markDefKey) {
293
+ return markDefKey
294
+ }
247
295
 
248
- return
249
- }
296
+ return mark
297
+ }) ?? []
250
298
 
251
- const endBlockChildKeys = endBlock.children.map((child) => child._key)
252
- const endBlockMarkDefsKeys =
253
- endBlock.markDefs?.map((markDef) => markDef._key) ?? []
254
-
255
- // Assign new keys to markDefs with duplicate keys and keep track of
256
- // the mapping between the old and new keys
257
- const markDefKeyMap = new Map<string, string>()
258
- const adjustedMarkDefs = block.markDefs?.map((markDef) => {
259
- if (endBlockMarkDefsKeys.includes(markDef._key)) {
260
- const newKey = context.keyGenerator()
261
- markDefKeyMap.set(markDef._key, newKey)
299
+ if (!isEqual(child.marks, marks)) {
262
300
  return {
263
- ...markDef,
264
- _key: newKey,
301
+ ...child,
302
+ _key: endBlockChildKeys.includes(child._key)
303
+ ? context.keyGenerator()
304
+ : child._key,
305
+ marks,
265
306
  }
266
307
  }
308
+ }
267
309
 
268
- return markDef
269
- })
270
-
271
- // Assign new keys to spans with duplicate keys and update any markDef
272
- // key if needed
273
- const adjustedChildren = block.children.map((child) => {
274
- if (isSpan(context, child)) {
275
- const marks =
276
- child.marks?.map((mark) => {
277
- const markDefKey = markDefKeyMap.get(mark)
278
-
279
- if (markDefKey) {
280
- return markDefKey
281
- }
282
-
283
- return mark
284
- }) ?? []
285
-
286
- if (!isEqual(child.marks, marks)) {
287
- return {
288
- ...child,
289
- _key: endBlockChildKeys.includes(child._key)
290
- ? context.keyGenerator()
291
- : child._key,
292
- marks,
293
- }
294
- }
310
+ if (endBlockChildKeys.includes(child._key)) {
311
+ return {
312
+ ...child,
313
+ _key: context.keyGenerator(),
295
314
  }
315
+ }
296
316
 
297
- if (endBlockChildKeys.includes(child._key)) {
298
- return {
299
- ...child,
300
- _key: context.keyGenerator(),
301
- }
317
+ return child
318
+ })
319
+
320
+ // Carry over the markDefs from the incoming block to the end block
321
+ Transforms.setNodes(
322
+ editor,
323
+ {
324
+ markDefs: [...(endBlock.markDefs ?? []), ...(adjustedMarkDefs ?? [])],
325
+ },
326
+ {
327
+ at: endBlockPath,
328
+ },
329
+ )
330
+
331
+ // If the children have changed, we need to create a new block with
332
+ // the adjusted children
333
+ const adjustedBlock = !isEqual(block.children, adjustedChildren)
334
+ ? {
335
+ ...block,
336
+ children: adjustedChildren as Descendant[],
302
337
  }
338
+ : block
303
339
 
304
- return child
340
+ if (select === 'end') {
341
+ Transforms.insertFragment(editor, [adjustedBlock], {
342
+ voids: true,
305
343
  })
306
344
 
307
- // Carry over the markDefs from the incoming block to the end block
308
- Transforms.setNodes(
309
- editor,
310
- {
311
- markDefs: [
312
- ...(endBlock.markDefs ?? []),
313
- ...(adjustedMarkDefs ?? []),
314
- ],
315
- },
316
- {
317
- at: endBlockPath,
318
- },
319
- )
320
-
321
- // If the children have changed, we need to create a new block with
322
- // the adjusted children
323
- const adjustedBlock = !isEqual(block.children, adjustedChildren)
324
- ? {
325
- ...block,
326
- children: adjustedChildren as Descendant[],
327
- }
328
- : block
345
+ return
346
+ }
329
347
 
330
- if (select === 'end') {
331
- Transforms.insertFragment(editor, [adjustedBlock], {
332
- voids: true,
333
- })
348
+ Transforms.insertFragment(editor, [adjustedBlock], {
349
+ at,
350
+ voids: true,
351
+ })
334
352
 
335
- return
353
+ if (select === 'start') {
354
+ Transforms.select(editor, selectionStartPoint)
355
+ } else {
356
+ if (!Point.equals(selectionStartPoint, endBlockEndPoint)) {
357
+ Transforms.select(editor, selectionStartPoint)
336
358
  }
359
+ }
360
+ } else {
361
+ if (!editor.isTextBlock(endBlock)) {
362
+ Transforms.insertNodes(editor, [block], {select: false})
337
363
 
338
- Transforms.insertFragment(editor, [adjustedBlock], {
339
- at: currentSelection,
340
- voids: true,
341
- })
364
+ const nextPath = [endBlockPath[0] + 1]
342
365
 
343
366
  if (select === 'start') {
344
- Transforms.select(editor, selectionStartPoint)
345
- } else {
346
- if (!Point.equals(selectionStartPoint, endBlockEndPoint)) {
347
- Transforms.select(editor, selectionStartPoint)
348
- }
367
+ Transforms.select(editor, Editor.start(editor, nextPath))
368
+ } else if (select === 'end') {
369
+ Transforms.select(editor, Editor.end(editor, nextPath))
349
370
  }
350
371
  } else {
351
- if (!editor.isTextBlock(endBlock)) {
352
- Transforms.insertNodes(editor, [block], {select: false})
372
+ const endBlockStartPoint = Editor.start(editor, endBlockPath)
373
+ const endBlockEndPoint = Editor.end(editor, endBlockPath)
374
+ const selectionStartPoint = Range.start(at)
375
+ const selectionEndPoint = Range.end(at)
376
+
377
+ if (
378
+ Range.isCollapsed(at) &&
379
+ Point.equals(selectionStartPoint, endBlockStartPoint)
380
+ ) {
381
+ Transforms.insertNodes(editor, [block], {
382
+ at: endBlockPath,
383
+ select: false,
384
+ })
385
+
386
+ if (select === 'start' || select === 'end') {
387
+ Transforms.select(editor, Editor.start(editor, endBlockPath))
388
+ }
353
389
 
390
+ if (isEmptyTextBlock(context, endBlock)) {
391
+ Transforms.removeNodes(editor, {at: Path.next(endBlockPath)})
392
+ }
393
+ } else if (
394
+ Range.isCollapsed(at) &&
395
+ Point.equals(selectionEndPoint, endBlockEndPoint)
396
+ ) {
354
397
  const nextPath = [endBlockPath[0] + 1]
355
398
 
356
- if (select === 'start') {
399
+ Transforms.insertNodes(editor, [block], {
400
+ at: nextPath,
401
+ select: false,
402
+ })
403
+
404
+ if (select === 'start' || select === 'end') {
357
405
  Transforms.select(editor, Editor.start(editor, nextPath))
358
- } else if (select === 'end') {
359
- Transforms.select(editor, Editor.end(editor, nextPath))
360
406
  }
361
- } else {
362
- const endBlockStartPoint = Editor.start(editor, endBlockPath)
363
- const endBlockEndPoint = Editor.end(editor, endBlockPath)
364
- const selectionStartPoint = Range.start(currentSelection)
365
- const selectionEndPoint = Range.end(currentSelection)
366
-
367
- if (
368
- Range.isCollapsed(currentSelection) &&
369
- Point.equals(selectionStartPoint, endBlockStartPoint)
370
- ) {
371
- Transforms.insertNodes(editor, [block], {
372
- at: endBlockPath,
373
- select: false,
374
- })
407
+ } else if (
408
+ Range.isExpanded(at) &&
409
+ Point.equals(selectionStartPoint, endBlockStartPoint) &&
410
+ Point.equals(selectionEndPoint, endBlockEndPoint)
411
+ ) {
412
+ Transforms.insertFragment(editor, [block], {
413
+ at,
414
+ })
375
415
 
376
- if (select === 'start' || select === 'end') {
377
- Transforms.select(editor, Editor.start(editor, endBlockPath))
378
- }
416
+ if (select === 'start') {
417
+ Transforms.select(editor, Editor.start(editor, endBlockPath))
418
+ } else if (select === 'end') {
419
+ Transforms.select(editor, Editor.end(editor, endBlockPath))
420
+ }
421
+ } else if (
422
+ Range.isExpanded(at) &&
423
+ Point.equals(selectionStartPoint, endBlockStartPoint)
424
+ ) {
425
+ Transforms.insertFragment(editor, [block], {
426
+ at,
427
+ })
379
428
 
380
- if (isEmptyTextBlock(context, endBlock)) {
381
- Transforms.removeNodes(editor, {at: Path.next(endBlockPath)})
382
- }
383
- } else if (
384
- Range.isCollapsed(currentSelection) &&
385
- Point.equals(selectionEndPoint, endBlockEndPoint)
386
- ) {
387
- const nextPath = [endBlockPath[0] + 1]
429
+ if (select === 'start') {
430
+ Transforms.select(editor, Editor.start(editor, endBlockPath))
431
+ } else if (select === 'end') {
432
+ Transforms.select(editor, Editor.end(editor, endBlockPath))
433
+ }
434
+ } else if (
435
+ Range.isExpanded(at) &&
436
+ Point.equals(selectionEndPoint, endBlockEndPoint)
437
+ ) {
438
+ Transforms.insertFragment(editor, [block], {
439
+ at,
440
+ })
388
441
 
389
- Transforms.insertNodes(editor, [block], {
390
- at: nextPath,
391
- select: false,
392
- })
442
+ if (select === 'start') {
443
+ Transforms.select(
444
+ editor,
445
+ Editor.start(editor, Path.next(endBlockPath)),
446
+ )
447
+ } else if (select === 'end') {
448
+ Transforms.select(
449
+ editor,
450
+ Editor.end(editor, Path.next(endBlockPath)),
451
+ )
452
+ }
453
+ } else {
454
+ const [focusChild] = getFocusChild({editor})
393
455
 
394
- if (select === 'start' || select === 'end') {
395
- Transforms.select(editor, Editor.start(editor, nextPath))
396
- }
397
- } else if (
398
- Range.isExpanded(currentSelection) &&
399
- Point.equals(selectionStartPoint, endBlockStartPoint) &&
400
- Point.equals(selectionEndPoint, endBlockEndPoint)
401
- ) {
402
- Transforms.insertFragment(editor, [block], {
403
- at: currentSelection,
456
+ if (focusChild && editor.isTextSpan(focusChild)) {
457
+ Transforms.splitNodes(editor, {
458
+ at,
404
459
  })
405
460
 
406
- if (select === 'start') {
407
- Transforms.select(editor, Editor.start(editor, endBlockPath))
408
- } else if (select === 'end') {
409
- Transforms.select(editor, Editor.end(editor, endBlockPath))
410
- }
411
- } else if (
412
- Range.isExpanded(currentSelection) &&
413
- Point.equals(selectionStartPoint, endBlockStartPoint)
414
- ) {
415
461
  Transforms.insertFragment(editor, [block], {
416
- at: currentSelection,
462
+ at,
417
463
  })
418
464
 
419
- if (select === 'start') {
420
- Transforms.select(editor, Editor.start(editor, endBlockPath))
421
- } else if (select === 'end') {
422
- Transforms.select(editor, Editor.end(editor, endBlockPath))
465
+ if (select === 'start' || select === 'end') {
466
+ Transforms.select(editor, [endBlockPath[0] + 1])
467
+ } else {
468
+ Transforms.select(editor, at)
423
469
  }
424
- } else if (
425
- Range.isExpanded(currentSelection) &&
426
- Point.equals(selectionEndPoint, endBlockEndPoint)
427
- ) {
428
- Transforms.insertFragment(editor, [block], {
429
- at: currentSelection,
470
+ } else {
471
+ const nextPath = [endBlockPath[0] + 1]
472
+ Transforms.insertNodes(editor, [block], {
473
+ at: nextPath,
474
+ select: false,
430
475
  })
476
+ Transforms.select(editor, at)
431
477
 
432
478
  if (select === 'start') {
433
- Transforms.select(
434
- editor,
435
- Editor.start(editor, Path.next(endBlockPath)),
436
- )
479
+ Transforms.select(editor, Editor.start(editor, nextPath))
437
480
  } else if (select === 'end') {
438
- Transforms.select(
439
- editor,
440
- Editor.end(editor, Path.next(endBlockPath)),
441
- )
442
- }
443
- } else {
444
- const currentSelection = editor.selection
445
- const [focusChild] = getFocusChild({editor})
446
-
447
- if (focusChild && editor.isTextSpan(focusChild)) {
448
- Transforms.splitNodes(editor, {
449
- at: currentSelection,
450
- })
451
-
452
- Transforms.insertFragment(editor, [block], {
453
- at: currentSelection,
454
- })
455
-
456
- if (select === 'start' || select === 'end') {
457
- Transforms.select(editor, [endBlockPath[0] + 1])
458
- } else {
459
- Transforms.select(editor, currentSelection)
460
- }
461
- } else {
462
- const nextPath = [endBlockPath[0] + 1]
463
- Transforms.insertNodes(editor, [block], {
464
- at: nextPath,
465
- select: false,
466
- })
467
- Transforms.select(editor, currentSelection)
468
-
469
- if (select === 'start') {
470
- Transforms.select(editor, Editor.start(editor, nextPath))
471
- } else if (select === 'end') {
472
- Transforms.select(editor, Editor.end(editor, nextPath))
473
- }
481
+ Transforms.select(editor, Editor.end(editor, nextPath))
474
482
  }
475
483
  }
476
484
  }