Skip to content

Commit

Permalink
Add allowedBlocksMiddleware
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed Jul 9, 2018
1 parent 84c1e73 commit 3dcb764
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 9 deletions.
4 changes: 2 additions & 2 deletions editor/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ InnerBlocks = compose( [
replaceInnerBlocks( blocks ) {
const uids = map( block.innerBlocks, 'uid' );
if ( uids.length ) {
replaceBlocks( uids, blocks );
replaceBlocks( uids, blocks, true );
} else {
insertBlocks( blocks, undefined, uid );
insertBlocks( blocks, undefined, uid, true );
}
},
updateNestedSettings( settings ) {
Expand Down
18 changes: 11 additions & 7 deletions editor/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,19 @@ export function toggleSelection( isSelectionEnabled = true ) {
* Returns an action object signalling that a blocks should be replaced with
* one or more replacement blocks.
*
* @param {(string|string[])} uids Block UID(s) to replace.
* @param {(Object|Object[])} blocks Replacement block(s).
* @param {(string|string[])} uids Block UID(s) to replace.
* @param {(Object|Object[])} blocks Replacement block(s).
* @param {?boolean} ignoreAllowedBlocksValidation Optional root UID of block list to insert.
*
* @return {Object} Action object.
*/
export function replaceBlocks( uids, blocks ) {
export function replaceBlocks( uids, blocks, ignoreAllowedBlocksValidation ) {
return {
type: 'REPLACE_BLOCKS',
uids: castArray( uids ),
blocks: castArray( blocks ),
time: Date.now(),
ignoreAllowedBlocksValidation,
};
}

Expand Down Expand Up @@ -301,19 +303,21 @@ export function insertBlock( block, index, rootUID ) {
* Returns an action object used in signalling that an array of blocks should
* be inserted, optionally at a specific index respective a root block list.
*
* @param {Object[]} blocks Block objects to insert.
* @param {?number} index Index at which block should be inserted.
* @param {?string} rootUID Optional root UID of block list to insert.
* @param {Object[]} blocks Block objects to insert.
* @param {?number} index Index at which block should be inserted.
* @param {?string} rootUID Optional root UID of block list to insert.
* @param {?boolean} ignoreAllowedBlocksValidation Optional root UID of block list to insert.
*
* @return {Object} Action object.
*/
export function insertBlocks( blocks, index, rootUID ) {
export function insertBlocks( blocks, index, rootUID, ignoreAllowedBlocksValidation ) {
return {
type: 'INSERT_BLOCKS',
blocks: castArray( blocks ),
index,
rootUID,
time: Date.now(),
ignoreAllowedBlocksValidation,
};
}

Expand Down
2 changes: 2 additions & 0 deletions editor/store/middlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { flowRight } from 'lodash';
* Internal dependencies
*/
import effects from './effects';
import allowedBlocksMiddleware from '../utils/allowed-blocks-middleware';

/**
* Applies the custom middlewares used specifically in the editor module.
Expand All @@ -21,6 +22,7 @@ function applyMiddlewares( store ) {
const middlewares = [
refx( effects ),
multi,
allowedBlocksMiddleware,
];

let enhancedDispatch = () => {
Expand Down
63 changes: 63 additions & 0 deletions editor/utils/allowed-blocks-middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

/**
* External dependencies
*/
import { every, filter, first } from 'lodash';

/**
* Internal dependencies
*/
import { canInsertBlockType, getBlock, getBlockName, getBlockRootUID } from '../store/selectors';

const allowedBlocksMiddleware = ( store ) => ( next ) => ( action ) => {
if ( action.ignoreAllowedBlocksValidation ) {
next( action );
return;
}
switch ( action.type ) {
// on insert we allow the action if at least one of the blocks can be inserted filtering the other blocks
case 'INSERT_BLOCKS': {
const allowedBlocks =
filter( action.blocks, ( block ) => block && canInsertBlockType( store.getState(), block.name, action.rootUID ) );
if ( allowedBlocks.length ) {
next( {
...action,
blocks: allowedBlocks,
} );
}
return;
}
case 'MOVE_BLOCK_TO_POSITION': {
const { fromRootUID, toRootUID, uid } = action;
const blockName = getBlockName( store.getState(), uid );
// currently the only constraint to move inside the same parent is locking
// locking was already handled
// it is not possible to use drag & drop if locking is active
if ( toRootUID === fromRootUID || canInsertBlockType( store.getState(), blockName, toRootUID ) ) {
next( action );
}
return;
}
case 'REPLACE_BLOCKS': {
const rootUID = getBlockRootUID( store.getState(), first( action.uids ) );
// replace is valid if the new blocks can be inserted in the root block
// or if we had a block of the same type in the position of the block being replaced.
const replaceIsValid = every( action.blocks, ( block, index ) => {
if ( canInsertBlockType( store.getState(), block.name, rootUID ) ) {
return true;
}
const uidBlockBeingReplaced = action.uids[ index ];
const blockBeingReplaced = uidBlockBeingReplaced && getBlock( store.getState(), uidBlockBeingReplaced );
return blockBeingReplaced && blockBeingReplaced.name === block.name;
} );
if ( replaceIsValid ) {
next( action );
}
return;
}
default:
next( action );
}
};

export default allowedBlocksMiddleware;

0 comments on commit 3dcb764

Please sign in to comment.