@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/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