Skip to content

Commit

Permalink
Update: Use new action REPLACE_INNER_BLOCKS for InnerBlocks replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed Mar 6, 2019
1 parent 7e1c1ed commit a6afb8e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,17 @@ specified client ID is to be removed.
* selectPrevious: True if the previous block should be
selected when a block is removed.

### replaceInnerBlocks

Returns an action object used in signalling that the inner blocks with the
specified client ID should be replaced.

*Parameters*

* rootClientId: Client ID of the block whose InnerBlocks will re replaced.
* blocks: Block objects to insert as new InnerBlocks
* updateSelection: If true block selection will be updated. If false, block selection will not change. Defaults to true.

### toggleBlockMode

Returns an action object used to toggle the block editing mode between
Expand Down
20 changes: 20 additions & 0 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,26 @@ export function removeBlock( clientId, selectPrevious ) {
return removeBlocks( [ clientId ], selectPrevious );
}

/**
* Returns an action object used in signalling that the inner blocks with the
* specified client ID should be replaced.
*
* @param {string} rootClientId Client ID of the block whose InnerBlocks will re replaced.
* @param {Object[]} blocks Block objects to insert as new InnerBlocks
* @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true.
*
* @return {Object} Action object.
*/
export function replaceInnerBlocks( rootClientId, blocks, updateSelection ) {
return {
type: 'REPLACE_INNER_BLOCKS',
rootClientId,
blocks,
updateSelection,
time: Date.now(),
};
}

/**
* Returns an action object used to toggle the block editing mode between
* visual and HTML modes.
Expand Down
34 changes: 34 additions & 0 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,38 @@ const withBlockReset = ( reducer ) => ( state, action ) => {
return reducer( state, action );
};

/**
* Higher-order reducer which targets the combined blocks reducer and handles
* the `REPLACE_INNER_BLOCKS` action. When dispatched, this action the state should become equivalent
* to the execution of a `REMOVE_BLOCKS` action containing all the child's of the root block followed by
* the execution of `INSERT_BLOCKS` with the new blocks.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withReplaceInnerBlocks = ( reducer ) => ( state, action ) => {
if ( action.type !== 'REPLACE_INNER_BLOCKS' ) {
return reducer( state, action );
}
let stateAfterBlocksRemoval = state;
if ( state.order[ action.rootClientId ] ) {
stateAfterBlocksRemoval = reducer( stateAfterBlocksRemoval, {
type: 'REMOVE_BLOCKS',
clientIds: state.order[ action.rootClientId ],
} );
}
let stateAfterInsert = stateAfterBlocksRemoval;
if ( action.blocks.length ) {
stateAfterInsert = reducer( stateAfterInsert, {
...action,
type: 'INSERT_BLOCKS',
index: 0,
} );
}
return stateAfterInsert;
};

/**
* Higher-order reducer which targets the combined blocks reducer and handles
* the `SAVE_REUSABLE_BLOCK_SUCCESS` action. This action can't be handled by
Expand Down Expand Up @@ -343,6 +375,7 @@ const withSaveReusableBlock = ( reducer ) => ( state, action ) => {
*/
export const blocks = flow(
combineReducers,
withReplaceInnerBlocks, // needs to be before withInnerBlocksRemoveCascade
withInnerBlocksRemoveCascade,
withBlockReset,
withSaveReusableBlock,
Expand Down Expand Up @@ -713,6 +746,7 @@ export function blockSelection( state = {
end: action.clientId,
initialPosition: action.initialPosition,
};
case 'REPLACE_INNER_BLOCKS': // REPLACE_INNER_BLOCKS and INSERT_BLOCKS should follow the same logic.
case 'INSERT_BLOCKS': {
if ( action.updateSelection ) {
return {
Expand Down
12 changes: 3 additions & 9 deletions packages/editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { pick, isEqual, map } from 'lodash';
import { pick, isEqual } from 'lodash';
import classnames from 'classnames';

/**
Expand Down Expand Up @@ -144,20 +144,14 @@ InnerBlocks = compose( [
} ),
withDispatch( ( dispatch, ownProps ) => {
const {
replaceBlocks,
insertBlocks,
replaceInnerBlocks,
updateBlockListSettings,
} = dispatch( 'core/block-editor' );
const { block, clientId, templateInsertUpdatesSelection = true } = ownProps;

return {
replaceInnerBlocks( blocks ) {
const clientIds = map( block.innerBlocks, 'clientId' );
if ( clientIds.length ) {
replaceBlocks( clientIds, blocks );
} else {
insertBlocks( blocks, undefined, clientId, templateInsertUpdatesSelection );
}
replaceInnerBlocks( clientId, blocks, block.innerBlocks.length === 0 && templateInsertUpdatesSelection );
},
updateNestedSettings( settings ) {
dispatch( updateBlockListSettings( clientId, settings ) );
Expand Down

0 comments on commit a6afb8e

Please sign in to comment.