@wordpress/blocks
Version:
Block API for WordPress.
247 lines (246 loc) • 7.92 kB
JavaScript
// 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