@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.
- package/lib/_chunks-dts/index.d.ts +8 -24
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js +2 -91
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +78 -2
- package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
- package/lib/_chunks-es/util.slice-text-block.js +1 -18
- package/lib/_chunks-es/util.slice-text-block.js.map +1 -1
- package/lib/index.js +128 -221
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.js +1 -2
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.d.ts +2 -0
- package/lib/selectors/index.js +92 -4
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.js +18 -3
- package/lib/utils/index.js.map +1 -1
- package/package.json +8 -8
- package/src/behaviors/behavior.abstract.decorator.ts +2 -10
- package/src/behaviors/behavior.abstract.delete.ts +1 -30
- package/src/behaviors/behavior.types.event.ts +4 -10
- package/src/operations/behavior.operation.decorator.add.ts +38 -131
- package/src/operations/behavior.operation.insert.block.ts +315 -307
- package/src/selectors/selector.get-trimmed-selection.ts +2 -0
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js +0 -81
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js.map +0 -1
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
|
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
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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:
|
|
126
|
+
Transforms.removeNodes(editor, {at: endBlockPath})
|
|
107
127
|
|
|
108
128
|
Transforms.insertNodes(editor, [block], {
|
|
109
|
-
at:
|
|
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,
|
|
136
|
+
Transforms.select(editor, Editor.start(editor, endBlockPath))
|
|
117
137
|
} else if (select === 'end') {
|
|
118
|
-
Transforms.select(editor, Editor.end(editor,
|
|
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
|
-
|
|
127
|
-
editor.isTextBlock(
|
|
146
|
+
endBlock &&
|
|
147
|
+
editor.isTextBlock(endBlock)
|
|
128
148
|
) {
|
|
129
|
-
const selectionBefore = Editor.end(editor,
|
|
149
|
+
const selectionBefore = Editor.end(editor, endBlockPath)
|
|
130
150
|
|
|
131
151
|
Transforms.insertFragment(editor, [block], {
|
|
132
|
-
at: Editor.end(editor,
|
|
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 =
|
|
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
|
-
|
|
156
|
-
const currentSelection = editor.selection
|
|
157
|
-
const selectionStartPoint = Range.start(currentSelection)
|
|
207
|
+
// placement === 'auto'
|
|
158
208
|
|
|
159
|
-
|
|
160
|
-
at: [selectionStartPoint.path[0]],
|
|
161
|
-
select: false,
|
|
162
|
-
})
|
|
209
|
+
const endBlockEndPoint = Editor.start(editor, endBlockPath)
|
|
163
210
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
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
|
-
|
|
183
|
-
|
|
225
|
+
voids: true,
|
|
226
|
+
at: atAfterDelete ?? undefined,
|
|
227
|
+
select: select !== 'none',
|
|
184
228
|
})
|
|
185
229
|
|
|
186
|
-
|
|
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
|
-
|
|
195
|
-
|
|
232
|
+
if (select === 'none' && atAfterInsert) {
|
|
233
|
+
Transforms.select(editor, atAfterInsert)
|
|
234
|
+
}
|
|
196
235
|
|
|
197
|
-
if (
|
|
198
|
-
Transforms.
|
|
236
|
+
if (focusBlock && isEqualToEmptyEditor([focusBlock], context.schema)) {
|
|
237
|
+
Transforms.removeNodes(editor, {at: focusBlockPath})
|
|
238
|
+
}
|
|
199
239
|
|
|
200
|
-
|
|
240
|
+
return
|
|
241
|
+
}
|
|
201
242
|
|
|
202
|
-
|
|
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
|
-
|
|
248
|
+
at: endBlockPath,
|
|
249
|
+
select: false,
|
|
206
250
|
})
|
|
251
|
+
Transforms.removeNodes(editor, {at: Path.next(endBlockPath)})
|
|
207
252
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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
|
-
|
|
232
|
-
|
|
281
|
+
return markDef
|
|
282
|
+
})
|
|
233
283
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
249
|
-
|
|
296
|
+
return mark
|
|
297
|
+
}) ?? []
|
|
250
298
|
|
|
251
|
-
|
|
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
|
-
...
|
|
264
|
-
_key:
|
|
301
|
+
...child,
|
|
302
|
+
_key: endBlockChildKeys.includes(child._key)
|
|
303
|
+
? context.keyGenerator()
|
|
304
|
+
: child._key,
|
|
305
|
+
marks,
|
|
265
306
|
}
|
|
266
307
|
}
|
|
308
|
+
}
|
|
267
309
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
-
|
|
340
|
+
if (select === 'end') {
|
|
341
|
+
Transforms.insertFragment(editor, [adjustedBlock], {
|
|
342
|
+
voids: true,
|
|
305
343
|
})
|
|
306
344
|
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
348
|
+
Transforms.insertFragment(editor, [adjustedBlock], {
|
|
349
|
+
at,
|
|
350
|
+
voids: true,
|
|
351
|
+
})
|
|
334
352
|
|
|
335
|
-
|
|
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
|
-
|
|
339
|
-
at: currentSelection,
|
|
340
|
-
voids: true,
|
|
341
|
-
})
|
|
364
|
+
const nextPath = [endBlockPath[0] + 1]
|
|
342
365
|
|
|
343
366
|
if (select === 'start') {
|
|
344
|
-
Transforms.select(editor,
|
|
345
|
-
} else {
|
|
346
|
-
|
|
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
|
-
|
|
352
|
-
|
|
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
|
-
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
377
|
-
|
|
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
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
)
|
|
387
|
-
|
|
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
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
-
|
|
395
|
-
|
|
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
|
|
462
|
+
at,
|
|
417
463
|
})
|
|
418
464
|
|
|
419
|
-
if (select === 'start') {
|
|
420
|
-
Transforms.select(editor,
|
|
421
|
-
} else
|
|
422
|
-
Transforms.select(editor,
|
|
465
|
+
if (select === 'start' || select === 'end') {
|
|
466
|
+
Transforms.select(editor, [endBlockPath[0] + 1])
|
|
467
|
+
} else {
|
|
468
|
+
Transforms.select(editor, at)
|
|
423
469
|
}
|
|
424
|
-
} else
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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
|
}
|