diff --git a/packages/editor/src/components/provider/constants.js b/packages/editor/src/components/provider/constants.js
deleted file mode 100644
index a81b2fd37563af..00000000000000
--- a/packages/editor/src/components/provider/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export const PAGE_CONTENT_BLOCK_TYPES = [
- 'core/post-title',
- 'core/post-featured-image',
- 'core/post-content',
-];
diff --git a/packages/editor/src/components/provider/disable-non-page-content-blocks.js b/packages/editor/src/components/provider/disable-non-page-content-blocks.js
index 48a8119350d78f..fd4722ebe40f4d 100644
--- a/packages/editor/src/components/provider/disable-non-page-content-blocks.js
+++ b/packages/editor/src/components/provider/disable-non-page-content-blocks.js
@@ -2,39 +2,46 @@
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
-import {
- useBlockEditingMode,
- store as blockEditorStore,
-} from '@wordpress/block-editor';
+import { store as blockEditorStore } from '@wordpress/block-editor';
import { useEffect } from '@wordpress/element';
-/**
- * Internal dependencies
- */
-import { PAGE_CONTENT_BLOCK_TYPES } from './constants';
+const PAGE_CONTENT_BLOCKS = [
+ 'core/post-title',
+ 'core/post-featured-image',
+ 'core/post-content',
+];
+
+function useDisableNonPageContentBlocks() {
+ const contentIds = useSelect( ( select ) => {
+ const { getBlocksByName, getBlockParents, getBlockName } =
+ select( blockEditorStore );
+ return getBlocksByName( PAGE_CONTENT_BLOCKS ).filter( ( clientId ) =>
+ getBlockParents( clientId ).every( ( parentClientId ) => {
+ const parentBlockName = getBlockName( parentClientId );
+ return (
+ parentBlockName !== 'core/query' &&
+ ! PAGE_CONTENT_BLOCKS.includes( parentBlockName )
+ );
+ } )
+ );
+ }, [] );
-function DisableBlock( { clientId } ) {
- const isDescendentOfQueryLoop = useSelect(
- ( select ) => {
- const { getBlockParentsByBlockName } = select( blockEditorStore );
- return (
- getBlockParentsByBlockName( clientId, 'core/query' ).length !==
- 0
- );
- },
- [ clientId ]
- );
- const mode = isDescendentOfQueryLoop ? undefined : 'contentOnly';
const { setBlockEditingMode, unsetBlockEditingMode } =
useDispatch( blockEditorStore );
+
useEffect( () => {
- if ( mode ) {
- setBlockEditingMode( clientId, mode );
- return () => {
- unsetBlockEditingMode( clientId );
- };
+ setBlockEditingMode( '', 'disabled' ); // Disable editing at the root level.
+
+ for ( const contentId of contentIds ) {
+ setBlockEditingMode( contentId, 'contentOnly' ); // Re-enable each content block.
}
- }, [ clientId, mode, setBlockEditingMode, unsetBlockEditingMode ] );
+ return () => {
+ unsetBlockEditingMode( '' );
+ for ( const contentId of contentIds ) {
+ unsetBlockEditingMode( contentId );
+ }
+ };
+ }, [ contentIds, setBlockEditingMode, unsetBlockEditingMode ] );
}
/**
@@ -42,14 +49,5 @@ function DisableBlock( { clientId } ) {
* page content to be edited.
*/
export default function DisableNonPageContentBlocks() {
- useBlockEditingMode( 'disabled' );
- const clientIds = useSelect( ( select ) => {
- return select( blockEditorStore ).getBlocksByName(
- PAGE_CONTENT_BLOCK_TYPES
- );
- }, [] );
-
- return clientIds.map( ( clientId ) => {
- return ;
- } );
+ useDisableNonPageContentBlocks();
}
diff --git a/packages/editor/src/components/provider/test/disable-non-page-content-blocks.js b/packages/editor/src/components/provider/test/disable-non-page-content-blocks.js
new file mode 100644
index 00000000000000..d76530828a7999
--- /dev/null
+++ b/packages/editor/src/components/provider/test/disable-non-page-content-blocks.js
@@ -0,0 +1,90 @@
+/**
+ * External dependencies
+ */
+import { render } from '@testing-library/react';
+
+/**
+ * WordPress dependencies
+ */
+import { createRegistry, RegistryProvider } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import DisableNonPageContentBlocks from '../disable-non-page-content-blocks';
+
+describe( 'DisableNonPageContentBlocks', () => {
+ it( 'disables page content blocks', () => {
+ const testBlocks = {
+ 0: 'core/template-part',
+ /**/ '00': 'core/site-title',
+ /**/ '01': 'core/navigation',
+ 1: 'core/group',
+ /**/ 10: 'core/post-title',
+ /**/ 11: 'core/post-featured-image',
+ /**/ 12: 'core/post-content',
+ /**/ /**/ 120: 'core/paragraph',
+ /**/ /**/ 121: 'core/post-featured-image',
+ 2: 'core/query',
+ /**/ 20: 'core/post-title',
+ /**/ 21: 'core/post-featured-image',
+ /**/ 22: 'core/post-content',
+ 3: 'core/template-part',
+ /**/ 30: 'core/paragraph',
+ };
+
+ const setBlockEditingMode = jest.fn( () => ( {
+ type: 'SET_BLOCK_EDITING_MODE',
+ } ) );
+ const unsetBlockEditingMode = jest.fn( () => ( {
+ type: 'UNSET_BLOCK_EDITING_MODE',
+ } ) );
+
+ const registry = createRegistry( {
+ 'core/block-editor': {
+ reducer: () => {},
+ selectors: {
+ getBlocksByName( state, blockNames ) {
+ return Object.keys( testBlocks ).filter( ( clientId ) =>
+ blockNames.includes( testBlocks[ clientId ] )
+ );
+ },
+ getBlockParents( state, clientId ) {
+ return clientId.slice( 0, -1 ).split( '' );
+ },
+ getBlockName( state, clientId ) {
+ return testBlocks[ clientId ];
+ },
+ },
+ actions: {
+ setBlockEditingMode,
+ unsetBlockEditingMode,
+ },
+ },
+ } );
+
+ const { unmount } = render(
+
+
+
+ );
+
+ expect( setBlockEditingMode.mock.calls ).toEqual( [
+ [ '', 'disabled' ], // root
+ [ '10', 'contentOnly' ], // post-title
+ [ '11', 'contentOnly' ], // post-featured-image
+ [ '12', 'contentOnly' ], // post-content
+ // NOT the post-featured-image nested within post-content
+ // NOT any of the content blocks within query
+ ] );
+
+ unmount();
+
+ expect( unsetBlockEditingMode.mock.calls ).toEqual( [
+ [ '' ], // root
+ [ '10' ], // post-title
+ [ '11' ], // post-featured-image
+ [ '12' ], // post-content
+ ] );
+ } );
+} );