@portabletext/to-html
Version:
Render Portable Text to HTML
354 lines (352 loc) • 12.3 kB
JavaScript
;
const _excluded = ["block", "list", "listItem", "marks", "types"],
_excluded2 = ["listItem"],
_excluded3 = ["_key"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
Object.defineProperty(exports, "__esModule", {
value: !0
});
var toolkit = require("@portabletext/toolkit");
const defaultLists = {
number: ({
children
}) => `<ol>${children}</ol>`,
bullet: ({
children
}) => `<ul>${children}</ul>`
},
DefaultListItem = ({
children
}) => `<li>${children}</li>`,
allowedProtocols = ["http", "https", "mailto", "tel"],
charMap = {
"&": "amp",
"<": "lt",
">": "gt",
'"': "quot",
"'": "#x27"
};
function escapeHTML(str) {
return str.replace(/[&<>"']/g, s => `&${charMap[s]};`);
}
function uriLooksSafe(uri) {
const url = (uri || "").trim(),
first = url.charAt(0);
if (first === "#" || first === "/") return !0;
const colonIndex = url.indexOf(":");
if (colonIndex === -1) return !0;
const proto = url.slice(0, colonIndex).toLowerCase();
if (allowedProtocols.indexOf(proto) !== -1) return !0;
const queryIndex = url.indexOf("?");
if (queryIndex !== -1 && colonIndex > queryIndex) return !0;
const hashIndex = url.indexOf("#");
return hashIndex !== -1 && colonIndex > hashIndex;
}
const link = ({
children,
value
}) => {
const href = (value == null ? void 0 : value.href) || "";
return uriLooksSafe(href) ? `<a href="${escapeHTML(href)}">${children}</a>` : children;
},
defaultMarks = {
em: ({
children
}) => `<em>${children}</em>`,
strong: ({
children
}) => `<strong>${children}</strong>`,
code: ({
children
}) => `<code>${children}</code>`,
underline: ({
children
}) => `<span style="text-decoration:underline">${children}</span>`,
"strike-through": ({
children
}) => `<del>${children}</del>`,
link
},
getTemplate = (type, prop) => `Unknown ${type}, specify a component for it in the \`components.${prop}\` option`,
unknownTypeWarning = typeName => getTemplate(`block type "${typeName}"`, "types"),
unknownMarkWarning = markType => getTemplate(`mark type "${markType}"`, "marks"),
unknownBlockStyleWarning = blockStyle => getTemplate(`block style "${blockStyle}"`, "block"),
unknownListStyleWarning = listStyle => getTemplate(`list style "${listStyle}"`, "list"),
unknownListItemStyleWarning = listStyle => getTemplate(`list item style "${listStyle}"`, "listItem");
function printWarning(message) {
console.warn(message);
}
const DefaultUnknownType = ({
value,
isInline
}) => {
const warning = unknownTypeWarning(value._type);
return isInline ? `<span style="display:none">${warning}</span>` : `<div style="display:none">${warning}</div>`;
},
DefaultUnknownMark = ({
markType,
children
}) => `<span class="unknown__pt__mark__${markType}">${children}</span>`,
DefaultUnknownBlockStyle = ({
children
}) => `<p>${children}</p>`,
DefaultUnknownList = ({
children
}) => `<ul>${children}</ul>`,
DefaultUnknownListItem = ({
children
}) => `<li>${children}</li>`,
DefaultHardBreak = () => "<br/>",
defaultPortableTextBlockStyles = {
normal: ({
children
}) => `<p>${children}</p>`,
blockquote: ({
children
}) => `<blockquote>${children}</blockquote>`,
h1: ({
children
}) => `<h1>${children}</h1>`,
h2: ({
children
}) => `<h2>${children}</h2>`,
h3: ({
children
}) => `<h3>${children}</h3>`,
h4: ({
children
}) => `<h4>${children}</h4>`,
h5: ({
children
}) => `<h5>${children}</h5>`,
h6: ({
children
}) => `<h6>${children}</h6>`
},
defaultComponents = {
types: {},
block: defaultPortableTextBlockStyles,
marks: defaultMarks,
list: defaultLists,
listItem: DefaultListItem,
hardBreak: DefaultHardBreak,
unknownType: DefaultUnknownType,
unknownMark: DefaultUnknownMark,
unknownList: DefaultUnknownList,
unknownListItem: DefaultUnknownListItem,
unknownBlockStyle: DefaultUnknownBlockStyle
};
function mergeComponents(parent, overrides) {
const {
block,
list,
listItem,
marks,
types
} = overrides,
rest = _objectWithoutProperties(overrides, _excluded);
return _objectSpread(_objectSpread({}, parent), {}, {
block: mergeDeeply(parent, overrides, "block"),
list: mergeDeeply(parent, overrides, "list"),
listItem: mergeDeeply(parent, overrides, "listItem"),
marks: mergeDeeply(parent, overrides, "marks"),
types: mergeDeeply(parent, overrides, "types")
}, rest);
}
function mergeDeeply(parent, overrides, key) {
const override = overrides[key],
parentVal = parent[key];
return typeof override == "function" || override && typeof parentVal == "function" ? override : override ? _objectSpread(_objectSpread({}, parentVal), override) : parentVal;
}
function toHTML(value, options = {}) {
const {
components: componentOverrides,
onMissingComponent: missingComponentHandler = printWarning
} = options,
handleMissingComponent = missingComponentHandler || noop,
blocks = Array.isArray(value) ? value : [value],
nested = toolkit.nestLists(blocks, "html"),
components = componentOverrides ? mergeComponents(defaultComponents, componentOverrides) : defaultComponents,
renderNode = getNodeRenderer(components, handleMissingComponent);
return nested.map((node, index) => renderNode({
node,
index,
isInline: !1,
renderNode
})).join("");
}
const getNodeRenderer = (components, handleMissingComponent) => {
function renderNode(options) {
const {
node,
index,
isInline
} = options;
return toolkit.isPortableTextToolkitList(node) ? renderList(node, index) : toolkit.isPortableTextListItemBlock(node) ? renderListItem(node, index) : toolkit.isPortableTextToolkitSpan(node) ? renderSpan(node) : toolkit.isPortableTextBlock(node) ? renderBlock(node, index, isInline) : toolkit.isPortableTextToolkitTextNode(node) ? renderText(node) : renderCustomBlock(node, index, isInline);
}
function renderListItem(node, index) {
const tree = serializeBlock({
node,
index,
isInline: !1,
renderNode
}),
renderer = components.listItem,
itemHandler = (typeof renderer == "function" ? renderer : renderer[node.listItem]) || components.unknownListItem;
if (itemHandler === components.unknownListItem) {
const style = node.listItem || "bullet";
handleMissingComponent(unknownListItemStyleWarning(style), {
type: style,
nodeType: "listItemStyle"
});
}
let children = tree.children;
if (node.style && node.style !== "normal") {
const {
listItem
} = node,
blockNode = _objectWithoutProperties(node, _excluded2);
children = renderNode({
node: blockNode,
index,
isInline: !1,
renderNode
});
}
return itemHandler({
value: node,
index,
isInline: !1,
renderNode,
children
});
}
function renderList(node, index) {
const children = node.children.map((child, childIndex) => renderNode({
node: child._key ? child : _objectSpread(_objectSpread({}, child), {}, {
_key: `li-${index}-${childIndex}`
}),
index,
isInline: !1,
renderNode
})),
component = components.list,
list = (typeof component == "function" ? component : component[node.listItem]) || components.unknownList;
if (list === components.unknownList) {
const style = node.listItem || "bullet";
handleMissingComponent(unknownListStyleWarning(style), {
nodeType: "listStyle",
type: style
});
}
return list({
value: node,
index,
isInline: !1,
renderNode,
children: children.join("")
});
}
function renderSpan(node) {
const {
markDef,
markType,
markKey
} = node,
span = components.marks[markType] || components.unknownMark,
children = node.children.map((child, childIndex) => renderNode({
node: child,
index: childIndex,
isInline: !0,
renderNode
}));
return span === components.unknownMark && handleMissingComponent(unknownMarkWarning(markType), {
nodeType: "mark",
type: markType
}), span({
text: toolkit.spanToPlainText(node),
value: markDef,
markType,
markKey,
renderNode,
children: children.join("")
});
}
function renderBlock(node, index, isInline) {
const _serializeBlock = serializeBlock({
node,
index,
isInline,
renderNode
}),
{
_key
} = _serializeBlock,
props = _objectWithoutProperties(_serializeBlock, _excluded3),
style = props.node.style || "normal",
block = (typeof components.block == "function" ? components.block : components.block[style]) || components.unknownBlockStyle;
return block === components.unknownBlockStyle && handleMissingComponent(unknownBlockStyleWarning(style), {
nodeType: "blockStyle",
type: style
}), block(_objectSpread(_objectSpread({}, props), {}, {
value: props.node,
renderNode
}));
}
function renderText(node) {
if (node.text === `
`) {
const hardBreak = components.hardBreak;
return hardBreak ? hardBreak() : `
`;
}
return escapeHTML(node.text);
}
function renderCustomBlock(value, index, isInline) {
const node = components.types[value._type];
return node || handleMissingComponent(unknownTypeWarning(value._type), {
nodeType: "block",
type: value._type
}), (node || components.unknownType)({
value,
isInline,
index,
renderNode
});
}
return renderNode;
};
function serializeBlock(options) {
const {
node,
index,
isInline,
renderNode
} = options,
children = toolkit.buildMarksTree(node).map((child, i) => renderNode({
node: child,
isInline: !0,
index: i,
renderNode
}));
return {
_key: node._key || `block-${index}`,
children: children.join(""),
index,
isInline,
node
};
}
function noop() {}
exports.defaultComponents = defaultComponents;
exports.escapeHTML = escapeHTML;
exports.mergeComponents = mergeComponents;
exports.toHTML = toHTML;
exports.uriLooksSafe = uriLooksSafe;
//# sourceMappingURL=pt-to-html.js.map