@wordpress/blocks
Version:
Block API for WordPress.
356 lines (302 loc) • 11.7 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBlockType = getBlockType;
exports.getBlockStyles = getBlockStyles;
exports.getBlockVariations = getBlockVariations;
exports.getActiveBlockVariation = getActiveBlockVariation;
exports.getDefaultBlockVariation = getDefaultBlockVariation;
exports.getCategories = getCategories;
exports.getCollections = getCollections;
exports.getDefaultBlockName = getDefaultBlockName;
exports.getFreeformFallbackBlockName = getFreeformFallbackBlockName;
exports.getUnregisteredFallbackBlockName = getUnregisteredFallbackBlockName;
exports.getGroupingBlockName = getGroupingBlockName;
exports.hasBlockSupport = hasBlockSupport;
exports.isMatchingSearchTerm = isMatchingSearchTerm;
exports.hasChildBlocksWithInserterSupport = exports.hasChildBlocks = exports.getBlockSupport = exports.getChildBlockNames = exports.getBlockTypes = void 0;
var _rememo = _interopRequireDefault(require("rememo"));
var _lodash = require("lodash");
/**
* External dependencies
*/
/** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
/** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */
/** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
/**
* Given a block name or block type object, returns the corresponding
* normalized block type object.
*
* @param {Object} state Blocks state.
* @param {(string|Object)} nameOrType Block name or type object
*
* @return {Object} Block type object.
*/
const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? getBlockType(state, nameOrType) : nameOrType;
/**
* Returns all the available block types.
*
* @param {Object} state Data state.
*
* @return {Array} Block Types.
*/
const getBlockTypes = (0, _rememo.default)(state => {
return Object.values(state.blockTypes).map(blockType => {
return { ...blockType,
variations: getBlockVariations(state, blockType.name)
};
});
}, state => [state.blockTypes, state.blockVariations]);
/**
* Returns a block type by name.
*
* @param {Object} state Data state.
* @param {string} name Block type name.
*
* @return {Object?} Block Type.
*/
exports.getBlockTypes = getBlockTypes;
function getBlockType(state, name) {
return state.blockTypes[name];
}
/**
* Returns block styles by block name.
*
* @param {Object} state Data state.
* @param {string} name Block type name.
*
* @return {Array?} Block Styles.
*/
function getBlockStyles(state, name) {
return state.blockStyles[name];
}
/**
* Returns block variations by block name.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {WPBlockVariationScope} [scope] Block variation scope name.
*
* @return {(WPBlockVariation[]|void)} Block variations.
*/
function getBlockVariations(state, blockName, scope) {
const variations = state.blockVariations[blockName];
if (!variations || !scope) {
return variations;
}
return variations.filter(variation => {
// For backward compatibility reasons, variation's scope defaults to `block` and `inserter` when not set.
return (variation.scope || ['block', 'inserter']).includes(scope);
});
}
/**
* Returns the active block variation for a given block based on its attributes.
* Variations are determined by their `isActive` property.
* Which is either an array of block attribute keys or a function.
*
* In case of an array of block attribute keys, the `attributes` are compared
* to the variation's attributes using strict equality check.
*
* In case of function type, the function should accept a block's attributes
* and the variation's attributes and determines if a variation is active.
* A function that accepts a block's attributes and the variation's attributes and determines if a variation is active.
*
* @param {Object} state Data state.
* @param {string} blockName Name of block (example: “core/columns”).
* @param {Object} attributes Block attributes used to determine active variation.
* @param {WPBlockVariationScope} [scope] Block variation scope name.
*
* @return {(WPBlockVariation|undefined)} Active block variation.
*/
function getActiveBlockVariation(state, blockName, attributes, scope) {
const variations = getBlockVariations(state, blockName, scope);
const match = variations === null || variations === void 0 ? void 0 : variations.find(variation => {
var _variation$isActive;
if (Array.isArray(variation.isActive)) {
const blockType = getBlockType(state, blockName);
const attributeKeys = Object.keys(blockType.attributes || {});
const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute));
if (definedAttributes.length === 0) {
return false;
}
return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]);
}
return (_variation$isActive = variation.isActive) === null || _variation$isActive === void 0 ? void 0 : _variation$isActive.call(variation, attributes, variation.attributes);
});
return match;
}
/**
* Returns the default block variation for the given block type.
* When there are multiple variations annotated as the default one,
* the last added item is picked. This simplifies registering overrides.
* When there is no default variation set, it returns the first item.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {WPBlockVariationScope} [scope] Block variation scope name.
*
* @return {?WPBlockVariation} The default block variation.
*/
function getDefaultBlockVariation(state, blockName, scope) {
const variations = getBlockVariations(state, blockName, scope);
return (0, _lodash.findLast)(variations, 'isDefault') || (0, _lodash.first)(variations);
}
/**
* Returns all the available categories.
*
* @param {Object} state Data state.
*
* @return {WPBlockCategory[]} Categories list.
*/
function getCategories(state) {
return state.categories;
}
/**
* Returns all the available collections.
*
* @param {Object} state Data state.
*
* @return {Object} Collections list.
*/
function getCollections(state) {
return state.collections;
}
/**
* Returns the name of the default block name.
*
* @param {Object} state Data state.
*
* @return {string?} Default block name.
*/
function getDefaultBlockName(state) {
return state.defaultBlockName;
}
/**
* Returns the name of the block for handling non-block content.
*
* @param {Object} state Data state.
*
* @return {string?} Name of the block for handling non-block content.
*/
function getFreeformFallbackBlockName(state) {
return state.freeformFallbackBlockName;
}
/**
* Returns the name of the block for handling unregistered blocks.
*
* @param {Object} state Data state.
*
* @return {string?} Name of the block for handling unregistered blocks.
*/
function getUnregisteredFallbackBlockName(state) {
return state.unregisteredFallbackBlockName;
}
/**
* Returns the name of the block for handling unregistered blocks.
*
* @param {Object} state Data state.
*
* @return {string?} Name of the block for handling unregistered blocks.
*/
function getGroupingBlockName(state) {
return state.groupingBlockName;
}
/**
* Returns an array with the child blocks of a given block.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
*
* @return {Array} Array of child block names.
*/
const getChildBlockNames = (0, _rememo.default)((state, blockName) => {
return (0, _lodash.map)((0, _lodash.filter)(state.blockTypes, blockType => {
return (0, _lodash.includes)(blockType.parent, blockName);
}), ({
name
}) => name);
}, state => [state.blockTypes]);
/**
* Returns the block support value for a feature, if defined.
*
* @param {Object} state Data state.
* @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
*/
exports.getChildBlockNames = getChildBlockNames;
const getBlockSupport = (state, nameOrType, feature, defaultSupports) => {
const blockType = getNormalizedBlockType(state, nameOrType);
return (0, _lodash.get)(blockType, ['supports', ...feature.split('.')], defaultSupports);
};
/**
* Returns true if the block defines support for a feature, or false otherwise.
*
* @param {Object} state Data state.
* @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.
*/
exports.getBlockSupport = getBlockSupport;
function hasBlockSupport(state, nameOrType, feature, defaultSupports) {
return !!getBlockSupport(state, nameOrType, feature, defaultSupports);
}
/**
* Returns true if the block type by the given name or object value matches a
* search term, or false otherwise.
*
* @param {Object} state Blocks state.
* @param {(string|Object)} nameOrType Block name or type object.
* @param {string} searchTerm Search term by which to filter.
*
* @return {Object[]} Whether block type matches search term.
*/
function isMatchingSearchTerm(state, nameOrType, searchTerm) {
const blockType = getNormalizedBlockType(state, nameOrType);
const getNormalizedSearchTerm = (0, _lodash.flow)([// Disregard diacritics.
// Input: "média"
_lodash.deburr, // Lowercase.
// Input: "MEDIA"
term => term.toLowerCase(), // Strip leading and trailing whitespace.
// Input: " media "
term => term.trim()]);
const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm);
const isSearchMatch = (0, _lodash.flow)([getNormalizedSearchTerm, normalizedCandidate => (0, _lodash.includes)(normalizedCandidate, normalizedSearchTerm)]);
return isSearchMatch(blockType.title) || (0, _lodash.some)(blockType.keywords, isSearchMatch) || isSearchMatch(blockType.category);
}
/**
* Returns a boolean indicating if a block has child blocks or not.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
*
* @return {boolean} True if a block contains child blocks and false otherwise.
*/
const hasChildBlocks = (state, blockName) => {
return getChildBlockNames(state, blockName).length > 0;
};
/**
* Returns a boolean indicating if a block has at least one child block with inserter support.
*
* @param {Object} state Data state.
* @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 = (state, blockName) => {
return (0, _lodash.some)(getChildBlockNames(state, blockName), childBlockName => {
return hasBlockSupport(state, childBlockName, 'inserter', true);
});
};
exports.hasChildBlocksWithInserterSupport = hasChildBlocksWithInserterSupport;
//# sourceMappingURL=selectors.js.map