diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 466a9cbeb96c26..4dafaa291fcf31 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -131,7 +131,9 @@ export function* selectPreviousBlock( clientId ) { clientId ); - yield selectBlock( previousBlockClientId, -1 ); + if ( previousBlockClientId ) { + yield selectBlock( previousBlockClientId, -1 ); + } } /** @@ -147,7 +149,9 @@ export function* selectNextBlock( clientId ) { clientId ); - yield selectBlock( nextBlockClientId ); + if ( nextBlockClientId ) { + yield selectBlock( nextBlockClientId ); + } } /** @@ -633,7 +637,13 @@ export function selectionChange( clientId, attributeKey, startOffset, endOffset * @return {Object} Action object */ export function insertDefaultBlock( attributes, rootClientId, index ) { - const block = createBlock( getDefaultBlockName(), attributes ); + // Abort if there is no default block type (if it has been unregistered). + const defaultBlockName = getDefaultBlockName(); + if ( ! defaultBlockName ) { + return; + } + + const block = createBlock( defaultBlockName, attributes ); return insertBlock( block, index, rootClientId ); } diff --git a/packages/e2e-tests/specs/block-deletion.test.js b/packages/e2e-tests/specs/block-deletion.test.js index fb975fb61e88ce..6adcb01681bb2a 100644 --- a/packages/e2e-tests/specs/block-deletion.test.js +++ b/packages/e2e-tests/specs/block-deletion.test.js @@ -7,6 +7,7 @@ import { createNewPost, isInDefaultBlock, pressKeyWithModifier, + insertBlock, } from '@wordpress/e2e-test-utils'; const addThreeParagraphsToNewPost = async () => { @@ -130,4 +131,34 @@ describe( 'deleting all blocks', () => { // And focus is retained: expect( await isInDefaultBlock() ).toBe( true ); } ); + + it( 'gracefully removes blocks when the default block is not available', async () => { + // Regression Test: Previously, removing a block would not clear + // selection state when there were no other blocks to select. + // + // See: https://github.com/WordPress/gutenberg/issues/15458 + // See: https://github.com/WordPress/gutenberg/pull/15543 + await createNewPost(); + + // Unregister default block type. This may happen if the editor is + // configured to not allow the default (paragraph) block type, either + // by plugin editor settings filtering or user block preferences. + await page.evaluate( () => { + const defaultBlockName = wp.data.select( 'core/blocks' ).getDefaultBlockName(); + wp.data.dispatch( 'core/blocks' ).removeBlockTypes( defaultBlockName ); + } ); + + // Add and remove a block. + await insertBlock( 'Image' ); + await page.keyboard.press( 'Backspace' ); + + // Verify there is no selected block. + // TODO: There should be expectations around where focus is placed in + // this scenario. Currently, a focus loss occurs (not acceptable). + const selectedBlocksCount = await page.evaluate( () => { + return wp.data.select( 'core/block-editor' ).getSelectedBlockClientIds().length; + } ); + + expect( selectedBlocksCount ).toBe( 0 ); + } ); } );