UNPKG

@wordpress/blocks

Version:
178 lines (170 loc) 7.74 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.processBlockType = void 0; var _isPlainObject = require("is-plain-object"); var _reactIs = require("react-is"); var _deprecated = _interopRequireDefault(require("@wordpress/deprecated")); var _hooks = require("@wordpress/hooks"); var _warning = _interopRequireDefault(require("@wordpress/warning")); var _utils = require("../api/utils"); var _constants = require("../api/constants"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ /** * Mapping of legacy category slugs to their latest normal values, used to * accommodate updates of the default set of block categories. * * @type {Record<string,string>} */ const LEGACY_CATEGORY_MAPPING = { common: 'text', formatting: 'text', layout: 'design' }; /** * Merge block variations bootstrapped from the server and client. * * When a variation is registered in both places, its properties are merged. * * @param {Array} bootstrappedVariations - A block type variations from the server. * @param {Array} clientVariations - A block type variations from the client. * @return {Array} The merged array of block variations. */ function mergeBlockVariations(bootstrappedVariations = [], clientVariations = []) { const result = [...bootstrappedVariations]; clientVariations.forEach(clientVariation => { const index = result.findIndex(bootstrappedVariation => bootstrappedVariation.name === clientVariation.name); if (index !== -1) { result[index] = { ...result[index], ...clientVariation }; } else { result.push(clientVariation); } }); return result; } /** * Takes the unprocessed block type settings, merges them with block type metadata * and applies all the existing filters for the registered block type. * Next, it validates all the settings and performs additional processing to the block type definition. * * @param {string} name Block name. * @param {WPBlockType} blockSettings Unprocessed block type settings. * * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. */ const processBlockType = (name, blockSettings) => ({ select }) => { const bootstrappedBlockType = select.getBootstrappedBlockType(name); const blockType = { apiVersion: 1, name, icon: _constants.BLOCK_ICON_DEFAULT, keywords: [], attributes: {}, providesContext: {}, usesContext: [], selectors: {}, supports: {}, styles: [], blockHooks: {}, save: () => null, ...bootstrappedBlockType, ...blockSettings, // blockType.variations can be defined as a filePath. variations: mergeBlockVariations(Array.isArray(bootstrappedBlockType?.variations) ? bootstrappedBlockType.variations : [], Array.isArray(blockSettings?.variations) ? blockSettings.variations : []) }; const settings = (0, _hooks.applyFilters)('blocks.registerBlockType', blockType, name, null); if (settings.apiVersion <= 2) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)(`The block "${name}" is registered with API version 2 or lower. This means that the post editor may work as a non-iframe editor.\n` + `Since all editors are planned to work as iframes in the future, set the \`apiVersion\` field to 3 and test the block inside the iframe editor.\n` + `See: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/#version-3-wordpress-6-3`) : void 0; } if (settings.description && typeof settings.description !== 'string') { (0, _deprecated.default)('Declaring non-string block descriptions', { since: '6.2' }); } if (settings.deprecated) { settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( // Only keep valid deprecation keys. (0, _hooks.applyFilters)('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings // so that filters that depend on specific keys being // present don't fail. { // Omit deprecation keys here so that deprecations // can opt out of specific keys like "supports". ...(0, _utils.omit)(blockType, _constants.DEPRECATED_ENTRY_KEYS), ...deprecation }, blockType.name, deprecation)).filter(([key]) => _constants.DEPRECATED_ENTRY_KEYS.includes(key)))); } if (!(0, _isPlainObject.isPlainObject)(settings)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block settings must be a valid object.') : void 0; return; } if (typeof settings.save !== 'function') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('The "save" property must be a valid function.') : void 0; return; } if ('edit' in settings && !(0, _reactIs.isValidElementType)(settings.edit)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('The "edit" property must be a valid component.') : void 0; return; } // Canonicalize legacy categories to equivalent fallback. if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; } if ('category' in settings && !select.getCategories().some(({ slug }) => slug === settings.category)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('The block "' + name + '" is registered with an invalid category "' + settings.category + '".') : void 0; delete settings.category; } if (!('title' in settings) || settings.title === '') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('The block "' + name + '" must have a title.') : void 0; return; } if (typeof settings.title !== 'string') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block titles must be strings.') : void 0; return; } settings.icon = (0, _utils.normalizeIconObject)(settings.icon); if (!(0, _utils.isValidIcon)(settings.icon.src)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional') : void 0; return; } if (typeof settings?.parent === 'string' || settings?.parent instanceof String) { settings.parent = [settings.parent]; globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Parent must be undefined or an array of strings (block types), but it is a string.') : void 0; // Intentionally continue: // // While string values were never supported, they appeared to work with some unintended side-effects // that have been fixed by [#66250](https://github.com/WordPress/gutenberg/pull/66250). // // To be backwards-compatible, this code that automatically migrates strings to arrays. } if (!Array.isArray(settings?.parent) && settings?.parent !== undefined) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Parent must be undefined or an array of block types, but it is ', settings.parent) : void 0; return; } if (1 === settings?.parent?.length && name === settings.parent[0]) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block "' + name + '" cannot be a parent of itself. Please remove the block name from the parent list.') : void 0; return; } return settings; }; exports.processBlockType = processBlockType; //# sourceMappingURL=process-block-type.js.map