@wordpress/block-editor
Version:
444 lines (443 loc) • 14.4 kB
JavaScript
// packages/block-editor/src/store/private-selectors.js
import { createSelector, createRegistrySelector } from "@wordpress/data";
import {
hasBlockSupport,
privateApis as blocksPrivateApis
} from "@wordpress/blocks";
import {
getBlockOrder,
getBlockParents,
getBlockEditingMode,
getSettings,
canInsertBlockType,
getBlockName,
getTemplateLock,
getClientIdsWithDescendants,
getBlockRootClientId,
getBlockAttributes
} from "./selectors";
import {
checkAllowListRecursive,
getAllPatternsDependants,
getInsertBlockTypeDependants,
getGrammar,
mapUserPattern
} from "./utils";
import { STORE_NAME } from "./constants";
import { unlock } from "../lock-unlock";
import {
selectBlockPatternsKey,
reusableBlocksSelectKey,
sectionRootClientIdKey,
isIsolatedEditorKey
} from "./private-keys";
import { getBlockSettings } from "./get-block-settings";
var { isContentBlock } = unlock(blocksPrivateApis);
function isBlockInterfaceHidden(state) {
return state.isBlockInterfaceHidden;
}
function getLastInsertedBlocksClientIds(state) {
return state?.lastBlockInserted?.clientIds;
}
function getBlockWithoutAttributes(state, clientId) {
return state.blocks.byClientId.get(clientId);
}
var isBlockSubtreeDisabled = (state, clientId) => {
const isChildSubtreeDisabled = (childClientId) => {
return getBlockEditingMode(state, childClientId) === "disabled" && getBlockOrder(state, childClientId).every(
isChildSubtreeDisabled
);
};
return getBlockOrder(state, clientId).every(isChildSubtreeDisabled);
};
function isContainerInsertableToInContentOnlyMode(state, blockName, rootClientId) {
const isBlockContentBlock = isContentBlock(blockName);
const rootBlockName = getBlockName(state, rootClientId);
const isContainerContentBlock = isContentBlock(rootBlockName);
const isRootBlockMain = getSectionRootClientId(state) === rootClientId;
return isRootBlockMain || isContainerContentBlock && isBlockContentBlock;
}
function getEnabledClientIdsTreeUnmemoized(state, rootClientId) {
const blockOrder = getBlockOrder(state, rootClientId);
const result = [];
for (const clientId of blockOrder) {
const innerBlocks = getEnabledClientIdsTreeUnmemoized(
state,
clientId
);
if (getBlockEditingMode(state, clientId) !== "disabled") {
result.push({ clientId, innerBlocks });
} else {
result.push(...innerBlocks);
}
}
return result;
}
var getEnabledClientIdsTree = createRegistrySelector(
() => createSelector(getEnabledClientIdsTreeUnmemoized, (state) => [
state.blocks.order,
state.derivedBlockEditingModes,
state.blockEditingModes
])
);
var getEnabledBlockParents = createSelector(
(state, clientId, ascending = false) => {
return getBlockParents(state, clientId, ascending).filter(
(parent) => getBlockEditingMode(state, parent) !== "disabled"
);
},
(state) => [
state.blocks.parents,
state.blockEditingModes,
state.settings.templateLock,
state.blockListSettings
]
);
function getRemovalPromptData(state) {
return state.removalPromptData;
}
function getBlockRemovalRules(state) {
return state.blockRemovalRules;
}
function getOpenedBlockSettingsMenu(state) {
return state.openedBlockSettingsMenu;
}
var getStyleOverrides = createSelector(
(state) => {
const clientIds = getClientIdsWithDescendants(state);
const clientIdMap = clientIds.reduce((acc, clientId, index) => {
acc[clientId] = index;
return acc;
}, {});
return [...state.styleOverrides].sort((overrideA, overrideB) => {
const [, { clientId: clientIdA }] = overrideA;
const [, { clientId: clientIdB }] = overrideB;
const aIndex = clientIdMap[clientIdA] ?? -1;
const bIndex = clientIdMap[clientIdB] ?? -1;
return aIndex - bIndex;
});
},
(state) => [state.blocks.order, state.styleOverrides]
);
function getRegisteredInserterMediaCategories(state) {
return state.registeredInserterMediaCategories;
}
var getInserterMediaCategories = createSelector(
(state) => {
const {
settings: {
inserterMediaCategories,
allowedMimeTypes,
enableOpenverseMediaCategory
},
registeredInserterMediaCategories
} = state;
if (!inserterMediaCategories && !registeredInserterMediaCategories.length || !allowedMimeTypes) {
return;
}
const coreInserterMediaCategoriesNames = inserterMediaCategories?.map(({ name }) => name) || [];
const mergedCategories = [
...inserterMediaCategories || [],
...(registeredInserterMediaCategories || []).filter(
({ name }) => !coreInserterMediaCategoriesNames.includes(name)
)
];
return mergedCategories.filter((category) => {
if (!enableOpenverseMediaCategory && category.name === "openverse") {
return false;
}
return Object.values(allowedMimeTypes).some(
(mimeType) => mimeType.startsWith(`${category.mediaType}/`)
);
});
},
(state) => [
state.settings.inserterMediaCategories,
state.settings.allowedMimeTypes,
state.settings.enableOpenverseMediaCategory,
state.registeredInserterMediaCategories
]
);
var hasAllowedPatterns = createRegistrySelector(
(select) => createSelector(
(state, rootClientId = null) => {
const { getAllPatterns: getAllPatterns2 } = unlock(select(STORE_NAME));
const patterns = getAllPatterns2();
const { allowedBlockTypes } = getSettings(state);
return patterns.some((pattern) => {
const { inserter = true } = pattern;
if (!inserter) {
return false;
}
const grammar = getGrammar(pattern);
return checkAllowListRecursive(grammar, allowedBlockTypes) && grammar.every(
({ name: blockName }) => canInsertBlockType(state, blockName, rootClientId)
);
});
},
(state, rootClientId) => [
...getAllPatternsDependants(select)(state),
...getInsertBlockTypeDependants(select)(state, rootClientId)
]
)
);
var getPatternBySlug = createRegistrySelector(
(select) => createSelector(
(state, patternName) => {
if (patternName?.startsWith("core/block/")) {
const _id = parseInt(
patternName.slice("core/block/".length),
10
);
const block = unlock(select(STORE_NAME)).getReusableBlocks().find(({ id }) => id === _id);
if (!block) {
return null;
}
return mapUserPattern(
block,
state.settings.__experimentalUserPatternCategories
);
}
return [
// This setting is left for back compat.
...state.settings.__experimentalBlockPatterns ?? [],
...state.settings[selectBlockPatternsKey]?.(select) ?? []
].find(({ name }) => name === patternName);
},
(state, patternName) => patternName?.startsWith("core/block/") ? [
unlock(select(STORE_NAME)).getReusableBlocks(),
state.settings.__experimentalReusableBlocks
] : [
state.settings.__experimentalBlockPatterns,
state.settings[selectBlockPatternsKey]?.(select)
]
)
);
var getAllPatterns = createRegistrySelector(
(select) => createSelector((state) => {
return [
...unlock(select(STORE_NAME)).getReusableBlocks().map(
(userPattern) => mapUserPattern(
userPattern,
state.settings.__experimentalUserPatternCategories
)
),
// This setting is left for back compat.
...state.settings.__experimentalBlockPatterns ?? [],
...state.settings[selectBlockPatternsKey]?.(select) ?? []
].filter(
(x, index, arr) => index === arr.findIndex((y) => x.name === y.name)
);
}, getAllPatternsDependants(select))
);
var EMPTY_ARRAY = [];
var getReusableBlocks = createRegistrySelector(
(select) => (state) => {
const reusableBlocksSelect = state.settings[reusableBlocksSelectKey];
return (reusableBlocksSelect ? reusableBlocksSelect(select) : state.settings.__experimentalReusableBlocks) ?? EMPTY_ARRAY;
}
);
function getLastFocus(state) {
return state.lastFocus;
}
function isDragging(state) {
return state.isDragging;
}
function getExpandedBlock(state) {
return state.expandedBlock;
}
var getContentLockingParent = (state, clientId) => {
let current = clientId;
let result;
while (!result && (current = state.blocks.parents.get(current))) {
if (getTemplateLock(state, current) === "contentOnly") {
result = current;
}
}
return result;
};
var getParentSectionBlock = (state, clientId) => {
let current = clientId;
let result;
while (current = state.blocks.parents.get(current)) {
if (isSectionBlock(state, current)) {
result = current;
}
}
return result;
};
function isSectionBlock(state, clientId) {
if (clientId === state.editedContentOnlySection) {
return false;
}
const blockName = getBlockName(state, clientId);
if (blockName === "core/block") {
return true;
}
const attributes = getBlockAttributes(state, clientId);
const isTemplatePart = blockName === "core/template-part";
const isIsolatedEditor = state.settings?.[isIsolatedEditorKey];
if ((attributes?.metadata?.patternName || isTemplatePart) && !!window?.__experimentalContentOnlyPatternInsertion && !isIsolatedEditor) {
return true;
}
const hasContentOnlyTempateLock = getTemplateLock(state, clientId) === "contentOnly";
const rootClientId = getBlockRootClientId(state, clientId);
const hasRootContentOnlyTemplateLock = getTemplateLock(state, rootClientId) === "contentOnly";
if (hasContentOnlyTempateLock && !hasRootContentOnlyTemplateLock) {
return true;
}
return false;
}
function getEditedContentOnlySection(state) {
return state.editedContentOnlySection;
}
function isWithinEditedContentOnlySection(state, clientId) {
if (!state.editedContentOnlySection) {
return false;
}
if (state.editedContentOnlySection === clientId) {
return true;
}
let current = clientId;
while (current = state.blocks.parents.get(current)) {
if (state.editedContentOnlySection === current) {
return true;
}
}
return false;
}
var getBlockStyles = createSelector(
(state, clientIds) => clientIds.reduce((styles, clientId) => {
styles[clientId] = state.blocks.attributes.get(clientId)?.style;
return styles;
}, {}),
(state, clientIds) => [
...clientIds.map(
(clientId) => state.blocks.attributes.get(clientId)?.style
)
]
);
function getSectionRootClientId(state) {
return state.settings?.[sectionRootClientIdKey];
}
function isZoomOut(state) {
return state.zoomLevel === "auto-scaled" || state.zoomLevel < 100;
}
function getZoomLevel(state) {
return state.zoomLevel;
}
function getClosestAllowedInsertionPoint(state, name, clientId = "") {
const blockNames = Array.isArray(name) ? name : [name];
const areBlockNamesAllowedInClientId = (id) => blockNames.every(
(currentName) => canInsertBlockType(state, currentName, id)
);
if (!clientId) {
if (areBlockNamesAllowedInClientId(clientId)) {
return clientId;
}
const sectionRootClientId = getSectionRootClientId(state);
if (sectionRootClientId && areBlockNamesAllowedInClientId(sectionRootClientId)) {
return sectionRootClientId;
}
return null;
}
let current = clientId;
while (current !== null && !areBlockNamesAllowedInClientId(current)) {
const parentClientId = getBlockRootClientId(state, current);
current = parentClientId;
}
return current;
}
function getClosestAllowedInsertionPointForPattern(state, pattern, clientId) {
const { allowedBlockTypes } = getSettings(state);
const isAllowed = checkAllowListRecursive(
getGrammar(pattern),
allowedBlockTypes
);
if (!isAllowed) {
return null;
}
const names = getGrammar(pattern).map(({ blockName: name }) => name);
return getClosestAllowedInsertionPoint(state, names, clientId);
}
function getInsertionPoint(state) {
return state.insertionPoint;
}
var isBlockHidden = (state, clientId) => {
const blockName = getBlockName(state, clientId);
if (!hasBlockSupport(state, blockName, "visibility", true)) {
return false;
}
const attributes = state.blocks.attributes.get(clientId);
return attributes?.metadata?.blockVisibility === false;
};
function hasBlockSpotlight(state) {
return !!state.hasBlockSpotlight || !!state.editedContentOnlySection;
}
function isEditLockedBlock(state, clientId) {
const attributes = getBlockAttributes(state, clientId);
return !!attributes?.lock?.edit;
}
function isMoveLockedBlock(state, clientId) {
const attributes = getBlockAttributes(state, clientId);
if (attributes?.lock?.move !== void 0) {
return !!attributes?.lock?.move;
}
const rootClientId = getBlockRootClientId(state, clientId);
const templateLock = getTemplateLock(state, rootClientId);
return templateLock === "all";
}
function isRemoveLockedBlock(state, clientId) {
const attributes = getBlockAttributes(state, clientId);
if (attributes?.lock?.remove !== void 0) {
return !!attributes?.lock?.remove;
}
const rootClientId = getBlockRootClientId(state, clientId);
const templateLock = getTemplateLock(state, rootClientId);
return templateLock === "all" || templateLock === "insert";
}
function isLockedBlock(state, clientId) {
return isEditLockedBlock(state, clientId) || isMoveLockedBlock(state, clientId) || isRemoveLockedBlock(state, clientId);
}
export {
getAllPatterns,
getBlockRemovalRules,
getBlockSettings,
getBlockStyles,
getBlockWithoutAttributes,
getClosestAllowedInsertionPoint,
getClosestAllowedInsertionPointForPattern,
getContentLockingParent,
getEditedContentOnlySection,
getEnabledBlockParents,
getEnabledClientIdsTree,
getExpandedBlock,
getInserterMediaCategories,
getInsertionPoint,
getLastFocus,
getLastInsertedBlocksClientIds,
getOpenedBlockSettingsMenu,
getParentSectionBlock,
getPatternBySlug,
getRegisteredInserterMediaCategories,
getRemovalPromptData,
getReusableBlocks,
getSectionRootClientId,
getStyleOverrides,
getZoomLevel,
hasAllowedPatterns,
hasBlockSpotlight,
isBlockHidden,
isBlockInterfaceHidden,
isBlockSubtreeDisabled,
isContainerInsertableToInContentOnlyMode,
isDragging,
isEditLockedBlock,
isLockedBlock,
isMoveLockedBlock,
isRemoveLockedBlock,
isSectionBlock,
isWithinEditedContentOnlySection,
isZoomOut
};
//# sourceMappingURL=private-selectors.js.map