UNPKG

@wordpress/blocks

Version:
933 lines (882 loc) 34.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getBlockBindingsSource = getBlockBindingsSource; exports.getBlockBindingsSources = getBlockBindingsSources; exports.getBlockSupport = getBlockSupport; exports.getBlockType = getBlockType; exports.getBlockTypes = getBlockTypes; exports.getChildBlockNames = exports.getBlockVariations = void 0; exports.getDefaultBlockName = getDefaultBlockName; exports.getFreeformContentHandlerName = getFreeformContentHandlerName; exports.getGroupingBlockName = getGroupingBlockName; exports.getUnregisteredTypeHandlerName = getUnregisteredTypeHandlerName; exports.hasBlockSupport = hasBlockSupport; exports.hasChildBlocksWithInserterSupport = exports.hasChildBlocks = void 0; exports.isReusableBlock = isReusableBlock; exports.isTemplatePart = isTemplatePart; exports.registerBlockBindingsSource = void 0; exports.registerBlockCollection = registerBlockCollection; exports.registerBlockStyle = void 0; exports.registerBlockType = registerBlockType; exports.registerBlockVariation = void 0; exports.setDefaultBlockName = setDefaultBlockName; exports.setFreeformContentHandlerName = setFreeformContentHandlerName; exports.setGroupingBlockName = setGroupingBlockName; exports.setUnregisteredTypeHandlerName = setUnregisteredTypeHandlerName; exports.unregisterBlockBindingsSource = unregisterBlockBindingsSource; exports.unregisterBlockCollection = unregisterBlockCollection; exports.unregisterBlockStyle = void 0; exports.unregisterBlockType = unregisterBlockType; exports.unregisterBlockVariation = void 0; exports.unstable__bootstrapServerSideBlockDefinitions = unstable__bootstrapServerSideBlockDefinitions; var _data = require("@wordpress/data"); var _i18n = require("@wordpress/i18n"); var _warning = _interopRequireDefault(require("@wordpress/warning")); var _store = require("../store"); var _lockUnlock = require("../lock-unlock"); /** * WordPress dependencies */ /** * Internal dependencies */ const i18nBlockSchema = { title: "block title", description: "block description", keywords: ["block keyword"], styles: [{ label: "block style label" }], variations: [{ title: "block variation title", description: "block variation description", keywords: ["block variation keyword"] }] }; /** * An icon type definition. One of a Dashicon slug, an element, * or a component. * * @typedef {(string|Element|Component)} WPIcon * * @see https://developer.wordpress.org/resource/dashicons/ */ /** * Render behavior of a block type icon; one of a Dashicon slug, an element, * or a component. * * @typedef {WPIcon} WPBlockTypeIconRender */ /** * An object describing a normalized block type icon. * * @typedef {Object} WPBlockTypeIconDescriptor * * @property {WPBlockTypeIconRender} src Render behavior of the icon, * one of a Dashicon slug, an * element, or a component. * @property {string} background Optimal background hex string * color when displaying icon. * @property {string} foreground Optimal foreground hex string * color when displaying icon. * @property {string} shadowColor Optimal shadow hex string * color when displaying icon. */ /** * Value to use to render the icon for a block type in an editor interface, * either a Dashicon slug, an element, a component, or an object describing * the icon. * * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon */ /** * Named block variation scopes. * * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope */ /** * An object describing a variation defined for the block type. * * @typedef {Object} WPBlockVariation * * @property {string} name The unique and machine-readable name. * @property {string} title A human-readable variation title. * @property {string} [description] A detailed variation description. * @property {string} [category] Block type category classification, * used in search interfaces to arrange * block types by category. * @property {WPIcon} [icon] An icon helping to visualize the variation. * @property {boolean} [isDefault] Indicates whether the current variation is * the default one. Defaults to `false`. * @property {Object} [attributes] Values which override block attributes. * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. * @property {Object} [example] Example provides structured data for * the block preview. You can set to * `undefined` to disable the preview shown * for the block type. * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation * is applicable. When not provided, it * assumes all available scopes. * @property {string[]} [keywords] An array of terms (which can be translated) * that help users discover the variation * while searching. * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. * Function that accepts a block's attributes and the * variation's attributes and determines if a variation is active. * This function doesn't try to find a match dynamically based * on all block's attributes, as in many cases some attributes are irrelevant. * An example would be for `embed` block where we only care * about `providerNameSlug` attribute's value. * We can also use a `string[]` to tell which attributes * should be compared as a shorthand. Each attributes will * be matched and the variation will be active if all of them are matching. */ /** * Defined behavior of a block type. * * @typedef {Object} WPBlockType * * @property {string} name Block type's namespaced name. * @property {string} title Human-readable block type label. * @property {string} [description] A detailed block type description. * @property {string} [category] Block type category classification, * used in search interfaces to arrange * block types by category. * @property {WPBlockTypeIcon} [icon] Block type icon. * @property {string[]} [keywords] Additional keywords to produce block * type as result in search interfaces. * @property {Object} [attributes] Block type attributes. * @property {Component} [save] Optional component describing * serialized markup structure of a * block type. * @property {Component} edit Component rendering an element to * manipulate the attributes of a block * in the context of an editor. * @property {WPBlockVariation[]} [variations] The list of block variations. * @property {Object} [example] Example provides structured data for * the block preview. When not defined * then no preview is shown. */ /** * An object describing a Block Bindings source. * * @typedef {Object} WPBlockBindingsSource * * @property {string} name The unique and machine-readable name. * @property {string} [label] Human-readable label. Optional when it is defined in the server. * @property {Array} [usesContext] Optional array of context needed by the source only in the editor. * @property {Function} [getValues] Optional function to get the values from the source. * @property {Function} [setValues] Optional function to update multiple values connected to the source. * @property {Function} [canUserEditValue] Optional function to determine if the user can edit the value. */ function isObject(object) { return object !== null && typeof object === 'object'; } /** * Sets the server side block definition of blocks. * * Ignored from documentation due to being marked as unstable. * * @ignore * * @param {Object} definitions Server-side block definitions */ // eslint-disable-next-line camelcase function unstable__bootstrapServerSideBlockDefinitions(definitions) { const { addBootstrappedBlockType } = (0, _lockUnlock.unlock)((0, _data.dispatch)(_store.store)); for (const [name, blockType] of Object.entries(definitions)) { addBootstrappedBlockType(name, blockType); } } /** * Gets block settings from metadata loaded from `block.json` file * * @param {Object} metadata Block metadata loaded from `block.json`. * @param {string} metadata.textdomain Textdomain to use with translations. * * @return {Object} Block settings. */ function getBlockSettingsFromMetadata({ textdomain, ...metadata }) { const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks', 'allowedBlocks']; const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); if (textdomain) { Object.keys(i18nBlockSchema).forEach(key => { if (!settings[key]) { return; } settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); }); } return settings; } /** * Registers a new block provided a unique name and an object defining its * behavior. Once registered, the block is made available as an option to any * editor interface where blocks are implemented. * * For more in-depth information on registering a custom block see the * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). * * @param {string|Object} blockNameOrMetadata Block type name or its metadata. * @param {Object} settings Block settings. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { registerBlockType } from '@wordpress/blocks' * * registerBlockType( 'namespace/block-name', { * title: __( 'My First Block' ), * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, * save: () => <div>Hello from the saved content!</div>, * } ); * ``` * * @return {WPBlockType | undefined} The block, if it has been successfully registered; * otherwise `undefined`. */ function registerBlockType(blockNameOrMetadata, settings) { const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; if (typeof name !== 'string') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block names must be strings.') : void 0; return; } if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block') : void 0; return; } if ((0, _data.select)(_store.store).getBlockType(name)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block "' + name + '" is already registered.') : void 0; return; } const { addBootstrappedBlockType, addUnprocessedBlockType } = (0, _lockUnlock.unlock)((0, _data.dispatch)(_store.store)); if (isObject(blockNameOrMetadata)) { const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); addBootstrappedBlockType(name, metadata); } addUnprocessedBlockType(name, settings); return (0, _data.select)(_store.store).getBlockType(name); } /** * Translates block settings provided with metadata using the i18n schema. * * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. * @param {string|string[]|Object[]} settingValue Value for the block setting. * @param {string} textdomain Textdomain to use with translations. * * @return {string|string[]|Object[]} Translated setting. */ function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain return (0, _i18n._x)(settingValue, i18nSchema, textdomain); } if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); } if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { return Object.keys(settingValue).reduce((accumulator, key) => { if (!i18nSchema[key]) { accumulator[key] = settingValue[key]; return accumulator; } accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); return accumulator; }, {}); } return settingValue; } /** * Registers a new block collection to group blocks in the same namespace in the inserter. * * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. * @param {Object} settings The block collection settings. * @param {string} settings.title The title to display in the block inserter. * @param {Object} [settings.icon] The icon to display in the block inserter. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; * * // Register the collection. * registerBlockCollection( 'my-collection', { * title: __( 'Custom Collection' ), * } ); * * // Register a block in the same namespace to add it to the collection. * registerBlockType( 'my-collection/block-name', { * title: __( 'My First Block' ), * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, * save: () => <div>'Hello from the saved content!</div>, * } ); * ``` */ function registerBlockCollection(namespace, { title, icon }) { (0, _data.dispatch)(_store.store).addBlockCollection(namespace, title, icon); } /** * Unregisters a block collection * * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace * * @example * ```js * import { unregisterBlockCollection } from '@wordpress/blocks'; * * unregisterBlockCollection( 'my-collection' ); * ``` */ function unregisterBlockCollection(namespace) { (0, _data.dispatch)(_store.store).removeBlockCollection(namespace); } /** * Unregisters a block. * * @param {string} name Block name. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { unregisterBlockType } from '@wordpress/blocks'; * * const ExampleComponent = () => { * return ( * <Button * onClick={ () => * unregisterBlockType( 'my-collection/block-name' ) * } * > * { __( 'Unregister my custom block.' ) } * </Button> * ); * }; * ``` * * @return {WPBlockType | undefined} The previous block value, if it has been successfully * unregistered; otherwise `undefined`. */ function unregisterBlockType(name) { const oldBlock = (0, _data.select)(_store.store).getBlockType(name); if (!oldBlock) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block "' + name + '" is not registered.') : void 0; return; } (0, _data.dispatch)(_store.store).removeBlockTypes(name); return oldBlock; } /** * Assigns name of block for handling non-block content. * * @param {string} blockName Block name. */ function setFreeformContentHandlerName(blockName) { (0, _data.dispatch)(_store.store).setFreeformFallbackBlockName(blockName); } /** * Retrieves name of block handling non-block content, or undefined if no * handler has been defined. * * @return {?string} Block name. */ function getFreeformContentHandlerName() { return (0, _data.select)(_store.store).getFreeformFallbackBlockName(); } /** * Retrieves name of block used for handling grouping interactions. * * @return {?string} Block name. */ function getGroupingBlockName() { return (0, _data.select)(_store.store).getGroupingBlockName(); } /** * Assigns name of block handling unregistered block types. * * @param {string} blockName Block name. */ function setUnregisteredTypeHandlerName(blockName) { (0, _data.dispatch)(_store.store).setUnregisteredFallbackBlockName(blockName); } /** * Retrieves name of block handling unregistered block types, or undefined if no * handler has been defined. * * @return {?string} Block name. */ function getUnregisteredTypeHandlerName() { return (0, _data.select)(_store.store).getUnregisteredFallbackBlockName(); } /** * Assigns the default block name. * * @param {string} name Block name. * * @example * ```js * import { setDefaultBlockName } from '@wordpress/blocks'; * * const ExampleComponent = () => { * * return ( * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> * { __( 'Set the default block to Heading' ) } * </Button> * ); * }; * ``` */ function setDefaultBlockName(name) { (0, _data.dispatch)(_store.store).setDefaultBlockName(name); } /** * Assigns name of block for handling block grouping interactions. * * This function lets you select a different block to group other blocks in instead of the * default `core/group` block. This function must be used in a component or when the DOM is fully * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ * * @param {string} name Block name. * * @example * ```js * import { setGroupingBlockName } from '@wordpress/blocks'; * * const ExampleComponent = () => { * * return ( * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> * { __( 'Wrap in columns' ) } * </Button> * ); * }; * ``` */ function setGroupingBlockName(name) { (0, _data.dispatch)(_store.store).setGroupingBlockName(name); } /** * Retrieves the default block name. * * @return {?string} Block name. */ function getDefaultBlockName() { return (0, _data.select)(_store.store).getDefaultBlockName(); } /** * Returns a registered block type. * * @param {string} name Block name. * * @return {?Object} Block type. */ function getBlockType(name) { return (0, _data.select)(_store.store)?.getBlockType(name); } /** * Returns all registered blocks. * * @return {Array} Block settings. */ function getBlockTypes() { return (0, _data.select)(_store.store).getBlockTypes(); } /** * Returns the block support value for a feature, if defined. * * @param {(string|Object)} nameOrType Block name or type object * @param {string} feature Feature to retrieve * @param {*} defaultSupports Default value to return if not * explicitly defined * * @return {?*} Block support value */ function getBlockSupport(nameOrType, feature, defaultSupports) { return (0, _data.select)(_store.store).getBlockSupport(nameOrType, feature, defaultSupports); } /** * Returns true if the block defines support for a feature, or false otherwise. * * @param {(string|Object)} nameOrType Block name or type object. * @param {string} feature Feature to test. * @param {boolean} defaultSupports Whether feature is supported by * default if not explicitly defined. * * @return {boolean} Whether block supports feature. */ function hasBlockSupport(nameOrType, feature, defaultSupports) { return (0, _data.select)(_store.store).hasBlockSupport(nameOrType, feature, defaultSupports); } /** * Determines whether or not the given block is a reusable block. This is a * special block type that is used to point to a global block stored via the * API. * * @param {Object} blockOrType Block or Block Type to test. * * @return {boolean} Whether the given block is a reusable block. */ function isReusableBlock(blockOrType) { return blockOrType?.name === 'core/block'; } /** * Determines whether or not the given block is a template part. This is a * special block type that allows composing a page template out of reusable * design elements. * * @param {Object} blockOrType Block or Block Type to test. * * @return {boolean} Whether the given block is a template part. */ function isTemplatePart(blockOrType) { return blockOrType?.name === 'core/template-part'; } /** * Returns an array with the child blocks of a given block. * * @param {string} blockName Name of block (example: “latest-posts”). * * @return {Array} Array of child block names. */ const getChildBlockNames = blockName => { return (0, _data.select)(_store.store).getChildBlockNames(blockName); }; /** * Returns a boolean indicating if a block has child blocks or not. * * @param {string} blockName Name of block (example: “latest-posts”). * * @return {boolean} True if a block contains child blocks and false otherwise. */ exports.getChildBlockNames = getChildBlockNames; const hasChildBlocks = blockName => { return (0, _data.select)(_store.store).hasChildBlocks(blockName); }; /** * Returns a boolean indicating if a block has at least one child block with inserter support. * * @param {string} blockName Block type name. * * @return {boolean} True if a block contains at least one child blocks with inserter support * and false otherwise. */ exports.hasChildBlocks = hasChildBlocks; const hasChildBlocksWithInserterSupport = blockName => { return (0, _data.select)(_store.store).hasChildBlocksWithInserterSupport(blockName); }; /** * Registers a new block style for the given block types. * * For more information on connecting the styles with CSS * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). * * @param {string|Array} blockNames Name of blocks e.g. “core/latest-posts” or `["core/group", "core/columns"]`. * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { registerBlockStyle } from '@wordpress/blocks'; * import { Button } from '@wordpress/components'; * * * const ExampleComponent = () => { * return ( * <Button * onClick={ () => { * registerBlockStyle( 'core/quote', { * name: 'fancy-quote', * label: __( 'Fancy Quote' ), * } ); * } } * > * { __( 'Add a new block style for core/quote' ) } * </Button> * ); * }; * ``` */ exports.hasChildBlocksWithInserterSupport = hasChildBlocksWithInserterSupport; const registerBlockStyle = (blockNames, styleVariation) => { (0, _data.dispatch)(_store.store).addBlockStyles(blockNames, styleVariation); }; /** * Unregisters a block style for the given block. * * @param {string} blockName Name of block (example: “core/latest-posts”). * @param {string} styleVariationName Name of class applied to the block. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { unregisterBlockStyle } from '@wordpress/blocks'; * import { Button } from '@wordpress/components'; * * const ExampleComponent = () => { * return ( * <Button * onClick={ () => { * unregisterBlockStyle( 'core/quote', 'plain' ); * } } * > * { __( 'Remove the "Plain" block style for core/quote' ) } * </Button> * ); * }; * ``` */ exports.registerBlockStyle = registerBlockStyle; const unregisterBlockStyle = (blockName, styleVariationName) => { (0, _data.dispatch)(_store.store).removeBlockStyles(blockName, styleVariationName); }; /** * Returns an array with the variations of a given block type. * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. * * @ignore * * @param {string} blockName Name of block (example: “core/columns”). * @param {WPBlockVariationScope} [scope] Block variation scope name. * * @return {(WPBlockVariation[]|void)} Block variations. */ exports.unregisterBlockStyle = unregisterBlockStyle; const getBlockVariations = (blockName, scope) => { return (0, _data.select)(_store.store).getBlockVariations(blockName, scope); }; /** * Registers a new block variation for the given block type. * * For more information on block variations see * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). * * @param {string} blockName Name of the block (example: “core/columns”). * @param {WPBlockVariation} variation Object describing a block variation. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { registerBlockVariation } from '@wordpress/blocks'; * import { Button } from '@wordpress/components'; * * const ExampleComponent = () => { * return ( * <Button * onClick={ () => { * registerBlockVariation( 'core/embed', { * name: 'custom', * title: __( 'My Custom Embed' ), * attributes: { providerNameSlug: 'custom' }, * } ); * } } * > * __( 'Add a custom variation for core/embed' ) } * </Button> * ); * }; * ``` */ exports.getBlockVariations = getBlockVariations; const registerBlockVariation = (blockName, variation) => { if (typeof variation.name !== 'string') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Variation names must be unique strings.') : void 0; } (0, _data.dispatch)(_store.store).addBlockVariations(blockName, variation); }; /** * Unregisters a block variation defined for the given block type. * * @param {string} blockName Name of the block (example: “core/columns”). * @param {string} variationName Name of the variation defined for the block. * * @example * ```js * import { __ } from '@wordpress/i18n'; * import { unregisterBlockVariation } from '@wordpress/blocks'; * import { Button } from '@wordpress/components'; * * const ExampleComponent = () => { * return ( * <Button * onClick={ () => { * unregisterBlockVariation( 'core/embed', 'youtube' ); * } } * > * { __( 'Remove the YouTube variation from core/embed' ) } * </Button> * ); * }; * ``` */ exports.registerBlockVariation = registerBlockVariation; const unregisterBlockVariation = (blockName, variationName) => { (0, _data.dispatch)(_store.store).removeBlockVariations(blockName, variationName); }; /** * Registers a new block bindings source with an object defining its * behavior. Once registered, the source is available to be connected * to the supported block attributes. * * @since 6.7.0 Introduced in WordPress core. * * @param {WPBlockBindingsSource} source Object describing a block bindings source. * * @example * ```js * import { _x } from '@wordpress/i18n'; * import { registerBlockBindingsSource } from '@wordpress/blocks' * * registerBlockBindingsSource( { * name: 'plugin/my-custom-source', * label: _x( 'My Custom Source', 'block bindings source' ), * usesContext: [ 'postType' ], * getValues: getSourceValues, * setValues: updateMyCustomValuesInBatch, * canUserEditValue: () => true, * } ); * ``` */ exports.unregisterBlockVariation = unregisterBlockVariation; const registerBlockBindingsSource = source => { const { name, label, usesContext, getValues, setValues, canUserEditValue, getFieldsList } = source; const existingSource = (0, _lockUnlock.unlock)((0, _data.select)(_store.store)).getBlockBindingsSource(name); /* * Check if the source has been already registered on the client. * If any property expected to be "client-only" is defined, return a warning. */ const serverProps = ['label', 'usesContext']; for (const prop in existingSource) { if (!serverProps.includes(prop) && existingSource[prop]) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source "' + name + '" is already registered.') : void 0; return; } } // Check the `name` property is correct. if (!name) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source must contain a name.') : void 0; return; } if (typeof name !== 'string') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source name must be a string.') : void 0; return; } if (/[A-Z]+/.test(name)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source name must not contain uppercase characters.') : void 0; return; } if (!/^[a-z0-9/-]+$/.test(name)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source.') : void 0; return; } if (!/^[a-z0-9-]+\/[a-z0-9-]+$/.test(name)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source.') : void 0; return; } // Check the `label` property is correct. if (!label && !existingSource?.label) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source must contain a label.') : void 0; return; } if (label && typeof label !== 'string') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source label must be a string.') : void 0; return; } if (label && existingSource?.label && label !== existingSource?.label) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings "' + name + '" source label was overridden.') : void 0; } // Check the `usesContext` property is correct. if (usesContext && !Array.isArray(usesContext)) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source usesContext must be an array.') : void 0; return; } // Check the `getValues` property is correct. if (getValues && typeof getValues !== 'function') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source getValues must be a function.') : void 0; return; } // Check the `setValues` property is correct. if (setValues && typeof setValues !== 'function') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source setValues must be a function.') : void 0; return; } // Check the `canUserEditValue` property is correct. if (canUserEditValue && typeof canUserEditValue !== 'function') { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source canUserEditValue must be a function.') : void 0; return; } // Check the `getFieldsList` property is correct. if (getFieldsList && typeof getFieldsList !== 'function') { // eslint-disable-next-line no-console globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source getFieldsList must be a function.') : void 0; return; } return (0, _lockUnlock.unlock)((0, _data.dispatch)(_store.store)).addBlockBindingsSource(source); }; /** * Unregisters a block bindings source by providing its name. * * @since 6.7.0 Introduced in WordPress core. * * @param {string} name The name of the block bindings source to unregister. * * @example * ```js * import { unregisterBlockBindingsSource } from '@wordpress/blocks'; * * unregisterBlockBindingsSource( 'plugin/my-custom-source' ); * ``` */ exports.registerBlockBindingsSource = registerBlockBindingsSource; function unregisterBlockBindingsSource(name) { const oldSource = getBlockBindingsSource(name); if (!oldSource) { globalThis.SCRIPT_DEBUG === true ? (0, _warning.default)('Block bindings source "' + name + '" is not registered.') : void 0; return; } (0, _lockUnlock.unlock)((0, _data.dispatch)(_store.store)).removeBlockBindingsSource(name); } /** * Returns a registered block bindings source by its name. * * @since 6.7.0 Introduced in WordPress core. * * @param {string} name Block bindings source name. * * @return {?Object} Block bindings source. */ function getBlockBindingsSource(name) { return (0, _lockUnlock.unlock)((0, _data.select)(_store.store)).getBlockBindingsSource(name); } /** * Returns all registered block bindings sources. * * @since 6.7.0 Introduced in WordPress core. * * @return {Array} Block bindings sources. */ function getBlockBindingsSources() { return (0, _lockUnlock.unlock)((0, _data.select)(_store.store)).getAllBlockBindingsSources(); } //# sourceMappingURL=registration.js.map