diff --git a/package-lock.json b/package-lock.json index f34656290d3c11..d47d18f74e86c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14506,6 +14506,7 @@ "@wordpress/shortcode": "file:packages/shortcode", "@wordpress/token-list": "file:packages/token-list", "@wordpress/url": "file:packages/url", + "@wordpress/warning": "file:packages/warning", "@wordpress/wordcount": "file:packages/wordcount", "classnames": "^2.2.5", "css-mediaquery": "^0.1.2", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 24e94fdfde1472..09ccc735d40ccf 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -55,6 +55,7 @@ "@wordpress/shortcode": "file:../shortcode", "@wordpress/token-list": "file:../token-list", "@wordpress/url": "file:../url", + "@wordpress/warning": "file:../warning", "@wordpress/wordcount": "file:../wordcount", "classnames": "^2.2.5", "css-mediaquery": "^0.1.2", diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index b7449439e72348..22206740781962 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -14,6 +14,7 @@ import { } from '@wordpress/blocks'; import { useMergeRefs } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; +import warning from '@wordpress/warning'; /** * Internal dependencies @@ -65,6 +66,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { index, mode, name, + blockAPIVersion, blockTitle, isPartOfSelection, adjustScrolling, @@ -89,11 +91,13 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { isAncestorMultiSelected( clientId ); const blockName = getBlockName( clientId ); const rootClientId = getBlockRootClientId( clientId ); + const blockType = getBlockType( blockName ); return { index: getBlockIndex( clientId, rootClientId ), mode: getBlockMode( clientId ), name: blockName, - blockTitle: getBlockType( blockName ).title, + blockAPIVersion: blockType.apiVersion, + blockTitle: blockType.title, isPartOfSelection: isSelected || isPartOfMultiSelection, adjustScrolling: isSelected || isFirstMultiSelectedBlock( clientId ), @@ -128,6 +132,12 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { } ), ] ); + if ( blockAPIVersion < 2 ) { + warning( + `Block type "${ name }" must support API version 2 or higher to work correctly with "useBlockProps" method.` + ); + } + return { ...wrapperProps, ...props, diff --git a/packages/warning/CHANGELOG.md b/packages/warning/CHANGELOG.md index ead32191d7af7d..d27c63316f8d40 100644 --- a/packages/warning/CHANGELOG.md +++ b/packages/warning/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- Ensure that the warning for a given message is logged only once. + ## 2.1.0 (2021-05-20) ## 2.0.0 (2021-05-14) diff --git a/packages/warning/src/index.js b/packages/warning/src/index.js index f81c561c0aaee1..bd9ec6e5268f8f 100644 --- a/packages/warning/src/index.js +++ b/packages/warning/src/index.js @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ +import { logged } from './utils'; + function isDev() { return ( typeof process !== 'undefined' && @@ -28,6 +33,11 @@ export default function warning( message ) { return; } + // Skip if already logged. + if ( message in logged ) { + return; + } + // eslint-disable-next-line no-console console.warn( message ); @@ -39,4 +49,6 @@ export default function warning( message ) { } catch ( x ) { // do nothing } + + logged[ message ] = true; } diff --git a/packages/warning/src/test/index.js b/packages/warning/src/test/index.js index aa97a8c661b260..9c6756fef9780d 100644 --- a/packages/warning/src/test/index.js +++ b/packages/warning/src/test/index.js @@ -2,12 +2,16 @@ * Internal dependencies */ import warning from '..'; +import { logged } from '../utils'; const initialNodeEnv = process.env.NODE_ENV; describe( 'warning', () => { afterEach( () => { process.env.NODE_ENV = initialNodeEnv; + for ( const key in logged ) { + delete logged[ key ]; + } } ); it( 'logs to console.warn when NODE_ENV is not "production"', () => { @@ -21,4 +25,13 @@ describe( 'warning', () => { warning( 'warning' ); expect( console ).not.toHaveWarned(); } ); + + it( 'should show a message once', () => { + warning( 'warning' ); + warning( 'warning' ); + + expect( console ).toHaveWarned(); + // eslint-disable-next-line no-console + expect( console.warn ).toHaveBeenCalledTimes( 1 ); + } ); } ); diff --git a/packages/warning/src/utils.js b/packages/warning/src/utils.js new file mode 100644 index 00000000000000..e8cbee087606c2 --- /dev/null +++ b/packages/warning/src/utils.js @@ -0,0 +1,7 @@ +/** + * Object map tracking messages which have been logged, for use in ensuring a + * message is only logged once. + * + * @type {Record} + */ +export const logged = Object.create( null );