@portabletext/block-tools 4.1.8 → 4.1.9
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 +5 -6
- package/src/HtmlDeserializer/flatten-nested-blocks.test.ts +0 -248
- package/src/HtmlDeserializer/flatten-nested-blocks.ts +0 -173
- package/src/HtmlDeserializer/helpers.ts +0 -108
- package/src/HtmlDeserializer/index.ts +0 -315
- package/src/HtmlDeserializer/preprocessors/index.ts +0 -15
- package/src/HtmlDeserializer/preprocessors/preprocessor.gdocs.ts +0 -66
- package/src/HtmlDeserializer/preprocessors/preprocessor.html.ts +0 -57
- package/src/HtmlDeserializer/preprocessors/preprocessor.notion.ts +0 -25
- package/src/HtmlDeserializer/preprocessors/preprocessor.whitespace.ts +0 -56
- package/src/HtmlDeserializer/preprocessors/preprocessor.word.ts +0 -92
- package/src/HtmlDeserializer/preprocessors/xpathResult.ts +0 -13
- package/src/HtmlDeserializer/rules/index.ts +0 -21
- package/src/HtmlDeserializer/rules/rules.gdocs.ts +0 -188
- package/src/HtmlDeserializer/rules/rules.html.ts +0 -356
- package/src/HtmlDeserializer/rules/rules.notion.ts +0 -57
- package/src/HtmlDeserializer/rules/rules.whitespace-text-node.ts +0 -31
- package/src/HtmlDeserializer/rules/rules.word.ts +0 -95
- package/src/HtmlDeserializer/trim-whitespace.ts +0 -157
- package/src/HtmlDeserializer/word-online/asserters.word-online.ts +0 -153
- package/src/HtmlDeserializer/word-online/preprocessor.word-online.ts +0 -263
- package/src/HtmlDeserializer/word-online/rules.word-online.ts +0 -390
- package/src/constants.ts +0 -104
- package/src/index.ts +0 -49
- package/src/rules/_exports/index.ts +0 -1
- package/src/rules/flatten-tables.test.ts +0 -495
- package/src/rules/flatten-tables.ts +0 -216
- package/src/rules/index.ts +0 -1
- package/src/schema-matchers.ts +0 -41
- package/src/types.ts +0 -100
- package/src/util/findBlockType.ts +0 -13
- package/src/util/normalizeBlock.ts +0 -171
- package/src/util/randomKey.ts +0 -28
- package/src/util/resolveJsType.ts +0 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/block-tools",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.9",
|
|
4
4
|
"description": "Can format HTML, Slate JSON or Sanity block array into any other format.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"portable-text",
|
|
@@ -33,14 +33,13 @@
|
|
|
33
33
|
"main": "./lib/index.js",
|
|
34
34
|
"types": "./lib/index.d.ts",
|
|
35
35
|
"files": [
|
|
36
|
-
"lib"
|
|
37
|
-
"src"
|
|
36
|
+
"lib"
|
|
38
37
|
],
|
|
39
38
|
"dependencies": {
|
|
40
39
|
"@sanity/types": "^4.20.3",
|
|
41
40
|
"lodash": "^4.17.21",
|
|
42
|
-
"@portabletext/sanity-bridge": "^1.2.
|
|
43
|
-
"@portabletext/schema": "^2.0.
|
|
41
|
+
"@portabletext/sanity-bridge": "^1.2.12",
|
|
42
|
+
"@portabletext/schema": "^2.0.1"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
45
|
"@sanity/pkg-utils": "^10.1.1",
|
|
@@ -52,7 +51,7 @@
|
|
|
52
51
|
"jsdom": "^27.0.0",
|
|
53
52
|
"typescript": "5.9.3",
|
|
54
53
|
"vitest": "^4.0.14",
|
|
55
|
-
"@portabletext/test": "^1.0.
|
|
54
|
+
"@portabletext/test": "^1.0.2"
|
|
56
55
|
},
|
|
57
56
|
"engines": {
|
|
58
57
|
"node": ">=20.19 <22 || >=22.12"
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import {compileSchema, defineSchema} from '@portabletext/schema'
|
|
2
|
-
import {describe, expect, test} from 'vitest'
|
|
3
|
-
import {createTestKeyGenerator} from '../../test/test-key-generator'
|
|
4
|
-
import {flattenNestedBlocks} from './flatten-nested-blocks'
|
|
5
|
-
|
|
6
|
-
describe(flattenNestedBlocks.name, () => {
|
|
7
|
-
test('flattening text blocks', () => {
|
|
8
|
-
const schema = compileSchema(defineSchema({}))
|
|
9
|
-
expect(
|
|
10
|
-
flattenNestedBlocks({schema}, [
|
|
11
|
-
{
|
|
12
|
-
_type: 'block',
|
|
13
|
-
children: [
|
|
14
|
-
{
|
|
15
|
-
_type: 'block',
|
|
16
|
-
children: [
|
|
17
|
-
{
|
|
18
|
-
_type: 'span',
|
|
19
|
-
marks: [],
|
|
20
|
-
text: 'foo',
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
markDefs: [],
|
|
24
|
-
style: 'normal',
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
markDefs: [],
|
|
28
|
-
style: 'normal',
|
|
29
|
-
},
|
|
30
|
-
]),
|
|
31
|
-
).toEqual([
|
|
32
|
-
{
|
|
33
|
-
_type: 'block',
|
|
34
|
-
children: [{_type: 'span', text: 'foo', marks: []}],
|
|
35
|
-
markDefs: [],
|
|
36
|
-
style: 'normal',
|
|
37
|
-
},
|
|
38
|
-
])
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test('flattening text blocks with block objects in schema', () => {
|
|
42
|
-
const schema = compileSchema(
|
|
43
|
-
defineSchema({blockObjects: [{name: 'image'}]}),
|
|
44
|
-
)
|
|
45
|
-
expect(
|
|
46
|
-
flattenNestedBlocks({schema}, [
|
|
47
|
-
{
|
|
48
|
-
_type: 'block',
|
|
49
|
-
children: [
|
|
50
|
-
{
|
|
51
|
-
_type: 'block',
|
|
52
|
-
children: [
|
|
53
|
-
{
|
|
54
|
-
_type: 'span',
|
|
55
|
-
text: 'foo',
|
|
56
|
-
marks: [],
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
markDefs: [],
|
|
60
|
-
style: 'normal',
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
markDefs: [],
|
|
64
|
-
style: 'normal',
|
|
65
|
-
},
|
|
66
|
-
]),
|
|
67
|
-
).toEqual([
|
|
68
|
-
{
|
|
69
|
-
_type: 'block',
|
|
70
|
-
children: [{_type: 'span', text: 'foo', marks: []}],
|
|
71
|
-
markDefs: [],
|
|
72
|
-
style: 'normal',
|
|
73
|
-
},
|
|
74
|
-
])
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('flattening text blocks with styles in schema', () => {
|
|
78
|
-
const schema = compileSchema(
|
|
79
|
-
defineSchema({
|
|
80
|
-
styles: [{name: 'h1'}],
|
|
81
|
-
}),
|
|
82
|
-
)
|
|
83
|
-
expect(
|
|
84
|
-
flattenNestedBlocks({schema}, [
|
|
85
|
-
{
|
|
86
|
-
_type: 'block',
|
|
87
|
-
children: [
|
|
88
|
-
{
|
|
89
|
-
_type: 'block',
|
|
90
|
-
children: [
|
|
91
|
-
{
|
|
92
|
-
_type: 'span',
|
|
93
|
-
marks: [],
|
|
94
|
-
text: 'foo',
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
markDefs: [],
|
|
98
|
-
style: 'normal',
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
|
-
markDefs: [],
|
|
102
|
-
style: 'h1',
|
|
103
|
-
},
|
|
104
|
-
]),
|
|
105
|
-
).toEqual([
|
|
106
|
-
{
|
|
107
|
-
_type: 'block',
|
|
108
|
-
children: [{_type: 'span', text: 'foo', marks: []}],
|
|
109
|
-
markDefs: [],
|
|
110
|
-
style: 'normal',
|
|
111
|
-
},
|
|
112
|
-
])
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
test('splitting text block', () => {
|
|
116
|
-
const keyGenerator = createTestKeyGenerator('k')
|
|
117
|
-
const schema = compileSchema(
|
|
118
|
-
defineSchema({
|
|
119
|
-
styles: [{name: 'h1'}],
|
|
120
|
-
annotations: [{name: 'link'}],
|
|
121
|
-
blockObjects: [{name: 'image'}],
|
|
122
|
-
}),
|
|
123
|
-
)
|
|
124
|
-
const blockKey = keyGenerator()
|
|
125
|
-
const fooKey = keyGenerator()
|
|
126
|
-
const imageKey = keyGenerator()
|
|
127
|
-
const barKey = keyGenerator()
|
|
128
|
-
const linkKey = keyGenerator()
|
|
129
|
-
|
|
130
|
-
expect(
|
|
131
|
-
flattenNestedBlocks({schema}, [
|
|
132
|
-
{
|
|
133
|
-
_key: blockKey,
|
|
134
|
-
_type: 'block',
|
|
135
|
-
children: [
|
|
136
|
-
{
|
|
137
|
-
_key: fooKey,
|
|
138
|
-
_type: 'span',
|
|
139
|
-
text: 'foo',
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
_key: imageKey,
|
|
143
|
-
_type: 'image',
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
_key: barKey,
|
|
147
|
-
_type: 'span',
|
|
148
|
-
text: 'bar',
|
|
149
|
-
marks: [linkKey],
|
|
150
|
-
},
|
|
151
|
-
],
|
|
152
|
-
style: 'h1',
|
|
153
|
-
markDefs: [
|
|
154
|
-
{
|
|
155
|
-
_key: linkKey,
|
|
156
|
-
_type: 'link',
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
},
|
|
160
|
-
]),
|
|
161
|
-
).toEqual([
|
|
162
|
-
{
|
|
163
|
-
_key: blockKey,
|
|
164
|
-
_type: 'block',
|
|
165
|
-
children: [{_key: fooKey, _type: 'span', text: 'foo'}],
|
|
166
|
-
style: 'h1',
|
|
167
|
-
markDefs: [{_key: linkKey, _type: 'link'}],
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
_key: imageKey,
|
|
171
|
-
_type: 'image',
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
_key: blockKey,
|
|
175
|
-
_type: 'block',
|
|
176
|
-
children: [
|
|
177
|
-
{_key: barKey, _type: 'span', text: 'bar', marks: [linkKey]},
|
|
178
|
-
],
|
|
179
|
-
style: 'h1',
|
|
180
|
-
markDefs: [{_key: linkKey, _type: 'link'}],
|
|
181
|
-
},
|
|
182
|
-
])
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
test('splitting text block with __block', () => {
|
|
186
|
-
const keyGenerator = createTestKeyGenerator('k')
|
|
187
|
-
const schema = compileSchema(
|
|
188
|
-
defineSchema({
|
|
189
|
-
blockObjects: [{name: 'image'}],
|
|
190
|
-
}),
|
|
191
|
-
)
|
|
192
|
-
const blockKey = keyGenerator()
|
|
193
|
-
const fooKey = keyGenerator()
|
|
194
|
-
const imageKey = keyGenerator()
|
|
195
|
-
const barKey = keyGenerator()
|
|
196
|
-
|
|
197
|
-
expect(
|
|
198
|
-
flattenNestedBlocks({schema}, [
|
|
199
|
-
{
|
|
200
|
-
_key: blockKey,
|
|
201
|
-
_type: 'block',
|
|
202
|
-
children: [
|
|
203
|
-
{
|
|
204
|
-
_key: fooKey,
|
|
205
|
-
_type: 'span',
|
|
206
|
-
text: 'foo',
|
|
207
|
-
marks: [],
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
_type: '__block',
|
|
211
|
-
block: {
|
|
212
|
-
_key: imageKey,
|
|
213
|
-
_type: 'image',
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
_key: barKey,
|
|
218
|
-
_type: 'span',
|
|
219
|
-
text: 'bar',
|
|
220
|
-
marks: [],
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
style: 'normal',
|
|
224
|
-
markDefs: [],
|
|
225
|
-
},
|
|
226
|
-
]),
|
|
227
|
-
).toEqual([
|
|
228
|
-
{
|
|
229
|
-
_key: blockKey,
|
|
230
|
-
_type: 'block',
|
|
231
|
-
children: [{_key: fooKey, _type: 'span', text: 'foo', marks: []}],
|
|
232
|
-
style: 'normal',
|
|
233
|
-
markDefs: [],
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
_key: imageKey,
|
|
237
|
-
_type: 'image',
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
_key: blockKey,
|
|
241
|
-
_type: 'block',
|
|
242
|
-
children: [{_key: barKey, _type: 'span', text: 'bar', marks: []}],
|
|
243
|
-
style: 'normal',
|
|
244
|
-
markDefs: [],
|
|
245
|
-
},
|
|
246
|
-
])
|
|
247
|
-
})
|
|
248
|
-
})
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import type {Schema} from '@portabletext/schema'
|
|
2
|
-
import {
|
|
3
|
-
isSpan,
|
|
4
|
-
isTextBlock,
|
|
5
|
-
type PortableTextBlock,
|
|
6
|
-
type PortableTextObject,
|
|
7
|
-
type PortableTextSpan,
|
|
8
|
-
type PortableTextTextBlock,
|
|
9
|
-
} from '@portabletext/schema'
|
|
10
|
-
import {isEqual} from 'lodash'
|
|
11
|
-
import {
|
|
12
|
-
isArbitraryTypedObject,
|
|
13
|
-
type ArbitraryTypedObject,
|
|
14
|
-
type TypedObject,
|
|
15
|
-
} from '../types'
|
|
16
|
-
|
|
17
|
-
export function flattenNestedBlocks(
|
|
18
|
-
context: {
|
|
19
|
-
schema: Schema
|
|
20
|
-
},
|
|
21
|
-
blocks: Array<ArbitraryTypedObject>,
|
|
22
|
-
): TypedObject[] {
|
|
23
|
-
const flattened = blocks.flatMap((block) => {
|
|
24
|
-
if (isBlockContainer(block)) {
|
|
25
|
-
return flattenNestedBlocks(context, [block.block])
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (isTextBlock(context, block)) {
|
|
29
|
-
const hasBlockObjects = block.children.some((child) => {
|
|
30
|
-
const knownBlockObject = context.schema.blockObjects.some(
|
|
31
|
-
(blockObject) => blockObject.name === child._type,
|
|
32
|
-
)
|
|
33
|
-
return knownBlockObject
|
|
34
|
-
})
|
|
35
|
-
const hasBlocks = block.children.some(
|
|
36
|
-
(child) => child._type === '__block' || child._type === 'block',
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
if (hasBlockObjects || hasBlocks) {
|
|
40
|
-
const splitChildren = getSplitChildren(context, block)
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
splitChildren.length === 1 &&
|
|
44
|
-
splitChildren[0].type === 'children' &&
|
|
45
|
-
isEqual(splitChildren[0].children, block.children)
|
|
46
|
-
) {
|
|
47
|
-
return [block]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return splitChildren.flatMap((slice) => {
|
|
51
|
-
if (slice.type === 'block object') {
|
|
52
|
-
return [slice.block]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (slice.type === 'block') {
|
|
56
|
-
return flattenNestedBlocks(context, [
|
|
57
|
-
slice.block as ArbitraryTypedObject,
|
|
58
|
-
])
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (slice.children.length > 0) {
|
|
62
|
-
if (
|
|
63
|
-
slice.children.every(
|
|
64
|
-
(child) => isSpan(context, child) && child.text.trim() === '',
|
|
65
|
-
)
|
|
66
|
-
) {
|
|
67
|
-
return []
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return flattenNestedBlocks(context, [
|
|
71
|
-
{
|
|
72
|
-
...block,
|
|
73
|
-
children: slice.children,
|
|
74
|
-
},
|
|
75
|
-
])
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return []
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return [block]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return [block]
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
return flattened
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function isBlockContainer(
|
|
92
|
-
block: ArbitraryTypedObject,
|
|
93
|
-
): block is BlockContainer {
|
|
94
|
-
return block._type === '__block' && isArbitraryTypedObject(block.block)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
type BlockContainer = {
|
|
98
|
-
_type: '__block'
|
|
99
|
-
block: ArbitraryTypedObject
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function getSplitChildren(
|
|
103
|
-
context: {schema: Schema},
|
|
104
|
-
block: PortableTextTextBlock,
|
|
105
|
-
) {
|
|
106
|
-
return block.children.reduce(
|
|
107
|
-
(slices, child) => {
|
|
108
|
-
const knownInlineObject = context.schema.inlineObjects.some(
|
|
109
|
-
(inlineObject) => inlineObject.name === child._type,
|
|
110
|
-
)
|
|
111
|
-
const knownBlockObject = context.schema.blockObjects.some(
|
|
112
|
-
(blockObject) => blockObject.name === child._type,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
const lastSlice = slices.pop()
|
|
116
|
-
|
|
117
|
-
if (!isSpan(context, child) && !knownInlineObject) {
|
|
118
|
-
if (knownBlockObject) {
|
|
119
|
-
return [
|
|
120
|
-
...slices,
|
|
121
|
-
...(lastSlice ? [lastSlice] : []),
|
|
122
|
-
{type: 'block object' as const, block: child},
|
|
123
|
-
]
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (child._type === '__block') {
|
|
128
|
-
return [
|
|
129
|
-
...slices,
|
|
130
|
-
...(lastSlice ? [lastSlice] : []),
|
|
131
|
-
{
|
|
132
|
-
type: 'block object' as const,
|
|
133
|
-
block: (child as any).block,
|
|
134
|
-
},
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (child._type === 'block') {
|
|
139
|
-
return [
|
|
140
|
-
...slices,
|
|
141
|
-
...(lastSlice ? [lastSlice] : []),
|
|
142
|
-
{type: 'block' as const, block: child},
|
|
143
|
-
]
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (lastSlice) {
|
|
147
|
-
if (lastSlice.type === 'children') {
|
|
148
|
-
return [
|
|
149
|
-
...slices,
|
|
150
|
-
{
|
|
151
|
-
type: 'children' as const,
|
|
152
|
-
children: [...lastSlice.children, child],
|
|
153
|
-
},
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return [
|
|
159
|
-
...slices,
|
|
160
|
-
...(lastSlice ? [lastSlice] : []),
|
|
161
|
-
{type: 'children' as const, children: [child]},
|
|
162
|
-
]
|
|
163
|
-
},
|
|
164
|
-
[] as Array<
|
|
165
|
-
| {
|
|
166
|
-
type: 'children'
|
|
167
|
-
children: Array<PortableTextSpan | PortableTextObject>
|
|
168
|
-
}
|
|
169
|
-
| {type: 'block object'; block: PortableTextObject}
|
|
170
|
-
| {type: 'block'; block: PortableTextBlock}
|
|
171
|
-
>,
|
|
172
|
-
)
|
|
173
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import type {Schema} from '@portabletext/schema'
|
|
2
|
-
import {isTextBlock, type PortableTextObject} from '@portabletext/schema'
|
|
3
|
-
import {DEFAULT_BLOCK} from '../constants'
|
|
4
|
-
import type {
|
|
5
|
-
ArbitraryTypedObject,
|
|
6
|
-
HtmlParser,
|
|
7
|
-
MinimalBlock,
|
|
8
|
-
MinimalSpan,
|
|
9
|
-
PlaceholderAnnotation,
|
|
10
|
-
PlaceholderDecorator,
|
|
11
|
-
TypedObject,
|
|
12
|
-
} from '../types'
|
|
13
|
-
import {resolveJsType} from '../util/resolveJsType'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Utility function that always return a lowerCase version of the element.tagName
|
|
17
|
-
*
|
|
18
|
-
* @param el - Element to get tag name for
|
|
19
|
-
* @returns Lowercase tagName for that element, or undefined if not an element
|
|
20
|
-
*/
|
|
21
|
-
export function tagName(el: HTMLElement | Node | null): string | undefined {
|
|
22
|
-
if (el && 'tagName' in el) {
|
|
23
|
-
return el.tagName.toLowerCase()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return undefined
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* A default `parseHtml` function that returns the html using `DOMParser`.
|
|
31
|
-
*
|
|
32
|
-
* @returns HTML Parser based on `DOMParser`
|
|
33
|
-
*/
|
|
34
|
-
export function defaultParseHtml(): HtmlParser {
|
|
35
|
-
if (resolveJsType(DOMParser) === 'undefined') {
|
|
36
|
-
throw new Error(
|
|
37
|
-
'The native `DOMParser` global which the `Html` deserializer uses by ' +
|
|
38
|
-
'default is not present in this environment. ' +
|
|
39
|
-
'You must supply the `options.parseHtml` function instead.',
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
return (html) => {
|
|
43
|
-
return new DOMParser().parseFromString(html, 'text/html')
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function ensureRootIsBlocks(
|
|
48
|
-
schema: Schema,
|
|
49
|
-
objects: Array<ArbitraryTypedObject>,
|
|
50
|
-
): ArbitraryTypedObject[] {
|
|
51
|
-
return objects.reduce((blocks, node, i, original) => {
|
|
52
|
-
if (node._type === 'block') {
|
|
53
|
-
blocks.push(node)
|
|
54
|
-
return blocks
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (node._type === '__block') {
|
|
58
|
-
blocks.push((node as any).block)
|
|
59
|
-
return blocks
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const lastBlock = blocks[blocks.length - 1]
|
|
63
|
-
if (
|
|
64
|
-
i > 0 &&
|
|
65
|
-
!isTextBlock({schema}, original[i - 1]) &&
|
|
66
|
-
isTextBlock({schema}, lastBlock)
|
|
67
|
-
) {
|
|
68
|
-
lastBlock.children.push(node as PortableTextObject)
|
|
69
|
-
return blocks
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const block = {
|
|
73
|
-
...DEFAULT_BLOCK,
|
|
74
|
-
children: [node],
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
blocks.push(block)
|
|
78
|
-
return blocks
|
|
79
|
-
}, [] as ArbitraryTypedObject[])
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function isNodeList(node: unknown): node is NodeList {
|
|
83
|
-
return Object.prototype.toString.call(node) === '[object NodeList]'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function isMinimalSpan(node: TypedObject): node is MinimalSpan {
|
|
87
|
-
return node._type === 'span'
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function isMinimalBlock(node: TypedObject): node is MinimalBlock {
|
|
91
|
-
return node._type === 'block'
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function isPlaceholderDecorator(
|
|
95
|
-
node: TypedObject,
|
|
96
|
-
): node is PlaceholderDecorator {
|
|
97
|
-
return node._type === '__decorator'
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function isPlaceholderAnnotation(
|
|
101
|
-
node: TypedObject,
|
|
102
|
-
): node is PlaceholderAnnotation {
|
|
103
|
-
return node._type === '__annotation'
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function isElement(node: Node): node is Element {
|
|
107
|
-
return node.nodeType === 1
|
|
108
|
-
}
|