Skip to content

Commit

Permalink
Allow content blocks to be explicitly disabled even when they have a …
Browse files Browse the repository at this point in the history
…derived mode
  • Loading branch information
talldan committed Dec 6, 2024
1 parent b15f5e3 commit cfbf48a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 149 deletions.
17 changes: 14 additions & 3 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2327,7 +2327,7 @@ function getDerivedBlockEditingModesForTree(
templatePartClientIds
);
// Allow contentOnly blocks in template parts outside of sections
// to be editable. Only disable blocks that aren't don't fit this criteria.
// to be editable. Only disable blocks that don't fit this criteria.
if ( ! isInTemplatePart && ! isContentBlock( blockName ) ) {
derivedBlockEditingModes.set( clientId, 'disabled' );
return;
Expand Down Expand Up @@ -2369,7 +2369,12 @@ function getDerivedBlockEditingModesForTree(
}
}

if ( blockName && isContentBlock( blockName ) ) {
if (
// Honor the explicit disabled mode for content blocks.
state.blockEditingModes.get( clientId ) !== 'disabled' &&
blockName &&
isContentBlock( blockName, clientId )
) {
derivedBlockEditingModes.set( clientId, 'contentOnly' );
return;
}
Expand Down Expand Up @@ -2598,11 +2603,15 @@ export function withDerivedBlockEditingModes( reducer ) {
}
break;
}
case 'SET_BLOCK_EDITING_MODE':
case 'UNSET_BLOCK_EDITING_MODE':
case 'SET_HAS_CONTROLLED_INNER_BLOCKS': {
const updatedBlock = nextState.blocks.tree.get(
action.clientId
);
// The block might have been removed.

// The block might have been removed in which case it'll be
// handled by the `REMOVE_BLOCKS` action.
if ( ! updatedBlock ) {
break;
}
Expand All @@ -2611,13 +2620,15 @@ export function withDerivedBlockEditingModes( reducer ) {
getDerivedBlockEditingModesUpdates( {
prevState: state,
nextState,
removedClientIds: [ action.clientId ],
addedBlocks: [ updatedBlock ],
isNavMode: false,
} );
const nextDerivedNavModeBlockEditingModes =
getDerivedBlockEditingModesUpdates( {
prevState: state,
nextState,
removedClientIds: [ action.clientId ],
addedBlocks: [ updatedBlock ],
isNavMode: true,
} );
Expand Down
196 changes: 50 additions & 146 deletions packages/block-editor/src/store/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
createBlock,
privateApis,
} from '@wordpress/blocks';
import { combineReducers, select } from '@wordpress/data';
import { store as preferencesStore } from '@wordpress/preferences';
import { combineReducers } from '@wordpress/data';

/**
* Internal dependencies
Expand Down Expand Up @@ -3576,6 +3575,7 @@ describe( 'state', () => {
blocks,
settings,
zoomLevel,
blockEditingModes,
} )
);

Expand All @@ -3598,15 +3598,6 @@ describe( 'state', () => {
describe( 'edit mode', () => {
let initialState;
beforeAll( () => {
select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'edit' ),
};
}
return select( storeName );
} );

initialState = dispatchActions(
[
{
Expand Down Expand Up @@ -3651,10 +3642,6 @@ describe( 'state', () => {
);
} );

afterAll( () => {
select.mockRestore();
} );

it( 'returns no block editing modes when zoomed out / navigation mode are not active and there are no synced patterns', () => {
expect( initialState.derivedBlockEditingModes ).toEqual(
new Map()
Expand All @@ -3665,15 +3652,6 @@ describe( 'state', () => {
describe( 'synced patterns', () => {
let initialState;
beforeAll( () => {
select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'edit' ),
};
}
return select( storeName );
} );

// Simulates how the editor typically inserts controlled blocks,
// - first the pattern is inserted with no inner blocks.
// - next the pattern is marked as a controlled block.
Expand Down Expand Up @@ -3818,10 +3796,6 @@ describe( 'state', () => {
);
} );

afterAll( () => {
select.mockRestore();
} );

it( 'returns the expected block editing modes for synced patterns', () => {
// Only the parent pattern and its own children that have bindings
// are in contentOnly mode. All other blocks are disabled.
Expand All @@ -3840,60 +3814,8 @@ describe( 'state', () => {
);
} );

it( 'removes block editing modes when synced patterns are removed', () => {
const { derivedBlockEditingModes } = dispatchActions(
[
{
type: 'REMOVE_BLOCKS',
clientIds: [ 'root-pattern' ],
},
],
testReducer,
initialState
);

expect( derivedBlockEditingModes ).toEqual( new Map() );
} );

it( 'returns the expected block editing modes for synced patterns when switching to navigation mode', () => {
select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'navigation' ),
};
}
return select( storeName );
} );

const {
derivedBlockEditingModes,
derivedNavModeBlockEditingModes,
} = dispatchActions(
[
{
type: 'SET_EDITOR_MODE',
mode: 'navigation',
},
],
testReducer,
initialState
);

expect( derivedBlockEditingModes ).toEqual(
new Map(
Object.entries( {
'pattern-paragraph': 'disabled',
'pattern-group': 'disabled',
'pattern-paragraph-with-overrides': 'contentOnly', // Pattern child with bindings.
'nested-pattern': 'disabled',
'nested-paragraph': 'disabled',
'nested-group': 'disabled',
'nested-paragraph-with-overrides': 'disabled',
} )
)
);

expect( derivedNavModeBlockEditingModes ).toEqual(
it( 'returns the expected block editing modes for synced patterns in navigation mode', () => {
expect( initialState.derivedNavModeBlockEditingModes ).toEqual(
new Map(
Object.entries( {
'': 'contentOnly', // Section root.
Expand All @@ -3912,15 +3834,21 @@ describe( 'state', () => {
} )
)
);
} );

select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'edit' ),
};
}
return select( storeName );
} );
it( 'removes block editing modes when synced patterns are removed', () => {
const { derivedBlockEditingModes } = dispatchActions(
[
{
type: 'REMOVE_BLOCKS',
clientIds: [ 'root-pattern' ],
},
],
testReducer,
initialState
);

expect( derivedBlockEditingModes ).toEqual( new Map() );
} );

it( 'returns the expected block editing modes for synced patterns when switching to zoomed out mode', () => {
Expand Down Expand Up @@ -3961,15 +3889,6 @@ describe( 'state', () => {
let initialState;

beforeAll( () => {
select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'navigation' ),
};
}
return select( storeName );
} );

initialState = dispatchActions(
[
{
Expand Down Expand Up @@ -4075,10 +3994,6 @@ describe( 'state', () => {
);
} );

afterAll( () => {
select.mockRestore();
} );

it( 'returns the expected block editing modes', () => {
expect( initialState.derivedNavModeBlockEditingModes ).toEqual(
new Map(
Expand All @@ -4099,6 +4014,38 @@ describe( 'state', () => {
);
} );

it( 'allows content blocks to be disabled explicitly using the block editing mode', () => {
const { derivedNavModeBlockEditingModes } = dispatchActions(
[
{
type: 'SET_BLOCK_EDITING_MODE',
clientId: 'paragraph-1',
mode: 'disabled',
},
],
testReducer,
initialState
);

expect( derivedNavModeBlockEditingModes ).toEqual(
new Map(
Object.entries( {
'': 'disabled',
header: 'contentOnly',
'header-group': 'disabled',
'header-paragraph': 'contentOnly',
footer: 'contentOnly',
'footer-paragraph': 'contentOnly',
'section-root': 'contentOnly',
'group-1': 'contentOnly',
'paragraph-1': 'disabled', // Block explicitly disabled.
'group-2': 'disabled',
'paragraph-2': 'contentOnly',
} )
)
);
} );

it( 'removes block editing modes when blocks are removed', () => {
const { derivedNavModeBlockEditingModes } = dispatchActions(
[
Expand Down Expand Up @@ -4315,49 +4262,6 @@ describe( 'state', () => {
);
} );

it( 'overrides navigation mode', () => {
select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'navigation' ),
};
}
return select( storeName );
} );

const { derivedBlockEditingModes } = dispatchActions(
[
{
type: 'SET_EDITOR_MODE',
mode: 'navigation',
},
],
testReducer,
initialState
);

expect( derivedBlockEditingModes ).toEqual(
new Map(
Object.entries( {
'': 'contentOnly', // Section root.
'group-1': 'contentOnly', // Section block.
'paragraph-1': 'disabled',
'group-2': 'disabled',
'paragraph-2': 'disabled',
} )
)
);

select.mockImplementation( ( storeName ) => {
if ( storeName === preferencesStore ) {
return {
get: jest.fn( () => 'edit' ),
};
}
return select( storeName );
} );
} );

it( 'removes block editing modes when blocks are removed', () => {
const { derivedBlockEditingModes } = dispatchActions(
[
Expand Down

0 comments on commit cfbf48a

Please sign in to comment.