@jverneaut/html-to-gutenberg
Version:
Create custom Gutenberg blocks from the HTML templates you already have.
98 lines (78 loc) • 2.75 kB
JavaScript
import { toHtml } from "hast-util-to-html";
import { parseRawValue } from "#utils-string/index.js";
const parseNodeAttributes = (blockNode, recursive = true) => {
const blockName = blockNode.properties.name;
const blockTemplate = [blockName];
let blockTemplateAttributes = {};
const blockAttributes = Object.keys(blockNode.properties).filter(
(propertyKey) => propertyKey !== "name",
);
// Retrieve attributes values set as <inner-block key="value">
if (blockAttributes.length) {
const attributesData = blockAttributes.reduce((acc, attributeKey) => {
let attributeValue = null;
if (blockNode.properties[attributeKey]) {
attributeValue = parseRawValue(blockNode.properties[attributeKey]);
}
return { ...acc, [attributeKey]: attributeValue };
}, {});
if (Object.keys(attributesData).length) {
blockTemplateAttributes = {
...blockTemplateAttributes,
...attributesData,
};
}
}
// Parse nested <block-attribute> elements
const attributesElements = blockNode.children.filter(
(node) =>
node.tagName === "block-attribute" && Object.keys(node.properties).length,
);
if (attributesElements.length) {
const attributesData = attributesElements.reduce(
(acc, attributeElement) => {
let attributeValue = null;
// Retrieve attributes values set as <block-attribute name="key" value="value">
if (attributeElement.properties.value) {
const rawValue = attributeElement.properties.value.trim();
if (rawValue) {
attributeValue = parseRawValue(rawValue);
}
}
// Retrieve attributes values set as <block-attribute name="key">value</block-attribute>
if (attributeElement.children.length) {
const rawValue = toHtml(attributeElement.children).trim();
if (rawValue) {
attributeValue = parseRawValue(rawValue);
}
}
return {
...acc,
[attributeElement.properties.name]: attributeValue,
};
},
{},
);
if (Object.keys(attributesData).length) {
blockTemplateAttributes = {
...blockTemplateAttributes,
...attributesData,
};
}
}
blockTemplate.push(blockTemplateAttributes);
if (recursive) {
// Parse nested blocks recursively
const innerBlockNodes = blockNode.children.filter(
(child) => child.tagName === "inner-block",
);
if (innerBlockNodes.length) {
const innerBlocks = innerBlockNodes.map((innerBlockNode) =>
parseNodeAttributes(innerBlockNode),
);
blockTemplate.push(innerBlocks);
}
}
return blockTemplate;
};
export default parseNodeAttributes;