Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 113 additions & 2 deletions dom.bs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,28 @@ urlPrefix: https://tc39.es/ecma262/#; spec: ECMASCRIPT
text: current realm; url: current-realm
text: realm; url: realm
text: surrounding agent; url: surrounding-agent
text: execution context stack; url: execution-context-stack
urlPrefix: https://w3c.github.io/hr-time/#; spec: HR-TIME
type:typedef; urlPrefix: dom-; text: DOMHighResTimeStamp
type:dfn; text: current high resolution time; url: dfn-current-high-resolution-time
type:dfn; text: relative high resolution coarse time; url: dfn-relative-high-resolution-coarse-time
urlPrefix: https://tc39.es/proposal-async-context/; spec: PROPOSAL-ASYNCCONTEXT
type: dfn; text: Async Context Mapping; url: async-context-mapping
type: abstract-op; text: AsyncContextSnapshot; url: sec-asynccontextsnapshot

# Link to HTML AsyncContext PR so the spec preview works
urlPrefix: https://whatpr.org/html/12152/infrastructure.html; spec: HTML
type: dfn; text: run; for: Async Context Mapping
</pre>

<pre class=biblio>
{
"PROPOSAL-ASYNCCONTEXT": {
"publisher": "Ecma",
"href": "https://tc39.es/proposal-async-context/",
"title": "AsyncContext"
}
}
</pre>

<pre class=link-defaults>
Expand Down Expand Up @@ -1073,6 +1091,15 @@ and a <dfn export for=EventTarget>legacy-canceled-activation behavior</dfn> algo
<p class=note>These algorithms only exist for checkbox and radio <{input}> elements and
are not to be used for anything else. [[!HTML]]

<p>Each {{EventTarget}} object has a <dfn for=EventTarget>preserved AsyncContext map</dfn>, which is
a <a>map</a> from strings representing event types to <a>Async Context Mappings</a>. This map is
initially empty. [[!PROPOSAL-ASYNCCONTEXT]]

<p class=note>This map is used to implement the [{{PropagatesAsyncContextToEvents}}] WebIDL extended
attribute. For simplicity, the map is defined on {{EventTarget}}, but it will always be empty unless
<a>this</a> implements an interface which either is annotated with this extended attribute or has a
regular operation annotated with it.

<dl class=domintro>
<dt><code><var>target</var> = new <a constructor for=EventTarget lt=EventTarget()>EventTarget</a>();</code>
<dd><p>Creates a new {{EventTarget}} object, which can be used by developers to <a>dispatch</a> and
Expand Down Expand Up @@ -1763,8 +1790,21 @@ initialized, and a <var>legacy target override flag</var>, run these steps:

<p class=note>This also allows for the {{Event/isTrusted}} attribute to be set to false.

<li><p>Return the result of <a>dispatching</a> <var>event</var> at <var>target</var>, with
<var>legacy target override flag</var> set if set.
<li><p>If the <a lt="execution context stack">JavaScript execution context stack</a> is empty, and
if (<var>target</var>'s <a for=EventTarget>preserved AsyncContext map</a>)[<var>e</var>]
<a for=map>exists</a>, then let <var>async context mapping</var> be (<var>target</var>'s
<a for=EventTarget>preserved AsyncContext map</a>)[<var>e</var>]. Otherwise, let <var>async context
mapping</var> be <a abstract-op>AsyncContextSnapshot</a>().

<li>
<p>Return the result of <a for="Async Context Mapping">running</a> the following steps with
<var>async context mapping</var>:

<ol>
<li><p>Return the result of <a>dispatching</a> <var>event</var> at <var>target</var>, with
<var>legacy target override flag</var> set if set.
</ol>
</li>
</ol>
</div>

Expand Down Expand Up @@ -1805,6 +1845,77 @@ that gave folks all the wrong ideas. <a>Events</a> do not represent or cause act
can only be used to influence an ongoing one.


<h3 id="propagates-async-context-to-events">The <dfn extended-attribute lt="PropagatesAsyncContextToEvents">[PropagatesAsyncContextToEvents]</dfn> extended attribute</h3>

<p>To enable integration with the TC39 AsyncContext proposal for events fired asynchronously as a
result of either a method call or the construction of an interface instance, we introduce the
[{{PropagatesAsyncContextToEvents}}] WebIDL [=extended attribute=]. [[!PROPOSAL-ASYNCCONTEXT]]

<p>The [{{PropagatesAsyncContextToEvents}}] extended attribute must take either a string or a list
of strings. It must only used on either an [=interface=] that inherits from {{EventTarget}}, or on a
[=regular operation=] declared on such an interface.

<p>Regular operations annotated with [{{PropagatesAsyncContextToEvents}}], as well as [=constructor
steps=] of an interface annotated with that extended attribute, must run the following steps in
place of the ones specified in their description:

<ol>
<li><p>If the [{{PropagatesAsyncContextToEvents}}] extended attribute takes a list of strings, let
<var>event types</var> be that list. Otherwise, the argument is a string; let <var>event
types</var> be a list containing that string.

<li>
<p>For each <var>event type</var> in <var>event types</var>, set (<a>this</a>'s
<a for=EventTarget>preserved AsyncContext map</a>)[<var>event type</var>] to
<a abstract-op>AsyncContextSnapshot</a>().

<p class=note>The return value of <a abstract-op>AsyncContextSnapshot</a>() will not change across
these invocations.
</li>

<li><p>Run the originally-specified steps for this regular operation. If the steps return a value
or throw an exception, return or throw it in turn.
</ol>

<p>Specifications should set this extended attribute on methods which start an async operation which
will eventually cause events to be fired on the instance on which the method was called.
<span class="non-normative">An example of this is the {{XMLHttpRequest}} and its
{{XMLHttpRequest/send}} method:</span> [[XHR]]

<pre highlight=idl>
[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
// ...
[PropagatesAsyncContextToEvents=("loadstart", "progress", "error", "load", "timeout", "loadend")] undefined send(optional (Document or XMLHttpRequestBodyInit)? body = null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would people feel about using AsyncContext.PropagatesToEvents as a naming pattern for the AsyncContext-related attributes, since there are multiple?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why wouldn't propagates: [...] be enough, if I might ask?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the question. This is about WebIDL, not some JS-exposed option.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough, apologies for the irrelevant question then 👋

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no similar namespacing in WebIDL extended attributes, and in fact extended attribute names currently can only be identifiers. But it seems like this could be changed without that much trouble, and without syntax conflicts.

// ...
};
</pre>

<p>Specifications should also set this extended attribute on interfaces which are only constructed
as a result of an operation which will eventually fire events on that instance.
<span class="non-normative">An example of this is {{IDBOpenDBRequest}}, instances of which can only
be created by the methods {{IDBFactory/open}} or {{IDBFactory/deleteDatabase}} of {{IDBFactory}},
both of which will result in events being fired on the returned {{IDBOpenDBRequest}} instance. Note
that here {{IDBFactory/open}} and {{IDBFactory/deleteDatabase}} are not annotated with any
AsyncContext-related extended attribute; only {{IDBOpenDBRequest}} is:</span> [[INDEXEDDB]]

<pre highlight=idl>
[Exposed=(Window,Worker)]
interface IDBFactory {
[NewObject] IDBOpenDBRequest open(DOMString name,
optional [EnforceRange] unsigned long long version);
[NewObject] IDBOpenDBRequest deleteDatabase(DOMString name);
// ...
};

[Exposed=(Window,Worker),
PropagatesAsyncContextToEvents=("success", "error", "blocked", "upgradeneeded")]
interface IDBOpenDBRequest : IDBRequest {
// ...
};
</pre>



<h2 id=aborting-ongoing-activities>Aborting ongoing activities</h2>

Expand Down