Skip to content

Commit

Permalink
Display children of inner block controllers in the block navigator (#…
Browse files Browse the repository at this point in the history
…24083)

* Add API to get all blocks even controlled ones

* Show inner block controller blocks in block navigator

* Create settings object for inner block param
  • Loading branch information
noahtallen authored Aug 13, 2020
1 parent b44996c commit bd954d2
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,15 @@ then the nested template part's child blocks will not be returned. This way,
the template block itself is considered part of the parent, but the children
are not.

You can override this behavior with the includeControlledInnerBlocks setting.
So if you call `getBlock( TP, { WPGetBlockSettings: true } )`, it will return
all nested blocks, including all child inner block controllers and their children.

_Parameters_

- _state_ `Object`: Editor state.
- _clientId_ `string`: Block client ID.
- _settings_ `?WPGetBlockSettings`: A settings object.

_Returns_

Expand Down Expand Up @@ -277,7 +282,8 @@ _Returns_

Returns all block objects for the current post being edited as an array in
the order they appear in the post. Note that this will exclude child blocks
of nested inner block controllers.
of nested inner block controllers unless the `includeControlledInnerBlocks`
setting is set to true.

Note: It's important to memoize this selector to avoid return a new instance
on each call. We use the block cache state for each top-level block of the
Expand All @@ -289,6 +295,7 @@ _Parameters_

- _state_ `Object`: Editor state.
- _rootClientId_ `?string`: Optional root client ID of block list.
- _settings_ `?WPGetBlockSettings`: A settings object.

_Returns_

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ export default compose(
} = select( 'core/block-editor' );
const selectedBlockClientId = getSelectedBlockClientId();
return {
rootBlocks: getBlocks(),
rootBlocks: getBlocks( '', { includeControlledInnerBlocks: true } ),
rootBlock: selectedBlockClientId
? getBlock(
getBlockHierarchyRootClientId( selectedBlockClientId )
getBlockHierarchyRootClientId( selectedBlockClientId ),
{ includeControlledInnerBlocks: true }
)
: null,
selectedBlockClientId,
Expand Down
43 changes: 32 additions & 11 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ import { Platform } from '@wordpress/element';
* text value. See `wp.richText.create`.
*/

/**
* Settings which can be passed to the getBlock or getBlocks selectors.
*
* @typedef {Object} WPGetBlockSettings
* @property {boolean} includeControlledInnerBlocks If true, include nested child
* blocks of inner block controllers.
* The default of false excludes
* nested blocks of inner block controllers.
*/

// Module constants
const MILLISECONDS_PER_HOUR = 3600 * 1000;
const MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
Expand Down Expand Up @@ -133,13 +143,18 @@ export function getBlockAttributes( state, clientId ) {
* the template block itself is considered part of the parent, but the children
* are not.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
* You can override this behavior with the includeControlledInnerBlocks setting.
* So if you call `getBlock( TP, { WPGetBlockSettings: true } )`, it will return
* all nested blocks, including all child inner block controllers and their children.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
* @param {?WPGetBlockSettings} settings A settings object.
*
* @return {Object} Parsed block object.
*/
export const getBlock = createSelector(
( state, clientId ) => {
( state, clientId, { includeControlledInnerBlocks = false } = {} ) => {
const block = state.blocks.byClientId[ clientId ];
if ( ! block ) {
return null;
Expand All @@ -148,9 +163,13 @@ export const getBlock = createSelector(
return {
...block,
attributes: getBlockAttributes( state, clientId ),
innerBlocks: areInnerBlocksControlled( state, clientId )
? EMPTY_ARRAY
: getBlocks( state, clientId ),
innerBlocks:
! includeControlledInnerBlocks &&
areInnerBlocksControlled( state, clientId )
? EMPTY_ARRAY
: getBlocks( state, clientId, {
includeControlledInnerBlocks,
} ),
};
},
( state, clientId ) => [
Expand Down Expand Up @@ -184,23 +203,25 @@ export const __unstableGetBlockWithoutInnerBlocks = createSelector(
/**
* Returns all block objects for the current post being edited as an array in
* the order they appear in the post. Note that this will exclude child blocks
* of nested inner block controllers.
* of nested inner block controllers unless the `includeControlledInnerBlocks`
* setting is set to true.
*
* Note: It's important to memoize this selector to avoid return a new instance
* on each call. We use the block cache state for each top-level block of the
* given clientID. This way, the selector only refreshes on changes to blocks
* associated with the given entity, and does not refresh when changes are made
* to blocks which are part of different inner block controllers.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
* @param {?WPGetBlockSettings} settings A settings object.
*
* @return {Object[]} Post blocks.
*/
export const getBlocks = createSelector(
( state, rootClientId ) => {
( state, rootClientId, { includeControlledInnerBlocks = false } = {} ) => {
return map( getBlockOrder( state, rootClientId ), ( clientId ) =>
getBlock( state, clientId )
getBlock( state, clientId, { includeControlledInnerBlocks } )
);
},
( state, rootClientId ) =>
Expand Down

0 comments on commit bd954d2

Please sign in to comment.