diff --git a/blocks/deprecated-hooks.js b/blocks/deprecated-hooks.js new file mode 100644 index 00000000000000..80bb42a2a8d948 --- /dev/null +++ b/blocks/deprecated-hooks.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { includes } from 'lodash'; + +/** + * WordPress dependencies + */ +import { addAction, addFilter } from '@wordpress/hooks'; +import deprecated from '@wordpress/deprecated'; + +const forwardDeprecatedHooks = ( oldHookName, ...args ) => { + const deprecatedHooks = [ + 'blocks.Autocomplete.completers', + 'blocks.BlockEdit', + 'blocks.BlockListBlock', + 'blocks.MediaUpload', + ]; + if ( includes( deprecatedHooks, oldHookName ) ) { + const newHookName = oldHookName.replace( 'blocks.', 'editor.' ); + deprecated( `${ oldHookName } filter`, { + version: '3.3', + alternative: newHookName, + } ); + addFilter( newHookName, ...args ); + } +}; + +addAction( 'hookAdded', 'core/editor/deprecated', forwardDeprecatedHooks ); diff --git a/blocks/index.js b/blocks/index.js index 2fed22406b3e9c..98698dbaa1062c 100644 --- a/blocks/index.js +++ b/blocks/index.js @@ -7,5 +7,6 @@ // // Blocks are inferred from the HTML source of a post through a parsing mechanism // and then stored as objects in state, from which it is then rendered for editing. +import './deprecated-hooks'; import './store'; export * from './api'; diff --git a/docs/extensibility/autocomplete.md b/docs/extensibility/autocomplete.md index 914c35af5c2290..ee1f2bc945852e 100644 --- a/docs/extensibility/autocomplete.md +++ b/docs/extensibility/autocomplete.md @@ -1,13 +1,13 @@ Autocomplete ============ -Gutenberg provides a `blocks.Autocomplete.completers` filter for extending and overriding the list of autocompleters used by blocks. +Gutenberg provides a `editor.Autocomplete.completers` filter for extending and overriding the list of autocompleters used by blocks. The `Autocomplete` component found in `@wordpress/editor` applies this filter. The `@wordpress/components` package provides the foundational `Autocomplete` component that does not apply such a filter, but blocks should generally use the component provided by `@wordpress/editor`. ### Example -Here is an example of using the `blocks.Autocomplete.completers` filter to add an acronym completer. You can find full documentation for the autocompleter interface with the `Autocomplete` component in the `@wordpress/components` package. +Here is an example of using the `editor.Autocomplete.completers` filter to add an acronym completer. You can find full documentation for the autocompleter interface with the `Autocomplete` component in the `@wordpress/components` package. {% codetabs %} {% ES5 %} @@ -46,7 +46,7 @@ function appendAcronymCompleter( completers, blockName ) { // Adding the filter wp.hooks.addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'my-plugin/autocompleters/acronyms', appendAcronymCompleter ); @@ -81,7 +81,7 @@ function appendAcronymCompleter( completers, blockName ) { // Adding the filter wp.hooks.addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'my-plugin/autocompleters/acronym', appendAcronymCompleter ); diff --git a/docs/extensibility/extending-blocks.md b/docs/extensibility/extending-blocks.md index c0579171bf3af6..8447aaed5cb7e4 100644 --- a/docs/extensibility/extending-blocks.md +++ b/docs/extensibility/extending-blocks.md @@ -10,10 +10,6 @@ To modify the behavior of existing blocks, Gutenberg exposes the following Filte Used to filter the block settings. It receives the block settings and the name of the block the registered block as arguments. -#### `blocks.BlockEdit` - -Used to modify the block's `edit` component. It receives the original block `edit` component and returns a new wrapped component. - #### `blocks.getSaveElement` A filter that applies to the result of a block's `save` function. This filter is used to replace or extend the element, for example using `wp.element.cloneElement` to modify the element's props or replace its children, or returning an entirely new element. @@ -70,6 +66,75 @@ Used internally by the default block (paragraph) to exclude the attributes from Used to filters an individual transform result from block transformation. All of the original blocks are passed, since transformations are many-to-many, not one-to-one. +#### `editor.BlockEdit` + +Used to modify the block's `edit` component. It receives the original block `BlockEdit` component and returns a new wrapped component. + +_Example:_ + +```js +var el = wp.element.createElement; + +var withInspectorControls = wp.element.createHigherOrderComponent( function( BlockEdit ) { + return function( props ) { + return el( + wp.element.Fragment, + {}, + el( + BlockEdit, + props + ), + el( + wp.editor.InspectorControls, + {}, + el( + wp.components.PanelBody, + {}, + 'My custom control' + ) + ) + ); + }; +}, 'withInspectorControls' ); + +wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); +``` + +#### `editor.BlockListBlock` + +Used to modify the block's wrapper component containing the block's `edit` component and all toolbars. It receives the original `BlockListBlock` component and returns a new wrapped component. + +_Example:_ + +```js +var el = wp.element.createElement; + +var withDataAlign = wp.element.createHigherOrderComponent( function( BlockListBlock ) { + return function( props ) { + var newProps = Object.assign( + {}, + props, + { + wrapperProps: Object.assign( + {}, + props.wrapperProps, + { + 'data-align': props.block.attributes.align + } + ) + } + ); + + return el( + BlockListBlock, + newProps + ); + }; +}, 'withAlign' ); + +wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-data-align', withDataAlign ); +``` + ## Removing Blocks ### Using a blacklist diff --git a/docs/reference/deprecated.md b/docs/reference/deprecated.md index 6d0a7505e7b9c3..653a9f3e62267d 100644 --- a/docs/reference/deprecated.md +++ b/docs/reference/deprecated.md @@ -4,15 +4,19 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo - `useOnce: true` has been removed from the Block API. Please use `supports.multiple: false` instead. - Serializing components using `componentWillMount` lifecycle method. Please use the constructor instead. + - `blocks.Autocomplete.completers` filter removed. Please use `editor.Autocomplete.completers` instead. + - `blocks.BlockEdit` filter removed. Please use `editor.BlockEdit` instead. + - `blocks.BlockListBlock` filter removed. Please use `editor.BlockListBlock` instead. + - `blocks.MediaUpload` filter removed. Please use `editor.MediaUpload` instead. ## 3.2.0 - `wp.data.withRehydratation` has been renamed to `wp.data.withRehydration`. - The `wp.editor.ImagePlaceholder` component is removed. Please use `wp.editor.MediaPlaceholder` instead. - `wp.utils.deprecated` function removed. Please use `wp.deprecated` instead. -- `getInserterItems`: the `allowedBlockTypes` argument was removed and the `parentUID` argument was added. -- `getFrecentInserterItems` selector removed. Please use `getInserterItems` instead. -- `getSupportedBlocks` selector removed. Please use `canInsertBlockType` instead. + - `getInserterItems`: the `allowedBlockTypes` argument was removed and the `parentUID` argument was added. + - `getFrecentInserterItems` selector removed. Please use `getInserterItems` instead. + - `getSupportedBlocks` selector removed. Please use `canInsertBlockType` instead. ## 3.1.0 @@ -24,18 +28,18 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo ## 3.0.0 -- `wp.blocks.registerCoreBlocks` function removed. Please use `wp.coreBlocks.registerCoreBlocks` instead. -- Raw TinyMCE event handlers for `RichText` have been deprecated. Please use [documented props](https://wordpress.org/gutenberg/handbook/block-api/rich-text-api/), ancestor event handler, or onSetup access to the internal editor instance event hub instead. + - `wp.blocks.registerCoreBlocks` function removed. Please use `wp.coreBlocks.registerCoreBlocks` instead. + - Raw TinyMCE event handlers for `RichText` have been deprecated. Please use [documented props](https://wordpress.org/gutenberg/handbook/block-api/rich-text-api/), ancestor event handler, or onSetup access to the internal editor instance event hub instead. ## 2.8.0 -- `Original autocompleter interface in wp.components.Autocomplete` updated. Please use `latest autocompleter interface` instead. See: https://github.com/WordPress/gutenberg/blob/master/components/autocomplete/README.md. -- `getInserterItems`: the `allowedBlockTypes` argument is now mandatory. -- `getFrecentInserterItems`: the `allowedBlockTypes` argument is now mandatory. + - `Original autocompleter interface in wp.components.Autocomplete` updated. Please use `latest autocompleter interface` instead. See: https://github.com/WordPress/gutenberg/blob/master/components/autocomplete/README.md. + - `getInserterItems`: the `allowedBlockTypes` argument is now mandatory. + - `getFrecentInserterItems`: the `allowedBlockTypes` argument is now mandatory. ## 2.7.0 -- `wp.element.getWrapperDisplayName` function removed. Please use `wp.element.createHigherOrderComponent` instead. + - `wp.element.getWrapperDisplayName` function removed. Please use `wp.element.createHigherOrderComponent` instead. ## 2.6.0 diff --git a/edit-post/hooks/blocks/index.js b/edit-post/hooks/components/index.js similarity index 73% rename from edit-post/hooks/blocks/index.js rename to edit-post/hooks/components/index.js index 35b318203784e7..20f16a7461def2 100644 --- a/edit-post/hooks/blocks/index.js +++ b/edit-post/hooks/components/index.js @@ -11,7 +11,7 @@ import MediaUpload from './media-upload'; const replaceMediaUpload = () => MediaUpload; addFilter( - 'blocks.MediaUpload', - 'core/edit-post/blocks/media-upload/replaceMediaUpload', + 'editor.MediaUpload', + 'core/edit-post/components/media-upload/replace-media-upload', replaceMediaUpload ); diff --git a/edit-post/hooks/blocks/media-upload/index.js b/edit-post/hooks/components/media-upload/index.js similarity index 100% rename from edit-post/hooks/blocks/media-upload/index.js rename to edit-post/hooks/components/media-upload/index.js diff --git a/edit-post/hooks/index.js b/edit-post/hooks/index.js index 91d683b62ae75b..ef9c274541dae3 100644 --- a/edit-post/hooks/index.js +++ b/edit-post/hooks/index.js @@ -1,6 +1,6 @@ /** * Internal dependencies */ -import './blocks'; +import './components'; import './more-menu'; import './validate-multiple-use'; diff --git a/edit-post/hooks/validate-multiple-use/index.js b/edit-post/hooks/validate-multiple-use/index.js index 388c03bce94f9b..db5b848e3e931e 100644 --- a/edit-post/hooks/validate-multiple-use/index.js +++ b/edit-post/hooks/validate-multiple-use/index.js @@ -125,7 +125,7 @@ function getOutboundType( blockName ) { } addFilter( - 'blocks.BlockEdit', - 'core/validation/multiple', + 'editor.BlockEdit', + 'core/edit-post/validate-multiple-use/with-multiple-validation', withMultipleValidation ); diff --git a/editor/components/autocomplete/README.md b/editor/components/autocomplete/README.md index bf3b564d3cb8e8..46fff1bd72b35c 100644 --- a/editor/components/autocomplete/README.md +++ b/editor/components/autocomplete/README.md @@ -1,6 +1,6 @@ Autocomplete ============ -This is an Autocomplete component for use in block UI. It is based on `Autocomplete` from `@wordpress/components` and takes the same props. In addition, it passes its autocompleters through a `blocks.Autocomplete.completers` filter to give developers an opportunity to override or extend them. +This is an Autocomplete component for use in block UI. It is based on `Autocomplete` from `@wordpress/components` and takes the same props. In addition, it passes its autocompleters through a `editor.Autocomplete.completers` filter to give developers an opportunity to override or extend them. The autocompleter interface is documented with the original `Autocomplete` component in `@wordpress/components`. diff --git a/editor/components/autocomplete/index.js b/editor/components/autocomplete/index.js index ea9f37ea639381..1a9c66f26597c1 100644 --- a/editor/components/autocomplete/index.js +++ b/editor/components/autocomplete/index.js @@ -78,10 +78,9 @@ export function withFilteredAutocompleters( Autocomplete ) { let nextCompleters = completers; const lastFilteredCompletersProp = nextCompleters; - // Todo: Rename filter - if ( hasFilter( 'blocks.Autocomplete.completers' ) ) { + if ( hasFilter( 'editor.Autocomplete.completers' ) ) { nextCompleters = applyFilters( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', // Provide copies so filters may directly modify them. nextCompleters && nextCompleters.map( clone ), blockName, diff --git a/editor/components/autocomplete/test/index.js b/editor/components/autocomplete/test/index.js index 91b9d442e9532c..bd6e217a27da4f 100644 --- a/editor/components/autocomplete/test/index.js +++ b/editor/components/autocomplete/test/index.js @@ -23,7 +23,7 @@ describe( 'Autocomplete', () => { let wrapper = null; afterEach( () => { - removeFilter( 'blocks.Autocomplete.completers', 'test/autocompleters-hook' ); + removeFilter( 'editor.Autocomplete.completers', 'test/autocompleters-hook' ); if ( wrapper ) { wrapper.unmount(); @@ -34,7 +34,7 @@ describe( 'Autocomplete', () => { it( 'filters supplied completers when next focused', () => { const completersFilter = jest.fn(); addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'test/autocompleters-hook', completersFilter ); @@ -55,7 +55,7 @@ describe( 'Autocomplete', () => { const completersFilter = jest.fn(); addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'test/autocompleters-hook', completersFilter ); @@ -70,7 +70,7 @@ describe( 'Autocomplete', () => { it( 'provides copies of completers to filter', () => { const completersFilter = jest.fn(); addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'test/autocompleters-hook', completersFilter ); @@ -91,7 +91,7 @@ describe( 'Autocomplete', () => { const expectedFilteredCompleters = [ {}, {} ]; const completersFilter = jest.fn( () => expectedFilteredCompleters ); addFilter( - 'blocks.Autocomplete.completers', + 'editor.Autocomplete.completers', 'test/autocompleters-hook', completersFilter ); diff --git a/editor/components/block-edit/edit.js b/editor/components/block-edit/edit.js index 9b20a0d286b885..4deaa389581be3 100644 --- a/editor/components/block-edit/edit.js +++ b/editor/components/block-edit/edit.js @@ -36,4 +36,4 @@ export const Edit = ( props ) => { ); }; -export default withFilters( 'blocks.BlockEdit' )( Edit ); +export default withFilters( 'editor.BlockEdit' )( Edit ); diff --git a/editor/components/media-upload/README.md b/editor/components/media-upload/README.md index ce9a7485354469..d54dccb4d699d0 100644 --- a/editor/components/media-upload/README.md +++ b/editor/components/media-upload/README.md @@ -14,8 +14,8 @@ import MediaUpload from './media-upload'; const replaceMediaUpload = () => MediaUpload; addFilter( - 'blocks.MediaUpload', - 'core/edit-post/blocks/media-upload/replaceMediaUpload', + 'editor.MediaUpload', + 'core/edit-post/components/media-upload/replace-media-upload', replaceMediaUpload ); ``` diff --git a/editor/components/media-upload/index.js b/editor/components/media-upload/index.js index 9485a0c8566182..38743329f818ff 100644 --- a/editor/components/media-upload/index.js +++ b/editor/components/media-upload/index.js @@ -6,11 +6,11 @@ import { withFilters } from '@wordpress/components'; /** * This is a placeholder for the media upload component necessary to make it possible to provide * an integration with the core blocks that handle media files. By default it renders nothing but - * it provides a way to have it overridden with the `blocks.MediaUpload` filter. + * it provides a way to have it overridden with the `editor.MediaUpload` filter. * * @return {WPElement} Media upload element. */ const MediaUpload = () => null; // Todo: rename the filter -export default withFilters( 'blocks.MediaUpload' )( MediaUpload ); +export default withFilters( 'editor.MediaUpload' )( MediaUpload ); diff --git a/editor/hooks/align.js b/editor/hooks/align.js index 4341d5a9299eac..a516fe54f652e3 100644 --- a/editor/hooks/align.js +++ b/editor/hooks/align.js @@ -97,7 +97,7 @@ export const withToolbarControls = createHigherOrderComponent( ( BlockEdit ) => * @param {Function} BlockListBlock Original component * @return {Function} Wrapped component */ -export const withAlign = createHigherOrderComponent( ( BlockListBlock ) => { +export const withDataAlign = createHigherOrderComponent( ( BlockListBlock ) => { return ( props ) => { const { align } = props.block.attributes; const validAlignments = getBlockValidAlignments( props.block.name ); @@ -109,7 +109,7 @@ export const withAlign = createHigherOrderComponent( ( BlockListBlock ) => { return ; }; -}, 'withAlign' ); +}, 'withDataAlign' ); /** * Override props assigned to save component to inject alignment class name if @@ -131,7 +131,7 @@ export function addAssignedAlign( props, blockType, attributes ) { } addFilter( 'blocks.registerBlockType', 'core/align/addAttribute', addAttribute ); -addFilter( 'editor.BlockListBlock', 'core/align/withAlign', withAlign ); -addFilter( 'blocks.BlockEdit', 'core/align/withToolbarControls', withToolbarControls ); +addFilter( 'editor.BlockListBlock', 'core/editor/align/with-data-align', withDataAlign ); +addFilter( 'editor.BlockEdit', 'core/editor/align/with-toolbar-controls', withToolbarControls ); addFilter( 'blocks.getSaveContent.extraProps', 'core/align/addAssignedAlign', addAssignedAlign ); diff --git a/editor/hooks/anchor.js b/editor/hooks/anchor.js index 2eb54e44aeb9d6..67f0b4298838fc 100644 --- a/editor/hooks/anchor.js +++ b/editor/hooks/anchor.js @@ -104,5 +104,5 @@ export function addSaveProps( extraProps, blockType, attributes ) { } addFilter( 'blocks.registerBlockType', 'core/anchor/attribute', addAttribute ); -addFilter( 'blocks.BlockEdit', 'core/anchor/inspector-control', withInspectorControl ); +addFilter( 'editor.BlockEdit', 'core/editor/anchor/with-inspector-control', withInspectorControl ); addFilter( 'blocks.getSaveContent.extraProps', 'core/anchor/save-props', addSaveProps ); diff --git a/editor/hooks/custom-class-name.js b/editor/hooks/custom-class-name.js index 86bf4e45a39187..9d94b40e653985 100644 --- a/editor/hooks/custom-class-name.js +++ b/editor/hooks/custom-class-name.js @@ -94,5 +94,5 @@ export function addSaveProps( extraProps, blockType, attributes ) { } addFilter( 'blocks.registerBlockType', 'core/custom-class-name/attribute', addAttribute ); -addFilter( 'blocks.BlockEdit', 'core/custom-class-name/inspector-control', withInspectorControl ); +addFilter( 'editor.BlockEdit', 'core/editor/custom-class-name/with-inspector-control', withInspectorControl ); addFilter( 'blocks.getSaveContent.extraProps', 'core/custom-class-name/save-props', addSaveProps ); diff --git a/editor/hooks/default-autocompleters.js b/editor/hooks/default-autocompleters.js index 5b4be9ca031d8d..7042b5b7b40a74 100644 --- a/editor/hooks/default-autocompleters.js +++ b/editor/hooks/default-autocompleters.js @@ -40,7 +40,7 @@ function setDefaultCompleters( completers, blockName ) { } addFilter( - 'blocks.Autocomplete.completers', - 'blocks/autocompleters/set-default-completers', + 'editor.Autocomplete.completers', + 'editor/autocompleters/set-default-completers', setDefaultCompleters ); diff --git a/editor/hooks/test/align.js b/editor/hooks/test/align.js index ea4c491d98c1d2..9c578a45742b2b 100644 --- a/editor/hooks/test/align.js +++ b/editor/hooks/test/align.js @@ -20,7 +20,7 @@ import { import { getBlockValidAlignments, withToolbarControls, - withAlign, + withDataAlign, addAssignedAlign, } from '../align'; @@ -150,7 +150,7 @@ describe( 'align', () => { } ); } ); - describe( 'withAlign', () => { + describe( 'withDataAlign', () => { it( 'should render with wrapper props', () => { registerBlockType( 'core/foo', { ...blockSettings, @@ -160,7 +160,7 @@ describe( 'align', () => { }, } ); - const EnhancedComponent = withAlign( ( { wrapperProps } ) => ( + const EnhancedComponent = withDataAlign( ( { wrapperProps } ) => (
) ); @@ -189,7 +189,7 @@ describe( 'align', () => { }, } ); - const EnhancedComponent = withAlign( ( { wrapperProps } ) => ( + const EnhancedComponent = withDataAlign( ( { wrapperProps } ) => (
) ); diff --git a/editor/hooks/test/default-autocompleters.js b/editor/hooks/test/default-autocompleters.js index 8afe8c43a6c4b9..c44f723a9efd5a 100644 --- a/editor/hooks/test/default-autocompleters.js +++ b/editor/hooks/test/default-autocompleters.js @@ -14,7 +14,7 @@ describe( 'default-autocompleters', () => { const defaultAutocompleters = [ userAutocompleter ]; it( 'provides default completers if none are provided', () => { - const result = applyFilters( 'blocks.Autocomplete.completers', null, BLOCK_NAME ); + const result = applyFilters( 'editor.Autocomplete.completers', null, BLOCK_NAME ); /* * Assert structural equality because defaults are provided as a * list of cloned completers (and not referentially equal). @@ -24,20 +24,20 @@ describe( 'default-autocompleters', () => { it( 'does not provide default completers for empty completer list', () => { const emptyList = []; - const result = applyFilters( 'blocks.Autocomplete.completers', emptyList, BLOCK_NAME ); + const result = applyFilters( 'editor.Autocomplete.completers', emptyList, BLOCK_NAME ); // Assert referential equality because the list should be unchanged. expect( result ).toBe( emptyList ); } ); it( 'does not provide default completers for a populated completer list', () => { const populatedList = [ {}, {} ]; - const result = applyFilters( 'blocks.Autocomplete.completers', populatedList, BLOCK_NAME ); + const result = applyFilters( 'editor.Autocomplete.completers', populatedList, BLOCK_NAME ); // Assert referential equality because the list should be unchanged. expect( result ).toBe( populatedList ); } ); it( 'provides copies of defaults so they may be directly modified', () => { - const result = applyFilters( 'blocks.Autocomplete.completers', null, BLOCK_NAME ); + const result = applyFilters( 'editor.Autocomplete.completers', null, BLOCK_NAME ); result.forEach( ( completer, i ) => { const defaultCompleter = defaultAutocompleters[ i ]; expect( completer ).not.toBe( defaultCompleter ); diff --git a/test/e2e/test-plugins/hooks-api/index.js b/test/e2e/test-plugins/hooks-api/index.js index 34cff1d758ad3f..eb45316565f386 100644 --- a/test/e2e/test-plugins/hooks-api/index.js +++ b/test/e2e/test-plugins/hooks-api/index.js @@ -53,7 +53,7 @@ } addFilter( - 'blocks.BlockEdit', + 'editor.BlockEdit', 'e2e/hooks-api/add-reset-block-button', addResetBlockButton, 100