@portabletext/editor 1.0.18 → 1.1.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/index.d.mts +140 -66
- package/lib/index.d.ts +140 -66
- package/lib/index.esm.js +1164 -410
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1164 -410
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1164 -410
- package/lib/index.mjs.map +1 -1
- package/package.json +8 -4
- package/src/editor/Editable.tsx +107 -36
- package/src/editor/PortableTextEditor.tsx +47 -12
- package/src/editor/__tests__/PortableTextEditor.test.tsx +42 -15
- package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
- package/src/editor/__tests__/RangeDecorations.test.tsx +0 -1
- package/src/editor/__tests__/handleClick.test.tsx +28 -9
- package/src/editor/__tests__/insert-block.test.tsx +22 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +30 -62
- package/src/editor/__tests__/utils.ts +10 -3
- package/src/editor/components/DraggableBlock.tsx +36 -13
- package/src/editor/components/Element.tsx +59 -17
- package/src/editor/components/Leaf.tsx +106 -68
- package/src/editor/components/SlateContainer.tsx +12 -5
- package/src/editor/components/Synchronizer.tsx +5 -2
- package/src/editor/hooks/usePortableTextEditor.ts +2 -2
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +9 -3
- package/src/editor/hooks/useSyncValue.test.tsx +9 -4
- package/src/editor/hooks/useSyncValue.ts +199 -130
- package/src/editor/nodes/DefaultAnnotation.tsx +6 -3
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +25 -7
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -550
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
- package/src/editor/plugins/createWithEditableAPI.ts +354 -115
- package/src/editor/plugins/createWithHotKeys.ts +41 -121
- package/src/editor/plugins/createWithInsertBreak.ts +166 -27
- package/src/editor/plugins/createWithInsertData.ts +60 -23
- package/src/editor/plugins/createWithMaxBlocks.ts +5 -2
- package/src/editor/plugins/createWithObjectKeys.ts +7 -3
- package/src/editor/plugins/createWithPatches.ts +60 -16
- package/src/editor/plugins/createWithPlaceholderBlock.ts +7 -3
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
- package/src/editor/plugins/createWithPortableTextLists.ts +21 -8
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +301 -155
- package/src/editor/plugins/createWithPortableTextSelections.ts +4 -2
- package/src/editor/plugins/createWithSchemaTypes.ts +25 -9
- package/src/editor/plugins/createWithUndoRedo.ts +107 -24
- package/src/editor/plugins/createWithUtils.ts +32 -10
- package/src/editor/plugins/index.ts +31 -10
- package/src/types/editor.ts +44 -15
- package/src/types/options.ts +4 -2
- package/src/types/slate.ts +2 -2
- package/src/utils/__tests__/dmpToOperations.test.ts +38 -13
- package/src/utils/__tests__/operationToPatches.test.ts +3 -2
- package/src/utils/__tests__/patchToOperations.test.ts +15 -4
- package/src/utils/__tests__/ranges.test.ts +8 -3
- package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
- package/src/utils/__tests__/values.test.ts +0 -1
- package/src/utils/applyPatch.ts +71 -20
- package/src/utils/getPortableTextMemberSchemaTypes.ts +30 -15
- package/src/utils/operationToPatches.ts +126 -43
- package/src/utils/paths.ts +24 -7
- package/src/utils/ranges.ts +12 -5
- package/src/utils/selection.ts +19 -7
- package/src/utils/validateValue.ts +118 -45
- package/src/utils/values.ts +31 -10
- package/src/utils/weakMaps.ts +18 -8
- package/src/utils/withChanges.ts +4 -2
- package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
- package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
- package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
type PortableTextTextBlock,
|
|
7
7
|
} from '@sanity/types'
|
|
8
8
|
import {flatten, isPlainObject, uniq} from 'lodash'
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
type InvalidValueResolution,
|
|
11
|
+
type PortableTextMemberSchemaTypes,
|
|
12
|
+
} from '../types/editor'
|
|
11
13
|
import {EMPTY_MARKDEFS} from './values'
|
|
12
14
|
|
|
13
15
|
export interface Validation {
|
|
@@ -23,8 +25,14 @@ export function validateValue(
|
|
|
23
25
|
): Validation {
|
|
24
26
|
let resolution: InvalidValueResolution | null = null
|
|
25
27
|
let valid = true
|
|
26
|
-
const validChildTypes = [
|
|
27
|
-
|
|
28
|
+
const validChildTypes = [
|
|
29
|
+
types.span.name,
|
|
30
|
+
...types.inlineObjects.map((t) => t.name),
|
|
31
|
+
]
|
|
32
|
+
const validBlockTypes = [
|
|
33
|
+
types.block.name,
|
|
34
|
+
...types.blockObjects.map((t) => t.name),
|
|
35
|
+
]
|
|
28
36
|
|
|
29
37
|
// Undefined is allowed
|
|
30
38
|
if (value === undefined) {
|
|
@@ -36,12 +44,14 @@ export function validateValue(
|
|
|
36
44
|
valid: false,
|
|
37
45
|
resolution: {
|
|
38
46
|
patches: [unset([])],
|
|
39
|
-
description:
|
|
47
|
+
description:
|
|
48
|
+
'Editor value must be an array of Portable Text blocks, or undefined.',
|
|
40
49
|
action: 'Unset the value',
|
|
41
50
|
item: value,
|
|
42
51
|
|
|
43
52
|
i18n: {
|
|
44
|
-
description:
|
|
53
|
+
description:
|
|
54
|
+
'inputs.portable-text.invalid-value.not-an-array.description',
|
|
45
55
|
action: 'inputs.portable-text.invalid-value.not-an-array.action',
|
|
46
56
|
},
|
|
47
57
|
},
|
|
@@ -59,7 +69,8 @@ export function validateValue(
|
|
|
59
69
|
item: blk,
|
|
60
70
|
|
|
61
71
|
i18n: {
|
|
62
|
-
description:
|
|
72
|
+
description:
|
|
73
|
+
'inputs.portable-text.invalid-value.not-an-object.description',
|
|
63
74
|
action: 'inputs.portable-text.invalid-value.not-an-object.action',
|
|
64
75
|
values: {index},
|
|
65
76
|
},
|
|
@@ -75,7 +86,8 @@ export function validateValue(
|
|
|
75
86
|
item: blk,
|
|
76
87
|
|
|
77
88
|
i18n: {
|
|
78
|
-
description:
|
|
89
|
+
description:
|
|
90
|
+
'inputs.portable-text.invalid-value.missing-key.description',
|
|
79
91
|
action: 'inputs.portable-text.invalid-value.missing-key.action',
|
|
80
92
|
values: {index},
|
|
81
93
|
},
|
|
@@ -88,14 +100,18 @@ export function validateValue(
|
|
|
88
100
|
if (blk._type === 'block') {
|
|
89
101
|
const currentBlockTypeName = types.block.name
|
|
90
102
|
resolution = {
|
|
91
|
-
patches: [
|
|
103
|
+
patches: [
|
|
104
|
+
set({...blk, _type: currentBlockTypeName}, [{_key: blk._key}]),
|
|
105
|
+
],
|
|
92
106
|
description: `Block with _key '${blk._key}' has invalid type name '${blk._type}'. According to the schema, the block type name is '${currentBlockTypeName}'`,
|
|
93
107
|
action: `Use type '${currentBlockTypeName}'`,
|
|
94
108
|
item: blk,
|
|
95
109
|
|
|
96
110
|
i18n: {
|
|
97
|
-
description:
|
|
98
|
-
|
|
111
|
+
description:
|
|
112
|
+
'inputs.portable-text.invalid-value.incorrect-block-type.description',
|
|
113
|
+
action:
|
|
114
|
+
'inputs.portable-text.invalid-value.incorrect-block-type.action',
|
|
99
115
|
values: {key: blk._key, expectedTypeName: currentBlockTypeName},
|
|
100
116
|
},
|
|
101
117
|
}
|
|
@@ -103,16 +119,23 @@ export function validateValue(
|
|
|
103
119
|
}
|
|
104
120
|
|
|
105
121
|
// If the block has no `_type`, but aside from that is a valid Portable Text block
|
|
106
|
-
if (
|
|
122
|
+
if (
|
|
123
|
+
!blk._type &&
|
|
124
|
+
isPortableTextTextBlock({...blk, _type: types.block.name})
|
|
125
|
+
) {
|
|
107
126
|
resolution = {
|
|
108
|
-
patches: [
|
|
127
|
+
patches: [
|
|
128
|
+
set({...blk, _type: types.block.name}, [{_key: blk._key}]),
|
|
129
|
+
],
|
|
109
130
|
description: `Block with _key '${blk._key}' is missing a type name. According to the schema, the block type name is '${types.block.name}'`,
|
|
110
131
|
action: `Use type '${types.block.name}'`,
|
|
111
132
|
item: blk,
|
|
112
133
|
|
|
113
134
|
i18n: {
|
|
114
|
-
description:
|
|
115
|
-
|
|
135
|
+
description:
|
|
136
|
+
'inputs.portable-text.invalid-value.missing-block-type.description',
|
|
137
|
+
action:
|
|
138
|
+
'inputs.portable-text.invalid-value.missing-block-type.action',
|
|
116
139
|
values: {key: blk._key, expectedTypeName: types.block.name},
|
|
117
140
|
},
|
|
118
141
|
}
|
|
@@ -127,7 +150,8 @@ export function validateValue(
|
|
|
127
150
|
item: blk,
|
|
128
151
|
|
|
129
152
|
i18n: {
|
|
130
|
-
description:
|
|
153
|
+
description:
|
|
154
|
+
'inputs.portable-text.invalid-value.missing-type.description',
|
|
131
155
|
action: 'inputs.portable-text.invalid-value.missing-type.action',
|
|
132
156
|
values: {key: blk._key},
|
|
133
157
|
},
|
|
@@ -142,7 +166,8 @@ export function validateValue(
|
|
|
142
166
|
item: blk,
|
|
143
167
|
|
|
144
168
|
i18n: {
|
|
145
|
-
description:
|
|
169
|
+
description:
|
|
170
|
+
'inputs.portable-text.invalid-value.disallowed-type.description',
|
|
146
171
|
action: 'inputs.portable-text.invalid-value.disallowed-type.action',
|
|
147
172
|
values: {key: blk._key, typeName: blk._type},
|
|
148
173
|
},
|
|
@@ -164,7 +189,8 @@ export function validateValue(
|
|
|
164
189
|
i18n: {
|
|
165
190
|
description:
|
|
166
191
|
'inputs.portable-text.invalid-value.missing-or-invalid-children.description',
|
|
167
|
-
action:
|
|
192
|
+
action:
|
|
193
|
+
'inputs.portable-text.invalid-value.missing-or-invalid-children.action',
|
|
168
194
|
values: {key: textBlock._key},
|
|
169
195
|
},
|
|
170
196
|
}
|
|
@@ -192,8 +218,10 @@ export function validateValue(
|
|
|
192
218
|
item: blk,
|
|
193
219
|
|
|
194
220
|
i18n: {
|
|
195
|
-
description:
|
|
196
|
-
|
|
221
|
+
description:
|
|
222
|
+
'inputs.portable-text.invalid-value.empty-children.description',
|
|
223
|
+
action:
|
|
224
|
+
'inputs.portable-text.invalid-value.empty-children.action',
|
|
197
225
|
values: {key: blk._key},
|
|
198
226
|
},
|
|
199
227
|
}
|
|
@@ -202,7 +230,11 @@ export function validateValue(
|
|
|
202
230
|
// Test that markDefs are valid if they exists
|
|
203
231
|
if (blk.markDefs && !Array.isArray(blk.markDefs)) {
|
|
204
232
|
resolution = {
|
|
205
|
-
patches: [
|
|
233
|
+
patches: [
|
|
234
|
+
set({...textBlock, markDefs: EMPTY_MARKDEFS}, [
|
|
235
|
+
{_key: textBlock._key},
|
|
236
|
+
]),
|
|
237
|
+
],
|
|
206
238
|
description: `Block has invalid required property 'markDefs'.`,
|
|
207
239
|
action: 'Add empty markDefs array',
|
|
208
240
|
item: textBlock,
|
|
@@ -210,7 +242,8 @@ export function validateValue(
|
|
|
210
242
|
i18n: {
|
|
211
243
|
description:
|
|
212
244
|
'inputs.portable-text.invalid-value.missing-or-invalid-markdefs.description',
|
|
213
|
-
action:
|
|
245
|
+
action:
|
|
246
|
+
'inputs.portable-text.invalid-value.missing-or-invalid-markdefs.action',
|
|
214
247
|
values: {key: textBlock._key},
|
|
215
248
|
},
|
|
216
249
|
}
|
|
@@ -227,7 +260,9 @@ export function validateValue(
|
|
|
227
260
|
// Test that all markDefs are in use (remove orphaned markDefs)
|
|
228
261
|
if (Array.isArray(blk.markDefs) && blk.markDefs.length > 0) {
|
|
229
262
|
const unusedMarkDefs: string[] = uniq(
|
|
230
|
-
blk.markDefs
|
|
263
|
+
blk.markDefs
|
|
264
|
+
.map((def) => def._key)
|
|
265
|
+
.filter((key) => !allUsedMarks.includes(key)),
|
|
231
266
|
)
|
|
232
267
|
if (unusedMarkDefs.length > 0) {
|
|
233
268
|
resolution = {
|
|
@@ -241,9 +276,14 @@ export function validateValue(
|
|
|
241
276
|
action: 'Remove unused mark definition item',
|
|
242
277
|
item: blk,
|
|
243
278
|
i18n: {
|
|
244
|
-
description:
|
|
245
|
-
|
|
246
|
-
|
|
279
|
+
description:
|
|
280
|
+
'inputs.portable-text.invalid-value.orphaned-mark-defs.description',
|
|
281
|
+
action:
|
|
282
|
+
'inputs.portable-text.invalid-value.orphaned-mark-defs.action',
|
|
283
|
+
values: {
|
|
284
|
+
key: blk._key,
|
|
285
|
+
unusedMarkDefs: unusedMarkDefs.map((m) => m.toString()),
|
|
286
|
+
},
|
|
247
287
|
},
|
|
248
288
|
}
|
|
249
289
|
return true
|
|
@@ -272,7 +312,9 @@ export function validateValue(
|
|
|
272
312
|
autoResolve: true,
|
|
273
313
|
patches: spanChildren.map((child) => {
|
|
274
314
|
return set(
|
|
275
|
-
(child.marks || []).filter(
|
|
315
|
+
(child.marks || []).filter(
|
|
316
|
+
(cMrk) => !orphanedMarks.includes(cMrk),
|
|
317
|
+
),
|
|
276
318
|
[{_key: blk._key}, 'children', {_key: child._key}, 'marks'],
|
|
277
319
|
)
|
|
278
320
|
}),
|
|
@@ -281,9 +323,14 @@ export function validateValue(
|
|
|
281
323
|
item: blk,
|
|
282
324
|
|
|
283
325
|
i18n: {
|
|
284
|
-
description:
|
|
285
|
-
|
|
286
|
-
|
|
326
|
+
description:
|
|
327
|
+
'inputs.portable-text.invalid-value.orphaned-marks.description',
|
|
328
|
+
action:
|
|
329
|
+
'inputs.portable-text.invalid-value.orphaned-marks.action',
|
|
330
|
+
values: {
|
|
331
|
+
key: blk._key,
|
|
332
|
+
orphanedMarks: orphanedMarks.map((m) => m.toString()),
|
|
333
|
+
},
|
|
287
334
|
},
|
|
288
335
|
}
|
|
289
336
|
return true
|
|
@@ -301,8 +348,10 @@ export function validateValue(
|
|
|
301
348
|
item: blk,
|
|
302
349
|
|
|
303
350
|
i18n: {
|
|
304
|
-
description:
|
|
305
|
-
|
|
351
|
+
description:
|
|
352
|
+
'inputs.portable-text.invalid-value.non-object-child.description',
|
|
353
|
+
action:
|
|
354
|
+
'inputs.portable-text.invalid-value.non-object-child.action',
|
|
306
355
|
values: {key: blk._key, index: cIndex},
|
|
307
356
|
},
|
|
308
357
|
}
|
|
@@ -313,14 +362,18 @@ export function validateValue(
|
|
|
313
362
|
const newChild = {...child, _key: keyGenerator()}
|
|
314
363
|
resolution = {
|
|
315
364
|
autoResolve: true,
|
|
316
|
-
patches: [
|
|
365
|
+
patches: [
|
|
366
|
+
set(newChild, [{_key: blk._key}, 'children', cIndex]),
|
|
367
|
+
],
|
|
317
368
|
description: `Child at index ${cIndex} is missing required _key in block with _key ${blk._key}.`,
|
|
318
369
|
action: 'Set a new random _key on the object',
|
|
319
370
|
item: blk,
|
|
320
371
|
|
|
321
372
|
i18n: {
|
|
322
|
-
description:
|
|
323
|
-
|
|
373
|
+
description:
|
|
374
|
+
'inputs.portable-text.invalid-value.missing-child-key.description',
|
|
375
|
+
action:
|
|
376
|
+
'inputs.portable-text.invalid-value.missing-child-key.action',
|
|
324
377
|
values: {key: blk._key, index: cIndex},
|
|
325
378
|
},
|
|
326
379
|
}
|
|
@@ -330,14 +383,18 @@ export function validateValue(
|
|
|
330
383
|
// Verify that children have valid types
|
|
331
384
|
if (!child._type) {
|
|
332
385
|
resolution = {
|
|
333
|
-
patches: [
|
|
386
|
+
patches: [
|
|
387
|
+
unset([{_key: blk._key}, 'children', {_key: child._key}]),
|
|
388
|
+
],
|
|
334
389
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' is missing '_type' property.`,
|
|
335
390
|
action: 'Remove the object',
|
|
336
391
|
item: blk,
|
|
337
392
|
|
|
338
393
|
i18n: {
|
|
339
|
-
description:
|
|
340
|
-
|
|
394
|
+
description:
|
|
395
|
+
'inputs.portable-text.invalid-value.missing-child-type.description',
|
|
396
|
+
action:
|
|
397
|
+
'inputs.portable-text.invalid-value.missing-child-type.action',
|
|
341
398
|
values: {key: blk._key, childKey: child._key},
|
|
342
399
|
},
|
|
343
400
|
}
|
|
@@ -346,7 +403,9 @@ export function validateValue(
|
|
|
346
403
|
|
|
347
404
|
if (!validChildTypes.includes(child._type)) {
|
|
348
405
|
resolution = {
|
|
349
|
-
patches: [
|
|
406
|
+
patches: [
|
|
407
|
+
unset([{_key: blk._key}, 'children', {_key: child._key}]),
|
|
408
|
+
],
|
|
350
409
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has invalid '_type' property (${child._type}).`,
|
|
351
410
|
action: 'Remove the object',
|
|
352
411
|
item: blk,
|
|
@@ -354,26 +413,40 @@ export function validateValue(
|
|
|
354
413
|
i18n: {
|
|
355
414
|
description:
|
|
356
415
|
'inputs.portable-text.invalid-value.disallowed-child-type.description',
|
|
357
|
-
action:
|
|
358
|
-
|
|
416
|
+
action:
|
|
417
|
+
'inputs.portable-text.invalid-value.disallowed-child-type.action',
|
|
418
|
+
values: {
|
|
419
|
+
key: blk._key,
|
|
420
|
+
childKey: child._key,
|
|
421
|
+
childType: child._type,
|
|
422
|
+
},
|
|
359
423
|
},
|
|
360
424
|
}
|
|
361
425
|
return true
|
|
362
426
|
}
|
|
363
427
|
|
|
364
428
|
// Verify that spans have .text property that is a string
|
|
365
|
-
if (
|
|
429
|
+
if (
|
|
430
|
+
child._type === types.span.name &&
|
|
431
|
+
typeof child.text !== 'string'
|
|
432
|
+
) {
|
|
366
433
|
resolution = {
|
|
367
434
|
patches: [
|
|
368
|
-
set({...child, text: ''}, [
|
|
435
|
+
set({...child, text: ''}, [
|
|
436
|
+
{_key: blk._key},
|
|
437
|
+
'children',
|
|
438
|
+
{_key: child._key},
|
|
439
|
+
]),
|
|
369
440
|
],
|
|
370
441
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has missing or invalid text property!`,
|
|
371
442
|
action: `Write an empty text property to the object`,
|
|
372
443
|
item: blk,
|
|
373
444
|
|
|
374
445
|
i18n: {
|
|
375
|
-
description:
|
|
376
|
-
|
|
446
|
+
description:
|
|
447
|
+
'inputs.portable-text.invalid-value.invalid-span-text.description',
|
|
448
|
+
action:
|
|
449
|
+
'inputs.portable-text.invalid-value.invalid-span-text.action',
|
|
377
450
|
values: {key: blk._key, childKey: child._key},
|
|
378
451
|
},
|
|
379
452
|
}
|
package/src/utils/values.ts
CHANGED
|
@@ -6,12 +6,10 @@ import {
|
|
|
6
6
|
type PortableTextTextBlock,
|
|
7
7
|
} from '@sanity/types'
|
|
8
8
|
import {isEqual} from 'lodash'
|
|
9
|
-
import {type Descendant,
|
|
10
|
-
|
|
9
|
+
import {Element, Text, type Descendant, type Node} from 'slate'
|
|
11
10
|
import {type PortableTextMemberSchemaTypes} from '../types/editor'
|
|
12
11
|
|
|
13
12
|
export const EMPTY_MARKDEFS: PortableTextObject[] = []
|
|
14
|
-
export const EMPTY_MARKS: string[] = []
|
|
15
13
|
|
|
16
14
|
export const VOID_CHILD_KEY = 'void-child'
|
|
17
15
|
|
|
@@ -39,7 +37,9 @@ export function toSlateValue(
|
|
|
39
37
|
if (value && Array.isArray(value)) {
|
|
40
38
|
return value.map((block) => {
|
|
41
39
|
const {_type, _key, ...rest} = block
|
|
42
|
-
const voidChildren = [
|
|
40
|
+
const voidChildren = [
|
|
41
|
+
{_key: VOID_CHILD_KEY, _type: 'span', text: '', marks: []},
|
|
42
|
+
]
|
|
43
43
|
const isPortableText = block && block._type === schemaTypes.block.name
|
|
44
44
|
if (isPortableText) {
|
|
45
45
|
const textBlock = block as PortableTextTextBlock
|
|
@@ -112,22 +112,40 @@ export function fromSlateValue(
|
|
|
112
112
|
if (!_key || !_type) {
|
|
113
113
|
throw new Error('Not a valid block')
|
|
114
114
|
}
|
|
115
|
-
if (
|
|
115
|
+
if (
|
|
116
|
+
_type === textBlockType &&
|
|
117
|
+
'children' in block &&
|
|
118
|
+
Array.isArray(block.children) &&
|
|
119
|
+
_key
|
|
120
|
+
) {
|
|
116
121
|
let hasInlines = false
|
|
117
122
|
const children = block.children.map((child) => {
|
|
118
123
|
const {_type: _cType} = child
|
|
119
124
|
if ('value' in child && _cType !== 'span') {
|
|
120
125
|
hasInlines = true
|
|
121
126
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
122
|
-
const {
|
|
123
|
-
|
|
127
|
+
const {
|
|
128
|
+
value: v,
|
|
129
|
+
_key: k,
|
|
130
|
+
_type: t,
|
|
131
|
+
__inline: _i,
|
|
132
|
+
children: _c,
|
|
133
|
+
...rest
|
|
134
|
+
} = child
|
|
135
|
+
return keepObjectEquality(
|
|
136
|
+
{...rest, ...v, _key: k as string, _type: t as string},
|
|
137
|
+
keyMap,
|
|
138
|
+
)
|
|
124
139
|
}
|
|
125
140
|
return child
|
|
126
141
|
})
|
|
127
142
|
if (!hasInlines) {
|
|
128
143
|
return block as PortableTextBlock // Original object
|
|
129
144
|
}
|
|
130
|
-
return keepObjectEquality(
|
|
145
|
+
return keepObjectEquality(
|
|
146
|
+
{...block, children, _key, _type},
|
|
147
|
+
keyMap,
|
|
148
|
+
) as PortableTextBlock
|
|
131
149
|
}
|
|
132
150
|
const blockValue = 'value' in block && block.value
|
|
133
151
|
return keepObjectEquality(
|
|
@@ -171,7 +189,8 @@ export function findBlockAndIndexFromPath(
|
|
|
171
189
|
blockIndex = Number(firstPathSegment)
|
|
172
190
|
} else if (children) {
|
|
173
191
|
blockIndex = children.findIndex(
|
|
174
|
-
(blk) =>
|
|
192
|
+
(blk) =>
|
|
193
|
+
Element.isElement(blk) && isEqual({_key: blk._key}, firstPathSegment),
|
|
175
194
|
)
|
|
176
195
|
}
|
|
177
196
|
if (blockIndex > -1) {
|
|
@@ -189,7 +208,9 @@ export function findChildAndIndexFromPath(
|
|
|
189
208
|
if (isNumber) {
|
|
190
209
|
childIndex = Number(secondPathSegment)
|
|
191
210
|
} else {
|
|
192
|
-
childIndex = block.children.findIndex((child) =>
|
|
211
|
+
childIndex = block.children.findIndex((child) =>
|
|
212
|
+
isEqual({_key: child._key}, secondPathSegment),
|
|
213
|
+
)
|
|
193
214
|
}
|
|
194
215
|
if (childIndex > -1) {
|
|
195
216
|
return [block.children[childIndex] as Element | Text, childIndex]
|
package/src/utils/weakMaps.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {type Editor, type Element, type Range} from 'slate'
|
|
2
|
-
|
|
3
2
|
import {type EditorSelection} from '..'
|
|
4
3
|
|
|
5
4
|
// Is the editor currently receiving remote changes that are being applied to the content?
|
|
6
|
-
export const IS_PROCESSING_REMOTE_CHANGES: WeakMap<Editor, boolean> =
|
|
5
|
+
export const IS_PROCESSING_REMOTE_CHANGES: WeakMap<Editor, boolean> =
|
|
6
|
+
new WeakMap()
|
|
7
7
|
// Is the editor currently producing local changes that are not yet submitted?
|
|
8
|
-
export const IS_PROCESSING_LOCAL_CHANGES: WeakMap<Editor, boolean> =
|
|
8
|
+
export const IS_PROCESSING_LOCAL_CHANGES: WeakMap<Editor, boolean> =
|
|
9
|
+
new WeakMap()
|
|
9
10
|
|
|
10
11
|
// Is the editor dragging something?
|
|
11
12
|
export const IS_DRAGGING: WeakMap<Editor, boolean> = new WeakMap()
|
|
@@ -13,12 +14,21 @@ export const IS_DRAGGING: WeakMap<Editor, boolean> = new WeakMap()
|
|
|
13
14
|
export const IS_DRAGGING_BLOCK_ELEMENT: WeakMap<Editor, Element> = new WeakMap()
|
|
14
15
|
|
|
15
16
|
// When dragging elements, this will be the target element
|
|
16
|
-
export const IS_DRAGGING_ELEMENT_TARGET: WeakMap<Editor, Element> =
|
|
17
|
+
export const IS_DRAGGING_ELEMENT_TARGET: WeakMap<Editor, Element> =
|
|
18
|
+
new WeakMap()
|
|
17
19
|
// Target position for dragging over a block
|
|
18
|
-
export const IS_DRAGGING_BLOCK_TARGET_POSITION: WeakMap<
|
|
20
|
+
export const IS_DRAGGING_BLOCK_TARGET_POSITION: WeakMap<
|
|
21
|
+
Editor,
|
|
22
|
+
'top' | 'bottom'
|
|
23
|
+
> = new WeakMap()
|
|
19
24
|
|
|
20
|
-
export const KEY_TO_SLATE_ELEMENT: WeakMap<Editor, any | undefined> =
|
|
21
|
-
|
|
25
|
+
export const KEY_TO_SLATE_ELEMENT: WeakMap<Editor, any | undefined> =
|
|
26
|
+
new WeakMap()
|
|
27
|
+
export const KEY_TO_VALUE_ELEMENT: WeakMap<Editor, any | undefined> =
|
|
28
|
+
new WeakMap()
|
|
22
29
|
|
|
23
30
|
// Keep object relation to slate range in the portable-text-range
|
|
24
|
-
export const SLATE_TO_PORTABLE_TEXT_RANGE = new WeakMap<
|
|
31
|
+
export const SLATE_TO_PORTABLE_TEXT_RANGE = new WeakMap<
|
|
32
|
+
Range,
|
|
33
|
+
EditorSelection
|
|
34
|
+
>()
|
package/src/utils/withChanges.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {type Editor} from 'slate'
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
IS_PROCESSING_LOCAL_CHANGES,
|
|
4
|
+
IS_PROCESSING_REMOTE_CHANGES,
|
|
5
|
+
} from './weakMaps'
|
|
4
6
|
|
|
5
7
|
export function withRemoteChanges(editor: Editor, fn: () => void): void {
|
|
6
8
|
const prev = isChangingRemotely(editor) || false
|