diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 4e0dbdce40e7d..0b070a6d3c0db 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -1,3 +1,9 @@ +## Master + +### New Feature + +- Enable support for the 'all' hook in non production environments. + ## 2.0.4 (2019-01-03) ## 2.0.0 (2018-09-05) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index be0148f3747a0..952931c393bd1 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -52,4 +52,8 @@ Whenever an action or filter is added or removed, a matching `hookAdded` or `hoo * `hookAdded` action is triggered when `addFilter()` or `addAction()` method is called, passing values for `hookName`, `functionName`, `callback` and `priority`. * `hookRemoved` action is triggered when `removeFilter()` or `removeAction()` method is called, passing values for `hookName` and `functionName`. +### The `all` hook + +In non-minified builds developers can register a filter or action that will be called on *all* hooks, for example: `addAction( 'all', 'namespace', callbackFunction );`. Useful for debugging, the code supporting the `all` hook is stripped from the production code for performance reasons. +

Code is Poetry.

diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 66baaaa3e208c..d9c909b734af7 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -30,6 +30,14 @@ function createRunHook( hooks, returnFirstArg ) { const handlers = hooks[ hookName ].handlers; + // The following code is stripped from production builds. + if ( 'production' !== process.env.NODE_ENV ) { + // Handle any 'all' hooks registered. + if ( 'hookAdded' !== hookName && hooks.all ) { + handlers.push( ...hooks.all.handlers ); + } + } + if ( ! handlers || ! handlers.length ) { return returnFirstArg ? args[ 0 ] : diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index a31a0d2d113ce..20f27a30b9ae3 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -77,6 +77,7 @@ beforeEach( () => { delete hooks[ k ]; } + delete hooks.all; } ); } ); @@ -697,3 +698,47 @@ test( 'removing a filter triggers a hookRemoved action passing all callback deta 'my_callback3' ); } ); + +test( 'add an all filter and run it any hook to trigger it', () => { + addFilter( 'all', 'my_callback', filterA ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); + expect( applyFilters( 'test.filter-anything', 'test' ) ).toBe( 'testa' ); +} ); + +test( 'add an all action and run it any hook to trigger it', () => { + addAction( 'all', 'my_callback', actionA ); + addAction( 'test.action', 'my_callback', actionA );// Doesn't get triggered. + doAction( 'test.action-anything' ); + expect( window.actionValue ).toBe( 'a' ); +} ); + +test( 'add multiple all filters and run it any hook to trigger them', () => { + addFilter( 'all', 'my_callback', filterA ); + addFilter( 'all', 'my_callback', filterB ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + expect( applyFilters( 'test.filter-anything', 'test' ) ).toBe( 'testab' ); +} ); + +test( 'add multiple all actions and run it any hook to trigger them', () => { + addAction( 'all', 'my_callback', actionA ); + addAction( 'all', 'my_callback', actionB ); + addAction( 'test.action', 'my_callback', actionA ); // Doesn't get triggered. + doAction( 'test.action-anything' ); + expect( window.actionValue ).toBe( 'ab' ); +} ); + +test( 'add multiple all filters and run it any hook to trigger them by priority', () => { + addFilter( 'all', 'my_callback', filterA, 11 ); + addFilter( 'all', 'my_callback', filterB, 10 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testba' ); + expect( applyFilters( 'test.filter-anything', 'test' ) ).toBe( 'testba' ); +} ); + +test( 'add multiple all actions and run it any hook to trigger them by priority', () => { + addAction( 'all', 'my_callback', actionA, 11 ); + addAction( 'all', 'my_callback', actionB, 10 ); + addAction( 'test.action', 'my_callback', actionA ); // Doesn't get triggered. + doAction( 'test.action-anything' ); + expect( window.actionValue ).toBe( 'ba' ); +} ); +