diff --git a/docs/data/data-core-editor.md b/docs/data/data-core-editor.md index 267184d78113e..5b823d1893d0d 100644 --- a/docs/data/data-core-editor.md +++ b/docs/data/data-core-editor.md @@ -1532,8 +1532,8 @@ inserted, optionally at a specific index respective a root block list. * block: Block object to insert. * index: Index at which block should be inserted. - * rootClientId: Optional root client ID of block list on which - to insert. + * rootClientId: Optional root client ID of block list on which to insert. + * updateSelection: If true block selection will be updated. If false, block selection will not change. Defaults to true. ### insertBlocks @@ -1544,8 +1544,8 @@ be inserted, optionally at a specific index respective a root block list. * blocks: Block objects to insert. * index: Index at which block should be inserted. - * rootClientId: Optional root client ID of block list on - which to insert. + * rootClientId: Optional root cliente ID of block list on which to insert. + * updateSelection: If true block selection will be updated. If false, block selection will not change. Defaults to true. ### showInsertionPoint diff --git a/packages/editor/src/components/inner-blocks/README.md b/packages/editor/src/components/inner-blocks/README.md index 494fb750fb74c..040b0d463861c 100644 --- a/packages/editor/src/components/inner-blocks/README.md +++ b/packages/editor/src/components/inner-blocks/README.md @@ -90,6 +90,13 @@ const TEMPLATE = [ [ 'core/columns', {}, [ The previous example creates an InnerBlocks area containing two columns one with an image and the other with a paragraph. +### `templateInsertUpdatesSelection` +* **Type:** `Boolean` +* **Default:** `true` + +If true when child blocks in the template are inserted the selection is updated. +If false the selection should not be updated when child blocks specified in the template are inserted. + ### `templateLock` * **Type:** `String|Boolean` diff --git a/packages/editor/src/components/inner-blocks/index.js b/packages/editor/src/components/inner-blocks/index.js index c9252e912b5df..2183163221181 100644 --- a/packages/editor/src/components/inner-blocks/index.js +++ b/packages/editor/src/components/inner-blocks/index.js @@ -142,7 +142,7 @@ InnerBlocks = compose( [ insertBlocks, updateBlockListSettings, } = dispatch( 'core/editor' ); - const { block, clientId } = ownProps; + const { block, clientId, templateInsertUpdatesSelection = true } = ownProps; return { replaceInnerBlocks( blocks ) { @@ -150,7 +150,7 @@ InnerBlocks = compose( [ if ( clientIds.length ) { replaceBlocks( clientIds, blocks ); } else { - insertBlocks( blocks, undefined, clientId ); + insertBlocks( blocks, undefined, clientId, templateInsertUpdatesSelection ); } }, updateNestedSettings( settings ) { diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 7d5c0d71ee2d1..a77b27add51c2 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -295,35 +295,36 @@ export function moveBlockToPosition( clientId, fromRootClientId, toRootClientId, * Returns an action object used in signalling that a single block should be * inserted, optionally at a specific index respective a root block list. * - * @param {Object} block Block object to insert. - * @param {?number} index Index at which block should be inserted. - * @param {?string} rootClientId Optional root client ID of block list on which - * to insert. + * @param {Object} block Block object to insert. + * @param {?number} index Index at which block should be inserted. + * @param {?string} rootClientId Optional root client ID of block list on which to insert. + * @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 insertBlock( block, index, rootClientId ) { - return insertBlocks( [ block ], index, rootClientId ); +export function insertBlock( block, index, rootClientId, updateSelection = true ) { + return insertBlocks( [ block ], index, rootClientId, updateSelection ); } /** * 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} rootClientId Optional root client ID of block list on - * which to insert. + * @param {Object[]} blocks Block objects to insert. + * @param {?number} index Index at which block should be inserted. + * @param {?string} rootClientId Optional root cliente ID of block list on which to insert. + * @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 insertBlocks( blocks, index, rootClientId ) { +export function insertBlocks( blocks, index, rootClientId, updateSelection = true ) { return { type: 'INSERT_BLOCKS', blocks: castArray( blocks ), index, rootClientId, time: Date.now(), + updateSelection, }; } diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index e95b010dc94d9..9ea2259b2c791 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -705,14 +705,18 @@ export function blockSelection( state = { end: action.clientId, initialPosition: action.initialPosition, }; - case 'INSERT_BLOCKS': - return { - ...state, - start: action.blocks[ 0 ].clientId, - end: action.blocks[ 0 ].clientId, - initialPosition: null, - isMultiSelecting: false, - }; + case 'INSERT_BLOCKS': { + if ( action.updateSelection ) { + return { + ...state, + start: action.blocks[ 0 ].clientId, + end: action.blocks[ 0 ].clientId, + initialPosition: null, + isMultiSelecting: false, + }; + } + return state; + } case 'REMOVE_BLOCKS': if ( ! action.clientIds || ! action.clientIds.length || action.clientIds.indexOf( state.start ) === -1 ) { return state; diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index 4358054f8573b..b071dc78204fb 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -188,6 +188,7 @@ describe( 'actions', () => { index, rootClientId: 'testclientid', time: expect.any( Number ), + updateSelection: true, } ); } ); } ); @@ -204,6 +205,7 @@ describe( 'actions', () => { index, rootClientId: 'testclientid', time: expect.any( Number ), + updateSelection: true, } ); } ); } ); diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index 7d75ce2c55b4f..005fd9127690f 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -1567,6 +1567,7 @@ describe( 'state', () => { clientId: 'ribs', name: 'core/freeform', } ], + updateSelection: true, } ); expect( state3 ).toEqual( { @@ -1577,6 +1578,24 @@ describe( 'state', () => { } ); } ); + it( 'should not select inserted block if updateSelection flag is false', () => { + const original = deepFreeze( { start: 'a', end: 'b' } ); + + const state3 = blockSelection( original, { + type: 'INSERT_BLOCKS', + blocks: [ { + clientId: 'ribs', + name: 'core/freeform', + } ], + updateSelection: false, + } ); + + expect( state3 ).toEqual( { + start: 'a', + end: 'b', + } ); + } ); + it( 'should not update the state if the block moved is already selected', () => { const original = deepFreeze( { start: 'ribs', end: 'ribs' } ); const state = blockSelection( original, {