UNPKG

@wordpress/blocks

Version:
96 lines (89 loc) 3.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.doBlocksMatchTemplate = doBlocksMatchTemplate; exports.synchronizeBlocksWithTemplate = synchronizeBlocksWithTemplate; var _element = require("@wordpress/element"); var _convertLegacyBlock = require("./parser/convert-legacy-block"); var _factory = require("./factory"); var _registration = require("./registration"); /** * WordPress dependencies */ /** * Internal dependencies */ /** * Checks whether a list of blocks matches a template by comparing the block names. * * @param {Array} blocks Block list. * @param {Array} template Block template. * * @return {boolean} Whether the list of blocks matches a templates. */ function doBlocksMatchTemplate(blocks = [], template = []) { return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { const block = blocks[index]; return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); }); } const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; function normalizeAttributes(schema, values) { if (!values) { return {}; } return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); } function normalizeAttribute(definition, value) { if (isHTMLAttribute(definition) && Array.isArray(value)) { // Introduce a deprecated call at this point // When we're confident that "children" format should be removed from the templates. return (0, _element.renderToString)(value); } if (isQueryAttribute(definition) && value) { return value.map(subValues => { return normalizeAttributes(definition.query, subValues); }); } return value; } /** * Synchronize a block list with a block template. * * Synchronizing a block list with a block template means that we loop over the blocks * keep the block as is if it matches the block at the same position in the template * (If it has the same name) and if doesn't match, we create a new block based on the template. * Extra blocks not present in the template are removed. * * @param {Array} blocks Block list. * @param {Array} template Block template. * * @return {Array} Updated Block list. */ function synchronizeBlocksWithTemplate(blocks = [], template) { // If no template is provided, return blocks unmodified. if (!template) { return blocks; } return template.map(([name, attributes, innerBlocksTemplate], index) => { var _blockType$attributes; const block = blocks[index]; if (block && block.name === name) { const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); return { ...block, innerBlocks }; } // To support old templates that were using the "children" format // for the attributes using "html" strings now, we normalize the template attributes // before creating the blocks. const blockType = (0, _registration.getBlockType)(name); const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); const [blockName, blockAttributes] = (0, _convertLegacyBlock.convertLegacyBlockNameAndAttributes)(name, normalizedAttributes); return (0, _factory.createBlock)(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); }); } //# sourceMappingURL=templates.js.map