-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce withEvent
and require Interactivity API actions that use the event
object to use it
#64944
Comments
cc @luisherranz @gziolo @cbravobernal @DAreRodz @westonruter As touched on in the discussion, can we add this to #63232? |
I don't think this is quite right. Even if an action uses the Search blockgutenberg/packages/block-library/src/search/index.php Lines 194 to 195 in 537fb18
gutenberg/packages/block-library/src/search/view.js Lines 47 to 68 in 537fb18
Navigation block
gutenberg/packages/block-library/src/navigation/view.js Lines 141 to 160 in 537fb18
|
Actually, no error is emitted when So passing the proxied event should still be done so this warning can be emitted to the console. |
That's a good point. So it's not about whether the I think the main new question this raises is what a suitable more accurate name than Paging @luisherranz @gziolo @cbravobernal to get your thoughts on the name. |
I had a good chat with Felix about this today. Let's say that there is a A risk with Finally, it would also seem useful to pass a proxied |
@westonruter Thanks for the summary, that is in line with how I recall our conversation. A few minor notes:
Worth a reminder that this would only show deprecation warnings initially (i.e. this issue), and it would still call
I think the approach of only requiring |
The challenge is that document.querySelector( 'input.async' ).addEventListener( 'click', ( event ) => {
const target = event.currentTarget;
setTimeout( () => {
event.preventDefault();
console.info( 'Look ma, no error!' );
console.info( 'sync', target );
console.info( 'async', event.currentTarget );
} );
} );
I'm happy with the more specific name, and |
@gziolo Great points. This means we should keep an eye out for other Related idea (not a blocker for implementing this): Would it make sense for something like |
The event object has many interfaces. We would have to investigate it further, but it might be tricky to properly handle it on our end. To give a quick example eventPhase: document.querySelector( 'input.async' ).addEventListener( 'click', ( event ) => {
const sync = event.eventPhase;
setTimeout( () => {
event.preventDefault();
console.info( 'Look ma, no error!' );
console.info( 'sync', sync );
console.info( 'async', event.eventPhase );
} );
} ); This is a good example where it's expected that the event changes over time. There will be many similar things, for example when you use mouse events, when it becomes async, the cursor ( At the same time, the potential proxy object has enough to detect whether the sync execution has finished and show warnings for devs. Maybe it's enough to print some note that they are accessing the event in the async mode and leave a link to the docs with more details. |
Thanks for providing additional context. We should probably discard my previous idea then and not try to be smart about certain event properties. Warning about async access when that doesn't work is probably all we should do in the proxied event. |
@luisherranz @gziolo @cbravobernal Now that WP 6.7 is out, I'd love for us to move this forward, so that it can go in one of the next Gutenberg releases and, eventually, WordPress 6.8. This would be great as it's only the first part of a multi-step solution that requires multiple WordPress releases. Is that something one of you would be able to work on? If not, I would appreciate any guidance on where (some of) the relevant code lives, as I haven't touched any of it so far. So it would take me some onboarding, but I'd be happy to give it a stab if nobody beats me to it. :) Related: Is there already an Interactivity API overview issue for WP 6.8? Asking since this was initially in #63232, but we should probably move it now. |
Not yet. But we plan to open one this week or, at the latest, next week.
Absolutely 😄 Do we have an agreement on the final design and naming? Is the idea to make it work something like this? store( '...', {
actions: {
sync: withSyncEvent(event) => {
event.preventDefault();
// ...
},
async(event) {
// This is fine.
const value = event.target.value;
// This logs a warning during the deprecation phase
// and throws an error afterward.
event.preventDefault();
}
}
); |
@luisherranz That's exactly the plan I think, based on the previous conversation. I've just updated the issue description to include the iterations we discussed. |
@felixarntz, thank you for bringing it up again. It's definitely a great idea to put it as an action item on the Intereactivity iteration issue for WordPress 6.8. Looking at my current backlog of planned tasks, I can only offer help with reviews and testing. |
I plan to start exploring a PR this week. Any hints / recommendations for where in the code to look / any known quirks to consider would be much appreciated. |
Let me know if that's enough or if you need more details. |
This issue is the result of #64729. It is the first issue of a few sequential ones, with the goal to automatically run Interactivity API store actions asynchronously (i.e. after yielding to the main thread) whenever possible.
What problem does this address?
Currently, the decision whether to run an action asynchronously has to be made by the person using the action in a directive (by using e.g.
data-wp-on-async
instead ofdata-wp-on
). This is cumbersome, as that decision can be made purely based on the action implementation itself, independently of how it is used in a directive. The decision for whether an action should be run after yielding to the main thread should be handled by the action itself.Additionally, the concept of yielding to the main thread is still relatively new, and many developers are not too familiar with it. Leaving the decision up to developers will therefore likely not yield (pun intended) to much adoption. On the other hand, knowing whether the action uses the
event
object is a very simple thing that every JS developer should understand. And because yielding to the main thread is universally a good thing, for better performance it makes sense to automatically do that whenever possible (which is the case unless synchronous methods from theevent
objects are used in the action).What is your proposed solution?
Updated as of 2024-11-19:
A
withSyncEvent
helper should be introduced that should then be adopted by every Interactivity API store actions that use theevent
object in a way that requires synchronous access (e.g. to callevent.preventDefault()
). This will eventually allow to yield to the main thread automatically for every single action, unless the action useswithSyncEvent
.Since the latter is technically a breaking change, we'll need to first deprecate synchronous usage of
event
without usingwithSyncEvent
. We can do so by proxying theevent
object. If the action does not yet usewithSyncEvent
but calls one of the synchronousevent
methods, the event proxy object should trigger deprecation warnings.Code example for how
withEvent
could be used:See #64729 (reply in thread) for the original idea.
For reference, this would trigger a deprecation warning going forward, since
withSyncEvent
is not used even though the action usesevent
:Overall plan
withSyncEvent
and trigger deprecations when usingevent
without it (via proxiedevent
object). This is essentially to prepare the ecosystem for the async first change.withSyncEvent
. We can consider still passing the proxiedevent
object to other functions, but now the synchronous calls would simply fail with an error, so passing it would be mostly for better DX (more clear error messaging where code still does it wrong).data-wp-on-async
just the same asdata-wp-on
. In other words, there's no longer a reason to usedata-wp-on-async
.data-wp-on*
variants forwindow
anddocument
.data-wp-on-async
and itswindow
anddocument
equivalents.data-wp-on-async
should be removed (or at least clearly marked as outdated/deprecated).data-wp-on-async
(and the other async directives) entirely.This issue is only about the 1. step from the list above.
The text was updated successfully, but these errors were encountered: