Skip to content

Commit

Permalink
Blocks: Apply the most recent filters to previously registered blocks (
Browse files Browse the repository at this point in the history
…#34299)

* Blocks: Try to split block registration from filtering

* Experiment with data control for processing block settings

* Add store controls that reapplies block type filters

* Add test block and filter to validate if it works

* Meassure impact on the loading time when 100 custom blocks and filters registerd

* Reapply block type filters for all editor screens

* Remove test code examples

* Improve code documentation for new functionality

* Remove broken functionality in the block types reducer

* Apply suggestions from code review

* Provide the default value for variations iin block type to align with WordPress core

* Improve handling for block styles and variations when `ADD_BLOCK_TYPES` called again

* Update buildBlockTypeItem to correctly fetch block type variations

* Test: Add e2e test that ensures that filters can be added after block registration

* Blocks: Move logic to actions and remove controls

* Rename __experimentalAddBlockType to __experimentalRegisterBlockType

* Improve the description for __experimentalReapplyBlockTypeFilters
  • Loading branch information
gziolo authored Oct 14, 2021
1 parent 21831a9 commit 4ba530c
Show file tree
Hide file tree
Showing 16 changed files with 469 additions and 153 deletions.
5 changes: 2 additions & 3 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import createSelector from 'rememo';
import {
getBlockType,
getBlockTypes,
getBlockVariations,
hasBlockSupport,
getPossibleBlockTransformations,
parse,
Expand Down Expand Up @@ -1514,9 +1515,7 @@ const buildBlockTypeItem = ( state, { buildScope = 'inserter' } ) => (
};
if ( buildScope === 'transform' ) return blockItemBase;

const inserterVariations = blockType.variations.filter(
( { scope } ) => ! scope || scope.includes( 'inserter' )
);
const inserterVariations = getBlockVariations( blockType.name, 'inserter' );
return {
...blockItemBase,
initialAttributes: {},
Expand Down
3 changes: 3 additions & 0 deletions packages/blocks/src/api/raw-handling/test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jest.mock( '@wordpress/data', () => {
const mock = jest.fn();
return mock;
},
createRegistryControl() {
return jest.fn();
},
};
} );

Expand Down
127 changes: 16 additions & 111 deletions packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,25 @@ import {
camelCase,
isArray,
isEmpty,
isFunction,
isNil,
isObject,
isPlainObject,
isString,
mapKeys,
omit,
pick,
pickBy,
some,
} from 'lodash';

/**
* WordPress dependencies
*/
import { applyFilters } from '@wordpress/hooks';
import { select, dispatch } from '@wordpress/data';
import { _x } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import i18nBlockSchema from './i18n-block.json';
import { isValidIcon, normalizeIconObject } from './utils';
import { BLOCK_ICON_DEFAULT, DEPRECATED_ENTRY_KEYS } from './constants';
import { BLOCK_ICON_DEFAULT } from './constants';
import { store as blocksStore } from '../store';

/**
Expand Down Expand Up @@ -145,18 +139,6 @@ import { store as blocksStore } from '../store';
* then no preview is shown.
*/

/**
* Mapping of legacy category slugs to their latest normal values, used to
* accommodate updates of the default set of block categories.
*
* @type {Record<string,string>}
*/
const LEGACY_CATEGORY_MAPPING = {
common: 'text',
formatting: 'text',
layout: 'design',
};

export const serverSideBlockDefinitions = {};

/**
Expand Down Expand Up @@ -256,13 +238,24 @@ export function registerBlockType( blockNameOrMetadata, settings ) {
return;
}

if ( ! /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test( name ) ) {
console.error(
'Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block'
);
return;
}
if ( select( blocksStore ).getBlockType( name ) ) {
console.error( 'Block "' + name + '" is already registered.' );
return;
}

if ( isObject( blockNameOrMetadata ) ) {
unstable__bootstrapServerSideBlockDefinitions( {
[ name ]: getBlockSettingsFromMetadata( blockNameOrMetadata ),
} );
}

settings = {
const blockType = {
name,
icon: BLOCK_ICON_DEFAULT,
keywords: [],
Expand All @@ -271,103 +264,15 @@ export function registerBlockType( blockNameOrMetadata, settings ) {
usesContext: [],
supports: {},
styles: [],
variations: [],
save: () => null,
...serverSideBlockDefinitions?.[ name ],
...settings,
};

if ( ! /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test( name ) ) {
console.error(
'Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block'
);
return;
}
if ( select( blocksStore ).getBlockType( name ) ) {
console.error( 'Block "' + name + '" is already registered.' );
return;
}
dispatch( blocksStore ).__experimentalRegisterBlockType( blockType );

const preFilterSettings = { ...settings };
settings = applyFilters( 'blocks.registerBlockType', settings, name );

if ( settings.deprecated ) {
settings.deprecated = settings.deprecated.map( ( deprecation ) =>
pick(
// Only keep valid deprecation keys.
applyFilters(
'blocks.registerBlockType',
// Merge deprecation keys with pre-filter settings
// so that filters that depend on specific keys being
// present don't fail.
{
// Omit deprecation keys here so that deprecations
// can opt out of specific keys like "supports".
...omit( preFilterSettings, DEPRECATED_ENTRY_KEYS ),
...deprecation,
},
name
),
DEPRECATED_ENTRY_KEYS
)
);
}

if ( ! isPlainObject( settings ) ) {
console.error( 'Block settings must be a valid object.' );
return;
}

if ( ! isFunction( settings.save ) ) {
console.error( 'The "save" property must be a valid function.' );
return;
}
if ( 'edit' in settings && ! isFunction( settings.edit ) ) {
console.error( 'The "edit" property must be a valid function.' );
return;
}

// Canonicalize legacy categories to equivalent fallback.
if ( LEGACY_CATEGORY_MAPPING.hasOwnProperty( settings.category ) ) {
settings.category = LEGACY_CATEGORY_MAPPING[ settings.category ];
}

if (
'category' in settings &&
! some( select( blocksStore ).getCategories(), {
slug: settings.category,
} )
) {
console.warn(
'The block "' +
name +
'" is registered with an invalid category "' +
settings.category +
'".'
);
delete settings.category;
}

if ( ! ( 'title' in settings ) || settings.title === '' ) {
console.error( 'The block "' + name + '" must have a title.' );
return;
}
if ( typeof settings.title !== 'string' ) {
console.error( 'Block titles must be strings.' );
return;
}

settings.icon = normalizeIconObject( settings.icon );
if ( ! isValidIcon( settings.icon.src ) ) {
console.error(
'The icon passed is invalid. ' +
'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional'
);
return;
}

dispatch( blocksStore ).addBlockTypes( settings );

return settings;
return select( blocksStore ).getBlockType( name );
}

/**
Expand Down
15 changes: 15 additions & 0 deletions packages/blocks/src/api/test/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
save: noop,
category: 'text',
title: 'block title',
Expand Down Expand Up @@ -272,6 +273,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
save: expect.any( Function ),
} );
} );
Expand Down Expand Up @@ -307,6 +309,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
}
);
} );
Expand Down Expand Up @@ -338,6 +341,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -371,6 +375,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -406,6 +411,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -473,6 +479,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -503,6 +510,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -547,6 +555,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -605,6 +614,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand All @@ -630,6 +640,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand Down Expand Up @@ -715,6 +726,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
save: () => null,
...get(
serverSideBlockDefinitions,
Expand Down Expand Up @@ -969,6 +981,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
expect( getBlockTypes() ).toEqual( [] );
} );
Expand Down Expand Up @@ -1047,6 +1060,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );

Expand All @@ -1071,6 +1085,7 @@ describe( 'blocks', () => {
keywords: [],
supports: {},
styles: [],
variations: [],
} );
} );
} );
Expand Down
Loading

0 comments on commit 4ba530c

Please sign in to comment.