@wordpress/block-editor
Version:
653 lines (651 loc) • 24.6 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/block-editor/src/components/block-list/block.js
var block_exports = {};
__export(block_exports, {
default: () => block_default
});
module.exports = __toCommonJS(block_exports);
var import_clsx = __toESM(require("clsx"));
var import_element = require("@wordpress/element");
var import_blocks = require("@wordpress/blocks");
var import_components = require("@wordpress/components");
var import_data = require("@wordpress/data");
var import_compose = require("@wordpress/compose");
var import_dom = require("@wordpress/dom");
var import_block_edit = __toESM(require("../block-edit/index.cjs"));
var import_block_invalid_warning = __toESM(require("./block-invalid-warning.cjs"));
var import_block_crash_warning = __toESM(require("./block-crash-warning.cjs"));
var import_block_crash_boundary = __toESM(require("./block-crash-boundary.cjs"));
var import_block_html = __toESM(require("./block-html.cjs"));
var import_use_block_props = require("./use-block-props/index.cjs");
var import_store = require("../../store/index.cjs");
var import_layout = require("./layout.cjs");
var import_private_block_context = require("./private-block-context.cjs");
var import_block_visibility = require("../block-visibility/index.cjs");
var import_lock_unlock = require("../../lock-unlock.cjs");
var import_private_keys = require("../../store/private-keys.cjs");
var import_jsx_runtime = require("react/jsx-runtime");
function mergeWrapperProps(propsA, propsB) {
const newProps = {
...propsA,
...propsB
};
if (propsA?.hasOwnProperty("className") && propsB?.hasOwnProperty("className")) {
newProps.className = (0, import_clsx.default)(propsA.className, propsB.className);
}
if (propsA?.hasOwnProperty("style") && propsB?.hasOwnProperty("style")) {
newProps.style = { ...propsA.style, ...propsB.style };
}
return newProps;
}
function Block({ children, isHtml, ...props }) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...(0, import_use_block_props.useBlockProps)(props, { __unstableIsHtml: isHtml }), children });
}
function BlockListBlock({
block: { __unstableBlockSource },
mode,
isLocked,
canRemove,
clientId,
isSelected,
isSelectionEnabled,
className,
__unstableLayoutClassNames: layoutClassNames,
name,
isValid,
attributes,
wrapperProps,
setAttributes,
onReplace,
onRemove,
onInsertBlocksAfter,
onMerge,
toggleSelection
}) {
const {
mayDisplayControls,
mayDisplayParentControls,
isSelectionWithinCurrentSection,
themeSupportsLayout,
...context
} = (0, import_element.useContext)(import_private_block_context.PrivateBlockContext);
const parentLayout = (0, import_layout.useLayout)() || {};
let blockEdit = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_block_edit.default,
{
name,
isSelected,
attributes,
setAttributes,
insertBlocksAfter: isLocked ? void 0 : onInsertBlocksAfter,
onReplace: canRemove ? onReplace : void 0,
onRemove: canRemove ? onRemove : void 0,
mergeBlocks: canRemove ? onMerge : void 0,
clientId,
isSelectionEnabled,
toggleSelection,
__unstableLayoutClassNames: layoutClassNames,
__unstableParentLayout: Object.keys(parentLayout).length ? parentLayout : void 0,
mayDisplayControls,
mayDisplayParentControls,
mayDisplayPatternEditingControls: isSelectionWithinCurrentSection,
blockEditingMode: context.blockEditingMode,
isPreviewMode: context.isPreviewMode
}
);
const blockType = (0, import_blocks.getBlockType)(name);
if (blockType?.getEditWrapperProps) {
wrapperProps = mergeWrapperProps(
wrapperProps,
blockType.getEditWrapperProps(attributes)
);
}
const isAligned = wrapperProps && !!wrapperProps["data-align"] && !themeSupportsLayout;
const isSticky = className?.includes("is-position-sticky");
if (isAligned) {
blockEdit = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: (0, import_clsx.default)("wp-block", isSticky && className),
"data-align": wrapperProps["data-align"],
children: blockEdit
}
);
}
let block;
if (!isValid) {
const saveContent = __unstableBlockSource ? (0, import_blocks.serializeRawBlock)(__unstableBlockSource) : (0, import_blocks.getSaveContent)(blockType, attributes);
block = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Block, { className: "has-warning", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_invalid_warning.default, { clientId }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_element.RawHTML, { children: (0, import_dom.safeHTML)(saveContent) })
] });
} else if (mode === "html") {
block = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "none" }, children: blockEdit }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Block, { isHtml: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_html.default, { clientId }) })
] });
} else if (blockType?.apiVersion > 1) {
block = blockEdit;
} else {
block = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Block, { children: blockEdit });
}
const { "data-align": dataAlign, ...restWrapperProps } = wrapperProps ?? {};
const updatedWrapperProps = {
...restWrapperProps,
className: (0, import_clsx.default)(
restWrapperProps.className,
dataAlign && themeSupportsLayout && `align${dataAlign}`,
!(dataAlign && isSticky) && className
)
};
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_private_block_context.PrivateBlockContext.Provider,
{
value: {
wrapperProps: updatedWrapperProps,
isAligned,
isSelectionWithinCurrentSection,
...context
},
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_block_crash_boundary.default,
{
fallback: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Block, { className: "has-warning", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_crash_warning.default, {}) }),
children: block
}
)
}
);
}
var applyWithDispatch = (0, import_data.withDispatch)((dispatch, ownProps, registry) => {
const {
updateBlockAttributes,
insertBlocks,
mergeBlocks,
replaceBlocks,
toggleSelection,
__unstableMarkLastChangeAsPersistent,
moveBlocksToPosition,
removeBlock,
selectBlock
} = dispatch(import_store.store);
return {
setAttributes(nextAttributes) {
const { getMultiSelectedBlockClientIds } = registry.select(import_store.store);
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds();
const { clientId, attributes } = ownProps;
const clientIds = multiSelectedBlockClientIds.length ? multiSelectedBlockClientIds : [clientId];
const newAttributes = typeof nextAttributes === "function" ? nextAttributes(attributes) : nextAttributes;
updateBlockAttributes(clientIds, newAttributes);
},
onInsertBlocks(blocks, index) {
const { rootClientId } = ownProps;
insertBlocks(blocks, index, rootClientId);
},
onInsertBlocksAfter(blocks) {
const { clientId, rootClientId } = ownProps;
const { getBlockIndex } = registry.select(import_store.store);
const index = getBlockIndex(clientId);
insertBlocks(blocks, index + 1, rootClientId);
},
onMerge(forward) {
const { clientId, rootClientId } = ownProps;
const {
getPreviousBlockClientId,
getNextBlockClientId,
getBlock,
getBlockAttributes,
getBlockName,
getBlockOrder,
getBlockIndex,
getBlockRootClientId,
canInsertBlockType
} = registry.select(import_store.store);
function switchToDefaultOrRemove() {
const block = getBlock(clientId);
const defaultBlockName = (0, import_blocks.getDefaultBlockName)();
const defaultBlockType = (0, import_blocks.getBlockType)(defaultBlockName);
if (getBlockName(clientId) !== defaultBlockName) {
const replacement = (0, import_blocks.switchToBlockType)(
block,
defaultBlockName
);
if (replacement && replacement.length) {
replaceBlocks(clientId, replacement);
}
} else if ((0, import_blocks.isUnmodifiedDefaultBlock)(block)) {
const nextBlockClientId = getNextBlockClientId(clientId);
if (nextBlockClientId) {
registry.batch(() => {
removeBlock(clientId);
selectBlock(nextBlockClientId);
});
}
} else if (defaultBlockType.merge) {
const attributes = defaultBlockType.merge(
{},
block.attributes
);
replaceBlocks(
[clientId],
[(0, import_blocks.createBlock)(defaultBlockName, attributes)]
);
}
}
function moveFirstItemUp(_clientId, changeSelection = true) {
const wrapperBlockName = getBlockName(_clientId);
const wrapperBlockType = (0, import_blocks.getBlockType)(wrapperBlockName);
const isTextualWrapper = wrapperBlockType.category === "text";
const targetRootClientId = getBlockRootClientId(_clientId);
const blockOrder = getBlockOrder(_clientId);
const [firstClientId] = blockOrder;
if (blockOrder.length === 1 && (0, import_blocks.isUnmodifiedBlock)(getBlock(firstClientId))) {
removeBlock(_clientId);
} else if (isTextualWrapper) {
registry.batch(() => {
if (canInsertBlockType(
getBlockName(firstClientId),
targetRootClientId
)) {
moveBlocksToPosition(
[firstClientId],
_clientId,
targetRootClientId,
getBlockIndex(_clientId)
);
} else {
const replacement = (0, import_blocks.switchToBlockType)(
getBlock(firstClientId),
(0, import_blocks.getDefaultBlockName)()
);
if (replacement && replacement.length && replacement.every(
(block) => canInsertBlockType(
block.name,
targetRootClientId
)
)) {
insertBlocks(
replacement,
getBlockIndex(_clientId),
targetRootClientId,
changeSelection
);
removeBlock(firstClientId, false);
} else {
switchToDefaultOrRemove();
}
}
if (!getBlockOrder(_clientId).length && (0, import_blocks.isUnmodifiedBlock)(getBlock(_clientId))) {
removeBlock(_clientId, false);
}
});
} else {
switchToDefaultOrRemove();
}
}
if (forward) {
if (rootClientId) {
const nextRootClientId = getNextBlockClientId(rootClientId);
if (nextRootClientId) {
if (getBlockName(rootClientId) === getBlockName(nextRootClientId)) {
const rootAttributes = getBlockAttributes(rootClientId);
const previousRootAttributes = getBlockAttributes(nextRootClientId);
if (Object.keys(rootAttributes).every(
(key) => rootAttributes[key] === previousRootAttributes[key]
)) {
registry.batch(() => {
moveBlocksToPosition(
getBlockOrder(nextRootClientId),
nextRootClientId,
rootClientId
);
removeBlock(nextRootClientId, false);
});
return;
}
} else {
mergeBlocks(rootClientId, nextRootClientId);
return;
}
}
}
const nextBlockClientId = getNextBlockClientId(clientId);
if (!nextBlockClientId) {
return;
}
if (getBlockOrder(nextBlockClientId).length) {
moveFirstItemUp(nextBlockClientId, false);
} else {
mergeBlocks(clientId, nextBlockClientId);
}
} else {
const previousBlockClientId = getPreviousBlockClientId(clientId);
if (previousBlockClientId) {
mergeBlocks(previousBlockClientId, clientId);
} else if (rootClientId) {
const previousRootClientId = getPreviousBlockClientId(rootClientId);
if (previousRootClientId && getBlockName(rootClientId) === getBlockName(previousRootClientId)) {
const rootAttributes = getBlockAttributes(rootClientId);
const previousRootAttributes = getBlockAttributes(previousRootClientId);
if (Object.keys(rootAttributes).every(
(key) => rootAttributes[key] === previousRootAttributes[key]
)) {
registry.batch(() => {
moveBlocksToPosition(
getBlockOrder(rootClientId),
rootClientId,
previousRootClientId
);
removeBlock(rootClientId, false);
});
return;
}
}
moveFirstItemUp(rootClientId);
} else {
switchToDefaultOrRemove();
}
}
},
onReplace(blocks, indexToSelect, initialPosition) {
if (blocks.length && !(0, import_blocks.isUnmodifiedDefaultBlock)(blocks[blocks.length - 1])) {
__unstableMarkLastChangeAsPersistent();
}
const replacementBlocks = blocks?.length === 1 && Array.isArray(blocks[0]) ? blocks[0] : blocks;
replaceBlocks(
[ownProps.clientId],
replacementBlocks,
indexToSelect,
initialPosition
);
},
onRemove() {
removeBlock(ownProps.clientId);
},
toggleSelection(selectionEnabled) {
toggleSelection(selectionEnabled);
}
};
});
BlockListBlock = (0, import_compose.compose)(
applyWithDispatch,
(0, import_components.withFilters)("editor.BlockListBlock")
)(BlockListBlock);
function BlockListBlockProvider(props) {
const { clientId, rootClientId } = props;
const selectedProps = (0, import_data.useSelect)(
(select) => {
const {
isBlockSelected,
getBlockMode,
isSelectionEnabled: isSelectionEnabled2,
getTemplateLock,
isSectionBlock: _isSectionBlock,
getParentSectionBlock,
getBlockWithoutAttributes,
getBlockAttributes,
canRemoveBlock,
canMoveBlock,
getSettings,
getEditedContentOnlySection,
getBlockEditingMode,
getBlockName,
isFirstMultiSelectedBlock,
getMultiSelectedBlockClientIds,
hasSelectedInnerBlock,
getBlocksByName,
getBlockIndex,
isBlockMultiSelected,
isBlockSubtreeDisabled,
isBlockHighlighted,
__unstableIsFullySelected,
__unstableSelectionHasUnmergeableBlock,
isBlockBeingDragged,
isDragging: isDragging2,
__unstableHasActiveBlockOverlayActive,
getSelectedBlocksInitialCaretPosition
} = (0, import_lock_unlock.unlock)(select(import_store.store));
const blockWithoutAttributes2 = getBlockWithoutAttributes(clientId);
if (!blockWithoutAttributes2) {
return;
}
const {
hasBlockSupport: _hasBlockSupport,
getActiveBlockVariation
} = select(import_blocks.store);
const attributes2 = getBlockAttributes(clientId);
const { name: blockName, isValid: isValid2 } = blockWithoutAttributes2;
const blockType2 = (0, import_blocks.getBlockType)(blockName);
const settings = getSettings();
const {
supportsLayout,
isPreviewMode: isPreviewMode2,
__experimentalBlockBindingsSupportedAttributes
} = settings;
const bindableAttributes2 = __experimentalBlockBindingsSupportedAttributes?.[blockName];
const blockVisibility2 = attributes2?.metadata?.blockVisibility;
const deviceType2 = settings?.[import_private_keys.deviceTypeKey]?.toLowerCase() || "desktop";
const hasLightBlockWrapper = blockType2?.apiVersion > 1;
const previewContext = {
isPreviewMode: isPreviewMode2,
blockWithoutAttributes: blockWithoutAttributes2,
name: blockName,
attributes: attributes2,
isValid: isValid2,
themeSupportsLayout: supportsLayout,
index: getBlockIndex(clientId),
isReusable: (0, import_blocks.isReusableBlock)(blockType2),
className: hasLightBlockWrapper ? attributes2.className : void 0,
defaultClassName: hasLightBlockWrapper ? (0, import_blocks.getBlockDefaultClassName)(blockName) : void 0,
blockTitle: blockType2?.title,
bindableAttributes: bindableAttributes2,
blockVisibility: blockVisibility2,
deviceType: deviceType2
};
if (isPreviewMode2) {
return previewContext;
}
const _isSelected = isBlockSelected(clientId);
const canRemove2 = canRemoveBlock(clientId);
const canMove2 = canMoveBlock(clientId);
const match = getActiveBlockVariation(blockName, attributes2);
const isMultiSelected2 = isBlockMultiSelected(clientId);
const checkDeep = true;
const isAncestorOfSelectedBlock = hasSelectedInnerBlock(
clientId,
checkDeep
);
const blockEditingMode2 = getBlockEditingMode(clientId);
const sectionBlockClientId = _isSectionBlock(clientId) ? clientId : getParentSectionBlock(clientId);
const multiple = (0, import_blocks.hasBlockSupport)(blockName, "multiple", true);
const blocksWithSameName = multiple ? [] : getBlocksByName(blockName);
const isInvalid = blocksWithSameName.length && blocksWithSameName[0] !== clientId;
return {
...previewContext,
mode: getBlockMode(clientId),
isSelectionEnabled: isSelectionEnabled2(),
isLocked: !!getTemplateLock(rootClientId),
isSectionBlock: _isSectionBlock(clientId),
isWithinSectionBlock: !!sectionBlockClientId,
isSelectionWithinCurrentSection: isBlockSelected(sectionBlockClientId) || hasSelectedInnerBlock(sectionBlockClientId, checkDeep),
blockType: blockType2,
canRemove: canRemove2,
canMove: canMove2,
isSelected: _isSelected,
isEditingContentOnlySection: getEditedContentOnlySection() === clientId,
blockEditingMode: blockEditingMode2,
mayDisplayControls: _isSelected || isFirstMultiSelectedBlock(clientId) && getMultiSelectedBlockClientIds().every(
(id) => getBlockName(id) === blockName
),
mayDisplayParentControls: _hasBlockSupport(
getBlockName(clientId),
"__experimentalExposeControlsToChildren",
false
) && hasSelectedInnerBlock(clientId),
blockApiVersion: blockType2?.apiVersion || 1,
blockTitle: match?.title || blockType2?.title,
isSubtreeDisabled: blockEditingMode2 === "disabled" && isBlockSubtreeDisabled(clientId),
hasOverlay: __unstableHasActiveBlockOverlayActive(clientId) && !isDragging2(),
initialPosition: _isSelected ? getSelectedBlocksInitialCaretPosition() : void 0,
isHighlighted: isBlockHighlighted(clientId),
isMultiSelected: isMultiSelected2,
isPartiallySelected: isMultiSelected2 && !__unstableIsFullySelected() && !__unstableSelectionHasUnmergeableBlock(),
isDragging: isBlockBeingDragged(clientId),
hasChildSelected: isAncestorOfSelectedBlock,
isEditingDisabled: blockEditingMode2 === "disabled",
hasEditableOutline: blockEditingMode2 !== "disabled" && getBlockEditingMode(rootClientId) === "disabled",
originalBlockClientId: isInvalid ? blocksWithSameName[0] : false,
blockVisibility: blockVisibility2,
deviceType: deviceType2
};
},
[clientId, rootClientId]
);
const {
isPreviewMode,
// Fill values that end up as a public API and may not be defined in
// preview mode.
mode = "visual",
isSelectionEnabled = false,
isLocked = false,
canRemove = false,
canMove = false,
blockWithoutAttributes,
name,
attributes,
isValid,
isSelected = false,
themeSupportsLayout,
isEditingContentOnlySection,
blockEditingMode,
mayDisplayControls,
mayDisplayParentControls,
index,
blockApiVersion,
blockType,
blockTitle,
isSubtreeDisabled,
hasOverlay,
initialPosition,
isHighlighted,
isMultiSelected,
isPartiallySelected,
isReusable,
isDragging,
hasChildSelected,
isSectionBlock,
isWithinSectionBlock,
isSelectionWithinCurrentSection,
isEditingDisabled,
hasEditableOutline,
className,
defaultClassName,
originalBlockClientId,
bindableAttributes,
blockVisibility,
deviceType
} = selectedProps;
const { isBlockCurrentlyHidden } = (0, import_block_visibility.useBlockVisibility)({
blockVisibility,
deviceType
});
const block = (0, import_element.useMemo)(
() => ({ ...blockWithoutAttributes, attributes }),
[blockWithoutAttributes, attributes]
);
if (!selectedProps) {
return null;
}
const privateContext = {
isPreviewMode,
clientId,
className,
index,
mode,
name,
blockApiVersion,
blockType,
blockTitle,
isSelected,
isSubtreeDisabled,
hasOverlay,
initialPosition,
blockEditingMode,
isHighlighted,
isMultiSelected,
isPartiallySelected,
isReusable,
isDragging,
hasChildSelected,
isSectionBlock,
isWithinSectionBlock,
isSelectionWithinCurrentSection,
isEditingDisabled,
hasEditableOutline,
isEditingContentOnlySection,
defaultClassName,
mayDisplayControls,
mayDisplayParentControls,
originalBlockClientId,
themeSupportsLayout,
canMove,
isBlockCurrentlyHidden,
bindableAttributes,
blockVisibility,
deviceType
};
if (isBlockCurrentlyHidden && !isSelected && !isMultiSelected && !hasChildSelected) {
return null;
}
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_private_block_context.PrivateBlockContext.Provider, { value: privateContext, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
BlockListBlock,
{
...props,
...{
mode,
isSelectionEnabled,
isLocked,
canRemove,
canMove,
// Users of the editor.BlockListBlock filter used to be able
// to access the block prop. Ideally these blocks would rely
// on the clientId prop only. This is kept for backward
// compatibility reasons.
block,
name,
attributes,
isValid,
isSelected
}
}
) });
}
var block_default = (0, import_element.memo)(BlockListBlockProvider);
//# sourceMappingURL=block.cjs.map