From baf40932190aea6a93ffcdcdf0247fd488822404 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 22 Oct 2024 13:28:09 +0100 Subject: [PATCH] Fix content only lock behavior --- .../src/components/inner-blocks/index.js | 6 ---- .../components/inner-blocks/index.native.js | 7 ++-- .../use-nested-settings-update.js | 11 ++----- .../src/store/private-selectors.js | 5 ++- packages/block-editor/src/store/selectors.js | 14 ++++++-- .../block-editor/src/store/test/selectors.js | 33 ++++++++++++++++--- .../editor/various/content-only-lock.spec.js | 16 +++++++++ 7 files changed, 65 insertions(+), 27 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index e79c188018cb50..856481a0d863f0 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -73,13 +73,11 @@ function UncontrolledInnerBlocks( props ) { layout, name, blockType, - parentLock, defaultLayout, } = props; useNestedSettingsUpdate( clientId, - parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, @@ -196,7 +194,6 @@ export function useInnerBlocksProps( props = {}, options = {} ) { const { getBlockName, isZoomOut, - getTemplateLock, getBlockRootClientId, getBlockEditingMode, getBlockSettings, @@ -233,7 +230,6 @@ export function useInnerBlocksProps( props = {}, options = {} ) { ), name: blockName, blockType: getBlockType( blockName ), - parentLock: getTemplateLock( parentClientId ), parentClientId, isDropZoneDisabled: _isDropZoneDisabled, defaultLayout, @@ -245,7 +241,6 @@ export function useInnerBlocksProps( props = {}, options = {} ) { __experimentalCaptureToolbars, name, blockType, - parentLock, parentClientId, isDropZoneDisabled, defaultLayout, @@ -272,7 +267,6 @@ export function useInnerBlocksProps( props = {}, options = {} ) { layout, name, blockType, - parentLock, defaultLayout, ...options, }; diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js index 1398a5abd51e4b..5717ac2c96a1e2 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -105,13 +105,11 @@ function UncontrolledInnerBlocks( props ) { const context = useBlockContext( clientId ); - const { nestingLevel, parentLock } = useSelect( + const { nestingLevel } = useSelect( ( select ) => { - const { getBlockParents, getTemplateLock, getBlockRootClientId } = - select( blockEditorStore ); + const { getBlockParents } = select( blockEditorStore ); return { nestingLevel: getBlockParents( clientId )?.length, - parentLock: getTemplateLock( getBlockRootClientId( clientId ) ), }; }, [ clientId ] @@ -119,7 +117,6 @@ function UncontrolledInnerBlocks( props ) { useNestedSettingsUpdate( clientId, - parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index bc07a5a1829e2b..773c9f70cd23a7 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -41,7 +41,6 @@ function useShallowMemo( value ) { * came from props. * * @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 * in inner blocks. * @param {string[]} prioritizedInserterBlocks Block names and/or block variations to be prioritized in the inserter, in the format {blockName}/{variationName}. @@ -63,7 +62,6 @@ function useShallowMemo( value ) { */ export default function useNestedSettingsUpdate( clientId, - parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, @@ -90,16 +88,11 @@ export default function useNestedSettingsUpdate( prioritizedInserterBlocks ); - const _templateLock = - templateLock === undefined || parentLock === 'contentOnly' - ? parentLock - : templateLock; - useLayoutEffect( () => { const newSettings = { allowedBlocks: _allowedBlocks, prioritizedInserterBlocks: _prioritizedInserterBlocks, - templateLock: _templateLock, + templateLock, }; // These values are not defined for RN, so only include them if they @@ -176,7 +169,7 @@ export default function useNestedSettingsUpdate( clientId, _allowedBlocks, _prioritizedInserterBlocks, - _templateLock, + templateLock, defaultBlock, directInsert, __experimentalDefaultBlock, diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index 40cd1d7845fab0..d340c3f614bdac 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -17,6 +17,7 @@ import { getClientIdsWithDescendants, getBlockRootClientId, __unstableGetEditorMode, + getBlockListSettings, } from './selectors'; import { checkAllowListRecursive, @@ -522,7 +523,9 @@ export function isSectionBlock( state, clientId ) { const sectionClientIds = getBlockOrder( state, sectionRootClientId ); return ( getBlockName( state, clientId ) === 'core/block' || - getTemplateLock( state, clientId ) === 'contentOnly' || + // This is different than getTemplateLock + // because children of sections are not sections automatically. + getBlockListSettings( state, clientId )?.templateLock || ( ( __unstableGetEditorMode( state ) === 'navigation' || isZoomOut( state ) ) && sectionClientIds.includes( clientId ) ) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d7a824dcc7880e..aa182082b40f26 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1572,7 +1572,17 @@ export function getTemplateLock( state, rootClientId ) { return state.settings.templateLock ?? false; } - return getBlockListSettings( state, rootClientId )?.templateLock ?? false; + const currentLock = getBlockListSettings( + state, + rootClientId + )?.templateLock; + if ( currentLock !== undefined ) { + return currentLock; + } + return getTemplateLock( + state, + getBlockRootClientId( state, rootClientId ) + ); } /** @@ -2948,7 +2958,7 @@ export function __unstableHasActiveBlockOverlayActive( state, clientId ) { return true; } - // In navigation mode, the block overlay is active when the block is not + // For sections, the block overlay is active when the block is not // selected (and doesn't contain a selected child). The same behavior is // also enabled in all modes for blocks that have controlled children // (reusable block, template part, navigation), unless explicitly disabled diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index 00aa085f667093..8cf1e93edd494d 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -3830,28 +3830,45 @@ describe( 'selectors', () => { it( 'should return false if the specified clientId was not found', () => { const state = { - settings: { templateLock: 'all' }, + settings: {}, blockListSettings: { chicken: { templateLock: 'insert', }, + ribs: {}, + }, + blocks: { + parents: new Map( + Object.entries( { + chicken: '', + ribs: '', + } ) + ), }, }; expect( getTemplateLock( state, 'ribs' ) ).toBe( false ); } ); - it( 'should return false if template lock was not set on the specified block', () => { + it( 'should return the parent lock if the specified clientId was not found', () => { const state = { settings: { templateLock: 'all' }, blockListSettings: { chicken: { - test: 'tes1t', + templateLock: 'insert', }, }, + blocks: { + parents: new Map( + Object.entries( { + chicken: '', + ribs: '', + } ) + ), + }, }; - expect( getTemplateLock( state, 'chicken' ) ).toBe( false ); + expect( getTemplateLock( state, 'ribs' ) ).toBe( 'all' ); } ); it( 'should return the template lock for the specified clientId', () => { @@ -3862,6 +3879,14 @@ describe( 'selectors', () => { templateLock: 'insert', }, }, + blocks: { + parents: new Map( + Object.entries( { + chicken: '', + ribs: '', + } ) + ), + }, }; expect( getTemplateLock( state, 'chicken' ) ).toBe( 'insert' ); diff --git a/test/e2e/specs/editor/various/content-only-lock.spec.js b/test/e2e/specs/editor/various/content-only-lock.spec.js index 9784aea1ee068f..03f70b6c8d270f 100644 --- a/test/e2e/specs/editor/various/content-only-lock.spec.js +++ b/test/e2e/specs/editor/various/content-only-lock.spec.js @@ -24,6 +24,13 @@ test.describe( 'Content-only lock', () => { ` ); await pageUtils.pressKeys( 'secondary+M' ); + + // First click selects the section. + await editor.canvas + .locator( 'role=document[name="Block: Group"i]' ) + .click(); + + // Second click selects the content. await editor.canvas .locator( 'role=document[name="Block: Paragraph"i]' ) .click(); @@ -50,9 +57,18 @@ test.describe( 'Content-only lock', () => { ` ); await pageUtils.pressKeys( 'secondary+M' ); + + // First click selects the section. + await editor.canvas + .locator( 'role=document[name="Block: Group"i]' ) + .first() + .click(); + + // Second click selects the content. await editor.canvas .locator( 'role=document[name="Block: Paragraph"i]' ) .click(); + await page.keyboard.type( ' WP' ); await expect.poll( editor.getBlocks ).toMatchObject( [ {