Skip to content

Commit

Permalink
List/quote: unwrap inner block when pressing Backspace at start (#45075)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored Dec 1, 2022
1 parent 93d317a commit 5164e8e
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 96 deletions.
90 changes: 68 additions & 22 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
serializeRawBlock,
switchToBlockType,
store as blocksStore,
getDefaultBlockName,
isUnmodifiedBlock,
} from '@wordpress/blocks';
import { withFilters } from '@wordpress/components';
import {
Expand Down Expand Up @@ -311,7 +313,6 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
__unstableMarkLastChangeAsPersistent,
moveBlocksToPosition,
removeBlock,
selectBlock,
} = dispatch( blockEditorStore );

// Do not add new properties here, use `useDispatch` instead to avoid
Expand Down Expand Up @@ -348,8 +349,71 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
getBlockAttributes,
getBlockName,
getBlockOrder,
getBlockIndex,
getBlockRootClientId,
canInsertBlockType,
} = registry.select( blockEditorStore );

/**
* Moves the block with clientId up one level. If the block type
* cannot be inserted at the new location, it will be attempted to
* convert to the default block type.
*
* @param {string} _clientId The block to move.
* @param {boolean} changeSelection Whether to change the selection
* to the moved block.
*/
function moveFirstItemUp( _clientId, changeSelection = true ) {
const targetRootClientId = getBlockRootClientId( _clientId );
const blockOrder = getBlockOrder( _clientId );
const [ firstClientId ] = blockOrder;

if (
blockOrder.length === 1 &&
isUnmodifiedBlock( getBlock( firstClientId ) )
) {
removeBlock( _clientId );
} else {
if (
canInsertBlockType(
getBlockName( firstClientId ),
targetRootClientId
)
) {
moveBlocksToPosition(
[ firstClientId ],
_clientId,
targetRootClientId,
getBlockIndex( _clientId )
);
} else {
const replacement = switchToBlockType(
getBlock( firstClientId ),
getDefaultBlockName()
);

if ( replacement && replacement.length ) {
registry.batch( () => {
insertBlocks(
replacement,
getBlockIndex( _clientId ),
targetRootClientId,
changeSelection
);
removeBlock( firstClientId, false );
} );
}
}

if (
! getBlockOrder( _clientId ).length &&
isUnmodifiedBlock( getBlock( _clientId ) )
) {
removeBlock( _clientId, false );
}
}
}

// For `Delete` or forward merge, we should do the exact same thing
// as `Backspace`, but from the other block.
if ( forward ) {
Expand Down Expand Up @@ -400,15 +464,8 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
return;
}

// Check if it's possibile to "unwrap" the following block
// before trying to merge.
const replacement = switchToBlockType(
getBlock( nextBlockClientId ),
'*'
);

if ( replacement && replacement.length ) {
replaceBlocks( nextBlockClientId, replacement );
if ( getBlockOrder( nextBlockClientId ).length ) {
moveFirstItemUp( nextBlockClientId, false );
} else {
mergeBlocks( clientId, nextBlockClientId );
}
Expand Down Expand Up @@ -453,18 +510,7 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
}
}

// Attempt to "unwrap" the block contents when there's no
// preceding block to merge with.
const replacement = switchToBlockType(
getBlock( rootClientId ),
'*'
);
if ( replacement && replacement.length ) {
registry.batch( () => {
replaceBlocks( rootClientId, replacement );
selectBlock( replacement[ 0 ].clientId, 0 );
} );
}
moveFirstItemUp( rootClientId );
}
}
},
Expand Down
90 changes: 69 additions & 21 deletions packages/block-editor/src/components/block-list/block.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
getBlockType,
__experimentalGetAccessibleBlockLabel as getAccessibleBlockLabel,
switchToBlockType,
getDefaultBlockName,
isUnmodifiedBlock,
} from '@wordpress/blocks';
import { useSetting } from '@wordpress/block-editor';

Expand Down Expand Up @@ -436,8 +438,72 @@ export default compose( [
getBlockAttributes,
getBlockName,
getBlockOrder,
getBlockIndex,
getBlockRootClientId,
canInsertBlockType,
} = registry.select( blockEditorStore );

/**
* Moves the block with clientId up one level. If the block type
* cannot be inserted at the new location, it will be attempted to
* convert to the default block type.
*
* @param {string} _clientId The block to move.
* @param {boolean} changeSelection Whether to change the selection
* to the moved block.
*/
function moveFirstItemUp( _clientId, changeSelection = true ) {
const targetRootClientId =
getBlockRootClientId( _clientId );
const blockOrder = getBlockOrder( _clientId );
const [ firstClientId ] = blockOrder;

if (
blockOrder.length === 1 &&
isUnmodifiedBlock( getBlock( firstClientId ) )
) {
removeBlock( _clientId );
} else {
if (
canInsertBlockType(
getBlockName( firstClientId ),
targetRootClientId
)
) {
moveBlocksToPosition(
[ firstClientId ],
_clientId,
targetRootClientId,
getBlockIndex( _clientId )
);
} else {
const replacement = switchToBlockType(
getBlock( firstClientId ),
getDefaultBlockName()
);

if ( replacement && replacement.length ) {
registry.batch( () => {
insertBlocks(
replacement,
getBlockIndex( _clientId ),
targetRootClientId,
changeSelection
);
removeBlock( firstClientId, false );
} );
}
}

if (
! getBlockOrder( _clientId ).length &&
isUnmodifiedBlock( getBlock( _clientId ) )
) {
removeBlock( _clientId, false );
}
}
}

// For `Delete` or forward merge, we should do the exact same thing
// as `Backspace`, but from the other block.
if ( forward ) {
Expand Down Expand Up @@ -488,15 +554,8 @@ export default compose( [
return;
}

// Check if it's possibile to "unwrap" the following block
// before trying to merge.
const replacement = switchToBlockType(
getBlock( nextBlockClientId ),
'*'
);

if ( replacement && replacement.length ) {
replaceBlocks( nextBlockClientId, replacement );
if ( getBlockOrder( nextBlockClientId ).length ) {
moveFirstItemUp( nextBlockClientId, false );
} else {
mergeBlocks( clientId, nextBlockClientId );
}
Expand Down Expand Up @@ -541,18 +600,7 @@ export default compose( [
}
}

// Attempt to "unwrap" the block contents when there's no
// preceding block to merge with.
const replacement = switchToBlockType(
getBlock( rootClientId ),
'*'
);
if ( replacement && replacement.length ) {
registry.batch( () => {
replaceBlocks( rootClientId, replacement );
selectBlock( replacement[ 0 ].clientId, 0 );
} );
}
moveFirstItemUp( rootClientId );
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/list-item/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';
import transforms from './transforms';

const { name } = metadata;

Expand All @@ -25,6 +26,7 @@ export const settings = {
content: attributes.content + attributesToMerge.content,
};
},
transforms,
};

export const init = () => initBlock( { name, metadata, settings } );
17 changes: 17 additions & 0 deletions packages/block-library/src/list-item/transforms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* WordPress dependencies
*/
import { createBlock } from '@wordpress/blocks';

const transforms = {
to: [
{
type: 'block',
blocks: [ 'core/paragraph' ],
transform: ( attributes ) =>
createBlock( 'core/paragraph', attributes ),
},
],
};

export default transforms;
14 changes: 8 additions & 6 deletions packages/block-library/src/list/test/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ describe( 'List block', () => {
` );
} );

it( 'unwraps list items when attempting to merge with non-list block', async () => {
it( 'unwraps first item when attempting to merge with non-list block', async () => {
const initialHtml = `<!-- wp:paragraph -->
<p>A quick brown fox.</p>
<!-- /wp:paragraph -->
Expand Down Expand Up @@ -406,14 +406,16 @@ describe( 'List block', () => {
"<!-- wp:paragraph -->
<p>A quick brown fox.</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>One</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Two</p>
<!-- /wp:paragraph -->"
<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Two</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->"
` );
} );
} );
11 changes: 0 additions & 11 deletions packages/block-library/src/list/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,6 @@ const transforms = {
);
},
} ) ),
{
type: 'block',
blocks: [ '*' ],
transform: ( _attributes, childBlocks ) => {
return getListContentFlat( childBlocks ).map( ( content ) =>
createBlock( 'core/paragraph', {
content,
} )
);
},
},
],
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const transformationCategories = {
'core/paragraph',
'core/heading',
'core/list',
'core/list-item',
'core/quote',
'core/pullquote',
'core/preformatted',
Expand Down
20 changes: 16 additions & 4 deletions packages/blocks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,9 @@ _Returns_

- `boolean`: Whether the given block is a template part.

### isUnmodifiedDefaultBlock
### isUnmodifiedBlock

Determines whether the block is a default block
and its attributes are equal to the default attributes
Determines whether the block's attributes are equal to the default attributes
which means the block is unmodified.

_Parameters_
Expand All @@ -541,7 +540,20 @@ _Parameters_

_Returns_

- `boolean`: Whether the block is an unmodified default block
- `boolean`: Whether the block is an unmodified block.

### isUnmodifiedDefaultBlock

Determines whether the block is a default block and its attributes are equal
to the default attributes which means the block is unmodified.

_Parameters_

- _block_ `WPBlock`: Block Object

_Returns_

- `boolean`: Whether the block is an unmodified default block.

### isValidBlockContent

Expand Down
1 change: 1 addition & 0 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export {
unregisterBlockVariation,
} from './registration';
export {
isUnmodifiedBlock,
isUnmodifiedDefaultBlock,
normalizeIconObject,
isValidIcon,
Expand Down
Loading

0 comments on commit 5164e8e

Please sign in to comment.