UNPKG

@wordpress/block-library

Version:
118 lines (114 loc) 5.17 kB
/** * WordPress dependencies */ import { cloneBlock } from '@wordpress/blocks'; import { useSelect, useDispatch, useRegistry } from '@wordpress/data'; import { useState, useEffect } from '@wordpress/element'; import { Warning, store as blockEditorStore, useBlockProps } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies */ import { useParsePatternDependencies } from './recursion-detector'; import { jsx as _jsx } from "react/jsx-runtime"; const PatternEdit = ({ attributes, clientId }) => { const registry = useRegistry(); const selectedPattern = useSelect(select => select(blockEditorStore).__experimentalGetParsedPattern(attributes.slug), [attributes.slug]); const currentThemeStylesheet = useSelect(select => select(coreStore).getCurrentTheme()?.stylesheet, []); const { replaceBlocks, setBlockEditingMode, __unstableMarkNextChangeAsNotPersistent } = useDispatch(blockEditorStore); const { getBlockRootClientId, getBlockEditingMode } = useSelect(blockEditorStore); const [hasRecursionError, setHasRecursionError] = useState(false); const parsePatternDependencies = useParsePatternDependencies(); // Duplicated in packages/editor/src/components/start-template-options/index.js. function injectThemeAttributeInBlockTemplateContent(block) { if (block.innerBlocks.find(innerBlock => innerBlock.name === 'core/template-part')) { block.innerBlocks = block.innerBlocks.map(innerBlock => { if (innerBlock.name === 'core/template-part' && innerBlock.attributes.theme === undefined) { innerBlock.attributes.theme = currentThemeStylesheet; } return innerBlock; }); } if (block.name === 'core/template-part' && block.attributes.theme === undefined) { block.attributes.theme = currentThemeStylesheet; } return block; } // Run this effect when the component loads. // This adds the Pattern's contents to the post. // This change won't be saved. // It will continue to pull from the pattern file unless changes are made to its respective template part. useEffect(() => { if (!hasRecursionError && selectedPattern?.blocks) { try { parsePatternDependencies(selectedPattern); } catch (error) { setHasRecursionError(true); return; } // We batch updates to block list settings to avoid triggering cascading renders // for each container block included in a tree and optimize initial render. // Since the above uses microtasks, we need to use a microtask here as well, // because nested pattern blocks cannot be inserted if the parent block supports // inner blocks but doesn't have blockSettings in the state. window.queueMicrotask(() => { const rootClientId = getBlockRootClientId(clientId); // Clone blocks from the pattern before insertion to ensure they receive // distinct client ids. See https://github.com/WordPress/gutenberg/issues/50628. const clonedBlocks = selectedPattern.blocks.map(block => cloneBlock(injectThemeAttributeInBlockTemplateContent(block))); // If the pattern has a single block and categories, we should add the // categories of the pattern to the block's metadata. if (clonedBlocks.length === 1 && selectedPattern.categories?.length > 0) { clonedBlocks[0].attributes = { ...clonedBlocks[0].attributes, metadata: { ...clonedBlocks[0].attributes.metadata, categories: selectedPattern.categories, patternName: selectedPattern.name, name: clonedBlocks[0].attributes.metadata.name || selectedPattern.title } }; } const rootEditingMode = getBlockEditingMode(rootClientId); registry.batch(() => { // Temporarily set the root block to default mode to allow replacing the pattern. // This could happen when the page is disabling edits of non-content blocks. __unstableMarkNextChangeAsNotPersistent(); setBlockEditingMode(rootClientId, 'default'); __unstableMarkNextChangeAsNotPersistent(); replaceBlocks(clientId, clonedBlocks); // Restore the root block's original mode. __unstableMarkNextChangeAsNotPersistent(); setBlockEditingMode(rootClientId, rootEditingMode); }); }); } }, [clientId, hasRecursionError, selectedPattern, __unstableMarkNextChangeAsNotPersistent, replaceBlocks, getBlockEditingMode, setBlockEditingMode, getBlockRootClientId]); const props = useBlockProps(); if (hasRecursionError) { return /*#__PURE__*/_jsx("div", { ...props, children: /*#__PURE__*/_jsx(Warning, { children: sprintf( // translators: A warning in which %s is the name of a pattern. __('Pattern "%s" cannot be rendered inside itself.'), selectedPattern?.name) }) }); } return /*#__PURE__*/_jsx("div", { ...props }); }; export default PatternEdit; //# sourceMappingURL=edit.js.map