@portabletext/editor 3.0.1 → 3.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -0,0 +1,289 @@
1
+ import {compileSchema, defineSchema} from '@portabletext/schema'
2
+ import {createTestKeyGenerator} from '@portabletext/test'
3
+ import {describe, expect, test} from 'vitest'
4
+ import {toSlateBlock, VOID_CHILD_KEY} from './values'
5
+
6
+ describe(toSlateBlock.name, () => {
7
+ describe('text block', () => {
8
+ describe('with span', () => {
9
+ test('with _type', () => {
10
+ const keyGenerator = createTestKeyGenerator()
11
+ const blockKey = keyGenerator()
12
+ const spanKey = keyGenerator()
13
+
14
+ expect(
15
+ toSlateBlock(
16
+ {
17
+ _type: 'block',
18
+ _key: blockKey,
19
+ children: [{_key: spanKey, _type: 'span', text: 'foo'}],
20
+ },
21
+ {
22
+ schemaTypes: compileSchema(defineSchema({})),
23
+ },
24
+ ),
25
+ ).toEqual({
26
+ _type: 'block',
27
+ _key: blockKey,
28
+ children: [
29
+ {
30
+ _key: spanKey,
31
+ _type: 'span',
32
+ text: 'foo',
33
+ },
34
+ ],
35
+ style: 'normal',
36
+ })
37
+ })
38
+
39
+ test('without _type', () => {
40
+ const keyGenerator = createTestKeyGenerator()
41
+ const blockKey = keyGenerator()
42
+ const spanKey = keyGenerator()
43
+
44
+ expect(
45
+ toSlateBlock(
46
+ {
47
+ _type: 'block',
48
+ _key: blockKey,
49
+ children: [{_key: spanKey, text: 'foo'}],
50
+ },
51
+ {
52
+ schemaTypes: compileSchema(defineSchema({})),
53
+ },
54
+ ),
55
+ ).toEqual({
56
+ _type: 'block',
57
+ _key: blockKey,
58
+ children: [
59
+ {
60
+ _key: spanKey,
61
+ _type: 'span',
62
+ text: 'foo',
63
+ },
64
+ ],
65
+ style: 'normal',
66
+ })
67
+ })
68
+
69
+ test('wrong _type', () => {
70
+ const keyGenerator = createTestKeyGenerator()
71
+ const blockKey = keyGenerator()
72
+ const spanKey = keyGenerator()
73
+
74
+ expect(
75
+ toSlateBlock(
76
+ {
77
+ _type: 'block',
78
+ _key: blockKey,
79
+ children: [{_key: spanKey, _type: 'stock-ticker', text: 'foo'}],
80
+ },
81
+ {
82
+ schemaTypes: compileSchema(defineSchema({})),
83
+ },
84
+ ),
85
+ ).toEqual({
86
+ _type: 'block',
87
+ _key: blockKey,
88
+ children: [
89
+ {
90
+ _key: spanKey,
91
+ _type: 'stock-ticker',
92
+ children: [
93
+ {
94
+ _key: VOID_CHILD_KEY,
95
+ _type: 'span',
96
+ text: '',
97
+ marks: [],
98
+ },
99
+ ],
100
+ value: {text: 'foo'},
101
+ __inline: true,
102
+ },
103
+ ],
104
+ style: 'normal',
105
+ })
106
+ })
107
+ })
108
+
109
+ describe('with inline object', () => {
110
+ test('known inline object _type', () => {
111
+ const keyGenerator = createTestKeyGenerator()
112
+ const blockKey = keyGenerator()
113
+ const stockTickerKey = keyGenerator()
114
+
115
+ expect(
116
+ toSlateBlock(
117
+ {
118
+ _type: 'block',
119
+ _key: blockKey,
120
+ children: [
121
+ {_type: 'stock-ticker', _key: stockTickerKey, symbol: 'AAPL'},
122
+ ],
123
+ },
124
+ {
125
+ schemaTypes: compileSchema(
126
+ defineSchema({inlineObjects: [{name: 'stock-ticker'}]}),
127
+ ),
128
+ },
129
+ ),
130
+ ).toEqual({
131
+ _type: 'block',
132
+ _key: blockKey,
133
+ children: [
134
+ {
135
+ __inline: true,
136
+ _key: stockTickerKey,
137
+ _type: 'stock-ticker',
138
+ children: [
139
+ {
140
+ _key: VOID_CHILD_KEY,
141
+ _type: 'span',
142
+ text: '',
143
+ marks: [],
144
+ },
145
+ ],
146
+ value: {
147
+ symbol: 'AAPL',
148
+ },
149
+ },
150
+ ],
151
+ style: 'normal',
152
+ })
153
+ })
154
+
155
+ test('unknown inline object _type', () => {
156
+ const keyGenerator = createTestKeyGenerator()
157
+ const blockKey = keyGenerator()
158
+ const stockTickerKey = keyGenerator()
159
+
160
+ expect(
161
+ toSlateBlock(
162
+ {
163
+ _type: 'block',
164
+ _key: blockKey,
165
+ children: [
166
+ {_type: 'stock-ticker', _key: stockTickerKey, symbol: 'AAPL'},
167
+ ],
168
+ },
169
+ {
170
+ schemaTypes: compileSchema(defineSchema({})),
171
+ },
172
+ ),
173
+ ).toEqual({
174
+ _type: 'block',
175
+ _key: blockKey,
176
+ children: [
177
+ {
178
+ __inline: true,
179
+ _key: stockTickerKey,
180
+ _type: 'stock-ticker',
181
+ children: [
182
+ {
183
+ _key: VOID_CHILD_KEY,
184
+ _type: 'span',
185
+ text: '',
186
+ marks: [],
187
+ },
188
+ ],
189
+ value: {
190
+ symbol: 'AAPL',
191
+ },
192
+ },
193
+ ],
194
+ style: 'normal',
195
+ })
196
+ })
197
+ })
198
+
199
+ describe('with inline object with text prop', () => {
200
+ test('known inline object _type', () => {
201
+ const keyGenerator = createTestKeyGenerator()
202
+ const blockKey = keyGenerator()
203
+ const stockTickerKey = keyGenerator()
204
+
205
+ expect(
206
+ toSlateBlock(
207
+ {
208
+ _type: 'block',
209
+ _key: blockKey,
210
+ children: [
211
+ {_type: 'stock-ticker', _key: stockTickerKey, text: 'foo'},
212
+ ],
213
+ },
214
+ {
215
+ schemaTypes: compileSchema(
216
+ defineSchema({inlineObjects: [{name: 'stock-ticker'}]}),
217
+ ),
218
+ },
219
+ ),
220
+ ).toEqual({
221
+ _type: 'block',
222
+ _key: blockKey,
223
+ children: [
224
+ {
225
+ __inline: true,
226
+ _key: stockTickerKey,
227
+ _type: 'stock-ticker',
228
+ children: [
229
+ {
230
+ _key: VOID_CHILD_KEY,
231
+ _type: 'span',
232
+ text: '',
233
+ marks: [],
234
+ },
235
+ ],
236
+ value: {
237
+ text: 'foo',
238
+ },
239
+ },
240
+ ],
241
+ style: 'normal',
242
+ })
243
+ })
244
+
245
+ test('unknown inline object _type', () => {
246
+ const keyGenerator = createTestKeyGenerator()
247
+ const blockKey = keyGenerator()
248
+ const stockTickerKey = keyGenerator()
249
+
250
+ expect(
251
+ toSlateBlock(
252
+ {
253
+ _type: 'block',
254
+ _key: blockKey,
255
+ children: [
256
+ {_type: 'stock-ticker', _key: stockTickerKey, text: 'foo'},
257
+ ],
258
+ },
259
+ {
260
+ schemaTypes: compileSchema(defineSchema({})),
261
+ },
262
+ ),
263
+ ).toEqual({
264
+ _type: 'block',
265
+ _key: blockKey,
266
+ children: [
267
+ {
268
+ __inline: true,
269
+ _key: stockTickerKey,
270
+ _type: 'stock-ticker',
271
+ children: [
272
+ {
273
+ _key: VOID_CHILD_KEY,
274
+ _type: 'span',
275
+ text: '',
276
+ marks: [],
277
+ },
278
+ ],
279
+ value: {
280
+ text: 'foo',
281
+ },
282
+ },
283
+ ],
284
+ style: 'normal',
285
+ })
286
+ })
287
+ })
288
+ })
289
+ })
@@ -54,11 +54,17 @@ export function toSlateBlock(
54
54
  const {_type: childType, _key: childKey, ...childProps} = child
55
55
  const propKeys = Object.keys(childProps)
56
56
 
57
- if (childType !== schemaTypes.span.name) {
57
+ if (childType === undefined) {
58
58
  if (propKeys.length === 1 && propKeys.at(0) === 'text') {
59
- return child
59
+ return {
60
+ _key: childKey,
61
+ _type: schemaTypes.span.name,
62
+ text: childProps.text,
63
+ }
60
64
  }
65
+ }
61
66
 
67
+ if (childType !== schemaTypes.span.name) {
62
68
  // Return 'slate' version of inline object where the actual
63
69
  // value is stored in the `value` property.
64
70
  // In slate, inline objects are represented as regular
@@ -1,7 +1,12 @@
1
1
  import {compileSchema, defineSchema} from '@portabletext/schema'
2
2
  import {createTestKeyGenerator} from '@portabletext/test'
3
3
  import {describe, expect, test} from 'vitest'
4
- import {parseBlock, parseInlineObject, parseSpan} from './parse-blocks'
4
+ import {
5
+ parseBlock,
6
+ parseChild,
7
+ parseInlineObject,
8
+ parseSpan,
9
+ } from './parse-blocks'
5
10
 
6
11
  describe(parseBlock.name, () => {
7
12
  test('null', () => {
@@ -265,12 +270,6 @@ describe(parseBlock.name, () => {
265
270
  text: '',
266
271
  marks: ['em'],
267
272
  },
268
- {
269
- _key: 'k6',
270
- _type: 'span',
271
- text: 'inline object or span?',
272
- marks: [],
273
- },
274
273
  ],
275
274
  markDefs: [],
276
275
  style: 'normal',
@@ -813,3 +812,41 @@ describe(parseInlineObject.name, () => {
813
812
  })
814
813
  })
815
814
  })
815
+
816
+ describe(parseChild.name, () => {
817
+ describe('inline object', () => {
818
+ describe('looks like text node', () => {
819
+ test('known inline object _type', () => {
820
+ expect(
821
+ parseChild({
822
+ context: {
823
+ keyGenerator: createTestKeyGenerator(),
824
+ schema: compileSchema(
825
+ defineSchema({inlineObjects: [{name: 'stock-ticker'}]}),
826
+ ),
827
+ },
828
+ markDefKeyMap: new Map(),
829
+ options: {validateFields: true},
830
+ child: {_type: 'stock-ticker', text: 'foo'},
831
+ }),
832
+ ).toEqual({_key: 'k0', _type: 'stock-ticker'})
833
+ })
834
+
835
+ test('unknown inline object _type', () => {
836
+ expect(
837
+ parseChild({
838
+ context: {
839
+ keyGenerator: createTestKeyGenerator(),
840
+ schema: compileSchema(
841
+ defineSchema({inlineObjects: [{name: 'stock-ticker'}]}),
842
+ ),
843
+ },
844
+ markDefKeyMap: new Map(),
845
+ options: {validateFields: true},
846
+ child: {_type: 'image', text: 'foo'},
847
+ }),
848
+ ).toBe(undefined)
849
+ })
850
+ })
851
+ })
852
+ })
@@ -190,11 +190,7 @@ export function parseTextBlock({
190
190
  : []
191
191
 
192
192
  const parsedChildren = unparsedChildren
193
- .map(
194
- (child) =>
195
- parseSpan({span: child, context, markDefKeyMap, options}) ??
196
- parseInlineObject({inlineObject: child, context, options}),
197
- )
193
+ .map((child) => parseChild({child, context, markDefKeyMap, options}))
198
194
  .filter((child) => child !== undefined)
199
195
  const marks = parsedChildren.flatMap((child) => child.marks ?? [])
200
196
 
@@ -288,6 +284,23 @@ export function parseTextBlock({
288
284
  return parsedBlock
289
285
  }
290
286
 
287
+ export function parseChild({
288
+ child,
289
+ context,
290
+ markDefKeyMap,
291
+ options,
292
+ }: {
293
+ child: unknown
294
+ context: Pick<EditorContext, 'keyGenerator' | 'schema'>
295
+ markDefKeyMap: Map<string, string>
296
+ options: {validateFields: boolean}
297
+ }): PortableTextSpan | PortableTextObject | undefined {
298
+ return (
299
+ parseSpan({span: child, context, markDefKeyMap, options}) ??
300
+ parseInlineObject({inlineObject: child, context, options})
301
+ )
302
+ }
303
+
291
304
  export function parseSpan({
292
305
  span,
293
306
  context,
@@ -339,13 +352,15 @@ export function parseSpan({
339
352
  return []
340
353
  })
341
354
 
342
- if (span._type !== context.schema.span.name) {
343
- if (
344
- !context.schema.inlineObjects.some(
345
- (inlineObject) => inlineObject.name === span._type,
346
- ) &&
347
- typeof span.text === 'string'
348
- ) {
355
+ if (
356
+ typeof span._type === 'string' &&
357
+ span._type !== context.schema.span.name
358
+ ) {
359
+ return undefined
360
+ }
361
+
362
+ if (typeof span._type !== 'string') {
363
+ if (typeof span.text === 'string') {
349
364
  return {
350
365
  _type: context.schema.span.name as 'span',
351
366
  _key: