: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
className: dist_clsx(className, {
'is-with-inserter': isInserterShown
onHoverEnd: maybeHideInserterPoint,
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, {
className: "block-editor-block-list__insertion-point-indicator",
"data-testid": "block-list-insertion-point-indicator"
}), isInserterShown && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, {
variants: inserterVariants,
className: dist_clsx('block-editor-block-list__insertion-point-inserter'),
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, {
position: "bottom center",
rootClientId: rootClientId,
__experimentalIsQuick: true,
openRef.current = isOpen;
function InsertionPoint(props) {
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
isBlockInsertionPointVisible,
const blockInsertionPoint = getBlockInsertionPoint();
insertionPoint: blockInsertionPoint,
isVisible: isBlockInsertionPointVisible(),
isBlockListEmpty: getBlockCount(blockInsertionPoint?.rootClientId) === 0
// Don't render the insertion point if the block list is empty.
// The insertion point will be represented by the appender instead.
* Render a popover that overlays the block when the desired operation is to replace it.
* Otherwise, render a popover in between blocks for the indication of inserting between them.
return insertionPoint.operation === 'replace' ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(drop_zone
// Force remount to trigger the animation.
}, `${insertionPoint.rootClientId}-${insertionPoint.index}`) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InbetweenInsertionPointPopover, {
operation: insertionPoint.operation,
nearestSide: insertionPoint.nearestSide,
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-in-between-inserter.js
function useInBetweenInserter() {
const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef);
const isInBetweenInserterDisabled = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree || select(store).__unstableGetEditorMode() === 'zoom-out', []);
getSelectedBlockClientIds,
__unstableIsWithinBlockOverlay,
} = (0,external_wp_data_namespaceObject.useSelect)(store);
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (isInBetweenInserterDisabled) {
function onMouseMove(event) {
// openRef is the reference to the insertion point between blocks.
// If the reference is not set or the insertion point is already open, return.
if (openRef === undefined || openRef.current) {
// Ignore text nodes sometimes detected in FireFox.
if (event.target.nodeType === event.target.TEXT_NODE) {
if (isMultiSelecting()) {
if (!event.target.classList.contains('block-editor-block-list__layout')) {
if (!event.target.classList.contains('is-root-container')) {
const blockElement = !!event.target.getAttribute('data-block') ? event.target : event.target.closest('[data-block]');
rootClientId = blockElement.getAttribute('data-block');
if (getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled' || getBlockName(rootClientId) === 'core/block') {
const orientation = getBlockListSettings(rootClientId)?.orientation || 'vertical';
const offsetTop = event.clientY;
const offsetLeft = event.clientX;
const children = Array.from(event.target.children);
let element = children.find(blockEl => {
const blockElRect = blockEl.getBoundingClientRect();
return blockEl.classList.contains('wp-block') && orientation === 'vertical' && blockElRect.top > offsetTop || blockEl.classList.contains('wp-block') && orientation === 'horizontal' && ((0,external_wp_i18n_namespaceObject.isRTL)() ? blockElRect.right < offsetLeft : blockElRect.left > offsetLeft);
// The block may be in an alignment wrapper, so check the first direct
// child if the element has no ID.
element = element.firstElementChild;
// Don't show the insertion point if a parent block has an "overlay"
// See https://github.com/WordPress/gutenberg/pull/34012#pullrequestreview-727762337
const clientId = element.id.slice('block-'.length);
if (!clientId || __unstableIsWithinBlockOverlay(clientId)) {
// Don't show the inserter when hovering above (conflicts with
// block toolbar) or inside selected block(s).
if (getSelectedBlockClientIds().includes(clientId)) {
const elementRect = element.getBoundingClientRect();
if (orientation === 'horizontal' && (event.clientY > elementRect.bottom || event.clientY < elementRect.top) || orientation === 'vertical' && (event.clientX > elementRect.right || event.clientX < elementRect.left)) {
const index = getBlockIndex(clientId);
// Don't show the in-between inserter before the first block in
// the list (preserves the original behaviour).
showInsertionPoint(rootClientId, index, {
__unstableWithInserter: true
node.addEventListener('mousemove', onMouseMove);
node.removeEventListener('mousemove', onMouseMove);
}, [openRef, getBlockListSettings, getBlockIndex, isMultiSelecting, showInsertionPoint, hideInsertionPoint, getSelectedBlockClientIds, isInBetweenInserterDisabled]);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/with-client-id.js
const withClientId = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => {
} = useBlockEditContext();
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, {
/* harmony default export */ const with_client_id = (withClientId);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/button-block-appender.js
const button_block_appender_ButtonBlockAppender = ({
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(button_block_appender, {
'block-list-appender__toggle': isToggle
showSeparator: showSeparator,
/* harmony default export */ const inner_blocks_button_block_appender = (with_client_id(button_block_appender_ButtonBlockAppender));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/default-block-appender.js
const default_block_appender_DefaultBlockAppender = ({
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultBlockAppender, {
/* harmony default export */ const default_block_appender = ((0,external_wp_compose_namespaceObject.compose)([with_client_id, (0,external_wp_data_namespaceObject.withSelect)((select, {
const blockClientIds = getBlockOrder(clientId);
lastBlockClientId: blockClientIds[blockClientIds.length - 1]
})])(default_block_appender_DefaultBlockAppender));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-nested-settings-update.js
/** @typedef {import('../../selectors').WPDirectInsertBlock } WPDirectInsertBlock */
const pendingSettingsUpdates = new WeakMap();
function useShallowMemo(value) {
const [prevValue, setPrevValue] = (0,external_wp_element_namespaceObject.useState)(value);
if (!external_wp_isShallowEqual_default()(prevValue, value)) {
* This hook is a side effect which updates the block-editor store when changes
* happen to inner block settings. The given props are transformed into a
* settings object, and if that is different from the current settings object in
* the block-editor store, then the store is updated with the new settings which
* @param {string} clientId The client ID of the block to update.
* @param {string} parentLock
* @param {string[]} allowedBlocks An array of block names which are permitted
* @param {string[]} prioritizedInserterBlocks Block names and/or block variations to be prioritized in the inserter, in the format {blockName}/{variationName}.
* @param {?WPDirectInsertBlock} defaultBlock The default block to insert: [ blockName, { blockAttributes } ].
* @param {?boolean} directInsert If a default block should be inserted directly by the appender.
* @param {?WPDirectInsertBlock} __experimentalDefaultBlock A deprecated prop for the default block to insert: [ blockName, { blockAttributes } ]. Use `defaultBlock` instead.
* @param {?boolean} __experimentalDirectInsert A deprecated prop for whether a default block should be inserted directly by the appender. Use `directInsert` instead.
* @param {string} [templateLock] The template lock specified for the inner
* blocks component. (e.g. "all")
* @param {boolean} captureToolbars Whether or children toolbars should be shown
* in the inner blocks component rather than on
* @param {string} orientation The direction in which the block
* @param {Object} layout The layout object for the block container.
function useNestedSettingsUpdate(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout) {
// Instead of adding a useSelect mapping here, please add to the useSelect
// mapping in InnerBlocks! Every subscription impacts performance.
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
// Implementors often pass a new array on every render,
// and the contents of the arrays are just strings, so the entire array
// can be passed as dependencies but We need to include the length of the array,
// otherwise if the arrays change length but the first elements are equal the comparison,
// does not works as expected.
const _allowedBlocks = useShallowMemo(allowedBlocks);
const _prioritizedInserterBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => prioritizedInserterBlocks,
// eslint-disable-next-line react-hooks/exhaustive-deps
prioritizedInserterBlocks);
const _templateLock = templateLock === undefined || parentLock === 'contentOnly' ? parentLock : templateLock;
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
allowedBlocks: _allowedBlocks,
prioritizedInserterBlocks: _prioritizedInserterBlocks,
templateLock: _templateLock
// These values are not defined for RN, so only include them if they
if (captureToolbars !== undefined) {
newSettings.__experimentalCaptureToolbars = captureToolbars;
// Orientation depends on layout,
// ideally the separate orientation prop should be deprecated.
if (orientation !== undefined) {
newSettings.orientation = orientation;
const layoutType = getLayoutType(layout?.type);
newSettings.orientation = layoutType.getOrientation(layout);
if (__experimentalDefaultBlock !== undefined) {
external_wp_deprecated_default()('__experimentalDefaultBlock', {
alternative: 'defaultBlock',
newSettings.defaultBlock = __experimentalDefaultBlock;
if (defaultBlock !== undefined) {
newSettings.defaultBlock = defaultBlock;
if (__experimentalDirectInsert !== undefined) {
external_wp_deprecated_default()('__experimentalDirectInsert', {
alternative: 'directInsert',
newSettings.directInsert = __experimentalDirectInsert;
if (directInsert !== undefined) {
newSettings.directInsert = directInsert;
if (newSettings.directInsert !== undefined && typeof newSettings.directInsert !== 'boolean') {
external_wp_deprecated_default()('Using `Function` as a `directInsert` argument', {
alternative: '`boolean` values',
// Batch updates to block list settings to avoid triggering cascading renders
// for each container block included in a tree and optimize initial render.
// To avoid triggering updateBlockListSettings for each container block
// causing X re-renderings for X container blocks,
// we batch all the updatedBlockListSettings in a single "data" batch
// which results in a single re-render.
if (!pendingSettingsUpdates.get(registry)) {
pendingSettingsUpdates.set(registry, {});
pendingSettingsUpdates.get(registry)[clientId] = newSettings;
window.queueMicrotask(() => {
const settings = pendingSettingsUpdates.get(registry);
if (Object.keys(settings).length) {
} = registry.dispatch(store);
updateBlockListSettings(settings);
pendingSettingsUpdates.set(registry, {});
}, [clientId, _allowedBlocks, _prioritizedInserterBlocks, _templateLock, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, captureToolbars, orientation, layout, registry]);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-inner-block-template-sync.js
* This hook makes sure that a block's inner blocks stay in sync with the given
* block "template". The template is a block hierarchy to which inner blocks must
* conform. If the blocks get "out of sync" with the template and the template
* is meant to be locked (e.g. templateLock = "all" or templateLock = "contentOnly"),
* then we replace the inner blocks with the correct value after synchronizing it with the template.
* @param {string} clientId The block client ID.
* @param {Object} template The template to match.
* @param {string} templateLock The template lock state for the inner blocks. For
* example, if the template lock is set to "all",
* then the inner blocks will stay in sync with the
* template. If not defined or set to false, then
* the inner blocks will not be synchronized with
* @param {boolean} templateInsertUpdatesSelection Whether or not to update the
* block-editor selection state when inner blocks
* are replaced after template synchronization.
function useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection) {
// Instead of adding a useSelect mapping here, please add to the useSelect
// mapping in InnerBlocks! Every subscription impacts performance.
getSelectedBlocksInitialCaretPosition,
} = (0,external_wp_data_namespaceObject.useSelect)(store);
__unstableMarkNextChangeAsNotPersistent
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
// Maintain a reference to the previous value so we can do a deep equality check.
const existingTemplate = (0,external_wp_element_namespaceObject.useRef)(null);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
// There's an implicit dependency between useInnerBlockTemplateSync and useNestedSettingsUpdate
// The former needs to happen after the latter and since the latter is using microtasks to batch updates (performance optimization),
// we need to schedule this one in a microtask as well.
// Example: If you remove queueMicrotask here, ctrl + click to insert quote block won't close the inserter.
window.queueMicrotask(() => {
// Only synchronize innerBlocks with template if innerBlocks are empty
// or a locking "all" or "contentOnly" exists directly on the block.
const currentInnerBlocks = getBlocks(clientId);
const shouldApplyTemplate = currentInnerBlocks.length === 0 || templateLock === 'all' || templateLock === 'contentOnly';
const hasTemplateChanged = !es6_default()(template, existingTemplate.current);
if (!shouldApplyTemplate || !hasTemplateChanged) {
existingTemplate.current = template;
const nextBlocks = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(currentInnerBlocks, template);
if (!es6_default()(nextBlocks, currentInnerBlocks)) {
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, nextBlocks, currentInnerBlocks.length === 0 && templateInsertUpdatesSelection && nextBlocks.length !== 0 && isBlockSelected(clientId),
// This ensures the "initialPosition" doesn't change when applying the template