Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inserter: take into account children to disable blocks #8075

Merged
merged 12 commits into from
Aug 14, 2018
25 changes: 24 additions & 1 deletion packages/editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import {
castArray,
flatMap,
find,
first,
get,
Expand Down Expand Up @@ -564,6 +565,28 @@ export const getBlocks = createSelector(
]
);

/**
* Returns an array containing the clientIds of the top-level blocks
* and their descendants of any depth (for nested blocks).
*
* @param {Object} state Global application state.
*
* @return {Array} ids of top-level and descendant blocks.
*/
export const getClientIdsWithDescendants = createSelector(
( state ) => {
const getDescendants = ( clientIds ) => flatMap( clientIds, ( clientId ) => {
const descendants = getBlockOrder( state, clientId );
return [ ...descendants, ...getDescendants( descendants ) ];
} );
const topLevelIds = getBlockOrder( state );
return [ ...topLevelIds, ...getDescendants( topLevelIds ) ];
},
( state ) => [
state.editor.present.blockOrder,
]
);

/**
* Returns the total number of blocks, or the total number of blocks with a specific name in a post.
* The number returned includes nested blocks.
Expand Down Expand Up @@ -1546,7 +1569,7 @@ export const getInserterItems = createSelector(

let isDisabled = false;
if ( ! hasBlockSupport( blockType.name, 'multiple', true ) ) {
isDisabled = some( getBlocks( state ), { name: blockType.name } );
isDisabled = some( getBlocksByClientId( state, getClientIdsWithDescendants( state ) ), { name: blockType.name } );
}

const isContextual = isArray( blockType.parent );
Expand Down
64 changes: 63 additions & 1 deletion packages/editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const {
getBlock,
getBlocks,
getBlockCount,
getClientIdsWithDescendants,
hasSelectedBlock,
getSelectedBlock,
getSelectedBlockClientId,
Expand Down Expand Up @@ -1731,6 +1732,67 @@ describe( 'selectors', () => {
} );
} );

describe( 'getClientIdsWithDescendants', () => {
it( 'should return the ids for top-level blocks and their descendants of any depth (for nested blocks).', () => {
const state = {
currentPost: {},
editor: {
present: {
blocksByClientId: {
'uuid-2': { clientId: 'uuid-2', name: 'core/image', attributes: {} },
'uuid-4': { clientId: 'uuid-4', name: 'core/paragraph', attributes: {} },
'uuid-6': { clientId: 'uuid-6', name: 'core/paragraph', attributes: {} },
'uuid-8': { clientId: 'uuid-8', name: 'core/block', attributes: {} },
'uuid-10': { clientId: 'uuid-10', name: 'core/columns', attributes: {} },
'uuid-12': { clientId: 'uuid-12', name: 'core/column', attributes: {} },
'uuid-14': { clientId: 'uuid-14', name: 'core/column', attributes: {} },
'uuid-16': { clientId: 'uuid-16', name: 'core/quote', attributes: {} },
'uuid-18': { clientId: 'uuid-18', name: 'core/block', attributes: {} },
'uuid-20': { clientId: 'uuid-20', name: 'core/gallery', attributes: {} },
'uuid-22': { clientId: 'uuid-22', name: 'core/block', attributes: {} },
'uuid-24': { clientId: 'uuid-24', name: 'core/columns', attributes: {} },
'uuid-26': { clientId: 'uuid-26', name: 'core/column', attributes: {} },
'uuid-28': { clientId: 'uuid-28', name: 'core/column', attributes: {} },
'uuid-30': { clientId: 'uuid-30', name: 'core/paragraph', attributes: {} },
},
blockOrder: {
'': [ 'uuid-6', 'uuid-8', 'uuid-10', 'uuid-22' ],
'uuid-2': [ ],
'uuid-4': [ ],
'uuid-6': [ ],
'uuid-8': [ ],
'uuid-10': [ 'uuid-12', 'uuid-14' ],
'uuid-12': [ 'uuid-16' ],
'uuid-14': [ 'uuid-18' ],
'uuid-16': [ ],
'uuid-18': [ 'uuid-24' ],
'uuid-20': [ ],
'uuid-22': [ ],
'uuid-24': [ 'uuid-26', 'uuid-28' ],
'uuid-26': [ ],
'uuid-28': [ 'uuid-30' ],
},
edits: {},
},
},
};
expect( getClientIdsWithDescendants( state ) ).toEqual( [
'uuid-6',
'uuid-8',
'uuid-10',
'uuid-22',
'uuid-12',
'uuid-14',
'uuid-16',
'uuid-18',
'uuid-24',
'uuid-26',
'uuid-28',
'uuid-30',
] );
} );
} );

describe( 'getBlockCount', () => {
it( 'should return the number of top-level blocks in the post', () => {
const state = {
Expand Down Expand Up @@ -3216,7 +3278,7 @@ describe( 'selectors', () => {
editor: {
present: {
blocksByClientId: {
block1: { name: 'core/test-block-b' },
block1: { clientId: 'block1', name: 'core/test-block-b' },
},
blockOrder: {
'': [ 'block1' ],
Expand Down