@portabletext/block-tools 1.0.1 → 1.1.0

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.js CHANGED
@@ -1,10 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var flatten = require("lodash/flatten.js"), types = require("@sanity/types"), isEqual = require("lodash/isEqual.js"), uniq = require("lodash/uniq.js"), getRandomValues = require("get-random-values-esm");
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), uniq__default = /* @__PURE__ */ _interopDefaultCompat(uniq), getRandomValues__default = /* @__PURE__ */ _interopDefaultCompat(getRandomValues);
1
+ import flatten from "lodash/flatten.js";
2
+ import { isBlockSchemaType, isBlockChildrenObjectField, isObjectSchemaType, isBlockStyleObjectField, isBlockListObjectField, isTitledListValue, isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";
3
+ import isEqual from "lodash/isEqual.js";
4
+ import uniq from "lodash/uniq.js";
5
+ import getRandomValues from "get-random-values-esm";
8
6
  function findBlockType(type) {
9
7
  return type.type ? findBlockType(type.type) : type.name === "block";
10
8
  }
@@ -92,19 +90,19 @@ const PRESERVE_WHITESPACE_TAGS = ["pre", "textarea", "code"], BLOCK_DEFAULT_STYL
92
90
  ...HTML_HEADER_TAGS,
93
91
  ...HTML_MISC_TAGS
94
92
  };
95
- uniq__default.default(
93
+ uniq(
96
94
  Object.values(ELEMENT_MAP).filter((tag) => "style" in tag).map((tag) => tag.style)
97
95
  );
98
- uniq__default.default(
96
+ uniq(
99
97
  Object.values(HTML_DECORATOR_TAGS)
100
98
  );
101
99
  function blockContentFeatures(blockContentType) {
102
100
  if (!blockContentType)
103
101
  throw new Error("Parameter 'blockContentType' required");
104
102
  const blockType = blockContentType.of.find(findBlockType);
105
- if (!types.isBlockSchemaType(blockType))
103
+ if (!isBlockSchemaType(blockType))
106
104
  throw new Error("'block' type is not defined in this schema (required).");
107
- const ofType = blockType.fields.find(types.isBlockChildrenObjectField)?.type?.of;
105
+ const ofType = blockType.fields.find(isBlockChildrenObjectField)?.type?.of;
108
106
  if (!ofType)
109
107
  throw new Error("No `of` declaration found for blocks `children` field");
110
108
  const spanType = ofType.find(
@@ -115,9 +113,9 @@ function blockContentFeatures(blockContentType) {
115
113
  "No `span` type found in `block` schema type `children` definition"
116
114
  );
117
115
  const inlineObjectTypes = ofType.filter(
118
- (inlineType) => inlineType.name !== "span" && types.isObjectSchemaType(inlineType)
116
+ (inlineType) => inlineType.name !== "span" && isObjectSchemaType(inlineType)
119
117
  ), blockObjectTypes = blockContentType.of.filter(
120
- (memberType) => memberType.name !== blockType.name && types.isObjectSchemaType(memberType)
118
+ (memberType) => memberType.name !== blockType.name && isObjectSchemaType(memberType)
121
119
  );
122
120
  return {
123
121
  styles: resolveEnabledStyles(blockType),
@@ -133,7 +131,7 @@ function blockContentFeatures(blockContentType) {
133
131
  };
134
132
  }
135
133
  function resolveEnabledStyles(blockType) {
136
- const styleField = blockType.fields.find(types.isBlockStyleObjectField);
134
+ const styleField = blockType.fields.find(isBlockStyleObjectField);
137
135
  if (!styleField)
138
136
  throw new Error(
139
137
  "A field with name 'style' is not defined in the block type (required)."
@@ -159,7 +157,7 @@ function resolveEnabledDecorators(spanType) {
159
157
  return spanType.decorators;
160
158
  }
161
159
  function resolveEnabledListItems(blockType) {
162
- const listField = blockType.fields.find(types.isBlockListObjectField);
160
+ const listField = blockType.fields.find(isBlockListObjectField);
163
161
  if (!listField)
164
162
  throw new Error(
165
163
  "A field with name 'list' is not defined in the block type (required)."
@@ -174,7 +172,7 @@ function resolveEnabledListItems(blockType) {
174
172
  function getTitledListValuesFromEnumListOptions(options) {
175
173
  const list = options ? options.list : void 0;
176
174
  return Array.isArray(list) ? list.map(
177
- (item) => types.isTitledListValue(item) ? item : { title: item, value: item }
175
+ (item) => isTitledListValue(item) ? item : { title: item, value: item }
178
176
  ) : [];
179
177
  }
180
178
  const _XPathResult = {
@@ -397,7 +395,7 @@ function flattenNestedBlocks(blocks2) {
397
395
  const flattened = [], traverse = (nodes) => {
398
396
  const toRemove = [];
399
397
  nodes.forEach((node) => {
400
- depth === 0 && flattened.push(node), types.isPortableTextTextBlock(node) && (depth > 0 && (toRemove.push(node), flattened.push(node)), depth++, traverse(node.children)), node._type === "__block" && (toRemove.push(node), flattened.push(node.block));
398
+ depth === 0 && flattened.push(node), isPortableTextTextBlock(node) && (depth > 0 && (toRemove.push(node), flattened.push(node)), depth++, traverse(node.children)), node._type === "__block" && (toRemove.push(node), flattened.push(node.block));
401
399
  }), toRemove.forEach((node) => {
402
400
  nodes.splice(nodes.indexOf(node), 1);
403
401
  }), depth--;
@@ -417,11 +415,11 @@ function isWhiteSpaceChar(text) {
417
415
  }
418
416
  function trimWhitespace(blocks2) {
419
417
  return blocks2.forEach((block) => {
420
- types.isPortableTextTextBlock(block) && block.children.forEach((child, index) => {
418
+ isPortableTextTextBlock(block) && block.children.forEach((child, index) => {
421
419
  if (!isMinimalSpan(child))
422
420
  return;
423
421
  const nextChild = nextSpan(block, index), prevChild = prevSpan(block, index);
424
- index === 0 && (child.text = child.text.replace(/^[^\S\n]+/g, "")), index === block.children.length - 1 && (child.text = child.text.replace(/[^\S\n]+$/g, "")), /\s/.test(child.text.slice(Math.max(0, child.text.length - 1))) && nextChild && isMinimalSpan(nextChild) && /\s/.test(nextChild.text.slice(0, 1)) && (child.text = child.text.replace(/[^\S\n]+$/g, "")), /\s/.test(child.text.slice(0, 1)) && prevChild && isMinimalSpan(prevChild) && /\s/.test(prevChild.text.slice(Math.max(0, prevChild.text.length - 1))) && (child.text = child.text.replace(/^[^\S\n]+/g, "")), child.text || block.children.splice(index, 1), prevChild && isEqual__default.default(prevChild.marks, child.marks) && isWhiteSpaceChar(child.text) ? (prevChild.text += " ", block.children.splice(index, 1)) : nextChild && isEqual__default.default(nextChild.marks, child.marks) && isWhiteSpaceChar(child.text) && (nextChild.text = ` ${nextChild.text}`, block.children.splice(index, 1));
422
+ index === 0 && (child.text = child.text.replace(/^[^\S\n]+/g, "")), index === block.children.length - 1 && (child.text = child.text.replace(/[^\S\n]+$/g, "")), /\s/.test(child.text.slice(Math.max(0, child.text.length - 1))) && nextChild && isMinimalSpan(nextChild) && /\s/.test(nextChild.text.slice(0, 1)) && (child.text = child.text.replace(/[^\S\n]+$/g, "")), /\s/.test(child.text.slice(0, 1)) && prevChild && isMinimalSpan(prevChild) && /\s/.test(prevChild.text.slice(Math.max(0, prevChild.text.length - 1))) && (child.text = child.text.replace(/^[^\S\n]+/g, "")), child.text || block.children.splice(index, 1), prevChild && isEqual(prevChild.marks, child.marks) && isWhiteSpaceChar(child.text) ? (prevChild.text += " ", block.children.splice(index, 1)) : nextChild && isEqual(nextChild.marks, child.marks) && isWhiteSpaceChar(child.text) && (nextChild.text = ` ${nextChild.text}`, block.children.splice(index, 1));
425
423
  });
426
424
  }), blocks2;
427
425
  }
@@ -432,7 +430,7 @@ function ensureRootIsBlocks(blocks2) {
432
430
  if (node._type === "__block")
433
431
  return memo.push(node.block), memo;
434
432
  const lastBlock = memo[memo.length - 1];
435
- if (i > 0 && !types.isPortableTextTextBlock(original[i - 1]) && types.isPortableTextTextBlock(lastBlock))
433
+ if (i > 0 && !isPortableTextTextBlock(original[i - 1]) && isPortableTextTextBlock(lastBlock))
436
434
  return lastBlock.children.push(node), memo;
437
435
  const block = {
438
436
  ...DEFAULT_BLOCK,
@@ -591,9 +589,12 @@ function createGDocsRules(_blockContentType, options) {
591
589
  }
592
590
  ];
593
591
  }
592
+ function keyGenerator() {
593
+ return randomKey(12);
594
+ }
594
595
  function whatwgRNG(length = 16) {
595
596
  const rnds8 = new Uint8Array(length);
596
- return getRandomValues__default.default(rnds8), rnds8;
597
+ return getRandomValues(rnds8), rnds8;
597
598
  }
598
599
  const byteToHex = [];
599
600
  for (let i = 0; i < 256; ++i)
@@ -762,7 +763,7 @@ function createHTMLRules(_blockContentType, options) {
762
763
  return next(el.childNodes);
763
764
  let markDef;
764
765
  return linkEnabled ? (markDef = {
765
- _key: randomKey(12),
766
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
766
767
  _type: "link",
767
768
  href
768
769
  }, {
@@ -862,10 +863,10 @@ class HtmlDeserializer {
862
863
  const { rules = [], unstable_whitespaceOnPasteMode = "preserve" } = options;
863
864
  if (!blockContentType)
864
865
  throw new Error("Parameter 'blockContentType' is required");
865
- const standardRules = createRules(
866
- blockContentType,
867
- createRuleOptions(blockContentType)
868
- );
866
+ const standardRules = createRules(blockContentType, {
867
+ ...createRuleOptions(blockContentType),
868
+ keyGenerator: options.keyGenerator
869
+ });
869
870
  this.rules = [...rules, ...standardRules];
870
871
  const parseHtml = options.parseHtml || defaultParseHtml();
871
872
  this.blockContentType = blockContentType, this.parseHtml = (html) => preprocess(html, parseHtml, { unstable_whitespaceOnPasteMode }).body;
@@ -887,7 +888,7 @@ class HtmlDeserializer {
887
888
  (block) => block._type === "block"
888
889
  ).forEach((block) => {
889
890
  block.markDefs = block.markDefs || [], block.markDefs = block.markDefs.concat(
890
- this._markDefs.filter((def) => flatten__default.default(
891
+ this._markDefs.filter((def) => flatten(
891
892
  block.children.map((child) => child.marks || [])
892
893
  ).includes(def._key))
893
894
  );
@@ -1009,9 +1010,12 @@ class HtmlDeserializer {
1009
1010
  }
1010
1011
  function normalizeBlock(node, options = {}) {
1011
1012
  if (node._type !== (options.blockTypeName || "block"))
1012
- return "_key" in node ? node : { ...node, _key: randomKey(12) };
1013
+ return "_key" in node ? node : {
1014
+ ...node,
1015
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator()
1016
+ };
1013
1017
  const block = {
1014
- _key: randomKey(12),
1018
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
1015
1019
  children: [],
1016
1020
  markDefs: [],
1017
1021
  ...node
@@ -1020,7 +1024,7 @@ function normalizeBlock(node, options = {}) {
1020
1024
  return block.children = [
1021
1025
  {
1022
1026
  _type: "span",
1023
- _key: `${block._key}0`,
1027
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
1024
1028
  text: "",
1025
1029
  marks: []
1026
1030
  }
@@ -1029,13 +1033,13 @@ function normalizeBlock(node, options = {}) {
1029
1033
  return block.children = block.children.reduce(
1030
1034
  (acc, child) => {
1031
1035
  const previousChild = acc[acc.length - 1];
1032
- return previousChild && types.isPortableTextSpan(child) && types.isPortableTextSpan(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);
1036
+ return previousChild && isPortableTextSpan(child) && isPortableTextSpan(previousChild) && isEqual(previousChild.marks, child.marks) ? (lastChild && lastChild === child && child.text === "" && block.children.length > 1 || (previousChild.text += child.text), acc) : (acc.push(child), acc);
1033
1037
  },
1034
1038
  []
1035
- ).map((child, index) => {
1039
+ ).map((child) => {
1036
1040
  if (!child)
1037
1041
  throw new Error("missing child");
1038
- return child._key = `${block._key}${index}`, types.isPortableTextSpan(child) && (child.marks ? allowedDecorators && (child.marks = child.marks.filter((mark) => {
1042
+ return child._key = options.keyGenerator ? options.keyGenerator() : keyGenerator(), isPortableTextSpan(child) && (child.marks ? allowedDecorators && (child.marks = child.marks.filter((mark) => {
1039
1043
  const isAllowed = allowedDecorators.includes(mark), isUsed = block.markDefs?.some((def) => def._key === mark);
1040
1044
  return isAllowed || isUsed;
1041
1045
  })) : child.marks = [], usedMarkDefs.push(...child.marks)), child;
@@ -1044,13 +1048,15 @@ function normalizeBlock(node, options = {}) {
1044
1048
  ), block;
1045
1049
  }
1046
1050
  function htmlToBlocks(html, blockContentType, options = {}) {
1047
- return new HtmlDeserializer(blockContentType, options).deserialize(html).map((block) => normalizeBlock(block));
1051
+ return new HtmlDeserializer(blockContentType, options).deserialize(html).map((block) => normalizeBlock(block, { keyGenerator: options.keyGenerator }));
1048
1052
  }
1049
1053
  function getBlockContentFeatures(blockContentType) {
1050
1054
  return blockContentFeatures(blockContentType);
1051
1055
  }
1052
- exports.getBlockContentFeatures = getBlockContentFeatures;
1053
- exports.htmlToBlocks = htmlToBlocks;
1054
- exports.normalizeBlock = normalizeBlock;
1055
- exports.randomKey = randomKey;
1056
+ export {
1057
+ getBlockContentFeatures,
1058
+ htmlToBlocks,
1059
+ normalizeBlock,
1060
+ randomKey
1061
+ };
1056
1062
  //# sourceMappingURL=index.js.map