Skip to content

Commit

Permalink
Update to the stabilized API
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Sep 26, 2024
1 parent 968e72e commit 47b223b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 29 deletions.
33 changes: 8 additions & 25 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
isReusableBlock,
getBlockDefaultClassName,
hasBlockSupport,
__experimentalGetBlockAttributesNamesByRole,
store as blocksStore,
privateApis as blocksPrivateApis,
} from '@wordpress/blocks';
Expand All @@ -48,7 +47,7 @@ import { PrivateBlockContext } from './private-block-context';

import { unlock } from '../../lock-unlock';

const { isAttributeUnmodified } = unlock( blocksPrivateApis );
const { isBlockContentUnmodified } = unlock( blocksPrivateApis );

/**
* Merges wrapper props with special handling for classNames and styles.
Expand Down Expand Up @@ -311,26 +310,6 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
canInsertBlockType,
} = registry.select( blockEditorStore );

/**
* A block is "empty" if all of its content attributes are unmodified.
*
* @param {WPBlock} block The block to check.
* @return {boolean} Whether the block is empty.
*/
function isBlockEmpty( block ) {
const blockType = getBlockType( block.name );
const contentAttributes =
__experimentalGetBlockAttributesNamesByRole(
block.name,
'content'
);
return contentAttributes.every( ( attribute ) => {
const definition = blockType.attributes[ attribute ];
const value = block.attributes[ attribute ];
return isAttributeUnmodified( definition, value );
} );
}

function switchToDefaultOrRemove() {
const block = getBlock( clientId );
const defaultBlockName = getDefaultBlockName();
Expand Down Expand Up @@ -375,7 +354,8 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
} else {
registry.batch( () => {
const firstBlock = getBlock( firstClientId );
const isFirstBlockEmpty = isBlockEmpty( firstBlock );
const isFirstBlockContentUnmodified =
isBlockContentUnmodified( firstBlock );
const defaultBlockName = getDefaultBlockName();
const replacement = switchToBlockType(
firstBlock,
Expand All @@ -387,15 +367,18 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
canInsertBlockType( block.name, _clientId )
);

if ( isFirstBlockEmpty && canTransformToDefaultBlock ) {
if (
isFirstBlockContentUnmodified &&
canTransformToDefaultBlock
) {
// Step 1: If the block is empty and can be transformed to the default block type.
replaceBlocks(
firstClientId,
replacement,
changeSelection
);
} else if (
isFirstBlockEmpty &&
isFirstBlockContentUnmodified &&
firstBlock.name === defaultBlockName
) {
// Step 2: If the block is empty and is already the default block type.
Expand Down
4 changes: 2 additions & 2 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getBlockBindingsSource,
getBlockBindingsSources,
} from './registration';
import { isAttributeUnmodified } from './utils';
import { isBlockContentUnmodified } from './utils';

// The blocktype is the most important concept within the block API. It defines
// all aspects of the block configuration and its interfaces, including `edit`
Expand Down Expand Up @@ -184,5 +184,5 @@ lock( privateApis, {
unregisterBlockBindingsSource,
getBlockBindingsSource,
getBlockBindingsSources,
isAttributeUnmodified,
isBlockContentUnmodified,
} );
31 changes: 30 additions & 1 deletion packages/blocks/src/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const ICON_COLORS = [ '#191e23', '#f8f9f9' ];
* @param {*} value The attribute's value.
* @return {boolean} Whether the attribute is unmodified.
*/
export function isAttributeUnmodified( attributeDefinition, value ) {
function isAttributeUnmodified( attributeDefinition, value ) {
// Every attribute that has a default must match the default.
if ( attributeDefinition.hasOwnProperty( 'default' ) ) {
return value === attributeDefinition.default;
Expand Down Expand Up @@ -84,6 +84,35 @@ export function isUnmodifiedDefaultBlock( block ) {
return block.name === getDefaultBlockName() && isUnmodifiedBlock( block );
}

/**
* Determines whether the block content is unmodified. A block content is
* considered unmodified if all the attributes that have a role of 'content'
* are equal to the default attributes (or undefined).
* If the block does not have any attributes with a role of 'content', it
* will be considered unmodified if all the attributes are equal to the default
* attributes (or undefined).
*
* @param {WPBlock} block Block Object
* @return {boolean} Whether the block content is unmodified.
*/
export function isBlockContentUnmodified( block ) {
const contentAttributes = getBlockAttributesNamesByRole(
block.name,
'content'
);

if ( contentAttributes.length === 0 ) {
return isUnmodifiedBlock( block );
}

return contentAttributes.every( ( key ) => {
const definition = getBlockType( block.name )?.attributes[ key ];
const value = block.attributes[ key ];

return isAttributeUnmodified( definition, value );
} );
}

/**
* Function that checks if the parameter is a valid icon.
*
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/specs/editor/various/splitting-merging.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ test.describe( 'splitting and merging blocks (@firefox, @webkit)', () => {
} );

// Fix for https://github.com/WordPress/gutenberg/issues/65174.
test( 'should handle unwrapping and merging blocks', async ( {
test( 'should handle unwrapping and merging blocks with empty contents', async ( {
editor,
page,
} ) => {
Expand Down

0 comments on commit 47b223b

Please sign in to comment.