@portabletext/editor 1.49.0 → 1.49.2
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-cjs/editor-provider.cjs +22 -11
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs +2 -1
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs +26 -8
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/editor-provider.js +22 -11
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +2 -1
- package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js +26 -8
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.cjs +155 -158
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +160 -163
- package/lib/index.js.map +1 -1
- package/package.json +6 -6
- package/src/behaviors/behavior.abstract.split.ts +2 -2
- package/src/converters/converter.portable-text.ts +1 -0
- package/src/converters/converter.text-html.ts +1 -0
- package/src/converters/converter.text-plain.ts +1 -0
- package/src/editor/Editable.tsx +20 -48
- package/src/editor/__tests__/PortableTextEditor.test.tsx +3 -3
- package/src/editor/__tests__/RangeDecorations.test.tsx +2 -2
- package/src/editor/components/render-block-object.tsx +0 -1
- package/src/editor/components/render-element.tsx +3 -3
- package/src/editor/components/render-inline-object.tsx +9 -12
- package/src/editor/components/render-leaf.tsx +64 -0
- package/src/editor/components/render-span.tsx +260 -0
- package/src/editor/components/render-text-block.tsx +0 -1
- package/src/editor/components/render-text.tsx +18 -0
- package/src/internal-utils/parse-blocks.test.ts +20 -20
- package/src/internal-utils/parse-blocks.ts +57 -20
- package/src/operations/behavior.operation.annotation.add.ts +1 -1
- package/src/operations/behavior.operation.block.set.ts +1 -1
- package/src/operations/behavior.operation.block.unset.ts +2 -2
- package/src/operations/behavior.operation.insert-inline-object.ts +1 -1
- package/src/operations/behavior.operation.insert.block.ts +1 -1
- package/src/selectors/selector.get-trimmed-selection.test.ts +1 -0
- package/src/utils/util.merge-text-blocks.ts +1 -1
- package/src/editor/components/Leaf.tsx +0 -336
|
@@ -12,7 +12,7 @@ describe(parseBlock.name, () => {
|
|
|
12
12
|
keyGenerator: createTestKeyGenerator(),
|
|
13
13
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
14
14
|
},
|
|
15
|
-
options: {refreshKeys: false},
|
|
15
|
+
options: {refreshKeys: false, validateFields: true},
|
|
16
16
|
}),
|
|
17
17
|
).toBe(undefined)
|
|
18
18
|
})
|
|
@@ -25,7 +25,7 @@ describe(parseBlock.name, () => {
|
|
|
25
25
|
keyGenerator: createTestKeyGenerator(),
|
|
26
26
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
27
27
|
},
|
|
28
|
-
options: {refreshKeys: false},
|
|
28
|
+
options: {refreshKeys: false, validateFields: true},
|
|
29
29
|
}),
|
|
30
30
|
).toBe(undefined)
|
|
31
31
|
})
|
|
@@ -39,7 +39,7 @@ describe(parseBlock.name, () => {
|
|
|
39
39
|
keyGenerator: createTestKeyGenerator(),
|
|
40
40
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
41
41
|
},
|
|
42
|
-
options: {refreshKeys: false},
|
|
42
|
+
options: {refreshKeys: false, validateFields: true},
|
|
43
43
|
}),
|
|
44
44
|
).toBe(undefined)
|
|
45
45
|
})
|
|
@@ -54,7 +54,7 @@ describe(parseBlock.name, () => {
|
|
|
54
54
|
defineSchema({blockObjects: [{name: 'image'}]}),
|
|
55
55
|
),
|
|
56
56
|
},
|
|
57
|
-
options: {refreshKeys: false},
|
|
57
|
+
options: {refreshKeys: false, validateFields: true},
|
|
58
58
|
}),
|
|
59
59
|
).toBe(undefined)
|
|
60
60
|
})
|
|
@@ -69,7 +69,7 @@ describe(parseBlock.name, () => {
|
|
|
69
69
|
defineSchema({blockObjects: [{name: 'image'}]}),
|
|
70
70
|
),
|
|
71
71
|
},
|
|
72
|
-
options: {refreshKeys: false},
|
|
72
|
+
options: {refreshKeys: false, validateFields: true},
|
|
73
73
|
}),
|
|
74
74
|
).toEqual({
|
|
75
75
|
_key: 'k0',
|
|
@@ -87,7 +87,7 @@ describe(parseBlock.name, () => {
|
|
|
87
87
|
keyGenerator: createTestKeyGenerator(),
|
|
88
88
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
89
89
|
},
|
|
90
|
-
options: {refreshKeys: false},
|
|
90
|
+
options: {refreshKeys: false, validateFields: true},
|
|
91
91
|
}),
|
|
92
92
|
).toEqual({
|
|
93
93
|
_key: 'k0',
|
|
@@ -114,7 +114,7 @@ describe(parseBlock.name, () => {
|
|
|
114
114
|
keyGenerator: createTestKeyGenerator(),
|
|
115
115
|
schema: {...schema, block: {...schema.block, name: 'text'}},
|
|
116
116
|
},
|
|
117
|
-
options: {refreshKeys: false},
|
|
117
|
+
options: {refreshKeys: false, validateFields: true},
|
|
118
118
|
}),
|
|
119
119
|
).toEqual({
|
|
120
120
|
_key: 'k0',
|
|
@@ -149,7 +149,7 @@ describe(parseBlock.name, () => {
|
|
|
149
149
|
keyGenerator: createTestKeyGenerator(),
|
|
150
150
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
151
151
|
},
|
|
152
|
-
options: {refreshKeys: false},
|
|
152
|
+
options: {refreshKeys: false, validateFields: true},
|
|
153
153
|
}),
|
|
154
154
|
).toBe(undefined)
|
|
155
155
|
})
|
|
@@ -188,7 +188,7 @@ describe(parseBlock.name, () => {
|
|
|
188
188
|
}),
|
|
189
189
|
),
|
|
190
190
|
},
|
|
191
|
-
options: {refreshKeys: false},
|
|
191
|
+
options: {refreshKeys: false, validateFields: true},
|
|
192
192
|
}),
|
|
193
193
|
).toEqual({
|
|
194
194
|
_key: 'k0',
|
|
@@ -238,7 +238,7 @@ describe(parseBlock.name, () => {
|
|
|
238
238
|
defineSchema({lists: [{name: 'bullet'}]}),
|
|
239
239
|
),
|
|
240
240
|
},
|
|
241
|
-
options: {refreshKeys: false},
|
|
241
|
+
options: {refreshKeys: false, validateFields: true},
|
|
242
242
|
}),
|
|
243
243
|
).toEqual({
|
|
244
244
|
_key: 'k0',
|
|
@@ -267,7 +267,7 @@ describe(parseBlock.name, () => {
|
|
|
267
267
|
defineSchema({lists: [{name: 'bullet'}]}),
|
|
268
268
|
),
|
|
269
269
|
},
|
|
270
|
-
options: {refreshKeys: false},
|
|
270
|
+
options: {refreshKeys: false, validateFields: true},
|
|
271
271
|
}),
|
|
272
272
|
).toEqual({
|
|
273
273
|
_key: 'k0',
|
|
@@ -297,7 +297,7 @@ describe(parseSpan.name, () => {
|
|
|
297
297
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
298
298
|
},
|
|
299
299
|
markDefKeyMap: new Map(),
|
|
300
|
-
options: {refreshKeys: false},
|
|
300
|
+
options: {refreshKeys: false, validateFields: true},
|
|
301
301
|
}),
|
|
302
302
|
).toBe(undefined)
|
|
303
303
|
})
|
|
@@ -311,7 +311,7 @@ describe(parseSpan.name, () => {
|
|
|
311
311
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
312
312
|
},
|
|
313
313
|
markDefKeyMap: new Map(),
|
|
314
|
-
options: {refreshKeys: false},
|
|
314
|
+
options: {refreshKeys: false, validateFields: true},
|
|
315
315
|
}),
|
|
316
316
|
).toBe(undefined)
|
|
317
317
|
})
|
|
@@ -325,7 +325,7 @@ describe(parseSpan.name, () => {
|
|
|
325
325
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
326
326
|
},
|
|
327
327
|
markDefKeyMap: new Map(),
|
|
328
|
-
options: {refreshKeys: false},
|
|
328
|
+
options: {refreshKeys: false, validateFields: true},
|
|
329
329
|
}),
|
|
330
330
|
).toBe(undefined)
|
|
331
331
|
})
|
|
@@ -339,7 +339,7 @@ describe(parseSpan.name, () => {
|
|
|
339
339
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
340
340
|
},
|
|
341
341
|
markDefKeyMap: new Map(),
|
|
342
|
-
options: {refreshKeys: false},
|
|
342
|
+
options: {refreshKeys: false, validateFields: true},
|
|
343
343
|
}),
|
|
344
344
|
).toBe(undefined)
|
|
345
345
|
})
|
|
@@ -353,7 +353,7 @@ describe(parseSpan.name, () => {
|
|
|
353
353
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
354
354
|
},
|
|
355
355
|
markDefKeyMap: new Map(),
|
|
356
|
-
options: {refreshKeys: false},
|
|
356
|
+
options: {refreshKeys: false, validateFields: true},
|
|
357
357
|
}),
|
|
358
358
|
).toEqual({
|
|
359
359
|
_key: 'k0',
|
|
@@ -372,7 +372,7 @@ describe(parseSpan.name, () => {
|
|
|
372
372
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
373
373
|
},
|
|
374
374
|
markDefKeyMap: new Map(),
|
|
375
|
-
options: {refreshKeys: false},
|
|
375
|
+
options: {refreshKeys: false, validateFields: true},
|
|
376
376
|
}),
|
|
377
377
|
).toEqual({
|
|
378
378
|
_key: 'k0',
|
|
@@ -394,7 +394,7 @@ describe(parseSpan.name, () => {
|
|
|
394
394
|
schema: compileSchemaDefinition(defineSchema({})),
|
|
395
395
|
},
|
|
396
396
|
markDefKeyMap: new Map(),
|
|
397
|
-
options: {refreshKeys: false},
|
|
397
|
+
options: {refreshKeys: false, validateFields: true},
|
|
398
398
|
}),
|
|
399
399
|
).toEqual({
|
|
400
400
|
_key: 'k0',
|
|
@@ -418,7 +418,7 @@ describe(parseSpan.name, () => {
|
|
|
418
418
|
),
|
|
419
419
|
},
|
|
420
420
|
markDefKeyMap: new Map(),
|
|
421
|
-
options: {refreshKeys: false},
|
|
421
|
+
options: {refreshKeys: false, validateFields: true},
|
|
422
422
|
}),
|
|
423
423
|
).toEqual({
|
|
424
424
|
_key: 'k0',
|
|
@@ -442,7 +442,7 @@ describe(parseSpan.name, () => {
|
|
|
442
442
|
),
|
|
443
443
|
},
|
|
444
444
|
markDefKeyMap: new Map(),
|
|
445
|
-
options: {refreshKeys: false},
|
|
445
|
+
options: {refreshKeys: false, validateFields: true},
|
|
446
446
|
}),
|
|
447
447
|
).toEqual({
|
|
448
448
|
_key: 'k0',
|
|
@@ -19,6 +19,7 @@ export function parseBlocks({
|
|
|
19
19
|
blocks: unknown
|
|
20
20
|
options: {
|
|
21
21
|
refreshKeys: boolean
|
|
22
|
+
validateFields: boolean
|
|
22
23
|
}
|
|
23
24
|
}): Array<PortableTextBlock> {
|
|
24
25
|
if (!Array.isArray(blocks)) {
|
|
@@ -41,6 +42,7 @@ export function parseBlock({
|
|
|
41
42
|
block: unknown
|
|
42
43
|
options: {
|
|
43
44
|
refreshKeys: boolean
|
|
45
|
+
validateFields: boolean
|
|
44
46
|
}
|
|
45
47
|
}): PortableTextBlock | undefined {
|
|
46
48
|
return (
|
|
@@ -56,7 +58,7 @@ export function parseBlockObject({
|
|
|
56
58
|
}: {
|
|
57
59
|
blockObject: unknown
|
|
58
60
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
59
|
-
options: {refreshKeys: boolean}
|
|
61
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
60
62
|
}): PortableTextObject | undefined {
|
|
61
63
|
if (!isTypedObject(blockObject)) {
|
|
62
64
|
return undefined
|
|
@@ -99,7 +101,7 @@ export function isTextBlock(
|
|
|
99
101
|
parseTextBlock({
|
|
100
102
|
block,
|
|
101
103
|
context: {schema: context.schema, keyGenerator: () => ''},
|
|
102
|
-
options: {refreshKeys: false},
|
|
104
|
+
options: {refreshKeys: false, validateFields: false},
|
|
103
105
|
}) !== undefined
|
|
104
106
|
)
|
|
105
107
|
}
|
|
@@ -111,12 +113,28 @@ export function parseTextBlock({
|
|
|
111
113
|
}: {
|
|
112
114
|
block: unknown
|
|
113
115
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
114
|
-
options: {refreshKeys: boolean}
|
|
116
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
115
117
|
}): PortableTextTextBlock | undefined {
|
|
116
118
|
if (!isTypedObject(block)) {
|
|
117
119
|
return undefined
|
|
118
120
|
}
|
|
119
121
|
|
|
122
|
+
const customFields: Record<string, unknown> = {}
|
|
123
|
+
|
|
124
|
+
for (const key of Object.keys(block)) {
|
|
125
|
+
if (
|
|
126
|
+
key !== '_type' &&
|
|
127
|
+
key !== '_key' &&
|
|
128
|
+
key !== 'children' &&
|
|
129
|
+
key !== 'markDefs' &&
|
|
130
|
+
key !== 'style' &&
|
|
131
|
+
key !== 'listItem' &&
|
|
132
|
+
key !== 'level'
|
|
133
|
+
) {
|
|
134
|
+
customFields[key] = block[key]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
120
138
|
if (block._type !== context.schema.block.name) {
|
|
121
139
|
return undefined
|
|
122
140
|
}
|
|
@@ -195,6 +213,7 @@ export function parseTextBlock({
|
|
|
195
213
|
},
|
|
196
214
|
],
|
|
197
215
|
markDefs,
|
|
216
|
+
...(options.validateFields ? {} : customFields),
|
|
198
217
|
}
|
|
199
218
|
|
|
200
219
|
if (
|
|
@@ -235,7 +254,7 @@ export function isSpan(
|
|
|
235
254
|
span: child,
|
|
236
255
|
markDefKeyMap: new Map(),
|
|
237
256
|
context: {schema: context.schema, keyGenerator: () => ''},
|
|
238
|
-
options: {refreshKeys: false},
|
|
257
|
+
options: {refreshKeys: false, validateFields: false},
|
|
239
258
|
}) !== undefined
|
|
240
259
|
)
|
|
241
260
|
}
|
|
@@ -249,12 +268,25 @@ export function parseSpan({
|
|
|
249
268
|
span: unknown
|
|
250
269
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
251
270
|
markDefKeyMap: Map<string, string>
|
|
252
|
-
options: {refreshKeys: boolean}
|
|
271
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
253
272
|
}): PortableTextSpan | undefined {
|
|
254
273
|
if (!isTypedObject(span)) {
|
|
255
274
|
return undefined
|
|
256
275
|
}
|
|
257
276
|
|
|
277
|
+
const customFields: Record<string, unknown> = {}
|
|
278
|
+
|
|
279
|
+
for (const key of Object.keys(span)) {
|
|
280
|
+
if (
|
|
281
|
+
key !== '_type' &&
|
|
282
|
+
key !== '_key' &&
|
|
283
|
+
key !== 'text' &&
|
|
284
|
+
key !== 'marks'
|
|
285
|
+
) {
|
|
286
|
+
customFields[key] = span[key]
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
258
290
|
// In reality, the span schema name is always 'span', but we only the check here anyway
|
|
259
291
|
if (span._type !== context.schema.span.name || span._type !== 'span') {
|
|
260
292
|
return undefined
|
|
@@ -292,6 +324,7 @@ export function parseSpan({
|
|
|
292
324
|
: context.keyGenerator(),
|
|
293
325
|
text: typeof span.text === 'string' ? span.text : '',
|
|
294
326
|
marks,
|
|
327
|
+
...(options.validateFields ? {} : customFields),
|
|
295
328
|
}
|
|
296
329
|
}
|
|
297
330
|
|
|
@@ -302,7 +335,7 @@ export function parseInlineObject({
|
|
|
302
335
|
}: {
|
|
303
336
|
inlineObject: unknown
|
|
304
337
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
305
|
-
options: {refreshKeys: boolean}
|
|
338
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
306
339
|
}): PortableTextObject | undefined {
|
|
307
340
|
if (!isTypedObject(inlineObject)) {
|
|
308
341
|
return undefined
|
|
@@ -333,7 +366,7 @@ export function parseAnnotation({
|
|
|
333
366
|
}: {
|
|
334
367
|
annotation: TypedObject
|
|
335
368
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>
|
|
336
|
-
options: {refreshKeys: boolean}
|
|
369
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
337
370
|
}): PortableTextObject | undefined {
|
|
338
371
|
if (!isTypedObject(annotation)) {
|
|
339
372
|
return undefined
|
|
@@ -366,22 +399,26 @@ function parseObject({
|
|
|
366
399
|
context: Pick<EditorContext, 'keyGenerator'> & {
|
|
367
400
|
schemaType: EditorSchema['blockObjects'][0]
|
|
368
401
|
}
|
|
369
|
-
options: {refreshKeys: boolean}
|
|
402
|
+
options: {refreshKeys: boolean; validateFields: boolean}
|
|
370
403
|
}): PortableTextObject {
|
|
404
|
+
const {_type, _key, ...customFields} = object
|
|
405
|
+
|
|
371
406
|
// Validates all props on the object and only takes those that match
|
|
372
407
|
// the name of a field
|
|
373
|
-
const values =
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
408
|
+
const values = options.validateFields
|
|
409
|
+
? context.schemaType.fields.reduce<Record<string, unknown>>(
|
|
410
|
+
(fieldValues, field) => {
|
|
411
|
+
const fieldValue = object[field.name]
|
|
412
|
+
|
|
413
|
+
if (fieldValue !== undefined) {
|
|
414
|
+
fieldValues[field.name] = fieldValue
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return fieldValues
|
|
418
|
+
},
|
|
419
|
+
{},
|
|
420
|
+
)
|
|
421
|
+
: customFields
|
|
385
422
|
|
|
386
423
|
return {
|
|
387
424
|
_type: context.schemaType.name,
|
|
@@ -46,7 +46,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
46
46
|
const updatedTextBlock = parseBlock({
|
|
47
47
|
context,
|
|
48
48
|
block: omit(parsedBlock, propsToRemove),
|
|
49
|
-
options: {refreshKeys: false},
|
|
49
|
+
options: {refreshKeys: false, validateFields: true},
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
if (!updatedTextBlock) {
|
|
@@ -76,7 +76,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
76
76
|
parsedBlock,
|
|
77
77
|
operation.props.filter((prop) => prop !== '_type'),
|
|
78
78
|
),
|
|
79
|
-
options: {refreshKeys: false},
|
|
79
|
+
options: {refreshKeys: false, validateFields: true},
|
|
80
80
|
})
|
|
81
81
|
|
|
82
82
|
if (!updatedBlockObject) {
|
|
@@ -12,7 +12,7 @@ export const insertInlineObjectOperationImplementation: BehaviorOperationImpleme
|
|
|
12
12
|
_type: operation.inlineObject.name,
|
|
13
13
|
...(operation.inlineObject.value ?? {}),
|
|
14
14
|
},
|
|
15
|
-
options: {refreshKeys: false},
|
|
15
|
+
options: {refreshKeys: false, validateFields: true},
|
|
16
16
|
})
|
|
17
17
|
|
|
18
18
|
if (!parsedInlineObject) {
|
|
@@ -19,7 +19,7 @@ export const insertBlockOperationImplementation: BehaviorOperationImplementation
|
|
|
19
19
|
const parsedBlock = parseBlock({
|
|
20
20
|
block: operation.block,
|
|
21
21
|
context,
|
|
22
|
-
options: {refreshKeys: false},
|
|
22
|
+
options: {refreshKeys: false, validateFields: true},
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
if (!parsedBlock) {
|
|
@@ -18,7 +18,7 @@ export function mergeTextBlocks({
|
|
|
18
18
|
const parsedIncomingBlock = parseBlock({
|
|
19
19
|
context,
|
|
20
20
|
block: incomingBlock,
|
|
21
|
-
options: {refreshKeys: true},
|
|
21
|
+
options: {refreshKeys: true, validateFields: true},
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {
|