@@ -2540,8 +2540,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
2540
2540
<dfn data-x="map value" data-x-href="https://infra.spec.whatwg.org/#map-value">value</dfn>,
2541
2541
<dfn data-x="map entry" data-x-href="https://infra.spec.whatwg.org/#map-entry">entry</dfn>,
2542
2542
<dfn data-x="map exists" data-x-href="https://infra.spec.whatwg.org/#map-exists">exists</dfn>,
2543
- <dfn data-x="map get" data-x-href="https://infra.spec.whatwg.org/#map-get">getting the value of an entry</dfn>, and
2544
- <dfn data-x="map set" data-x-href="https://infra.spec.whatwg.org/#map-set">setting the value of an entry</dfn></li>
2543
+ <dfn data-x="map get" data-x-href="https://infra.spec.whatwg.org/#map-get">getting the value of an entry</dfn>,
2544
+ <dfn data-x="map set" data-x-href="https://infra.spec.whatwg.org/#map-set">setting the value of an entry</dfn>,
2545
+ <dfn data-x="map remove" data-x-href="https://infra.spec.whatwg.org/#map-remove">removing an entry</dfn>, and
2546
+ <dfn data-x="map iterate" data-x-href="https://infra.spec.whatwg.org/#map-iterate">iterate</dfn></li>
2545
2547
<li>The <dfn data-x-href="https://infra.spec.whatwg.org/#list">list</dfn> data structure and the associated definitions for
2546
2548
<dfn data-x="list append" data-x-href="https://infra.spec.whatwg.org/#list-append">append</dfn>,
2547
2549
<dfn data-x="list replace" data-x-href="https://infra.spec.whatwg.org/#list-remove">replace</dfn>,
@@ -26206,9 +26208,9 @@ img.decode().then(() => {
26206
26208
<div class="example">
26207
26209
<p>Because the <code data-x="dom-img-decode">decode()</code> method attempts to ensure that the
26208
26210
decoded image data is available for at least one frame, it can be combined with the <code
26209
- data-x="dom-window -requestAnimationFrame">requestAnimationFrame()</code> API. This means it can
26210
- be used with coding styles or frameworks that ensure that all DOM modifications are batched
26211
- together as <span data-x="list of animation frame callbacks">animation frame
26211
+ data-x="dom-AnimationFrameProvider -requestAnimationFrame">requestAnimationFrame()</code> API.
26212
+ This means it can be used with coding styles or frameworks that ensure that all DOM modifications
26213
+ are batched together as <span data-x="map of animation frame callbacks">animation frame
26212
26214
callbacks</span>:</p>
26213
26215
26214
26216
<pre><code class="js" data-x="">const container = document.querySelector("#container");
@@ -65456,7 +65458,8 @@ interface <dfn>OffscreenCanvasRenderingContext2D</dfn> {
65456
65458
<p>Copies the rendering context's <span data-x="offscreencontext2d-bitmap">bitmap</span> to
65457
65459
the bitmap of the <span data-x="offscreencanvas-placeholder">placeholder <code>canvas</code>
65458
65460
element</span> of the <span>associated <code>OffscreenCanvas</code> object</span>. The copy
65459
- operation is asynchronous.</p>
65461
+ operation is synchronous. Calling this method is not needed for the transfer, since it happens
65462
+ automatically during the <span>event loop</span> execution.</p>
65460
65463
</dd>
65461
65464
65462
65465
<dt><var>offscreenCanvas</var> = <var>offscreenCanvasRenderingContext2D</var> . <code subdfn
@@ -78159,15 +78162,10 @@ interface <dfn data-export="" data-dfn-type="interface">Window</dfn> : <span>Eve
78159
78162
DOMString? <span data-x="dom-prompt">prompt</span>(optional DOMString message = "", optional DOMString default = "");
78160
78163
void <span data-x="dom-print">print</span>();
78161
78164
78162
- unsigned long <span data-x="dom-window-requestAnimationFrame">requestAnimationFrame</span>(<span>FrameRequestCallback</span> callback);
78163
- void <span data-x="dom-window-cancelAnimationFrame">cancelAnimationFrame</span>(unsigned long handle);
78164
-
78165
78165
void <span data-x="dom-window-postMessage">postMessage</span>(any message, USVString targetOrigin, optional sequence<<span data-x="idl-object">object</span>> transfer = []);
78166
78166
};
78167
78167
<span>Window</span> includes <span>GlobalEventHandlers</span>;
78168
- <span>Window</span> includes <span>WindowEventHandlers</span>;
78169
-
78170
- callback <dfn>FrameRequestCallback</dfn> = void (<span>DOMHighResTimeStamp</span> time);</code></pre>
78168
+ <span>Window</span> includes <span>WindowEventHandlers</span>;</code></pre>
78171
78169
78172
78170
<!-- for more features to add here, look here:
78173
78171
http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_window.asp
@@ -89119,7 +89117,7 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
89119
89117
<li><p><i>Unnecessary rendering</i>: If there are <span data-x="browsing context">browsing
89120
89118
contexts</span> <var>browsingContexts</var> for which the user agent believes updating the
89121
89119
rendering would have no visible effect and which possess no <code>Document</code> objects with
89122
- a non-empty <span>list of animation frame callbacks</span>, then remove from <var>docs</var>
89120
+ a non-empty <span>map of animation frame callbacks</span>, then remove from <var>docs</var>
89123
89121
all <code>Document</code> objects whose <span data-x="concept-document-bc">browsing
89124
89122
context</span> is in <var>browsingContexts</var>. Invoke the <span>mark paint timing</span>
89125
89123
algorithm for each <code>Document</code> object removed.</p></li>
@@ -89186,13 +89184,40 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
89186
89184
</ol>
89187
89185
</li>
89188
89186
89189
- <li><p>If this is a <a href="#workers">worker</a> <span>event loop</span> (i.e. one running for a
89190
- <code>WorkerGlobalScope</code>), but there are no <span data-x="concept-task">tasks</span> in the
89191
- <span>event loop</span>'s <span data-x="task queue">task queues</span> and the
89192
- <code>WorkerGlobalScope</code> object's <span
89193
- data-x="dom-WorkerGlobalScope-closing">closing</span> flag is true, then destroy the <span>event
89194
- loop</span>, aborting these steps, resuming the <span>run a worker</span> steps described in the
89195
- <a href="#workers">Web workers</a> section below.</p></li>
89187
+ <li>
89188
+ <p>If this is a <a href="#workers">worker</a> <span>event loop</span> (i.e., one running for
89189
+ a <code>WorkerGlobalScope</code>):</p>
89190
+
89191
+ <ol>
89192
+ <li>
89193
+ <p>If this is a <span data-x="concept-AnimationFrameProvider-supported">supported</span>
89194
+ <code>DedicatedWorkerGlobalScope</code> and the user agent believes that it would benefit from
89195
+ having its rendering updated at this time, then:</p>
89196
+
89197
+ <ol>
89198
+ <li><p>Let <var>now</var> be the <span>current high resolution time</span>. <ref
89199
+ spec=HRT></p></li>
89200
+
89201
+ <li><p><span>Run the animation frame callbacks</span> for that
89202
+ <code>DedicatedWorkerGlobalScope</code>, passing in <var>now</var> as the
89203
+ timestamp.</p></li>
89204
+
89205
+ <li><p>Update the rendering of that dedicated worker to reflect the current state.</p></li>
89206
+ </ol>
89207
+
89208
+ <p class="note">Similar to the notes for <span data-x="update the rendering">updating the
89209
+ rendering</span> in a <span>browsing context</span> <span>event loop</span>, a user agent can
89210
+ determine the rate of rendering in the dedicated worker.</p>
89211
+ </li>
89212
+
89213
+ <li><p>If there are no <span data-x="concept-task">tasks</span> in the <span>event
89214
+ loop</span>'s <span data-x="task queue">task queues</span> and the
89215
+ <code>WorkerGlobalScope</code> object's <span
89216
+ data-x="dom-WorkerGlobalScope-closing">closing</span> flag is true, then destroy the
89217
+ <span>event loop</span>, aborting these steps, resuming the <span>run a worker</span> steps
89218
+ described in the <a href="#workers">Web workers</a> section below.</p></li>
89219
+ </ol>
89220
+ </li>
89196
89221
</ol>
89197
89222
89198
89223
<hr>
@@ -91586,10 +91611,10 @@ scheduleWork(); // queues a task to do lots of work</code></pre>
91586
91611
<p>Authors ought to be aware that scheduling a lot of microtasks has the same performance
91587
91612
downsides as running a lot of synchronous code. Both will prevent the browser from doing its own
91588
91613
work, such as rendering or scrolling. In many cases, <code
91589
- data-x="dom-window -requestAnimationFrame">requestAnimationFrame()</code> or
91614
+ data-x="dom-AnimationFrameProvider -requestAnimationFrame">requestAnimationFrame()</code> or
91590
91615
<code>requestIdleCallback()</code> is a better choice. In particular, if the goal is to run code
91591
91616
before the next rendering cycle, that is the purpose of <code
91592
- data-x="dom-window -requestAnimationFrame">requestAnimationFrame()</code>.</p>
91617
+ data-x="dom-AnimationFrameProvider -requestAnimationFrame">requestAnimationFrame()</code>.</p>
91593
91618
91594
91619
<p>As can be seen from the following examples, the best way of thinking about <code
91595
91620
data-x="dom-queueMicrotask">queueMicrotask()</code> is as a mechanism for rearranging synchronous
@@ -93686,67 +93711,134 @@ loadMySprites().then(runDemo);</code></pre>
93686
93711
93687
93712
<h3>Animation frames</h3>
93688
93713
93689
- <p>Each <code>Document</code> has a <dfn>list of animation frame callbacks</dfn>, which must be
93690
- initially empty, and an <dfn>animation frame callback identifier</dfn>, which is a number which
93691
- must initially be zero.</p>
93714
+ <p>Some objects include the <code>AnimationFrameProvider</code> interface mixin.</p>
93692
93715
93693
- <p>When the <dfn><code
93694
- data-x="dom-window-requestAnimationFrame">requestAnimationFrame()</code></dfn> method is called,
93695
- the user agent must run the following steps:</p>
93716
+ <pre class="idl">callback <dfn>FrameRequestCallback</dfn> = void (<span>DOMHighResTimeStamp</span> time);
93696
93717
93697
- <ol>
93718
+ interface mixin <dfn>AnimationFrameProvider</dfn> {
93719
+ unsigned long <span data-x="dom-AnimationFrameProvider-requestAnimationFrame">requestAnimationFrame</span>(<span>FrameRequestCallback</span> callback);
93720
+ void <span data-x="AnimationFrameProvider-cancelAnimationFrame">cancelAnimationFrame</span>(unsigned long handle);
93721
+ };
93722
+ <span>Window</span> includes <span>AnimationFrameProvider</span>;
93723
+ <span>DedicatedWorkerGlobalScope</span> includes <span>AnimationFrameProvider</span>;</pre>
93698
93724
93699
- <li><p>Let <var>document</var> be this <code>Window</code> object's <span
93700
- data-x="concept-document-window">associated <code>Document</code></span>.</p></li>
93725
+ <p>Each <code>AnimationFrameProvider</code> object also has a <dfn
93726
+ data-x="concept-AnimationFrameProvider-target-object">target object</dfn> that stores the
93727
+ provider's internal state. It is defined as follows:</p>
93701
93728
93702
- <li><p>Increment <var>document</var>'s <span>animation frame callback identifier</span> by
93703
- one.</p></li>
93729
+ <dl>
93730
+ <dt>If the <code>AnimationFrameProvider</code> is a <code>Window</code></dt>
93731
+ <dd>The <code>Window</code>'s <span data-x="concept-document-window">associated
93732
+ <code>Document</code></span></dd>
93704
93733
93705
- <li><p>Append the method's argument to <var>document</var>'s <span>list of animation frame
93706
- callbacks</span>, associated with <var>document</var>'s <span>animation frame callback
93707
- identifier</span>'s current value.</p></li >
93734
+ <dt>If the <code>AnimationFrameProvider</code> is a <code>DedicatedWorkerGlobalScope</code></dt>
93735
+ <dd>The <code>DedicatedWorkerGlobalScope</code></dd>
93736
+ </dl >
93708
93737
93709
- <li><p>Return <var>document</var>'s <span>animation frame callback identifier</span>'s current
93710
- value.</p></li>
93738
+ <p>Each <span data-x="concept-AnimationFrameProvider-target-object">target object</span> has a
93739
+ <dfn id="list-of-animation-frame-callbacks">map of animation frame callbacks</dfn>, which is an
93740
+ <span>ordered map</span> that must be initially empty, and an <dfn>animation frame callback
93741
+ identifier</dfn>, which is a number that must initially be zero.</p>
93711
93742
93712
- </ol>
93743
+ <p>An <code>AnimationFrameProvider</code> <var>provider</var> is considered <dfn
93744
+ data-x="concept-AnimationFrameProvider-supported">supported</dfn> if any of the following
93745
+ hold:</p>
93713
93746
93714
- <p>When the <dfn><code
93715
- data-x="dom-window-cancelAnimationFrame">cancelAnimationFrame()</code></dfn> method is called,
93716
- the user agent must run the following steps:</p>
93747
+ <ul class="brief">
93748
+ <li><var>provider</var> is a <code>Window</code>.</li>
93749
+
93750
+ <li><var>provider</var>'s <span>owner set</span> <span data-x="list contains">contains</span> a
93751
+ <code>Document</code> object.</li>
93752
+
93753
+ <li>Any of the <code>DedicatedWorkerGlobalScope</code> objects in <var>provider</var>'s
93754
+ <span>owner set</span> are <span
93755
+ data-x="concept-AnimationFrameProvider-supported">supported</span>.</li>
93756
+ </ul>
93757
+
93758
+ <hr>
93759
+
93760
+ <p>The <dfn><code
93761
+ data-x="dom-AnimationFrameProvider-requestAnimationFrame">requestAnimationFrame(<var>callback</var>)</code></dfn>
93762
+ method must run the following steps:</p>
93717
93763
93718
93764
<ol>
93765
+ <li><p>If this <code>AnimationFrameProvider</code> is not <span
93766
+ data-x="concept-AnimationFrameProvider-supported">supported</span>, then throw a
93767
+ <span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
93719
93768
93720
- <li><p>Let <var>document</var> be this <code>Window</code> object's <span
93721
- data-x="concept-document-window">associated <code>Document</code></span>.</p></li>
93769
+ <li><p>Let <var>target</var> be this <code>AnimationFrameProvider</code>'s <span
93770
+ data-x="concept-AnimationFrameProvider-target-object">target object</span>.</p></li>
93771
+
93772
+ <li><p>Increment <var>target</var>'s <span>animation frame callback identifier</span> by
93773
+ one, and let <var>handle</var> be the result.</p></li>
93722
93774
93723
- <li><p>Find the entry in <var>document </var>'s <span>list of animation frame callbacks</span>
93724
- that is associated with the value given by the method's argument .</p></li>
93775
+ <li><p>Let <var>callbacks</var> be <var>target </var>'s <span>map of animation frame
93776
+ callbacks</span> .</p></li>
93725
93777
93726
- <li><p>If there is such an entry, remove it from <var>document </var>'s <span>list of animation
93727
- frame callbacks</span >.</p></li>
93778
+ <li><p><span data-x="map set">Set</span> <var>callbacks </var>[<var>handle</var>] to
93779
+ <var>callback</var >.</p></li>
93728
93780
93781
+ <li><p>Return <var>handle</var>.</p></li>
93729
93782
</ol>
93730
93783
93731
- <p>When the user agent is to <dfn>run the animation frame callbacks</dfn> for a
93732
- <code>Document</code> < var>doc </var> with a timestamp <var>now</var>, it must run the following
93733
- steps:</p>
93784
+ <p>The <dfn><code
93785
+ data-x="AnimationFrameProvider-cancelAnimationFrame">cancelAnimationFrame(< var>handle </var>)</code></dfn>
93786
+ method must run the following steps:</p>
93734
93787
93735
93788
<ol>
93789
+ <li><p>If this <code>AnimationFrameProvider</code> is not <span
93790
+ data-x="concept-AnimationFrameProvider-supported">supported</span>, then throw a
93791
+ <span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
93736
93792
93737
- <li><p>Let <var>callbacks</var> be a list of the entries in <var>doc</var>'s <span>list of
93738
- animation frame callbacks</span>, in the order in which they were added to the list.</p></li>
93793
+ <li><p>Let <var>callbacks</var> be this <code>AnimationFrameProvider</code>'s <span
93794
+ data-x="concept-AnimationFrameProvider-target-object">target object</span>'s <span>map of
93795
+ animation frame callbacks</span>.</p></li>
93739
93796
93740
- <li><p>Set <var>doc</var>'s <span>list of animation frame callbacks</span> to the empty
93741
- list.</p></li>
93797
+ <li><p><span data-x="map remove">Remove</span> <var>callbacks</var>[<var>handle</var>].</p></li>
93798
+ </ol>
93799
+
93800
+ <p>To <dfn>run the animation frame callbacks</dfn> for a <span
93801
+ data-x="concept-AnimationFrameProvider-target-object">target object</span> <var>target</var> with
93802
+ a timestamp <var>now</var>:</p>
93742
93803
93743
- <li><p>For each entry in <var>callbacks</var>, in order: <span data-x="es-invoking-callback-functions">invoke the callback</span>, passing
93744
- <var>now </var> as the only argument, and if an exception is thrown, <span>report the
93745
- exception </span>. <ref spec=WEBIDL> </p></li>
93804
+ <ol>
93805
+ <li><p>Let < var>callbacks </var> be a clone of <var>target</var>'s <span>map of animation frame
93806
+ callbacks </span>.</p></li>
93746
93807
93808
+ <li><p>Set <var>target</var>'s <span>map of animation frame callbacks</span> to a new empty
93809
+ <span>ordered map</span>.</p></li>
93810
+
93811
+ <li><p><span data-x="map iterate">For each</span> <var>handle</var> → <var>callback</var> of
93812
+ <var>callbacks</var>, <span data-x="es-invoking-callback-functions">invoke</span>
93813
+ <var>callback</var>, passing <var>now</var> as the only argument, and if an exception is thrown,
93814
+ <span>report the exception</span>.</p></li>
93747
93815
</ol>
93748
93816
93817
+ <div class="example">
93818
+ <p>Inside workers, <code
93819
+ data-x="dom-AnimationFrameProvider-requestAnimationFrame">requestAnimationFrame()</code> can be
93820
+ used together with an <code>OffscreenCanvas</code> transferred from a <code>canvas</code>
93821
+ element. First, in the document, transfer control to the worker:</p>
93822
+
93823
+ <pre><code class="js" data-x="">const offscreenCanvas = document.getElementById("c").transferControlToOffscreen();
93824
+ worker.postMessage(offscreenCanvas, [offscreenCanvas]);</code></pre>
93825
+
93826
+ <p>Then, in the worker, the following code will draw a rectangle moving from left to right:</p>
93827
+
93828
+ <pre><code class="js" data-x="">let ctx, pos = 0;
93829
+ function draw(dt) {
93830
+ ctx.clearRect(0, 0, 100, 100);
93831
+ ctx.fillRect(pos, 0, 10, 10);
93832
+ pos += 10 * dt;
93833
+ requestAnimationFrame(draw);
93834
+ }
93749
93835
93836
+ self.onmessage = function(ev) {
93837
+ const transferredCanvas = ev.data;
93838
+ ctx = transferredCanvas.getContext("2d");
93839
+ draw();
93840
+ };</code></pre>
93841
+ </div>
93750
93842
93751
93843
<h2 split-filename="comms" id="comms">Communication</h2>
93752
93844
0 commit comments