Skip to content

Commit

Permalink
Allow overrides of the default list
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Apr 16, 2024
1 parent 37d44e8 commit 06f5975
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 30 deletions.
30 changes: 1 addition & 29 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { name as patternBlockName } from './index';
import { unlock } from '../lock-unlock';

const { useLayoutClasses } = unlock( blockEditorPrivateApis );
const { isOverridableBlock, PARTIAL_SYNCING_SUPPORTED_BLOCKS } =
const { isOverridableBlock, hasOverridableBlocks, getOverridableAttributes } =
unlock( patternsPrivateApis );

const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
Expand Down Expand Up @@ -91,34 +91,6 @@ const useInferredLayout = ( blocks, parentLayout ) => {
}, [ blocks, parentLayout ] );
};

function hasOverridableBlocks( blocks ) {
return blocks.some( ( block ) => {
if ( isOverridableBlock( block ) ) return true;
return hasOverridableBlocks( block.innerBlocks );
} );
}

function getOverridableAttributes( block ) {
const set = new Set();
for ( const [ attributeKey, binding ] of Object.entries(
block.attributes.metadata.bindings
) ) {
if (
attributeKey === '__default' &&
binding.source === 'core/pattern-overrides'
) {
PARTIAL_SYNCING_SUPPORTED_BLOCKS[ block.name ].forEach(
( attribute ) => {
set.add( attribute );
}
);
} else if ( binding.source === 'core/pattern-overrides' ) {
set.add( attributeKey );
}
}
return Array.from( set );
}

function applyInitialContentValuesToInnerBlocks(
blocks,
content = {},
Expand Down
45 changes: 45 additions & 0 deletions packages/patterns/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,48 @@ export function isOverridableBlock( block ) {
)
);
}

/**
* Determines whether the blocks list has overridable blocks.
*
* @param {WPBlock[]} blocks The blocks list.
*
* @return {boolean} `true` if the list has overridable blocks, `false` otherwise.
*/
export function hasOverridableBlocks( blocks ) {
return blocks.some( ( block ) => {
if ( isOverridableBlock( block ) ) return true;
return hasOverridableBlocks( block.innerBlocks );
} );
}

/**
* Get the overridable attributes for the give block.
*
* @param {WPBlock} block The block to test.
*
* @return {string[]} The attribute names in an array.
*/
export function getOverridableAttributes( block ) {
const set = new Set();
// get default attributes for the block.
if ( block.attributes.metadata.bindings.__default ) {
PARTIAL_SYNCING_SUPPORTED_BLOCKS[ block.name ].forEach(
( attribute ) => {
set.add( attribute );
}
);
}
// Any additional attributes and overrides.
for ( const [ attributeKey, binding ] of Object.entries(
block.attributes.metadata.bindings
) ) {
if ( attributeKey === '__default' ) continue;
if ( binding.source === 'core/pattern-overrides' ) {
set.add( attributeKey );
} else {
set.delete( attributeKey );
}
}
return Array.from( set );
}
69 changes: 69 additions & 0 deletions packages/patterns/src/api/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* Internal dependencies
*/
import { getOverridableAttributes } from '../';
import { PARTIAL_SYNCING_SUPPORTED_BLOCKS } from '../../constants';

/**
* WordPress dependencies
*/
import { createBlock } from '@wordpress/blocks';
import { registerCoreBlocks } from '@wordpress/block-library';

describe( 'getOverridableAttributes', () => {
beforeAll( () => {
registerCoreBlocks();
} );

it( 'should return an array of overridable attributes', () => {
const block = createBlock( 'core/paragraph', {
metadata: {
bindings: {
content: { source: 'core/pattern-overrides' },
},
},
} );

const attributes = getOverridableAttributes( block );

expect( attributes ).toEqual( [ 'content' ] );
} );

it( 'should return the default list for core blocks', () => {
const block = createBlock( 'core/image', {
metadata: {
bindings: {
__default: { source: 'core/pattern-overrides' },
},
},
} );

const attributes = getOverridableAttributes( block );

expect( attributes ).toEqual(
PARTIAL_SYNCING_SUPPORTED_BLOCKS[ 'core/image' ]
);
} );

it( 'should allow overrides of the default list', () => {
const block = createBlock( 'core/image', {
metadata: {
bindings: {
__default: { source: 'core/pattern-overrides' },
alt: { source: 'core/post-meta' },
width: { source: 'core/pattern-overrides' },
},
},
} );

const attributes = getOverridableAttributes( block );

const defaultAttributes = new Set(
PARTIAL_SYNCING_SUPPORTED_BLOCKS[ 'core/image' ]
);
defaultAttributes.delete( 'alt' );
defaultAttributes.add( 'width' );

expect( attributes ).toEqual( Array.from( defaultAttributes ) );
} );
} );
8 changes: 7 additions & 1 deletion packages/patterns/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import {
default as DuplicatePatternModal,
useDuplicatePatternProps,
} from './components/duplicate-pattern-modal';
import { isOverridableBlock } from './api';
import {
isOverridableBlock,
hasOverridableBlocks,
getOverridableAttributes,
} from './api';
import RenamePatternModal from './components/rename-pattern-modal';
import PatternsMenuItems from './components';
import RenamePatternCategoryModal from './components/rename-pattern-category-modal';
Expand All @@ -34,6 +38,8 @@ lock( privateApis, {
CreatePatternModalContents,
DuplicatePatternModal,
isOverridableBlock,
hasOverridableBlocks,
getOverridableAttributes,
useDuplicatePatternProps,
RenamePatternModal,
PatternsMenuItems,
Expand Down

0 comments on commit 06f5975

Please sign in to comment.