Skip to content

Commit

Permalink
Select Mode: Blocks outside the main sections root should be disabled (
Browse files Browse the repository at this point in the history
…#65518)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: getdave <[email protected]>
Co-authored-by: draganescu <[email protected]>
  • Loading branch information
4 people authored Sep 20, 2024
1 parent 27fe952 commit e9c3858
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 28 deletions.
73 changes: 52 additions & 21 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2901,6 +2901,14 @@ export function __unstableIsWithinBlockOverlay( state, clientId ) {
return false;
}

function isWithinBlock( state, clientId, parentClientId ) {
let parent = state.blocks.parents.get( clientId );
while ( !! parent && parent !== parentClientId ) {
parent = state.blocks.parents.get( parent );
}
return parent === parentClientId;
}

/**
* @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode
*/
Expand Down Expand Up @@ -2968,43 +2976,66 @@ export const getBlockEditingMode = createRegistrySelector(
return 'disabled';
}

if ( editorMode === 'navigation' ) {
const sectionRootClientId = getSectionRootClientId( state );

// The root section is "default mode"
if ( clientId === sectionRootClientId ) {
return 'default';
}

// Sections should always be contentOnly in navigation mode.
const sectionsClientIds = getBlockOrder(
state,
sectionRootClientId
);
if ( sectionsClientIds.includes( clientId ) ) {
return 'contentOnly';
}

// Blocks outside sections should be disabled.
const isWithinSectionRoot = isWithinBlock(
state,
clientId,
sectionRootClientId
);
if ( ! isWithinSectionRoot ) {
return 'disabled';
}

// The rest of the blocks depend on whether they are content blocks or not.
// This "flattens" the sections tree.
const name = getBlockName( state, clientId );
const isContent =
select( blocksStore ).__experimentalHasContentRoleAttribute(
name
);
return isContent ? 'contentOnly' : 'disabled';
}

// In normal mode, consider that an explicitely set editing mode takes over.
const blockEditingMode = state.blockEditingModes.get( clientId );
if ( blockEditingMode ) {
return blockEditingMode;
}

// In normal mode, top level is default mode.
if ( ! clientId ) {
return 'default';
}
const sectionRootClientId = getSectionRootClientId( state );
if (
editorMode === 'navigation' &&
clientId === sectionRootClientId
) {
return 'default';
}
const sectionsClientIds = getBlockOrder(
state,
sectionRootClientId
);

const rootClientId = getBlockRootClientId( state, clientId );
const templateLock = getTemplateLock( state, rootClientId );
if (
templateLock === 'contentOnly' ||
editorMode === 'navigation'
) {
// Sections should always be contentOnly in navigation mode.
// This will also cause them to display in List View providing
// a structure.
if ( sectionsClientIds.includes( clientId ) ) {
return 'contentOnly';
}
// If the parent of the block is contentOnly locked, check whether it's a content block.
if ( templateLock === 'contentOnly' ) {
const name = getBlockName( state, clientId );
const isContent =
select( blocksStore ).__experimentalHasContentRoleAttribute(
name
);
return isContent ? 'contentOnly' : 'disabled';
}
// Otherwise, check if there's an ancestor that is contentOnly
const parentMode = getBlockEditingMode( state, rootClientId );
return parentMode === 'contentOnly' ? 'default' : parentMode;
}
Expand Down
105 changes: 98 additions & 7 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { select, dispatch } from '@wordpress/data';
*/
import * as selectors from '../selectors';
import { store } from '../';
import { sectionRootClientIdKey } from '../private-keys';

const {
getBlockName,
Expand Down Expand Up @@ -4382,12 +4383,28 @@ describe( 'getBlockEditingMode', () => {
settings: {},
blocks: {
byClientId: new Map( [
[ '6cf70164-9097-4460-bcbf-200560546988', {} ], // Header
[ 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337', {} ], // Group
[ 'b26fc763-417d-4f01-b81c-2ec61e14a972', {} ], // | Post Title
[ '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f', {} ], // | Post Content
[ 'b3247f75-fd94-4fef-97f9-5bfd162cc416', {} ], // | | Paragraph
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', {} ], // | | Paragraph
[
'6cf70164-9097-4460-bcbf-200560546988',
{ name: 'core/template-part' },
], // Header
[
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
{ name: 'core/group' },
], // Group
[
'b26fc763-417d-4f01-b81c-2ec61e14a972',
{ name: 'core/post-title' },
], // | Post Title
[
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
{ name: 'core/group' },
], // | Group
[ 'b3247f75-fd94-4fef-97f9-5bfd162cc416', { name: 'core/p' } ], // | | Paragraph
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', { name: 'core/p' } ], // | | Paragraph
[
'9b9c5c3f-2e46-4f02-9e14-9fed515b958s',
{ name: 'core/group' },
], // | | Group
] ),
order: new Map( [
[
Expand All @@ -4411,10 +4428,12 @@ describe( 'getBlockEditingMode', () => {
[
'b3247f75-fd94-4fef-97f9-5bfd162cc416',
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
'9b9c5c3f-2e46-4f02-9e14-9fed515b958s',
],
],
[ 'b3247f75-fd94-4fef-97f9-5bfd162cc416', [] ],
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', [] ],
[ '9b9c5c3f-2e46-4f02-9e14-9fed515b958s', [] ],
] ),
parents: new Map( [
[ '6cf70164-9097-4460-bcbf-200560546988', '' ],
Expand All @@ -4435,6 +4454,10 @@ describe( 'getBlockEditingMode', () => {
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
],
[
'9b9c5c3f-2e46-4f02-9e14-9fed515b958s',
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
],
] ),
},
blockListSettings: {
Expand All @@ -4444,7 +4467,18 @@ describe( 'getBlockEditingMode', () => {
blockEditingModes: new Map( [] ),
};

const __experimentalHasContentRoleAttribute = jest.fn( () => false );
const navigationModeStateWithRootSection = {
...baseState,
editorMode: 'navigation',
settings: {
[ sectionRootClientIdKey ]: 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337', // The group is the "main" container
},
};

const __experimentalHasContentRoleAttribute = jest.fn( ( name ) => {
// consider paragraphs as content blocks.
return name === 'core/p';
} );
getBlockEditingMode.registry = {
select: jest.fn( () => ( {
__experimentalHasContentRoleAttribute,
Expand Down Expand Up @@ -4573,4 +4607,61 @@ describe( 'getBlockEditingMode', () => {
getBlockEditingMode( state, 'b3247f75-fd94-4fef-97f9-5bfd162cc416' )
).toBe( 'contentOnly' );
} );

it( 'in navigation mode, the root section container is default', () => {
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337'
)
).toBe( 'default' );
} );

it( 'in navigation mode, anything outside the section container is disabled', () => {
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'6cf70164-9097-4460-bcbf-200560546988'
)
).toBe( 'disabled' );
} );

it( 'in navigation mode, sections are contentOnly', () => {
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'b26fc763-417d-4f01-b81c-2ec61e14a972'
)
).toBe( 'contentOnly' );
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f'
)
).toBe( 'contentOnly' );
} );

it( 'in navigation mode, blocks with content attributes within sections are contentOnly', () => {
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'b3247f75-fd94-4fef-97f9-5bfd162cc416'
)
).toBe( 'contentOnly' );
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c'
)
).toBe( 'contentOnly' );
} );

it( 'in navigation mode, blocks without content attributes within sections are disabled', () => {
expect(
getBlockEditingMode(
navigationModeStateWithRootSection,
'9b9c5c3f-2e46-4f02-9e14-9fed515b958s'
)
).toBe( 'disabled' );
} );
} );

1 comment on commit e9c3858

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in e9c3858.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/10958231397
📝 Reported issues:

Please sign in to comment.