@wordpress/blocks
Version:
Block API for WordPress.
131 lines (130 loc) • 3.79 kB
JavaScript
// packages/blocks/src/api/raw-handling/utils.js
import { isPhrasingContent, getPhrasingContentSchema } from "@wordpress/dom";
import { hasBlockSupport } from "..";
import { getRawTransforms } from "./get-raw-transforms";
function getBlockContentSchemaFromTransforms(transforms, context) {
const phrasingContentSchema = getPhrasingContentSchema(context);
const schemaArgs = { phrasingContentSchema, isPaste: context === "paste" };
const schemas = transforms.map(({ isMatch, blockName, schema }) => {
const hasAnchorSupport = hasBlockSupport(blockName, "anchor");
schema = typeof schema === "function" ? schema(schemaArgs) : schema;
if (!hasAnchorSupport && !isMatch) {
return schema;
}
if (!schema) {
return {};
}
return Object.fromEntries(
Object.entries(schema).map(([key, value]) => {
let attributes = value.attributes || [];
if (hasAnchorSupport) {
attributes = [...attributes, "id"];
}
return [
key,
{
...value,
attributes,
isMatch: isMatch ? isMatch : void 0
}
];
})
);
});
function mergeTagNameSchemaProperties(objValue, srcValue, key) {
switch (key) {
case "children": {
if (objValue === "*" || srcValue === "*") {
return "*";
}
return { ...objValue, ...srcValue };
}
case "attributes":
case "require": {
return [...objValue || [], ...srcValue || []];
}
case "isMatch": {
if (!objValue || !srcValue) {
return void 0;
}
return (...args) => {
return objValue(...args) || srcValue(...args);
};
}
}
}
function mergeTagNameSchemas(a, b) {
for (const key in b) {
a[key] = a[key] ? mergeTagNameSchemaProperties(a[key], b[key], key) : { ...b[key] };
}
return a;
}
function mergeSchemas(a, b) {
for (const key in b) {
a[key] = a[key] ? mergeTagNameSchemas(a[key], b[key]) : { ...b[key] };
}
return a;
}
return schemas.reduce(mergeSchemas, {});
}
function getBlockContentSchema(context) {
return getBlockContentSchemaFromTransforms(getRawTransforms(), context);
}
function isPlain(HTML) {
if (!/<(?!br[ />])/i.test(HTML)) {
return true;
}
const doc = document.implementation.createHTMLDocument("");
doc.body.innerHTML = HTML;
if (doc.body.children.length !== 1) {
return false;
}
const wrapper = doc.body.children.item(0);
const descendants = wrapper.getElementsByTagName("*");
for (let i = 0; i < descendants.length; i++) {
if (descendants.item(i).tagName !== "BR") {
return false;
}
}
if (wrapper.tagName !== "SPAN") {
return false;
}
return true;
}
function deepFilterNodeList(nodeList, filters, doc, schema) {
Array.from(nodeList).forEach((node) => {
deepFilterNodeList(node.childNodes, filters, doc, schema);
filters.forEach((item) => {
if (!doc.contains(node)) {
return;
}
item(node, doc, schema);
});
});
}
function deepFilterHTML(HTML, filters = [], schema) {
const doc = document.implementation.createHTMLDocument("");
doc.body.innerHTML = HTML;
deepFilterNodeList(doc.body.childNodes, filters, doc, schema);
return doc.body.innerHTML;
}
function getSibling(node, which) {
const sibling = node[`${which}Sibling`];
if (sibling && isPhrasingContent(sibling)) {
return sibling;
}
const { parentNode } = node;
if (!parentNode || !isPhrasingContent(parentNode)) {
return;
}
return getSibling(parentNode, which);
}
export {
deepFilterHTML,
deepFilterNodeList,
getBlockContentSchema,
getBlockContentSchemaFromTransforms,
getSibling,
isPlain
};
//# sourceMappingURL=utils.js.map