UNPKG

@wordpress/blocks

Version:
247 lines (246 loc) 7.92 kB
// packages/blocks/src/api/utils.js import { colord, extend } from "colord"; import namesPlugin from "colord/plugins/names"; import a11yPlugin from "colord/plugins/a11y"; import { Component, isValidElement } from "@wordpress/element"; import { __, sprintf } from "@wordpress/i18n"; import { __unstableStripHTML as stripHTML } from "@wordpress/dom"; import { RichTextData } from "@wordpress/rich-text"; import deprecated from "@wordpress/deprecated"; import { BLOCK_ICON_DEFAULT } from "./constants"; import { getBlockType, getDefaultBlockName } from "./registration"; extend([namesPlugin, a11yPlugin]); var ICON_COLORS = ["#191e23", "#f8f9f9"]; function isUnmodifiedBlock(block, role) { const blockAttributes = getBlockType(block.name)?.attributes ?? {}; const attributesToCheck = role ? Object.entries(blockAttributes).filter(([key, definition]) => { if (role === "content" && key === "metadata") { return true; } return definition.role === role || definition.__experimentalRole === role; }) : Object.entries(blockAttributes); return attributesToCheck.every(([key, definition]) => { const value = block.attributes[key]; if (definition.hasOwnProperty("default")) { return value === definition.default; } if (definition.type === "rich-text") { return !value?.length; } return value === void 0; }); } function isUnmodifiedDefaultBlock(block, role) { return block.name === getDefaultBlockName() && isUnmodifiedBlock(block, role); } function isValidIcon(icon) { return !!icon && (typeof icon === "string" || isValidElement(icon) || typeof icon === "function" || icon instanceof Component); } function normalizeIconObject(icon) { icon = icon || BLOCK_ICON_DEFAULT; if (isValidIcon(icon)) { return { src: icon }; } if ("background" in icon) { const colordBgColor = colord(icon.background); const getColorContrast = (iconColor) => colordBgColor.contrast(iconColor); const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); return { ...icon, foreground: icon.foreground ? icon.foreground : ICON_COLORS.find( (iconColor) => getColorContrast(iconColor) === maxContrast ), shadowColor: colordBgColor.alpha(0.3).toRgbString() }; } return icon; } function normalizeBlockType(blockTypeOrName) { if (typeof blockTypeOrName === "string") { return getBlockType(blockTypeOrName); } return blockTypeOrName; } function getBlockLabel(blockType, attributes, context = "visual") { const { __experimentalLabel: getLabel, title } = blockType; const label = getLabel && getLabel(attributes, { context }); if (!label) { return title; } if (label.toPlainText) { return label.toPlainText(); } return stripHTML(label); } function getAccessibleBlockLabel(blockType, attributes, position, direction = "vertical") { const title = blockType?.title; const label = blockType ? getBlockLabel(blockType, attributes, "accessibility") : ""; const hasPosition = position !== void 0; const hasLabel = label && label !== title; if (hasPosition && direction === "vertical") { if (hasLabel) { return sprintf( /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ __("%1$s Block. Row %2$d. %3$s"), title, position, label ); } return sprintf( /* translators: accessibility text. 1: The block title. 2: The block row number. */ __("%1$s Block. Row %2$d"), title, position ); } else if (hasPosition && direction === "horizontal") { if (hasLabel) { return sprintf( /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ __("%1$s Block. Column %2$d. %3$s"), title, position, label ); } return sprintf( /* translators: accessibility text. 1: The block title. 2: The block column number. */ __("%1$s Block. Column %2$d"), title, position ); } if (hasLabel) { return sprintf( /* translators: accessibility text. 1: The block title. 2: The block label. */ __("%1$s Block. %2$s"), title, label ); } return sprintf( /* translators: accessibility text. %s: The block title. */ __("%s Block"), title ); } function getDefault(attributeSchema) { if (attributeSchema.default !== void 0) { return attributeSchema.default; } if (attributeSchema.type === "rich-text") { return new RichTextData(); } } function isBlockRegistered(name) { return getBlockType(name) !== void 0; } function __experimentalSanitizeBlockAttributes(name, attributes) { const blockType = getBlockType(name); if (void 0 === blockType) { throw new Error(`Block type '${name}' is not registered.`); } return Object.entries(blockType.attributes).reduce( (accumulator, [key, schema]) => { const value = attributes[key]; if (void 0 !== value) { if (schema.type === "rich-text") { if (value instanceof RichTextData) { accumulator[key] = value; } else if (typeof value === "string") { accumulator[key] = RichTextData.fromHTMLString(value); } } else if (schema.type === "string" && value instanceof RichTextData) { accumulator[key] = value.toHTMLString(); } else { accumulator[key] = value; } } else { const _default = getDefault(schema); if (void 0 !== _default) { accumulator[key] = _default; } } if (["node", "children"].indexOf(schema.source) !== -1) { if (typeof accumulator[key] === "string") { accumulator[key] = [accumulator[key]]; } else if (!Array.isArray(accumulator[key])) { accumulator[key] = []; } } return accumulator; }, {} ); } function getBlockAttributesNamesByRole(name, role) { const attributes = getBlockType(name)?.attributes; if (!attributes) { return []; } const attributesNames = Object.keys(attributes); if (!role) { return attributesNames; } return attributesNames.filter((attributeName) => { const attribute = attributes[attributeName]; if (attribute?.role === role) { return true; } if (attribute?.__experimentalRole === role) { deprecated("__experimentalRole attribute", { since: "6.7", version: "6.8", alternative: "role attribute", hint: `Check the block.json of the ${name} block.` }); return true; } return false; }); } var __experimentalGetBlockAttributesNamesByRole = (...args) => { deprecated("__experimentalGetBlockAttributesNamesByRole", { since: "6.7", version: "6.8", alternative: "getBlockAttributesNamesByRole" }); return getBlockAttributesNamesByRole(...args); }; function isContentBlock(name) { const blockType = getBlockType(name); const attributes = blockType?.attributes; const supportsContentRole = blockType?.supports?.contentRole; if (supportsContentRole) { return true; } if (!attributes) { return false; } return !!Object.keys(attributes)?.some((attributeKey) => { const attribute = attributes[attributeKey]; return attribute?.role === "content" || attribute?.__experimentalRole === "content"; }); } function omit(object, keys) { return Object.fromEntries( Object.entries(object).filter(([key]) => !keys.includes(key)) ); } export { __experimentalGetBlockAttributesNamesByRole, __experimentalSanitizeBlockAttributes, getAccessibleBlockLabel, getBlockAttributesNamesByRole, getBlockLabel, getDefault, isBlockRegistered, isContentBlock, isUnmodifiedBlock, isUnmodifiedDefaultBlock, isValidIcon, normalizeBlockType, normalizeIconObject, omit }; //# sourceMappingURL=utils.js.map