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`. (#60661)

* Allow multiple event handlers for the same type

* Add simple test

Co-authored-by: DAreRodz <darerodz@git.wordpress.org>
Co-authored-by: felixarntz <flixos90@git.wordpress.org>
Co-authored-by: luisherranz <luisherranz@git.wordpress.org>
  • Loading branch information
4 people authored and creativecoder committed May 1, 2024
1 parent 25c18ac commit 78859b1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,24 @@
data-wp-on--click="actions.clickHandler"
>Click me!</button>
</div>
<div data-wp-context='{"clicked":false,"clickCount":0,"isOpen":true}'>
<p
data-wp-text="context.clicked"
data-testid="multiple handlers clicked"
>false</p>
<p
data-wp-text="context.clickCount"
data-testid="multiple handlers clickCount"
>0</p>
<p
data-wp-text="context.isOpen"
data-testid="multiple handlers isOpen"
>true</p>
<button
data-testid="multiple handlers button"
data-wp-on--click="actions.setClicked"
data-wp-on--click--counter="actions.countClick"
data-wp-on--click--toggle="actions.toggle"
>Click me!</button>
</div>
</div>
12 changes: 12 additions & 0 deletions packages/e2e-tests/plugins/interactive-blocks/directive-on/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,17 @@ const { state } = store( 'directive-on', {
const context = getContext();
context.customEvents += 1;
},
setClicked: () => {
const context = getContext();
context.clicked = true;
},
countClick: () => {
const context = getContext();
context.clickCount += 1;
},
toggle: () => {
const context = getContext();
context.isOpen = ! context.isOpen;
},
},
} );
15 changes: 12 additions & 3 deletions packages/interactivity/src/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,22 @@ export default () => {

// data-wp-on--[event]
directive( 'on', ( { directives: { on }, element, evaluate } ) => {
const events = new Map();
on.filter( ( { suffix } ) => suffix !== 'default' ).forEach(
( entry ) => {
element.props[ `on${ entry.suffix }` ] = ( event ) => {
evaluate( entry, event );
};
const event = entry.suffix.split( '--' )[ 0 ];
if ( ! events.has( event ) ) events.set( event, new Set() );
events.get( event ).add( entry );
}
);

events.forEach( ( entries, eventType ) => {
element.props[ `on${ eventType }` ] = ( event ) => {
entries.forEach( ( entry ) => {
evaluate( entry, event );
} );
};
} );
} );

// data-wp-on-window--[event]
Expand Down
25 changes: 25 additions & 0 deletions test/e2e/specs/interactivity/directive-on.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,29 @@ test.describe( 'data-wp-on', () => {
.click( { clickCount: 3, delay: 100 } );
await expect( counter ).toHaveText( '3' );
} );

test( 'should work with multiple event handlers on the same event type', async ( {
page,
} ) => {
const button = page.getByTestId( 'multiple handlers button' );
const isOpen = page.getByTestId( 'multiple handlers isOpen' );
const clicked = page.getByTestId( 'multiple handlers clicked' );
const clickCount = page.getByTestId( 'multiple handlers clickCount' );

await expect( clicked ).toHaveText( 'false' );
await expect( clickCount ).toHaveText( '0' );
await expect( isOpen ).toHaveText( 'true' );

await button.click();

await expect( clicked ).toHaveText( 'true' );
await expect( clickCount ).toHaveText( '1' );
await expect( isOpen ).toHaveText( 'false' );

await button.click();

await expect( clicked ).toHaveText( 'true' );
await expect( clickCount ).toHaveText( '2' );
await expect( isOpen ).toHaveText( 'true' );
} );
} );

0 comments on commit 78859b1

Please sign in to comment.