@wordpress/blocks
Version:
Block API for WordPress.
333 lines (332 loc) • 10.4 kB
JavaScript
// packages/blocks/src/api/registration.js
import { select, dispatch } from "@wordpress/data";
import { _x } from "@wordpress/i18n";
import warning from "@wordpress/warning";
import i18nBlockSchema from "./i18n-block.json";
import { store as blocksStore } from "../store";
import { unlock } from "../lock-unlock";
function isObject(object) {
return object !== null && typeof object === "object";
}
function unstable__bootstrapServerSideBlockDefinitions(definitions) {
const { addBootstrappedBlockType } = unlock(dispatch(blocksStore));
for (const [name, blockType] of Object.entries(definitions)) {
addBootstrappedBlockType(name, blockType);
}
}
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;
}
function registerBlockType(blockNameOrMetadata, settings) {
const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata;
if (typeof name !== "string") {
warning("Block names must be strings.");
return;
}
if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) {
warning(
"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"
);
return;
}
if (select(blocksStore).getBlockType(name)) {
warning('Block "' + name + '" is already registered.');
return;
}
const { addBootstrappedBlockType, addUnprocessedBlockType } = unlock(
dispatch(blocksStore)
);
if (isObject(blockNameOrMetadata)) {
const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata);
addBootstrappedBlockType(name, metadata);
}
addUnprocessedBlockType(name, settings);
return select(blocksStore).getBlockType(name);
}
function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) {
if (typeof i18nSchema === "string" && typeof settingValue === "string") {
return _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;
}
function registerBlockCollection(namespace, { title, icon }) {
dispatch(blocksStore).addBlockCollection(namespace, title, icon);
}
function unregisterBlockCollection(namespace) {
dispatch(blocksStore).removeBlockCollection(namespace);
}
function unregisterBlockType(name) {
const oldBlock = select(blocksStore).getBlockType(name);
if (!oldBlock) {
warning('Block "' + name + '" is not registered.');
return;
}
dispatch(blocksStore).removeBlockTypes(name);
return oldBlock;
}
function setFreeformContentHandlerName(blockName) {
dispatch(blocksStore).setFreeformFallbackBlockName(blockName);
}
function getFreeformContentHandlerName() {
return select(blocksStore).getFreeformFallbackBlockName();
}
function getGroupingBlockName() {
return select(blocksStore).getGroupingBlockName();
}
function setUnregisteredTypeHandlerName(blockName) {
dispatch(blocksStore).setUnregisteredFallbackBlockName(blockName);
}
function getUnregisteredTypeHandlerName() {
return select(blocksStore).getUnregisteredFallbackBlockName();
}
function setDefaultBlockName(name) {
dispatch(blocksStore).setDefaultBlockName(name);
}
function setGroupingBlockName(name) {
dispatch(blocksStore).setGroupingBlockName(name);
}
function getDefaultBlockName() {
return select(blocksStore).getDefaultBlockName();
}
function getBlockType(name) {
return select(blocksStore)?.getBlockType(name);
}
function getBlockTypes() {
return select(blocksStore).getBlockTypes();
}
function getBlockSupport(nameOrType, feature, defaultSupports) {
return select(blocksStore).getBlockSupport(
nameOrType,
feature,
defaultSupports
);
}
function hasBlockSupport(nameOrType, feature, defaultSupports) {
return select(blocksStore).hasBlockSupport(
nameOrType,
feature,
defaultSupports
);
}
function isReusableBlock(blockOrType) {
return blockOrType?.name === "core/block";
}
function isTemplatePart(blockOrType) {
return blockOrType?.name === "core/template-part";
}
var getChildBlockNames = (blockName) => {
return select(blocksStore).getChildBlockNames(blockName);
};
var hasChildBlocks = (blockName) => {
return select(blocksStore).hasChildBlocks(blockName);
};
var hasChildBlocksWithInserterSupport = (blockName) => {
return select(blocksStore).hasChildBlocksWithInserterSupport(blockName);
};
var registerBlockStyle = (blockNames, styleVariation) => {
dispatch(blocksStore).addBlockStyles(blockNames, styleVariation);
};
var unregisterBlockStyle = (blockName, styleVariationName) => {
dispatch(blocksStore).removeBlockStyles(blockName, styleVariationName);
};
var getBlockVariations = (blockName, scope) => {
return select(blocksStore).getBlockVariations(blockName, scope);
};
var registerBlockVariation = (blockName, variation) => {
if (typeof variation.name !== "string") {
warning("Variation names must be unique strings.");
}
dispatch(blocksStore).addBlockVariations(blockName, variation);
};
var unregisterBlockVariation = (blockName, variationName) => {
dispatch(blocksStore).removeBlockVariations(blockName, variationName);
};
var registerBlockBindingsSource = (source) => {
const {
name,
label,
usesContext,
getValues,
setValues,
canUserEditValue,
getFieldsList
} = source;
const existingSource = unlock(
select(blocksStore)
).getBlockBindingsSource(name);
const serverProps = ["label", "usesContext"];
for (const prop in existingSource) {
if (!serverProps.includes(prop) && existingSource[prop]) {
warning(
'Block bindings source "' + name + '" is already registered.'
);
return;
}
}
if (!name) {
warning("Block bindings source must contain a name.");
return;
}
if (typeof name !== "string") {
warning("Block bindings source name must be a string.");
return;
}
if (/[A-Z]+/.test(name)) {
warning(
"Block bindings source name must not contain uppercase characters."
);
return;
}
if (!/^[a-z0-9/-]+$/.test(name)) {
warning(
"Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source."
);
return;
}
if (!/^[a-z0-9-]+\/[a-z0-9-]+$/.test(name)) {
warning(
"Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source."
);
return;
}
if (!label && !existingSource?.label) {
warning("Block bindings source must contain a label.");
return;
}
if (label && typeof label !== "string") {
warning("Block bindings source label must be a string.");
return;
}
if (label && existingSource?.label && label !== existingSource?.label) {
warning('Block bindings "' + name + '" source label was overridden.');
}
if (usesContext && !Array.isArray(usesContext)) {
warning("Block bindings source usesContext must be an array.");
return;
}
if (getValues && typeof getValues !== "function") {
warning("Block bindings source getValues must be a function.");
return;
}
if (setValues && typeof setValues !== "function") {
warning("Block bindings source setValues must be a function.");
return;
}
if (canUserEditValue && typeof canUserEditValue !== "function") {
warning("Block bindings source canUserEditValue must be a function.");
return;
}
if (getFieldsList && typeof getFieldsList !== "function") {
warning("Block bindings source getFieldsList must be a function.");
return;
}
return unlock(dispatch(blocksStore)).addBlockBindingsSource(source);
};
function unregisterBlockBindingsSource(name) {
const oldSource = getBlockBindingsSource(name);
if (!oldSource) {
warning('Block bindings source "' + name + '" is not registered.');
return;
}
unlock(dispatch(blocksStore)).removeBlockBindingsSource(name);
}
function getBlockBindingsSource(name) {
return unlock(select(blocksStore)).getBlockBindingsSource(name);
}
function getBlockBindingsSources() {
return unlock(select(blocksStore)).getAllBlockBindingsSources();
}
export {
getBlockBindingsSource,
getBlockBindingsSources,
getBlockSupport,
getBlockType,
getBlockTypes,
getBlockVariations,
getChildBlockNames,
getDefaultBlockName,
getFreeformContentHandlerName,
getGroupingBlockName,
getUnregisteredTypeHandlerName,
hasBlockSupport,
hasChildBlocks,
hasChildBlocksWithInserterSupport,
isReusableBlock,
isTemplatePart,
registerBlockBindingsSource,
registerBlockCollection,
registerBlockStyle,
registerBlockType,
registerBlockVariation,
setDefaultBlockName,
setFreeformContentHandlerName,
setGroupingBlockName,
setUnregisteredTypeHandlerName,
unregisterBlockBindingsSource,
unregisterBlockCollection,
unregisterBlockStyle,
unregisterBlockType,
unregisterBlockVariation,
unstable__bootstrapServerSideBlockDefinitions
};
//# sourceMappingURL=registration.js.map