- From: Nicolò Ribaudo <notifications@github.com>
- Date: Wed, 04 Jun 2025 07:08:29 -0700
- To: whatwg/dom <dom@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/dom/issues/1378@github.com>
nicolo-ribaudo created an issue (whatwg/dom#1378) ### What problem are you trying to solve? ## Context For the web integration of the [AsyncContext](https://github.com/tc39/proposal-async-context) proposal, we are exploring the possibility of not propagating the context through async JS-caused events. However, we received feedback that it'd be highly desirable to propagate it for `load`/`error` event, as their listener is conceptually a continuation of whatever started the loading process. Events/addEventListener are not the best primitive for signaling completion of some operation, which would be best suited by promises. If we can untangle the "I want to continue do something when this intermediate operation completes" use case (e.g. `load`/`error`) from the "start this new operation when something happens", we can avoid pushing complexity needed by the first one onto the second. https://github.com/whatwg/dom/issues/1038 proposed a method to create a promise that gets resolved once a given event is fired. For example (ignore the name, I don't think it's settled and I just came up with one): ```javascript const img = new Image(); img.src = srcURL; img.addEventListener("load", () => { /* continue doing something with the image */ }); // --> const img = new Image(); img.src = srcURL; await img.eventPromise("load"); /* continue doing something with the image */ ``` One problem with that proposal, that is discussed in its comments, is that it does not work with `preventDefault` and `stopPropagation`, because they need to be called synchronously and thus before that the promise resolves. ### What solutions exist today? / ### How would you solve it? ## Proposal In many cases `stopPropagation`/`stopImmediatePropagation`/`preventDefault` are called unconditionally at the beginning of the event listener callback. For those cases, a declarative API would be enough. Assuming that `.waitFor("load")` would take the same options bags as `.addEventListener` (only disallowing `once`, I guess), then it would look like: ```js await button.eventPromise("click", { preventDefault: true }); ``` With the `.addEventListener` API, it would be: ```js button.addEventListener("click", e => { e.preventDefault(); // do stuff }); // --> button.addEventListener("click", e => { // do stuff }, { preventDefault: true }); ``` I'm opening this as a separate issue from https://github.com/whatwg/dom/issues/1038 just because it would also apply to the non-promise API. It's most useful for the promise-based one, but in general it's nice to have declarative alternative to imperative ones. I'd be curious to know if it'd be helpful for implementations to know that an event is going to be prevented/stopped before calling the callback. ### Anything else? cc @annevk -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/dom/issues/1378 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/dom/issues/1378@github.com>
Received on Wednesday, 4 June 2025 14:08:33 UTC