@portabletext/editor 1.49.1 → 1.49.3
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/selector.get-text-before.cjs +2 -2
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +40 -230
- package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +201 -0
- package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -0
- package/lib/_chunks-cjs/use-editor.cjs +28 -0
- package/lib/_chunks-cjs/use-editor.cjs.map +1 -0
- package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs +79 -0
- package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs.map +1 -0
- package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +34 -0
- package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -0
- 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.selection-point-to-block-offset.cjs +6 -78
- package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs +26 -39
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +13 -201
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +203 -0
- package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -0
- package/lib/_chunks-es/use-editor.js +25 -0
- package/lib/_chunks-es/use-editor.js.map +1 -0
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js +80 -0
- package/lib/_chunks-es/util.child-selection-point-to-block-offset.js.map +1 -0
- package/lib/_chunks-es/util.is-equal-selection-points.js +35 -0
- package/lib/_chunks-es/util.is-equal-selection-points.js.map +1 -0
- 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.selection-point-to-block-offset.js +6 -77
- package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js +26 -39
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.cjs +9004 -292
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +8947 -220
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +23 -23
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.js +3 -3
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.cjs +22 -22
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.js +4 -3
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +10 -10
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.js +6 -4
- package/lib/utils/index.js.map +1 -1
- package/package.json +14 -14
- 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 +1 -0
- package/src/editor/components/render-element.tsx +3 -3
- package/src/editor/create-editor.ts +2 -58
- package/src/editor/editor-context.tsx +1 -1
- package/src/editor/editor-provider.tsx +4 -31
- package/src/editor/editor-selector.ts +2 -1
- package/src/editor/use-editor.ts +27 -0
- package/src/editor-event-listener.tsx +1 -1
- package/src/editor.ts +57 -0
- package/src/index.ts +9 -9
- package/src/internal-utils/parse-blocks.test.ts +20 -20
- package/src/internal-utils/parse-blocks.ts +57 -20
- package/src/internal-utils/text-selection.test.ts +11 -0
- 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/plugins/plugin.behavior.tsx +1 -1
- package/src/plugins/plugin.decorator-shortcut.ts +2 -2
- package/src/plugins/plugin.editor-ref.tsx +2 -2
- package/src/plugins/plugin.event-listener.tsx +1 -1
- package/src/plugins/plugin.markdown.tsx +1 -1
- package/src/selectors/selector.get-trimmed-selection.test.ts +1 -0
- package/src/utils/util.merge-text-blocks.ts +1 -1
- package/lib/_chunks-cjs/editor-provider.cjs +0 -8745
- package/lib/_chunks-cjs/editor-provider.cjs.map +0 -1
- package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs +0 -11
- package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs.map +0 -1
- package/lib/_chunks-cjs/util.is-selection-collapsed.cjs +0 -6
- package/lib/_chunks-cjs/util.is-selection-collapsed.cjs.map +0 -1
- package/lib/_chunks-es/editor-provider.js +0 -8771
- package/lib/_chunks-es/editor-provider.js.map +0 -1
- package/lib/_chunks-es/selector.get-focus-inline-object.js +0 -13
- package/lib/_chunks-es/selector.get-focus-inline-object.js.map +0 -1
- package/lib/_chunks-es/util.is-selection-collapsed.js +0 -7
- package/lib/_chunks-es/util.is-selection-collapsed.js.map +0 -1
|
@@ -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,
|
|
@@ -6,6 +6,17 @@ import {
|
|
|
6
6
|
} from './text-selection'
|
|
7
7
|
|
|
8
8
|
test(getTextSelection.name, () => {
|
|
9
|
+
const simpleBlock = {
|
|
10
|
+
_key: 'b1',
|
|
11
|
+
_type: 'block',
|
|
12
|
+
children: [{_key: 's1', _type: 'span', text: 'foo'}],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
expect(getTextSelection([simpleBlock], 'foo')).toEqual({
|
|
16
|
+
anchor: {path: [{_key: 'b1'}, 'children', {_key: 's1'}], offset: 0},
|
|
17
|
+
focus: {path: [{_key: 'b1'}, 'children', {_key: 's1'}], offset: 3},
|
|
18
|
+
})
|
|
19
|
+
|
|
9
20
|
const joinedBlock = {
|
|
10
21
|
_key: 'b1',
|
|
11
22
|
_type: 'block',
|
|
@@ -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) {
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
import {createDecoratorPairBehavior} from '../behaviors/behavior.decorator-pair'
|
|
11
11
|
import {effect, execute, forward} from '../behaviors/behavior.types.action'
|
|
12
12
|
import {defineBehavior} from '../behaviors/behavior.types.behavior'
|
|
13
|
-
import type {Editor} from '../editor
|
|
14
|
-
import {useEditor} from '../editor/editor-provider'
|
|
13
|
+
import type {Editor} from '../editor'
|
|
15
14
|
import type {EditorSchema} from '../editor/editor-schema'
|
|
15
|
+
import {useEditor} from '../editor/use-editor'
|
|
16
16
|
import type {BlockOffset} from '../types/block-offset'
|
|
17
17
|
import * as utils from '../utils'
|
|
18
18
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {useEffect} from 'react'
|
|
2
2
|
import {useEffectEvent} from 'use-effect-event'
|
|
3
3
|
import type {EditorEmittedEvent} from '../editor/editor-machine'
|
|
4
|
-
import {useEditor} from '../editor/editor
|
|
4
|
+
import {useEditor} from '../editor/use-editor'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @public
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
createMarkdownBehaviors,
|
|
4
4
|
type MarkdownBehaviorsConfig,
|
|
5
5
|
} from '../behaviors/behavior.markdown'
|
|
6
|
-
import {useEditor} from '../editor/editor-provider'
|
|
7
6
|
import type {EditorSchema} from '../editor/editor-schema'
|
|
7
|
+
import {useEditor} from '../editor/use-editor'
|
|
8
8
|
import {DecoratorShortcutPlugin} from './plugin.decorator-shortcut'
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -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)) {
|