From 70b6e7fc641d7d675a64928c47d037cbbd2e02b2 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Tue, 8 Feb 2022 11:25:49 +0000 Subject: [PATCH 1/8] add navigation nesting to block edit to be filtered --- packages/block-library/src/navigation-link/edit.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 43cab0244b940..2908ab28c8bb3 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -49,8 +49,6 @@ import { store as coreStore } from '@wordpress/core-data'; */ import { name } from './block.json'; -const MAX_NESTING = 5; - /** * A React hook to determine if it's dragging within the target element. * @@ -386,6 +384,7 @@ export default function NavigationLinkEdit( { onReplace, context, clientId, + maxNestingLevel = 5, } ) { const { id, @@ -452,7 +451,7 @@ export default function NavigationLinkEdit( { getBlockParentsByBlockName( clientId, [ name, 'core/navigation-submenu', - ] ).length >= MAX_NESTING, + ] ).length >= maxNestingLevel, isTopLevelLink: getBlockName( getBlockRootClientId( clientId ) ) === 'core/navigation', From 4ad4fdb2e8f554c0094e1a92c85bcb29769b736f Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Sun, 6 Mar 2022 10:56:24 +0000 Subject: [PATCH 2/8] makes maxNestingLevel available via context set by the navigation block --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/navigation-link/block.json | 1 + packages/block-library/src/navigation-link/edit.js | 2 +- packages/block-library/src/navigation-submenu/block.json | 1 + packages/block-library/src/navigation-submenu/edit.js | 6 ++---- packages/block-library/src/navigation/block.json | 7 ++++++- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index ffdba40b5f162..5dad36577e361 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -384,7 +384,7 @@ A collection of blocks that allow visitors to get around your site. ([Source](ht - **Name:** core/navigation - **Category:** theme - **Supports:** align (full, wide), anchor, inserter, spacing (blockGap, units), typography (fontSize, lineHeight), ~~html~~ -- **Attributes:** __unstableLocation, backgroundColor, customBackgroundColor, customOverlayBackgroundColor, customOverlayTextColor, customTextColor, hasIcon, openSubmenusOnClick, overlayBackgroundColor, overlayMenu, overlayTextColor, ref, rgbBackgroundColor, rgbTextColor, showSubmenuIcon, textColor +- **Attributes:** __unstableLocation, backgroundColor, customBackgroundColor, customOverlayBackgroundColor, customOverlayTextColor, customTextColor, hasIcon, maxNestingLevel, openSubmenusOnClick, overlayBackgroundColor, overlayMenu, overlayTextColor, ref, rgbBackgroundColor, rgbTextColor, showSubmenuIcon, textColor ## Navigation Area diff --git a/packages/block-library/src/navigation-link/block.json b/packages/block-library/src/navigation-link/block.json index fd1f0524432f1..5ce15a970d8c2 100644 --- a/packages/block-library/src/navigation-link/block.json +++ b/packages/block-library/src/navigation-link/block.json @@ -52,6 +52,7 @@ "fontSize", "customFontSize", "showSubmenuIcon", + "maxNestingLevel", "style" ], "supports": { diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 2908ab28c8bb3..889e125781c67 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -384,7 +384,6 @@ export default function NavigationLinkEdit( { onReplace, context, clientId, - maxNestingLevel = 5, } ) { const { id, @@ -399,6 +398,7 @@ export default function NavigationLinkEdit( { } = attributes; const [ isInvalid, isDraft ] = useIsInvalidLink( kind, type, id ); + const { maxNestingLevel } = context; const link = { url, diff --git a/packages/block-library/src/navigation-submenu/block.json b/packages/block-library/src/navigation-submenu/block.json index 97bd455a468e3..f311a9f36e41a 100644 --- a/packages/block-library/src/navigation-submenu/block.json +++ b/packages/block-library/src/navigation-submenu/block.json @@ -52,6 +52,7 @@ "fontSize", "customFontSize", "showSubmenuIcon", + "maxNestingLevel", "openSubmenusOnClick", "style" ], diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 998dc33c261d5..20b13acab973f 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -55,8 +55,6 @@ const DEFAULT_BLOCK = { name: 'core/navigation-link', }; -const MAX_NESTING = 5; - /** * A React hook to determine if it's dragging within the target element. * @@ -293,7 +291,7 @@ export default function NavigationSubmenuEdit( { url, opensInNewTab, }; - const { showSubmenuIcon, openSubmenusOnClick } = context; + const { showSubmenuIcon, maxNestingLevel, openSubmenusOnClick } = context; const { saveEntityRecord } = useDispatch( coreStore ); const { @@ -351,7 +349,7 @@ export default function NavigationSubmenuEdit( { return { isAtMaxNesting: getBlockParentsByBlockName( clientId, name ).length >= - MAX_NESTING, + maxNestingLevel, isTopLevelItem: getBlockParentsByBlockName( clientId, name ).length === 0, isParentOfSelectedBlock: hasSelectedInnerBlock( diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index 254e85903c9c9..b88f13d6ab27f 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -59,6 +59,10 @@ }, "customOverlayTextColor": { "type": "string" + }, + "maxNestingLevel": { + "type": "number", + "default": 3 } }, "usesContext": [ "navigationArea" ], @@ -76,7 +80,8 @@ "showSubmenuIcon": "showSubmenuIcon", "openSubmenusOnClick": "openSubmenusOnClick", "style": "style", - "orientation": "orientation" + "orientation": "orientation", + "maxNestingLevel": "maxNestingLevel" }, "supports": { "align": [ "wide", "full" ], From 2727aaf21e7733f350b3b6dffc9c34c5387c713d Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Sun, 6 Mar 2022 10:59:18 +0000 Subject: [PATCH 3/8] set the default maxNestingLevel to 5 --- packages/block-library/src/navigation/block.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index b88f13d6ab27f..dc904dc25eee1 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -62,7 +62,7 @@ }, "maxNestingLevel": { "type": "number", - "default": 3 + "default": 5 } }, "usesContext": [ "navigationArea" ], From 9541e7faacd6b30d2a8a6c14942cd70f98c075c9 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Mon, 7 Mar 2022 09:39:15 +0000 Subject: [PATCH 4/8] updates the fixture for the navigation block --- test/integration/fixtures/blocks/core__navigation.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/fixtures/blocks/core__navigation.json b/test/integration/fixtures/blocks/core__navigation.json index 08489c0019526..f1f5d211efd3a 100644 --- a/test/integration/fixtures/blocks/core__navigation.json +++ b/test/integration/fixtures/blocks/core__navigation.json @@ -6,7 +6,8 @@ "showSubmenuIcon": true, "openSubmenusOnClick": false, "overlayMenu": "mobile", - "hasIcon": true + "hasIcon": true, + "maxNestingLevel": 5 }, "innerBlocks": [] } From c1c4b1a59d32d30b5195a521e90ebf740726855c Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 11 Mar 2022 19:06:22 +0000 Subject: [PATCH 5/8] check max nesting level for the currently selected submenu block --- packages/block-library/src/navigation-submenu/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 20b13acab973f..e6fcdc97907de 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -348,8 +348,8 @@ export default function NavigationSubmenuEdit( { return { isAtMaxNesting: - getBlockParentsByBlockName( clientId, name ).length >= - maxNestingLevel, + getBlockParentsByBlockName( selectedBlockId, name ) + .length >= maxNestingLevel, isTopLevelItem: getBlockParentsByBlockName( clientId, name ).length === 0, isParentOfSelectedBlock: hasSelectedInnerBlock( From 51a2a9a41747c5e3ae7acc112d45adf7d6d8a2c0 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Thu, 24 Mar 2022 20:31:42 +0200 Subject: [PATCH 6/8] adds a test that tries setting nesting to zero and checks no submenus can be inserted --- .../specs/editor/blocks/navigation.test.js | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 41352a8b19255..16d8fbeb87eb5 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -884,6 +884,46 @@ describe( 'Navigation', () => { newMenuButton.click(); } + it( 'respects the nesting level', async () => { + await createNewPost(); + + await insertBlock( 'Navigation' ); + + const navBlock = await waitForBlock( 'Navigation' ); + + // Create empty Navigation block with no items + const startEmptyButton = await page.waitForXPath( + START_EMPTY_XPATH + ); + await startEmptyButton.click(); + + await populateNavWithOneItem(); + + await clickOnMoreMenuItem( 'Code editor' ); + const codeEditorInput = await page.waitForSelector( + '.editor-post-text-editor' + ); + + let code = await codeEditorInput.evaluate( ( el ) => el.value ); + code = code.replace( '} /-->', ',"maxNestingLevel":0} /-->' ); + await codeEditorInput.evaluate( + ( el, newCode ) => ( el.value = newCode ), + code + ); + await clickButton( 'Exit code editor' ); + + const blockAppender = navBlock.$( '.block-list-appender' ); + + expect( blockAppender ).not.toBeNull(); + + // Check the Submenu block is no longer present. + const navSubmenuSelector = + '[aria-label="Editor content"][role="region"] [aria-label="Block: Submenu"]'; + const submenuBlock = await page.$( navSubmenuSelector ); + + expect( submenuBlock ).toBeFalsy(); + } ); + it( 'does not retain uncontrolled inner blocks when creating a new entity', async () => { await createNewPost(); await clickOnMoreMenuItem( 'Code editor' ); From debc62e29f4f52d70d180adc13930da381b5e4d1 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 1 Apr 2022 21:25:03 +0300 Subject: [PATCH 7/8] localize the mutation of allowed submenu blocks so we don't affect other instances --- packages/block-library/src/navigation-submenu/edit.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index e6fcdc97907de..3b12a8a3ad886 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { escape, pull } from 'lodash'; +import { escape, without } from 'lodash'; /** * WordPress dependencies @@ -501,8 +501,9 @@ export default function NavigationSubmenuEdit( { // Always use overlay colors for submenus. const innerBlocksColors = getColors( context, true ); + let allowedBlocks = ALLOWED_BLOCKS; if ( isAtMaxNesting ) { - pull( ALLOWED_BLOCKS, 'core/navigation-submenu' ); + allowedBlocks = without( ALLOWED_BLOCKS, 'core/navigation-submenu' ); } const innerBlocksProps = useInnerBlocksProps( @@ -526,7 +527,7 @@ export default function NavigationSubmenuEdit( { }, }, { - allowedBlocks: ALLOWED_BLOCKS, + allowedBlocks, __experimentalDefaultBlock: DEFAULT_BLOCK, __experimentalDirectInsert: true, From 24323333fa7c55dbd236b7ad617abc7e6220c41c Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 1 Apr 2022 21:34:37 +0300 Subject: [PATCH 8/8] revert to clientId instead of selectedBlockId for getting max nesting --- packages/block-library/src/navigation-submenu/edit.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 3b12a8a3ad886..abbea4c63d8b4 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -348,8 +348,8 @@ export default function NavigationSubmenuEdit( { return { isAtMaxNesting: - getBlockParentsByBlockName( selectedBlockId, name ) - .length >= maxNestingLevel, + getBlockParentsByBlockName( clientId, name ).length >= + maxNestingLevel, isTopLevelItem: getBlockParentsByBlockName( clientId, name ).length === 0, isParentOfSelectedBlock: hasSelectedInnerBlock( @@ -501,10 +501,9 @@ export default function NavigationSubmenuEdit( { // Always use overlay colors for submenus. const innerBlocksColors = getColors( context, true ); - let allowedBlocks = ALLOWED_BLOCKS; - if ( isAtMaxNesting ) { - allowedBlocks = without( ALLOWED_BLOCKS, 'core/navigation-submenu' ); - } + const allowedBlocks = isAtMaxNesting + ? without( ALLOWED_BLOCKS, 'core/navigation-submenu' ) + : ALLOWED_BLOCKS; const innerBlocksProps = useInnerBlocksProps( {