Skip to content

Commit

Permalink
Interactivity API: Allow multiple event handlers for the same type wi…
Browse files Browse the repository at this point in the history
…th `data-wp-on-document` and `data-wp-on-window`. (#61009)

* Allow multiple handlers

* Add test in window events

* Move to only one pass

* Fix event deletion

* Add changelog and rename var

Co-authored-by: cbravobernal <[email protected]>
Co-authored-by: sirreal <[email protected]>
Co-authored-by: DAreRodz <[email protected]>
  • Loading branch information
4 people authored May 7, 2024
1 parent 36cb787 commit dc0ea2e
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@
<p data-wp-text="state.counter" data-testid="counter">0</p>
</div>
</div>
<div data-wp-on-document--keydown="actions.keydownHandler" data-wp-on-document--keydown--second="actions.keydownSecondHandler">
<p data-wp-text="state.keydownHandler" data-testid="keydownHandler">no</p>
<p data-wp-text="state.keydownSecondHandler" data-testid="keydownSecondHandler">no</p>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const { state } = store( 'directive-on-document', {
counter: 0,
isVisible: true,
isEventAttached: 'no',
keydownHandler: 'no',
keydownSecondHandler: 'no',
},
callbacks: {
keydownHandler() {
Expand All @@ -39,5 +41,11 @@ const { state } = store( 'directive-on-document', {
state.isEventAttached = 'no';
state.isVisible = ! state.isVisible;
},
keydownHandler: () => {
state.keydownHandler = 'yes';
},
keydownSecondHandler: () => {
state.keydownSecondHandler = 'yes';
}
}
} );
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@
<p data-wp-text="state.counter" data-testid="counter">0</p>
</div>
</div>
<div data-wp-on-window--resize="actions.resizeHandler" data-wp-on-window--resize--second="actions.resizeSecondHandler">
<p data-wp-text="state.resizeHandler" data-testid="resizeHandler">no</p>
<p data-wp-text="state.resizeSecondHandler" data-testid="resizeSecondHandler">no</p>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const { state } = store( 'directive-on-window', {
counter: 0,
isVisible: true,
isEventAttached: 'no',
resizeHandler: 'no',
resizeSecondHandler: 'no',
},
callbacks: {
resizeHandler() {
Expand All @@ -39,5 +41,11 @@ const { state } = store( 'directive-on-window', {
state.isEventAttached = 'no';
state.isVisible = ! state.isVisible;
},
resizeHandler: () => {
state.resizeHandler = 'yes';
},
resizeSecondHandler: () => {
state.resizeSecondHandler = 'yes';
}
}
} );
4 changes: 4 additions & 0 deletions packages/interactivity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Bug Fixes

- Allow multiple event handlers for the same type with `data-wp-on-document` and `data-wp-on-window`. ([#61009](https://github.com/WordPress/gutenberg/pull/61009))

## 5.6.0 (2024-05-02)

## 5.5.0 (2024-04-19)
Expand Down
12 changes: 6 additions & 6 deletions packages/interactivity/src/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,21 @@ const cssStringToObject = ( val ) => {
* @param {string} type 'window' or 'document'
* @return {void}
*/
const getGlobalEventDirective =
( type ) =>
( { directives, evaluate } ) => {
const getGlobalEventDirective = ( type ) => {
return ( { directives, evaluate } ) => {
directives[ `on-${ type }` ]
.filter( ( { suffix } ) => suffix !== 'default' )
.forEach( ( entry ) => {
const eventName = entry.suffix.split( '--', 1 )[ 0 ];
useInit( () => {
const cb = ( event ) => evaluate( entry, event );
const globalVar = type === 'window' ? window : document;
globalVar.addEventListener( entry.suffix, cb );
return () =>
globalVar.removeEventListener( entry.suffix, cb );
globalVar.addEventListener( eventName, cb );
return () => globalVar.removeEventListener( eventName, cb );
}, [] );
} );
};
};

export default () => {
// data-wp-context
Expand Down
21 changes: 21 additions & 0 deletions test/e2e/specs/interactivity/directive-on-document.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,25 @@ test.describe( 'data-wp-on-document', () => {
await page.keyboard.press( 'ArrowDown' );
await expect( counter ).toHaveText( '2' );
} );
test( 'should work with multiple event handlers on the same event type', async ( {
page,
} ) => {
const keydownHandler = page.getByTestId( 'keydownHandler' );
const keydownSecondHandler = page.getByTestId( 'keydownSecondHandler' );

// Initial value.
await expect( keydownHandler ).toHaveText( 'no' );
await expect( keydownSecondHandler ).toHaveText( 'no' );

// Make sure the event listener is attached.
await page
.getByTestId( 'isEventAttached' )
.filter( { hasText: 'yes' } )
.waitFor();

// This keyboard press should increase the counter.
await page.keyboard.press( 'ArrowDown' );
await expect( keydownHandler ).toHaveText( 'yes' );
await expect( keydownSecondHandler ).toHaveText( 'yes' );
} );
} );
21 changes: 21 additions & 0 deletions test/e2e/specs/interactivity/directive-on-window.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,25 @@ test.describe( 'data-wp-on-window', () => {
await page.setViewportSize( { width: 200, height: 600 } );
await expect( counter ).toHaveText( '2' );
} );
test( 'should work with multiple event handlers on the same event type', async ( {
page,
} ) => {
const resizeHandler = page.getByTestId( 'resizeHandler' );
const resizeSecondHandler = page.getByTestId( 'resizeSecondHandler' );

// Initial value.
await expect( resizeHandler ).toHaveText( 'no' );
await expect( resizeSecondHandler ).toHaveText( 'no' );

// Make sure the event listener is attached.
await page
.getByTestId( 'isEventAttached' )
.filter( { hasText: 'yes' } )
.waitFor();

// This keyboard press should increase the counter.
await page.setViewportSize( { width: 600, height: 600 } );
await expect( resizeHandler ).toHaveText( 'yes' );
await expect( resizeSecondHandler ).toHaveText( 'yes' );
} );
} );

0 comments on commit dc0ea2e

Please sign in to comment.