@portabletext/block-tools 3.5.14 → 4.0.1
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-dts/types.d.ts +1 -1
- package/lib/_chunks-es/helpers.js +3 -193
- package/lib/_chunks-es/helpers.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +193 -1
- package/lib/index.js.map +1 -1
- package/lib/rules/index.d.ts +1 -1
- package/package.json +14 -16
- package/src/HtmlDeserializer/helpers.ts +0 -21
- package/src/HtmlDeserializer/index.ts +22 -1
- package/lib/_chunks-cjs/helpers.cjs +0 -479
- package/lib/_chunks-cjs/helpers.cjs.map +0 -1
- package/lib/_chunks-dts/types.d.cts +0 -85
- package/lib/index.cjs +0 -654
- package/lib/index.cjs.map +0 -1
- package/lib/index.d.cts +0 -62
- package/lib/rules/index.cjs +0 -69
- package/lib/rules/index.cjs.map +0 -1
- package/lib/rules/index.d.cts +0 -72
package/lib/index.cjs
DELETED
|
@@ -1,654 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
-
var sanityBridge = require("@portabletext/sanity-bridge"), schema = require("@portabletext/schema"), flatten = require("lodash/flatten.js"), helpers = require("./_chunks-cjs/helpers.cjs"), isEqual = require("lodash/isEqual.js");
|
|
4
|
-
function _interopDefaultCompat(e) {
|
|
5
|
-
return e && typeof e == "object" && "default" in e ? e : { default: e };
|
|
6
|
-
}
|
|
7
|
-
var flatten__default = /* @__PURE__ */ _interopDefaultCompat(flatten), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual);
|
|
8
|
-
function keyGenerator() {
|
|
9
|
-
return randomKey(12);
|
|
10
|
-
}
|
|
11
|
-
function whatwgRNG(length = 16) {
|
|
12
|
-
const rnds8 = new Uint8Array(length);
|
|
13
|
-
return crypto.getRandomValues(rnds8), rnds8;
|
|
14
|
-
}
|
|
15
|
-
const byteToHex = [];
|
|
16
|
-
for (let i = 0; i < 256; ++i)
|
|
17
|
-
byteToHex[i] = (i + 256).toString(16).slice(1);
|
|
18
|
-
function randomKey(length) {
|
|
19
|
-
return whatwgRNG(length).reduce((str, n) => str + byteToHex[n], "").slice(0, length);
|
|
20
|
-
}
|
|
21
|
-
const LIST_CONTAINER_TAGS = Object.keys(helpers.HTML_LIST_CONTAINER_TAGS);
|
|
22
|
-
function isEmphasis$1(el) {
|
|
23
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
24
|
-
return /font-style\s*:\s*italic/.test(style || "");
|
|
25
|
-
}
|
|
26
|
-
function isStrong$1(el) {
|
|
27
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
28
|
-
return /font-weight\s*:\s*700/.test(style || "");
|
|
29
|
-
}
|
|
30
|
-
function isUnderline$1(el) {
|
|
31
|
-
if (!helpers.isElement(el) || helpers.tagName(el.parentNode) === "a")
|
|
32
|
-
return !1;
|
|
33
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
34
|
-
return /text-decoration\s*:\s*underline/.test(style || "");
|
|
35
|
-
}
|
|
36
|
-
function isStrikethrough(el) {
|
|
37
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
38
|
-
return /text-decoration\s*:\s*(?:.*line-through.*;)/.test(style || "");
|
|
39
|
-
}
|
|
40
|
-
function isGoogleDocs(el) {
|
|
41
|
-
return helpers.isElement(el) && !!el.getAttribute("data-is-google-docs");
|
|
42
|
-
}
|
|
43
|
-
function isRootNode(el) {
|
|
44
|
-
return helpers.isElement(el) && !!el.getAttribute("data-is-root-node");
|
|
45
|
-
}
|
|
46
|
-
function getListItemStyle$1(el) {
|
|
47
|
-
const parentTag = helpers.tagName(el.parentNode);
|
|
48
|
-
if (!(parentTag && !LIST_CONTAINER_TAGS.includes(parentTag)))
|
|
49
|
-
return helpers.tagName(el.parentNode) === "ul" ? "bullet" : "number";
|
|
50
|
-
}
|
|
51
|
-
function getListItemLevel$1(el) {
|
|
52
|
-
let level = 0;
|
|
53
|
-
if (helpers.tagName(el) === "li") {
|
|
54
|
-
let parentNode = el.parentNode;
|
|
55
|
-
for (; parentNode; ) {
|
|
56
|
-
const parentTag = helpers.tagName(parentNode);
|
|
57
|
-
parentTag && LIST_CONTAINER_TAGS.includes(parentTag) && level++, parentNode = parentNode.parentNode;
|
|
58
|
-
}
|
|
59
|
-
} else
|
|
60
|
-
level = 1;
|
|
61
|
-
return level;
|
|
62
|
-
}
|
|
63
|
-
const blocks = {
|
|
64
|
-
...helpers.HTML_BLOCK_TAGS,
|
|
65
|
-
...helpers.HTML_HEADER_TAGS
|
|
66
|
-
};
|
|
67
|
-
function getBlockStyle(schema2, el) {
|
|
68
|
-
const childTag = helpers.tagName(el.firstChild), block = childTag && blocks[childTag];
|
|
69
|
-
return block && schema2.styles.some((style) => style.name === block.style) ? block.style : helpers.BLOCK_DEFAULT_STYLE;
|
|
70
|
-
}
|
|
71
|
-
function createGDocsRules(schema2) {
|
|
72
|
-
return [
|
|
73
|
-
{
|
|
74
|
-
deserialize(el, next) {
|
|
75
|
-
if (helpers.isElement(el) && helpers.tagName(el) === "span" && isGoogleDocs(el)) {
|
|
76
|
-
if (!el.textContent)
|
|
77
|
-
return !el.previousSibling && !el.nextSibling && el.setAttribute("data-lonely-child", "true"), next(el.childNodes);
|
|
78
|
-
const span = {
|
|
79
|
-
...helpers.DEFAULT_SPAN,
|
|
80
|
-
marks: [],
|
|
81
|
-
text: el.textContent
|
|
82
|
-
};
|
|
83
|
-
return isStrong$1(el) && span.marks.push("strong"), isUnderline$1(el) && span.marks.push("underline"), isStrikethrough(el) && span.marks.push("strike-through"), isEmphasis$1(el) && span.marks.push("em"), span;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
deserialize(el, next) {
|
|
89
|
-
if (helpers.tagName(el) === "li" && isGoogleDocs(el))
|
|
90
|
-
return {
|
|
91
|
-
...helpers.DEFAULT_BLOCK,
|
|
92
|
-
listItem: getListItemStyle$1(el),
|
|
93
|
-
level: getListItemLevel$1(el),
|
|
94
|
-
style: getBlockStyle(schema2, el),
|
|
95
|
-
children: next(el.firstChild?.childNodes || [])
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
deserialize(el) {
|
|
101
|
-
if (helpers.tagName(el) === "br" && isGoogleDocs(el) && helpers.isElement(el) && el.classList.contains("apple-interchange-newline"))
|
|
102
|
-
return {
|
|
103
|
-
...helpers.DEFAULT_SPAN,
|
|
104
|
-
text: ""
|
|
105
|
-
};
|
|
106
|
-
if (helpers.tagName(el) === "br" && isGoogleDocs(el) && helpers.isElement(el) && el?.parentNode?.textContent === "")
|
|
107
|
-
return {
|
|
108
|
-
...helpers.DEFAULT_SPAN,
|
|
109
|
-
text: ""
|
|
110
|
-
};
|
|
111
|
-
if (helpers.tagName(el) === "br" && isGoogleDocs(el) && helpers.isElement(el) && isRootNode(el))
|
|
112
|
-
return {
|
|
113
|
-
...helpers.DEFAULT_SPAN,
|
|
114
|
-
text: ""
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
];
|
|
119
|
-
}
|
|
120
|
-
const whitespaceTextNodeRule = {
|
|
121
|
-
deserialize(node) {
|
|
122
|
-
return node.nodeName === "#text" && isWhitespaceTextNode(node) ? {
|
|
123
|
-
...helpers.DEFAULT_SPAN,
|
|
124
|
-
marks: [],
|
|
125
|
-
text: (node.textContent ?? "").replace(/\s\s+/g, " ")
|
|
126
|
-
} : void 0;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
function isWhitespaceTextNode(node) {
|
|
130
|
-
return (node.nodeType === 3 && (node.textContent || "").replace(/[\r\n]/g, " ").replace(/\s\s+/g, " ") === " " && node.nextSibling && node.nextSibling.nodeType !== 3 && node.previousSibling && node.previousSibling.nodeType !== 3 || node.textContent !== " ") && helpers.tagName(node.parentNode) !== "body";
|
|
131
|
-
}
|
|
132
|
-
function resolveListItem(schema2, listNodeTagName) {
|
|
133
|
-
if (listNodeTagName === "ul" && schema2.lists.some((list) => list.name === "bullet"))
|
|
134
|
-
return "bullet";
|
|
135
|
-
if (listNodeTagName === "ol" && schema2.lists.some((list) => list.name === "number"))
|
|
136
|
-
return "number";
|
|
137
|
-
}
|
|
138
|
-
function createHTMLRules(schema2, options) {
|
|
139
|
-
return [
|
|
140
|
-
whitespaceTextNodeRule,
|
|
141
|
-
{
|
|
142
|
-
// Pre element
|
|
143
|
-
deserialize(el) {
|
|
144
|
-
if (helpers.tagName(el) !== "pre")
|
|
145
|
-
return;
|
|
146
|
-
const isCodeEnabled = schema2.styles.some(
|
|
147
|
-
(style) => style.name === "code"
|
|
148
|
-
);
|
|
149
|
-
return {
|
|
150
|
-
_type: "block",
|
|
151
|
-
style: "normal",
|
|
152
|
-
markDefs: [],
|
|
153
|
-
children: [
|
|
154
|
-
{
|
|
155
|
-
...helpers.DEFAULT_SPAN,
|
|
156
|
-
marks: isCodeEnabled ? ["code"] : [],
|
|
157
|
-
text: el.textContent || ""
|
|
158
|
-
}
|
|
159
|
-
]
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
// Blockquote element
|
|
164
|
-
{
|
|
165
|
-
deserialize(el, next) {
|
|
166
|
-
if (helpers.tagName(el) !== "blockquote")
|
|
167
|
-
return;
|
|
168
|
-
const blocks2 = {
|
|
169
|
-
...helpers.HTML_BLOCK_TAGS,
|
|
170
|
-
...helpers.HTML_HEADER_TAGS
|
|
171
|
-
};
|
|
172
|
-
delete blocks2.blockquote;
|
|
173
|
-
const nonBlockquoteBlocks = Object.keys(blocks2), children = [];
|
|
174
|
-
return el.childNodes.forEach((node, index) => {
|
|
175
|
-
if (el.ownerDocument)
|
|
176
|
-
if (node.nodeType === 1 && nonBlockquoteBlocks.includes(
|
|
177
|
-
node.localName.toLowerCase()
|
|
178
|
-
)) {
|
|
179
|
-
const span = el.ownerDocument.createElement("span"), previousChild = children[children.length - 1];
|
|
180
|
-
previousChild && previousChild.nodeType === 3 && previousChild.textContent?.trim() && span.appendChild(el.ownerDocument.createTextNode("\r")), node.childNodes.forEach((cn) => {
|
|
181
|
-
span.appendChild(cn.cloneNode(!0));
|
|
182
|
-
}), index !== el.childNodes.length && span.appendChild(el.ownerDocument.createTextNode("\r")), children.push(span);
|
|
183
|
-
} else
|
|
184
|
-
children.push(node);
|
|
185
|
-
}), {
|
|
186
|
-
_type: "block",
|
|
187
|
-
style: "blockquote",
|
|
188
|
-
markDefs: [],
|
|
189
|
-
children: next(children)
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
// Block elements
|
|
194
|
-
{
|
|
195
|
-
deserialize(el, next) {
|
|
196
|
-
const blocks2 = {
|
|
197
|
-
...helpers.HTML_BLOCK_TAGS,
|
|
198
|
-
...helpers.HTML_HEADER_TAGS
|
|
199
|
-
}, tag = helpers.tagName(el);
|
|
200
|
-
let block = tag ? blocks2[tag] : void 0;
|
|
201
|
-
if (!block)
|
|
202
|
-
return;
|
|
203
|
-
if (el.parentNode && helpers.tagName(el.parentNode) === "li")
|
|
204
|
-
return next(el.childNodes);
|
|
205
|
-
const blockStyle = block.style;
|
|
206
|
-
return schema2.styles.some((style) => style.name === blockStyle) || (block = helpers.DEFAULT_BLOCK), {
|
|
207
|
-
...block,
|
|
208
|
-
children: next(el.childNodes)
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
// Ignore span tags
|
|
213
|
-
{
|
|
214
|
-
deserialize(el, next) {
|
|
215
|
-
const tag = helpers.tagName(el);
|
|
216
|
-
if (!(!tag || !(tag in helpers.HTML_SPAN_TAGS)))
|
|
217
|
-
return next(el.childNodes);
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
// Ignore div tags
|
|
221
|
-
{
|
|
222
|
-
deserialize(el, next) {
|
|
223
|
-
if (helpers.tagName(el) === "div")
|
|
224
|
-
return next(el.childNodes);
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
// Ignore list containers
|
|
228
|
-
{
|
|
229
|
-
deserialize(el, next) {
|
|
230
|
-
const tag = helpers.tagName(el);
|
|
231
|
-
if (!(!tag || !(tag in helpers.HTML_LIST_CONTAINER_TAGS)))
|
|
232
|
-
return next(el.childNodes);
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
// Deal with br's
|
|
236
|
-
{
|
|
237
|
-
deserialize(el) {
|
|
238
|
-
if (helpers.tagName(el) === "br")
|
|
239
|
-
return {
|
|
240
|
-
...helpers.DEFAULT_SPAN,
|
|
241
|
-
text: `
|
|
242
|
-
`
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
// Deal with list items
|
|
247
|
-
{
|
|
248
|
-
deserialize(el, next, block) {
|
|
249
|
-
const tag = helpers.tagName(el), listItem = tag ? helpers.HTML_LIST_ITEM_TAGS[tag] : void 0, parentTag = helpers.tagName(el.parentNode) || "";
|
|
250
|
-
if (!listItem || !el.parentNode || !helpers.HTML_LIST_CONTAINER_TAGS[parentTag])
|
|
251
|
-
return;
|
|
252
|
-
const enabledListItem = resolveListItem(schema2, parentTag);
|
|
253
|
-
return enabledListItem ? (listItem.listItem = enabledListItem, {
|
|
254
|
-
...listItem,
|
|
255
|
-
children: next(el.childNodes)
|
|
256
|
-
}) : block({ _type: "block", children: next(el.childNodes) });
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
// Deal with decorators - this is a limited set of known html elements that we know how to deserialize
|
|
260
|
-
{
|
|
261
|
-
deserialize(el, next) {
|
|
262
|
-
const decorator = helpers.HTML_DECORATOR_TAGS[helpers.tagName(el) || ""];
|
|
263
|
-
if (!(!decorator || !schema2.decorators.some(
|
|
264
|
-
(decoratorType) => decoratorType.name === decorator
|
|
265
|
-
)))
|
|
266
|
-
return {
|
|
267
|
-
_type: "__decorator",
|
|
268
|
-
name: decorator,
|
|
269
|
-
children: next(el.childNodes)
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
},
|
|
273
|
-
// Special case for hyperlinks, add annotation (if allowed by schema),
|
|
274
|
-
// If not supported just write out the link text and href in plain text.
|
|
275
|
-
{
|
|
276
|
-
deserialize(el, next) {
|
|
277
|
-
if (helpers.tagName(el) !== "a")
|
|
278
|
-
return;
|
|
279
|
-
const linkEnabled = schema2.annotations.some(
|
|
280
|
-
(annotation) => annotation.name === "link"
|
|
281
|
-
), href = helpers.isElement(el) && el.getAttribute("href");
|
|
282
|
-
return href ? linkEnabled ? {
|
|
283
|
-
_type: "__annotation",
|
|
284
|
-
markDef: {
|
|
285
|
-
_key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
|
|
286
|
-
_type: "link",
|
|
287
|
-
href
|
|
288
|
-
},
|
|
289
|
-
children: next(el.childNodes)
|
|
290
|
-
} : el.appendChild(el.ownerDocument.createTextNode(` (${href})`)) && next(el.childNodes) : next(el.childNodes);
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
deserialize(el, next) {
|
|
295
|
-
if (helpers.isElement(el) && (helpers.tagName(el) === "td" || helpers.tagName(el) === "th"))
|
|
296
|
-
return {
|
|
297
|
-
...helpers.DEFAULT_BLOCK,
|
|
298
|
-
children: next(el.childNodes)
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
deserialize(el) {
|
|
304
|
-
if (helpers.isElement(el) && helpers.tagName(el) === "img") {
|
|
305
|
-
const src = el.getAttribute("src") ?? void 0, alt = el.getAttribute("alt") ?? void 0, props = Object.fromEntries(
|
|
306
|
-
Array.from(el.attributes).map((attr) => [attr.name, attr.value])
|
|
307
|
-
), ancestorOfLonelyChild = el?.parentElement?.parentElement?.getAttribute("data-lonely-child"), ancestorOfListItem = el.closest("li") !== null;
|
|
308
|
-
if (ancestorOfLonelyChild && !ancestorOfListItem) {
|
|
309
|
-
const image2 = options.matchers?.image?.({
|
|
310
|
-
context: {
|
|
311
|
-
schema: schema2,
|
|
312
|
-
keyGenerator: options.keyGenerator ?? keyGenerator
|
|
313
|
-
},
|
|
314
|
-
props: {
|
|
315
|
-
...props,
|
|
316
|
-
...src ? { src } : {},
|
|
317
|
-
...alt ? { alt } : {}
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
if (image2)
|
|
321
|
-
return {
|
|
322
|
-
_type: "__block",
|
|
323
|
-
block: image2
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
const inlineImage = options.matchers?.inlineImage?.({
|
|
327
|
-
context: {
|
|
328
|
-
schema: schema2,
|
|
329
|
-
keyGenerator: options.keyGenerator ?? keyGenerator
|
|
330
|
-
},
|
|
331
|
-
props: {
|
|
332
|
-
...props,
|
|
333
|
-
...src ? { src } : {},
|
|
334
|
-
...alt ? { alt } : {}
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
if (inlineImage)
|
|
338
|
-
return inlineImage;
|
|
339
|
-
const image = options.matchers?.image?.({
|
|
340
|
-
context: {
|
|
341
|
-
schema: schema2,
|
|
342
|
-
keyGenerator: options.keyGenerator ?? keyGenerator
|
|
343
|
-
},
|
|
344
|
-
props: {
|
|
345
|
-
...props,
|
|
346
|
-
...src ? { src } : {},
|
|
347
|
-
...alt ? { alt } : {}
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
if (image)
|
|
351
|
-
return {
|
|
352
|
-
_type: "__block",
|
|
353
|
-
block: image
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
];
|
|
359
|
-
}
|
|
360
|
-
function isEmphasis(el) {
|
|
361
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
362
|
-
return /font-style:italic/.test(style || "");
|
|
363
|
-
}
|
|
364
|
-
function isStrong(el) {
|
|
365
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
366
|
-
return /font-weight:700/.test(style || "") || /font-weight:600/.test(style || "");
|
|
367
|
-
}
|
|
368
|
-
function isUnderline(el) {
|
|
369
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
370
|
-
return /text-decoration:underline/.test(style || "");
|
|
371
|
-
}
|
|
372
|
-
function isNotion(el) {
|
|
373
|
-
return helpers.isElement(el) && !!el.getAttribute("data-is-notion");
|
|
374
|
-
}
|
|
375
|
-
function createNotionRules() {
|
|
376
|
-
return [
|
|
377
|
-
{
|
|
378
|
-
deserialize(el) {
|
|
379
|
-
if (helpers.isElement(el) && helpers.tagName(el) === "span" && isNotion(el)) {
|
|
380
|
-
const span = {
|
|
381
|
-
...helpers.DEFAULT_SPAN,
|
|
382
|
-
marks: [],
|
|
383
|
-
text: el.textContent
|
|
384
|
-
};
|
|
385
|
-
return isStrong(el) && span.marks.push("strong"), isUnderline(el) && span.marks.push("underline"), isEmphasis(el) && span.marks.push("em"), span;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
];
|
|
390
|
-
}
|
|
391
|
-
function getListItemStyle(el) {
|
|
392
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
393
|
-
if (style && style.match(/lfo\d+/))
|
|
394
|
-
return style.match("lfo1") ? "bullet" : "number";
|
|
395
|
-
}
|
|
396
|
-
function getListItemLevel(el) {
|
|
397
|
-
const style = helpers.isElement(el) && el.getAttribute("style");
|
|
398
|
-
if (!style)
|
|
399
|
-
return;
|
|
400
|
-
const levelMatch = style.match(/level\d+/);
|
|
401
|
-
if (!levelMatch)
|
|
402
|
-
return;
|
|
403
|
-
const [level] = levelMatch[0].match(/\d/) || [];
|
|
404
|
-
return (level ? Number.parseInt(level, 10) : 1) || 1;
|
|
405
|
-
}
|
|
406
|
-
function isWordListElement(el) {
|
|
407
|
-
return helpers.isElement(el) && el.className ? el.className === "MsoListParagraphCxSpFirst" || el.className === "MsoListParagraphCxSpMiddle" || el.className === "MsoListParagraphCxSpLast" : !1;
|
|
408
|
-
}
|
|
409
|
-
function createWordRules() {
|
|
410
|
-
return [
|
|
411
|
-
{
|
|
412
|
-
deserialize(el, next) {
|
|
413
|
-
if (helpers.tagName(el) === "p" && isWordListElement(el))
|
|
414
|
-
return {
|
|
415
|
-
...helpers.DEFAULT_BLOCK,
|
|
416
|
-
listItem: getListItemStyle(el),
|
|
417
|
-
level: getListItemLevel(el),
|
|
418
|
-
style: helpers.BLOCK_DEFAULT_STYLE,
|
|
419
|
-
children: next(el.childNodes)
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
];
|
|
424
|
-
}
|
|
425
|
-
function createRules(schema2, options) {
|
|
426
|
-
return [
|
|
427
|
-
...createWordRules(),
|
|
428
|
-
...createNotionRules(),
|
|
429
|
-
...createGDocsRules(schema2),
|
|
430
|
-
...createHTMLRules(schema2, options)
|
|
431
|
-
];
|
|
432
|
-
}
|
|
433
|
-
class HtmlDeserializer {
|
|
434
|
-
keyGenerator;
|
|
435
|
-
schema;
|
|
436
|
-
rules;
|
|
437
|
-
parseHtml;
|
|
438
|
-
_markDefs = [];
|
|
439
|
-
/**
|
|
440
|
-
* Create a new serializer respecting a Sanity block content type's schema
|
|
441
|
-
*
|
|
442
|
-
* @param blockContentType - Schema type for array containing _at least_ a block child type
|
|
443
|
-
* @param options - Options for the deserialization process
|
|
444
|
-
*/
|
|
445
|
-
constructor(schema2, options = {}) {
|
|
446
|
-
const { rules = [], unstable_whitespaceOnPasteMode = "preserve" } = options, standardRules = createRules(schema2, {
|
|
447
|
-
keyGenerator: options.keyGenerator,
|
|
448
|
-
matchers: options.matchers
|
|
449
|
-
});
|
|
450
|
-
this.schema = schema2, this.keyGenerator = options.keyGenerator ?? keyGenerator, this.rules = [...rules, ...standardRules];
|
|
451
|
-
const parseHtml = options.parseHtml || helpers.defaultParseHtml();
|
|
452
|
-
this.parseHtml = (html) => helpers.preprocess(html, parseHtml, { unstable_whitespaceOnPasteMode }).body;
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Deserialize HTML.
|
|
456
|
-
*
|
|
457
|
-
* @param html - The HTML to deserialize, as a string
|
|
458
|
-
* @returns Array of blocks - either portable text blocks or other allowed blocks
|
|
459
|
-
*/
|
|
460
|
-
deserialize = (html) => {
|
|
461
|
-
this._markDefs = [];
|
|
462
|
-
const { parseHtml } = this, fragment = parseHtml(html), children = Array.from(fragment.childNodes), blocks2 = helpers.trimWhitespace(
|
|
463
|
-
this.schema,
|
|
464
|
-
helpers.flattenNestedBlocks(
|
|
465
|
-
{ schema: this.schema },
|
|
466
|
-
helpers.ensureRootIsBlocks(
|
|
467
|
-
this.schema,
|
|
468
|
-
this.deserializeElements(children)
|
|
469
|
-
)
|
|
470
|
-
)
|
|
471
|
-
);
|
|
472
|
-
return this._markDefs.length > 0 && blocks2.filter((block) => schema.isTextBlock({ schema: this.schema }, block)).forEach((block) => {
|
|
473
|
-
block.markDefs = block.markDefs || [], block.markDefs = block.markDefs.concat(
|
|
474
|
-
this._markDefs.filter((def) => flatten__default.default(
|
|
475
|
-
block.children.map((child) => child.marks || [])
|
|
476
|
-
).includes(def._key))
|
|
477
|
-
);
|
|
478
|
-
}), blocks2.map((block) => (block._type === "block" && (block._type = this.schema.block.name), block));
|
|
479
|
-
};
|
|
480
|
-
/**
|
|
481
|
-
* Deserialize an array of DOM elements.
|
|
482
|
-
*
|
|
483
|
-
* @param elements - Array of DOM elements to deserialize
|
|
484
|
-
* @returns
|
|
485
|
-
*/
|
|
486
|
-
deserializeElements = (elements = []) => {
|
|
487
|
-
let nodes = [];
|
|
488
|
-
return elements.forEach((element) => {
|
|
489
|
-
nodes = nodes.concat(this.deserializeElement(element));
|
|
490
|
-
}), nodes;
|
|
491
|
-
};
|
|
492
|
-
/**
|
|
493
|
-
* Deserialize a DOM element
|
|
494
|
-
*
|
|
495
|
-
* @param element - Deserialize a DOM element
|
|
496
|
-
* @returns
|
|
497
|
-
*/
|
|
498
|
-
deserializeElement = (element) => {
|
|
499
|
-
const next = (elements) => {
|
|
500
|
-
if (helpers.isNodeList(elements))
|
|
501
|
-
return this.deserializeElements(Array.from(elements));
|
|
502
|
-
if (Array.isArray(elements))
|
|
503
|
-
return this.deserializeElements(elements);
|
|
504
|
-
if (elements)
|
|
505
|
-
return this.deserializeElement(elements);
|
|
506
|
-
}, block = (props) => ({
|
|
507
|
-
_type: "__block",
|
|
508
|
-
block: props
|
|
509
|
-
});
|
|
510
|
-
let node;
|
|
511
|
-
for (let i = 0; i < this.rules.length; i++) {
|
|
512
|
-
const rule = this.rules[i];
|
|
513
|
-
if (!rule.deserialize)
|
|
514
|
-
continue;
|
|
515
|
-
const ret = rule.deserialize(element, next, block), type = helpers.resolveJsType(ret);
|
|
516
|
-
if (type !== "array" && type !== "object" && type !== "null" && type !== "undefined")
|
|
517
|
-
throw new Error(
|
|
518
|
-
`A rule returned an invalid deserialized representation: "${node}".`
|
|
519
|
-
);
|
|
520
|
-
if (ret !== void 0) {
|
|
521
|
-
{
|
|
522
|
-
if (ret === null)
|
|
523
|
-
throw new Error("Deserializer rule returned `null`");
|
|
524
|
-
Array.isArray(ret) ? node = ret : helpers.isPlaceholderDecorator(ret) ? node = this.deserializeDecorator(ret) : helpers.isPlaceholderAnnotation(ret) ? node = this.deserializeAnnotation(ret) : node = ret;
|
|
525
|
-
}
|
|
526
|
-
if (ret && !Array.isArray(ret) && helpers.isMinimalBlock(ret) && "listItem" in ret) {
|
|
527
|
-
let parent = element.parentNode?.parentNode;
|
|
528
|
-
for (; parent && helpers.tagName(parent) === "li"; )
|
|
529
|
-
parent = parent.parentNode?.parentNode, ret.level = ret.level ? ret.level + 1 : 1;
|
|
530
|
-
}
|
|
531
|
-
ret && !Array.isArray(ret) && helpers.isMinimalBlock(ret) && ret.style === "blockquote" && ret.children.forEach((child, index) => {
|
|
532
|
-
helpers.isMinimalSpan(child) && child.text === "\r" && (child.text = `
|
|
533
|
-
`, (index === 0 || index === ret.children.length - 1) && ret.children.splice(index, 1));
|
|
534
|
-
});
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
return node || next(element.childNodes) || [];
|
|
539
|
-
};
|
|
540
|
-
/**
|
|
541
|
-
* Deserialize a `__decorator` type
|
|
542
|
-
* (an internal made up type to process decorators exclusively)
|
|
543
|
-
*
|
|
544
|
-
* @param decorator -
|
|
545
|
-
* @returns array of ...
|
|
546
|
-
*/
|
|
547
|
-
deserializeDecorator = (decorator) => {
|
|
548
|
-
const { name } = decorator, applyDecorator = (node) => {
|
|
549
|
-
if (helpers.isPlaceholderDecorator(node))
|
|
550
|
-
return this.deserializeDecorator(node);
|
|
551
|
-
if (helpers.isMinimalSpan(node))
|
|
552
|
-
node.marks = node.marks || [], node.text.trim() && node.marks.unshift(name);
|
|
553
|
-
else if ("children" in node && Array.isArray(node.children)) {
|
|
554
|
-
const block = node;
|
|
555
|
-
block.children = block.children.map(applyDecorator);
|
|
556
|
-
}
|
|
557
|
-
return node;
|
|
558
|
-
};
|
|
559
|
-
return decorator.children.reduce((children, node) => {
|
|
560
|
-
const ret = applyDecorator(node);
|
|
561
|
-
return Array.isArray(ret) ? children.concat(ret) : (children.push(ret), children);
|
|
562
|
-
}, []);
|
|
563
|
-
};
|
|
564
|
-
/**
|
|
565
|
-
* Deserialize a `__annotation` object.
|
|
566
|
-
* (an internal made up type to process annotations exclusively)
|
|
567
|
-
*
|
|
568
|
-
* @param annotation -
|
|
569
|
-
* @returns Array of...
|
|
570
|
-
*/
|
|
571
|
-
deserializeAnnotation = (annotation) => {
|
|
572
|
-
const { markDef } = annotation;
|
|
573
|
-
this._markDefs.push(markDef);
|
|
574
|
-
const applyAnnotation = (node) => {
|
|
575
|
-
if (helpers.isPlaceholderAnnotation(node))
|
|
576
|
-
return this.deserializeAnnotation(node);
|
|
577
|
-
if (helpers.isMinimalSpan(node))
|
|
578
|
-
node.marks = node.marks || [], node.text.trim() && node.marks.unshift(markDef._key);
|
|
579
|
-
else if ("children" in node && Array.isArray(node.children)) {
|
|
580
|
-
const block = node;
|
|
581
|
-
block.children = block.children.map(applyAnnotation);
|
|
582
|
-
}
|
|
583
|
-
return node;
|
|
584
|
-
};
|
|
585
|
-
return annotation.children.reduce((children, node) => {
|
|
586
|
-
const ret = applyAnnotation(node);
|
|
587
|
-
return Array.isArray(ret) ? children.concat(ret) : (children.push(ret), children);
|
|
588
|
-
}, []);
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
function normalizeBlock(node, options = {}) {
|
|
592
|
-
const schema$1 = {
|
|
593
|
-
block: {
|
|
594
|
-
name: options.blockTypeName || "block"
|
|
595
|
-
},
|
|
596
|
-
span: {
|
|
597
|
-
name: "span"
|
|
598
|
-
},
|
|
599
|
-
styles: [],
|
|
600
|
-
lists: [],
|
|
601
|
-
decorators: [],
|
|
602
|
-
annotations: [],
|
|
603
|
-
blockObjects: [],
|
|
604
|
-
inlineObjects: []
|
|
605
|
-
};
|
|
606
|
-
if (node._type !== (options.blockTypeName || "block"))
|
|
607
|
-
return "_key" in node ? node : {
|
|
608
|
-
...node,
|
|
609
|
-
_key: options.keyGenerator ? options.keyGenerator() : keyGenerator()
|
|
610
|
-
};
|
|
611
|
-
const block = {
|
|
612
|
-
_key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
|
|
613
|
-
children: [],
|
|
614
|
-
markDefs: [],
|
|
615
|
-
...node
|
|
616
|
-
}, lastChild = block.children[block.children.length - 1];
|
|
617
|
-
if (!lastChild)
|
|
618
|
-
return block.children = [
|
|
619
|
-
{
|
|
620
|
-
_type: "span",
|
|
621
|
-
_key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
|
|
622
|
-
text: "",
|
|
623
|
-
marks: []
|
|
624
|
-
}
|
|
625
|
-
], block;
|
|
626
|
-
const usedMarkDefs = [], allowedDecorators = options.allowedDecorators && Array.isArray(options.allowedDecorators) ? options.allowedDecorators : !1;
|
|
627
|
-
return block.children = block.children.reduce(
|
|
628
|
-
(acc, child) => {
|
|
629
|
-
const previousChild = acc[acc.length - 1];
|
|
630
|
-
return previousChild && schema.isSpan({ schema: schema$1 }, child) && schema.isSpan({ schema: schema$1 }, previousChild) && isEqual__default.default(previousChild.marks, child.marks) ? (lastChild && lastChild === child && child.text === "" && block.children.length > 1 || (previousChild.text += child.text), acc) : (acc.push(child), acc);
|
|
631
|
-
},
|
|
632
|
-
[]
|
|
633
|
-
).map((child) => {
|
|
634
|
-
if (!child)
|
|
635
|
-
throw new Error("missing child");
|
|
636
|
-
return child._key = options.keyGenerator ? options.keyGenerator() : keyGenerator(), schema.isSpan({ schema: schema$1 }, child) && (child.marks ? allowedDecorators && (child.marks = child.marks.filter((mark) => {
|
|
637
|
-
const isAllowed = allowedDecorators.includes(mark), isUsed = block.markDefs?.some((def) => def._key === mark);
|
|
638
|
-
return isAllowed || isUsed;
|
|
639
|
-
})) : child.marks = [], usedMarkDefs.push(...child.marks)), child;
|
|
640
|
-
}), block.markDefs = (block.markDefs || []).filter(
|
|
641
|
-
(markDef) => usedMarkDefs.includes(markDef._key)
|
|
642
|
-
), block;
|
|
643
|
-
}
|
|
644
|
-
function htmlToBlocks(html, schemaType, options = {}) {
|
|
645
|
-
const schema2 = isSanitySchema(schemaType) ? sanityBridge.sanitySchemaToPortableTextSchema(schemaType) : schemaType;
|
|
646
|
-
return new HtmlDeserializer(schema2, options).deserialize(html).map((block) => normalizeBlock(block, { keyGenerator: options.keyGenerator }));
|
|
647
|
-
}
|
|
648
|
-
function isSanitySchema(schema2) {
|
|
649
|
-
return schema2.hasOwnProperty("jsonType");
|
|
650
|
-
}
|
|
651
|
-
exports.htmlToBlocks = htmlToBlocks;
|
|
652
|
-
exports.normalizeBlock = normalizeBlock;
|
|
653
|
-
exports.randomKey = randomKey;
|
|
654
|
-
//# sourceMappingURL=index.cjs.map
|