[html5] r8510 - [giow] (0) Lay the groundwork for interruptible microtasks, mutation-observer st [...]

whatwg at whatwg.org whatwg at whatwg.org
Mon Feb 24 19:53:17 PST 2014


Author: ianh
Date: 2014-02-24 19:53:16 -0800 (Mon, 24 Feb 2014)
New Revision: 8510

Modified:
   complete.html
   index
   source
Log:
[giow] (0) Lay the groundwork for interruptible microtasks, mutation-observer style.
Fixing https://www.w3.org/Bugs/Public/show_bug.cgi?id=22296
Affected topics: Canvas, DOM APIs, HTML, Video Text Tracks, Video and Audio

Modified: complete.html
===================================================================
--- complete.html	2014-02-24 22:53:41 UTC (rev 8509)
+++ complete.html	2014-02-25 03:53:16 UTC (rev 8510)
@@ -298,7 +298,7 @@
 
   <header class=head id=head><p><a href=http://www.whatwg.org/ class=logo><img width=101 src=/images/logo alt=WHATWG height=101></a></p>
    <hgroup><h1 class=allcaps>HTML</h1>
-    <h2 class="no-num no-toc">Living Standard — Last Updated 24 February 2014</h2>
+    <h2 class="no-num no-toc">Living Standard — Last Updated 25 February 2014</h2>
    </hgroup><dl><dt><strong>Web developer edition:</strong></dt>
     <dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
     <dt>Multiple-page version:</dt>
@@ -14042,7 +14042,7 @@
   If the style sheet referenced no other resources (e.g. it was an internal style sheet given by a
   <code><a href=#the-style-element>style</a></code> element with no <code title="">@import</code> rules), then the style rules must
   be synchronously made available to script; otherwise, the style rules must only be made available
-  to script once the <a href=#event-loop>event loop</a> reaches its "update the rendering" step.</p>
+  to script once the <a href=#event-loop>event loop</a> reaches its <i>update the rendering</i> step.</p>
 
   <p>A style sheet in the context of the <code><a href=#document>Document</a></code> of an <a href=#html-parser>HTML parser</a> or
   <a href=#xml-parser>XML parser</a> is said to be <dfn id=a-style-sheet-that-is-blocking-scripts>a style sheet that is blocking scripts</dfn> if the
@@ -27359,8 +27359,7 @@
    doesn't fire in the loop case). -->
 
    <li><p>As defined above, the <code title=dom-media-ended><a href=#dom-media-ended>ended</a></code> IDL attribute starts
-   returning true once the <a href=#event-loop>event loop</a>'s current <a href=#concept-task title=concept-task>task</a>
-   ends.</li>
+   returning true once the <a href=#event-loop>event loop</a> returns to step 1.</li>
 
    <li><p><a href=#queue-a-task>Queue a task</a> to <a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-media-timeupdate><a href=#event-media-timeupdate>timeupdate</a></code> at the <a href=#media-element>media element</a>.</li>
 
@@ -31472,9 +31471,9 @@
   <a href=#slaved-media-elements>slaved media elements</a>, even while these tracks are playing. How smoothly the media
   plays back in such situations is another quality-of-implementation issue.</p>
 
-  <hr><p>When a <a href=#media-element>media element</a> that is paused is <a href=#remove-an-element-from-a-document title="remove an element from a
+  <hr><!--CLEANUP--><p>When a <a href=#media-element>media element</a> that is paused is <a href=#remove-an-element-from-a-document title="remove an element from a
   document">removed from a document</a> and not reinserted before the next time the <a href=#event-loop>event
-  loop</a> spins, implementations that are resource constrained are encouraged to take that
+  loop</a> reaches step 1, implementations that are resource constrained are encouraged to take that
   opportunity to release all hardware resources (like video planes, networking resources, and data
   buffers) used by the <a href=#media-element>media element</a>. (User agents still have to keep track of the
   playback position and so forth, though, in case playback is later restarted.)</p>
@@ -58041,7 +58040,7 @@
 
      <dd><p><a href=#inform>Inform the user</a> that the focus is at the location given by the
      intended path. User agents may wait until the next time the <a href=#event-loop>event loop</a> reaches its
-     "update the rendering" step to optionally inform the user.</dd>
+     <i>update the rendering</i> step to optionally inform the user.</dd>
 
      <dt>Otherwise</dt>
 
@@ -58079,7 +58078,7 @@
 
      <dd><p><a href=#inform>Inform the user</a> that the focus is at the location given by the
      intended path. The user agent may wait until the next time the <a href=#event-loop>event loop</a> reaches
-     its "update the rendering" step to optionally inform the user.</dd>
+     its <i>update the rendering</i> step to optionally inform the user.</dd>
 
      <dt>Otherwise</dt>
 
@@ -58118,7 +58117,7 @@
    <li><p>Optionally, <a href=#inform>inform the user</a> that the caret or selection (or both)
    cover <var title="">the specified rectangle</var> of the canvas. If the
    <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object's <a href=#concept-canvas-context-bitmap-mode title=concept-canvas-context-bitmap-mode>context bitmap mode</a> was <a href=#concept-canvas-fixed title=concept-canvas-fixed>fixed</a> when the method was invoked, the user agent may wait
-   until the next time the <a href=#event-loop>event loop</a> reaches its "update the rendering" step to
+   until the next time the <a href=#event-loop>event loop</a> reaches its <i>update the rendering</i> step to
    optionally inform the user.</li>
 
   </ol><p id=inform>"Inform the user", as used in this section, does not imply any persistent state
@@ -71869,7 +71868,7 @@
 
   <div class=impl>
 
-  <h4 id=event-loops><span class=secno>7.1.4 </span>Event loops</h4>
+  <h4 id=event-loops><span class=secno>7.1.4 </span>Event loops</h4> <!-- <dfn>event loop</dfn> -->
 
   <h5 id=definitions-1><span class=secno>7.1.4.1 </span>Definitions</h5>
 
@@ -71965,6 +71964,9 @@
   the time, keeping the interface responsive but not starving other task queues, and never
   processing events from any one <a href=#task-source>task source</a> out of order.</p>
 
+  <p>Each <a href=#event-loop>event loop</a> has a <dfn id=currently-running-task>currently running task</dfn>. Initially, this is null.
+  It is used to handle reentrancy.</p>
+
   <hr><p>A user agent may have one <dfn id=storage-mutex>storage mutex</dfn>. This mutex is used to control access to
   shared state like cookies. At any one point, the <a href=#storage-mutex>storage mutex</a> is either free, or
   owned by a particular <a href=#event-loop>event loop</a> or instance of the <a href=#fetch title=fetch>fetching</a> algorithm.</p>
@@ -71995,19 +71997,24 @@
   <p>An <a href=#event-loop>event loop</a> must continually run through the following steps for as long as it
   exists:</p>
 
-  <ol><!-- if you add a step here, make sure to go through the spec updating references to the "first
-   step" or "step 1" of the event loop --><!--CLEANUP--><li><p>Run the oldest <a href=#concept-task title=concept-task>task</a> on one of the <a href=#event-loop>event
+  <ol><!-- lots of places in the spec refer to "step 1" --><!--CLEANUP--><li><p>Select the oldest <a href=#concept-task title=concept-task>task</a> on one of the <a href=#event-loop>event
    loop</a>'s <a href=#task-queue title="task queue">task queues</a>, if any, ignoring, in the case of a <a href=#browsing-context>browsing context</a> <a href=#event-loop>event loop</a>, tasks whose
    associated <code><a href=#document>Document</a></code>s are not <a href=#fully-active>fully active</a>. The user agent may pick any
    <a href=#task-queue>task queue</a>.</li>
 
-   <!-- warning! if you renumber these steps, make sure to update the "spin the event loop"
-   algorithm below! -->
+   <!-- note: reference to 'previous step' below -->
 
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to the <a href=#concept-task title=concept-task>task</a> selected in the previous step.</li>
+
+   <li><p><i>Run</i>: Run the selected <a href=#concept-task title=concept-task>task</a>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to
+   null.</li>
+
    <li><p>If the <a href=#storage-mutex>storage mutex</a> is now owned by the <a href=#event-loop>event loop</a>, release it
    so that it is once again free.</li>
 
-   <li><p>If a task was run in the first step above, remove that task from its <a href=#task-queue>task
+   <li><p>If a task was run in the <i>run</i> step above, remove that task from its <a href=#task-queue>task
    queue</a>.</li>
 
    <li>
@@ -72019,7 +72026,8 @@
 
      <li><p><a href=#provide-a-stable-state>Provide a stable state</a>.</li>
 
-     <li><p>If necessary, update the rendering or user interface of any <code><a href=#document>Document</a></code> or
+<!--CLEANUP-->
+     <li><p><i>Update the rendering</i>: If necessary, update the rendering or user interface of any <code><a href=#document>Document</a></code> or
      <a href=#browsing-context>browsing context</a> to reflect the current state.</li>
 
     </ol></li>
@@ -72033,11 +72041,20 @@
 
   </ol><hr><p>Each <a href=#event-loop>event loop</a> has a <dfn id=microtask-queue>microtask queue</dfn>. A <dfn id=microtask>microtask</dfn> is a
   <a href=#concept-task title=concept-task>task</a> that is originally to be queued on the <a href=#microtask-queue>microtask
-  queue</a> rather than a <a href=#task-queue>task queue</a>. When an algorithm requires a
-  <a href=#microtask>microtask</a> to be <dfn id=queue-a-microtask title="queue a microtask">queued</dfn>, it must be appended
-  to the relevant <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask queue</a>; the <a href=#task-source>task
-  source</a> of such a <a href=#microtask>microtask</a> is the <dfn id=microtask-task-source>microtask task source</dfn>.</p>
+  queue</a> rather than a <a href=#task-queue>task queue</a>. There are two kinds of <a href=#microtask title=microtask>microtasks</a>: <dfn id=solitary-callback-microtask title="solitary callback microtask">solitary callback
+  microtasks</dfn>, and <dfn id=compound-microtask title="compound microtask">compound microtasks</dfn>.</p>
 
+  <p class=note>This specification only has <a href=#solitary-callback-microtask title="solitary callback microtask">solitary
+  callback microtasks</a>. Specifications that use <a href=#compound-microtask title="compound microtask">compound
+  microtasks</a> have to take extra care to <a href=#execute-a-compound-microtask-subtask title="execute a compound microtask
+  subtask">wrap callbacks</a> to handle <a href=#spin-the-event-loop title="spin the event loop">spinning the event
+  loop</a>.</p>
+
+  <p>When an algorithm requires a <a href=#microtask>microtask</a> to be <dfn id=queue-a-microtask title="queue a
+  microtask">queued</dfn>, it must be appended to the relevant <a href=#event-loop>event loop</a>'s
+  <a href=#microtask-queue>microtask queue</a>; the <a href=#task-source>task source</a> of such a <a href=#microtask>microtask</a> is the
+  <dfn id=microtask-task-source>microtask task source</dfn>.</p>
+
   <p class=note>It is possible for a <a href=#microtask>microtask</a> to be moved to a regular <a href=#task-queue>task
   queue</a>, if, during its initial execution, it <a href=#spin-the-event-loop title="spin the event loop">spins the
   event loop</a>. In that case, the <a href=#microtask-task-source>microtask task source</a> is the <a href=#task-source>task
@@ -72081,10 +72098,14 @@
    <li><p><i>Microtask queue handling</i>: If the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
    queue</a> is empty, jump to the <i>done</i> step below.</li>
 
+   <li><p>Select the oldest <a href=#microtask>microtask</a> on the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
+   queue</a>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to the <a href=#concept-task title=concept-task>task</a> selected in the previous step.</li>
+
    <li>
 
-    <p>Run the oldest <a href=#microtask>microtask</a> on the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
-    queue</a>.</p>
+    <p><i>Run</i>: Run the selected <a href=#concept-task title=concept-task>task</a>.</p>
 
     <p class=note>This will typically invoke scripted callbacks, which eventually calls the
     <a href=#clean-up-after-running-a-callback>clean up after running a callback</a> steps, which call this <a href=#perform-a-microtask-checkpoint>perform a microtask
@@ -72093,6 +72114,9 @@
 
    </li>
 
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to
+   null.</li>
+
    <li><p>If the <a href=#storage-mutex>storage mutex</a> is now owned by the <a href=#event-loop>event loop</a>, release it
    so that it is once again free.</li>
 
@@ -72102,6 +72126,24 @@
    <li><p><i>Done</i>: Let the <a href=#performing-a-microtask-checkpoint>performing a microtask checkpoint</a> flag be
    false.</li>
 
+  </ol><p>If, while a <a href=#compound-microtask>compound microtask</a> is running, the user agent is required to
+  <dfn id=execute-a-compound-microtask-subtask>execute a compound microtask subtask</dfn> to run a series of steps, the user agent must run
+  the following steps:</p>
+
+  <ol><li><p>Let <var title="">parent</var> be the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running
+   task</a> (the currently running <a href=#compound-microtask>compound microtask</a>).</li>
+
+   <li><p>Let <var title="">subtask</var> be a new <a href=#concept-task title=concept-task>task</a> that
+   consists of running the given series of steps. The <a href=#task-source>task source</a> of such a
+   <a href=#microtask>microtask</a> is the <a href=#microtask-task-source>microtask task source</a>. This is a <dfn id=compound-microtask-subtask>compound
+   microtask subtask</dfn>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to <var title="">subtask</var>.</li>
+
+   <li><p>Run <var title="">subtask</var>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to <var title="">parent</var>.</li>
+
   </ol><hr><p>When the user agent is to <dfn id=provide-a-stable-state>provide a stable state</dfn>, if any asynchronously-running
   algorithms are <dfn id=await-a-stable-state title="await a stable state">awaiting a stable state</dfn>, then the user
   agent must run their <dfn id=synchronous-section>synchronous section</dfn> and then resume running their asynchronous
@@ -72116,9 +72158,22 @@
 
   <hr><p>When an algorithm says to <dfn id=spin-the-event-loop>spin the event loop</dfn> until a condition <var title="">goal</var> is met, the user agent must run the following steps:</p>
 
-  <ol><li><p>Let <var title="">task source</var> be the <a href=#task-source>task source</a> of the currently
-   running <a href=#concept-task title=concept-task>task</a>.</li>
+  <ol><li>
 
+    <p>Let <var title="">task</var> be the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running
+    task</a>.</p>
+
+    <p class=note>This might be a <a href=#microtask>microtask</a>, in which case it is a <a href=#solitary-callback-microtask>solitary
+    callback microtask</a>. It could also be a <a href=#compound-microtask-subtask>compound microtask subtask</a>, or a
+    regular <a href=#concept-task title=concept-task>task</a> that is not a <a href=#microtask>microtask</a>. It will
+    <em>not</em> be a <a href=#compound-microtask>compound microtask</a>.</p> <!-- well, not unless we messed up in the
+    speccing, anyway... -->
+
+   </li>
+
+   <li><p>Let <var title="">task source</var> be <var title="">task</var>'s <a href=#task-source>task
+   source</a>.</li>
+
    <li><p>Let <var title="">old stack of script settings objects</var> be a copy of the <a href=#stack-of-script-settings-objects>stack
    of script settings objects</a>.</li>
 
@@ -72130,20 +72185,20 @@
 
    <li>
 
-    <p>Stop the currently running <a href=#concept-task title=concept-task>task</a>, allowing the <a href=#event-loop>event
-    loop</a> to resume, but continue these steps asynchronously.</p>
+    <p>Stop <var title="">task</var>, allowing whatever algorithm that invoked it to resume, but
+    continue these steps asynchronously.</p>
 
-    <p class=note>This either causes the <a href=#event-loop>event loop</a> to move on to the second step of
-    its processing model, or causes the <a href=#perform-a-microtask-checkpoint>perform a microtask checkpoint</a> algorithm to
-    move on to its next step, depending on how the <a href=#concept-task title=concept-task>task</a> came to be
-    run.</p>
+    <p class=note>This causes one of the following algorithms to continue: the <a href=#event-loop>event
+    loop</a>'s main set of steps, the <a href=#perform-a-microtask-checkpoint>perform a microtask checkpoint</a> algorithm, or
+    the <a href=#execute-a-compound-microtask-subtask>execute a compound microtask subtask</a> algorithm to continue.</p>
 
    </li>
 
    <li><p>Wait until the condition <var title="">goal</var> is met.</li>
 
+<!--CLEANUP-->
    <li><p><a href=#queue-a-task>Queue a task</a> to continue running these steps, using the <a href=#task-source>task
-   source</a> <var title="">task source</var>. Wait until this task runs before continuing these
+   source</a> <var title="">task source</var>. Wait until this new task runs before continuing these
    steps.</li>
 
    <li><p>Replace the <a href=#stack-of-script-settings-objects>stack of script settings objects</a> with the <var title="">old
@@ -81189,10 +81244,10 @@
 
     </dl></li>
 
-  </ol><hr><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn> attribute must
+  </ol><hr><!--CLEANUP--><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn> attribute must
   return the number of bytes of application data (UTF-8 text and binary data) that have been queued
   using <code title=dom-WebSocket-send><a href=#dom-websocket-send>send()</a></code> but that, as of the last time the <a href=#event-loop>event
-  loop</a> started executing a <a href=#concept-task title=concept-task>task</a>, had not yet been
+  loop</a> reached step 1, had not yet been
   transmitted to the network. (This thus includes any text sent during the execution of the current
   task, regardless of whether the user agent is able to transmit text asynchronously with script
   execution.) This does not include framing overhead incurred by the protocol, or buffering done by
@@ -81579,20 +81634,23 @@
 
   <h4 id=garbage-collection-1><span class=secno>9.3.7 </span>Garbage collection</h4>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-CONNECTING><a href=#dom-websocket-connecting>CONNECTING</a></code> (0) as of
-  the last time the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must not be garbage collected if there are any event listeners
+  the last time the <a href=#event-loop>event loop</a> started reached step 1 must not be garbage collected if there are any event listeners
   registered for <code title=event-open><a href=#event-open>open</a></code> events, <code title=event-message><a href=#event-message>message</a></code> events, <code title=event-error><a href=#event-error>error</a></code> events, or
   <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1) as of the last time
-  the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must not be
+  the <a href=#event-loop>event loop</a> reached step 1 must not be
   garbage collected if there are any event listeners registered for <code title=event-message><a href=#event-message>message</a></code> events, <code title=event-error><a href=#event-error>error</a></code>, or <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2) as of the last
-  time the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must
+  time the <a href=#event-loop>event loop</a> reached step 1 must
   not be garbage collected if there are any event listeners registered for <code title=event-error><a href=#event-error>error</a></code> or <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
   <p>A <code><a href=#websocket>WebSocket</a></code> object with <i title="the WebSocket connection is established"><a href=#the-websocket-connection-is-established>an

Modified: index
===================================================================
--- index	2014-02-24 22:53:41 UTC (rev 8509)
+++ index	2014-02-25 03:53:16 UTC (rev 8510)
@@ -298,7 +298,7 @@
 
   <header class=head id=head><p><a href=http://www.whatwg.org/ class=logo><img width=101 src=/images/logo alt=WHATWG height=101></a></p>
    <hgroup><h1 class=allcaps>HTML</h1>
-    <h2 class="no-num no-toc">Living Standard — Last Updated 24 February 2014</h2>
+    <h2 class="no-num no-toc">Living Standard — Last Updated 25 February 2014</h2>
    </hgroup><dl><dt><strong>Web developer edition:</strong></dt>
     <dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
     <dt>Multiple-page version:</dt>
@@ -14042,7 +14042,7 @@
   If the style sheet referenced no other resources (e.g. it was an internal style sheet given by a
   <code><a href=#the-style-element>style</a></code> element with no <code title="">@import</code> rules), then the style rules must
   be synchronously made available to script; otherwise, the style rules must only be made available
-  to script once the <a href=#event-loop>event loop</a> reaches its "update the rendering" step.</p>
+  to script once the <a href=#event-loop>event loop</a> reaches its <i>update the rendering</i> step.</p>
 
   <p>A style sheet in the context of the <code><a href=#document>Document</a></code> of an <a href=#html-parser>HTML parser</a> or
   <a href=#xml-parser>XML parser</a> is said to be <dfn id=a-style-sheet-that-is-blocking-scripts>a style sheet that is blocking scripts</dfn> if the
@@ -27359,8 +27359,7 @@
    doesn't fire in the loop case). -->
 
    <li><p>As defined above, the <code title=dom-media-ended><a href=#dom-media-ended>ended</a></code> IDL attribute starts
-   returning true once the <a href=#event-loop>event loop</a>'s current <a href=#concept-task title=concept-task>task</a>
-   ends.</li>
+   returning true once the <a href=#event-loop>event loop</a> returns to step 1.</li>
 
    <li><p><a href=#queue-a-task>Queue a task</a> to <a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-media-timeupdate><a href=#event-media-timeupdate>timeupdate</a></code> at the <a href=#media-element>media element</a>.</li>
 
@@ -31472,9 +31471,9 @@
   <a href=#slaved-media-elements>slaved media elements</a>, even while these tracks are playing. How smoothly the media
   plays back in such situations is another quality-of-implementation issue.</p>
 
-  <hr><p>When a <a href=#media-element>media element</a> that is paused is <a href=#remove-an-element-from-a-document title="remove an element from a
+  <hr><!--CLEANUP--><p>When a <a href=#media-element>media element</a> that is paused is <a href=#remove-an-element-from-a-document title="remove an element from a
   document">removed from a document</a> and not reinserted before the next time the <a href=#event-loop>event
-  loop</a> spins, implementations that are resource constrained are encouraged to take that
+  loop</a> reaches step 1, implementations that are resource constrained are encouraged to take that
   opportunity to release all hardware resources (like video planes, networking resources, and data
   buffers) used by the <a href=#media-element>media element</a>. (User agents still have to keep track of the
   playback position and so forth, though, in case playback is later restarted.)</p>
@@ -58041,7 +58040,7 @@
 
      <dd><p><a href=#inform>Inform the user</a> that the focus is at the location given by the
      intended path. User agents may wait until the next time the <a href=#event-loop>event loop</a> reaches its
-     "update the rendering" step to optionally inform the user.</dd>
+     <i>update the rendering</i> step to optionally inform the user.</dd>
 
      <dt>Otherwise</dt>
 
@@ -58079,7 +58078,7 @@
 
      <dd><p><a href=#inform>Inform the user</a> that the focus is at the location given by the
      intended path. The user agent may wait until the next time the <a href=#event-loop>event loop</a> reaches
-     its "update the rendering" step to optionally inform the user.</dd>
+     its <i>update the rendering</i> step to optionally inform the user.</dd>
 
      <dt>Otherwise</dt>
 
@@ -58118,7 +58117,7 @@
    <li><p>Optionally, <a href=#inform>inform the user</a> that the caret or selection (or both)
    cover <var title="">the specified rectangle</var> of the canvas. If the
    <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object's <a href=#concept-canvas-context-bitmap-mode title=concept-canvas-context-bitmap-mode>context bitmap mode</a> was <a href=#concept-canvas-fixed title=concept-canvas-fixed>fixed</a> when the method was invoked, the user agent may wait
-   until the next time the <a href=#event-loop>event loop</a> reaches its "update the rendering" step to
+   until the next time the <a href=#event-loop>event loop</a> reaches its <i>update the rendering</i> step to
    optionally inform the user.</li>
 
   </ol><p id=inform>"Inform the user", as used in this section, does not imply any persistent state
@@ -71869,7 +71868,7 @@
 
   <div class=impl>
 
-  <h4 id=event-loops><span class=secno>7.1.4 </span>Event loops</h4>
+  <h4 id=event-loops><span class=secno>7.1.4 </span>Event loops</h4> <!-- <dfn>event loop</dfn> -->
 
   <h5 id=definitions-1><span class=secno>7.1.4.1 </span>Definitions</h5>
 
@@ -71965,6 +71964,9 @@
   the time, keeping the interface responsive but not starving other task queues, and never
   processing events from any one <a href=#task-source>task source</a> out of order.</p>
 
+  <p>Each <a href=#event-loop>event loop</a> has a <dfn id=currently-running-task>currently running task</dfn>. Initially, this is null.
+  It is used to handle reentrancy.</p>
+
   <hr><p>A user agent may have one <dfn id=storage-mutex>storage mutex</dfn>. This mutex is used to control access to
   shared state like cookies. At any one point, the <a href=#storage-mutex>storage mutex</a> is either free, or
   owned by a particular <a href=#event-loop>event loop</a> or instance of the <a href=#fetch title=fetch>fetching</a> algorithm.</p>
@@ -71995,19 +71997,24 @@
   <p>An <a href=#event-loop>event loop</a> must continually run through the following steps for as long as it
   exists:</p>
 
-  <ol><!-- if you add a step here, make sure to go through the spec updating references to the "first
-   step" or "step 1" of the event loop --><!--CLEANUP--><li><p>Run the oldest <a href=#concept-task title=concept-task>task</a> on one of the <a href=#event-loop>event
+  <ol><!-- lots of places in the spec refer to "step 1" --><!--CLEANUP--><li><p>Select the oldest <a href=#concept-task title=concept-task>task</a> on one of the <a href=#event-loop>event
    loop</a>'s <a href=#task-queue title="task queue">task queues</a>, if any, ignoring, in the case of a <a href=#browsing-context>browsing context</a> <a href=#event-loop>event loop</a>, tasks whose
    associated <code><a href=#document>Document</a></code>s are not <a href=#fully-active>fully active</a>. The user agent may pick any
    <a href=#task-queue>task queue</a>.</li>
 
-   <!-- warning! if you renumber these steps, make sure to update the "spin the event loop"
-   algorithm below! -->
+   <!-- note: reference to 'previous step' below -->
 
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to the <a href=#concept-task title=concept-task>task</a> selected in the previous step.</li>
+
+   <li><p><i>Run</i>: Run the selected <a href=#concept-task title=concept-task>task</a>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to
+   null.</li>
+
    <li><p>If the <a href=#storage-mutex>storage mutex</a> is now owned by the <a href=#event-loop>event loop</a>, release it
    so that it is once again free.</li>
 
-   <li><p>If a task was run in the first step above, remove that task from its <a href=#task-queue>task
+   <li><p>If a task was run in the <i>run</i> step above, remove that task from its <a href=#task-queue>task
    queue</a>.</li>
 
    <li>
@@ -72019,7 +72026,8 @@
 
      <li><p><a href=#provide-a-stable-state>Provide a stable state</a>.</li>
 
-     <li><p>If necessary, update the rendering or user interface of any <code><a href=#document>Document</a></code> or
+<!--CLEANUP-->
+     <li><p><i>Update the rendering</i>: If necessary, update the rendering or user interface of any <code><a href=#document>Document</a></code> or
      <a href=#browsing-context>browsing context</a> to reflect the current state.</li>
 
     </ol></li>
@@ -72033,11 +72041,20 @@
 
   </ol><hr><p>Each <a href=#event-loop>event loop</a> has a <dfn id=microtask-queue>microtask queue</dfn>. A <dfn id=microtask>microtask</dfn> is a
   <a href=#concept-task title=concept-task>task</a> that is originally to be queued on the <a href=#microtask-queue>microtask
-  queue</a> rather than a <a href=#task-queue>task queue</a>. When an algorithm requires a
-  <a href=#microtask>microtask</a> to be <dfn id=queue-a-microtask title="queue a microtask">queued</dfn>, it must be appended
-  to the relevant <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask queue</a>; the <a href=#task-source>task
-  source</a> of such a <a href=#microtask>microtask</a> is the <dfn id=microtask-task-source>microtask task source</dfn>.</p>
+  queue</a> rather than a <a href=#task-queue>task queue</a>. There are two kinds of <a href=#microtask title=microtask>microtasks</a>: <dfn id=solitary-callback-microtask title="solitary callback microtask">solitary callback
+  microtasks</dfn>, and <dfn id=compound-microtask title="compound microtask">compound microtasks</dfn>.</p>
 
+  <p class=note>This specification only has <a href=#solitary-callback-microtask title="solitary callback microtask">solitary
+  callback microtasks</a>. Specifications that use <a href=#compound-microtask title="compound microtask">compound
+  microtasks</a> have to take extra care to <a href=#execute-a-compound-microtask-subtask title="execute a compound microtask
+  subtask">wrap callbacks</a> to handle <a href=#spin-the-event-loop title="spin the event loop">spinning the event
+  loop</a>.</p>
+
+  <p>When an algorithm requires a <a href=#microtask>microtask</a> to be <dfn id=queue-a-microtask title="queue a
+  microtask">queued</dfn>, it must be appended to the relevant <a href=#event-loop>event loop</a>'s
+  <a href=#microtask-queue>microtask queue</a>; the <a href=#task-source>task source</a> of such a <a href=#microtask>microtask</a> is the
+  <dfn id=microtask-task-source>microtask task source</dfn>.</p>
+
   <p class=note>It is possible for a <a href=#microtask>microtask</a> to be moved to a regular <a href=#task-queue>task
   queue</a>, if, during its initial execution, it <a href=#spin-the-event-loop title="spin the event loop">spins the
   event loop</a>. In that case, the <a href=#microtask-task-source>microtask task source</a> is the <a href=#task-source>task
@@ -72081,10 +72098,14 @@
    <li><p><i>Microtask queue handling</i>: If the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
    queue</a> is empty, jump to the <i>done</i> step below.</li>
 
+   <li><p>Select the oldest <a href=#microtask>microtask</a> on the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
+   queue</a>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to the <a href=#concept-task title=concept-task>task</a> selected in the previous step.</li>
+
    <li>
 
-    <p>Run the oldest <a href=#microtask>microtask</a> on the <a href=#event-loop>event loop</a>'s <a href=#microtask-queue>microtask
-    queue</a>.</p>
+    <p><i>Run</i>: Run the selected <a href=#concept-task title=concept-task>task</a>.</p>
 
     <p class=note>This will typically invoke scripted callbacks, which eventually calls the
     <a href=#clean-up-after-running-a-callback>clean up after running a callback</a> steps, which call this <a href=#perform-a-microtask-checkpoint>perform a microtask
@@ -72093,6 +72114,9 @@
 
    </li>
 
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to
+   null.</li>
+
    <li><p>If the <a href=#storage-mutex>storage mutex</a> is now owned by the <a href=#event-loop>event loop</a>, release it
    so that it is once again free.</li>
 
@@ -72102,6 +72126,24 @@
    <li><p><i>Done</i>: Let the <a href=#performing-a-microtask-checkpoint>performing a microtask checkpoint</a> flag be
    false.</li>
 
+  </ol><p>If, while a <a href=#compound-microtask>compound microtask</a> is running, the user agent is required to
+  <dfn id=execute-a-compound-microtask-subtask>execute a compound microtask subtask</dfn> to run a series of steps, the user agent must run
+  the following steps:</p>
+
+  <ol><li><p>Let <var title="">parent</var> be the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running
+   task</a> (the currently running <a href=#compound-microtask>compound microtask</a>).</li>
+
+   <li><p>Let <var title="">subtask</var> be a new <a href=#concept-task title=concept-task>task</a> that
+   consists of running the given series of steps. The <a href=#task-source>task source</a> of such a
+   <a href=#microtask>microtask</a> is the <a href=#microtask-task-source>microtask task source</a>. This is a <dfn id=compound-microtask-subtask>compound
+   microtask subtask</dfn>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> to <var title="">subtask</var>.</li>
+
+   <li><p>Run <var title="">subtask</var>.</li>
+
+   <li><p>Set the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running task</a> back to <var title="">parent</var>.</li>
+
   </ol><hr><p>When the user agent is to <dfn id=provide-a-stable-state>provide a stable state</dfn>, if any asynchronously-running
   algorithms are <dfn id=await-a-stable-state title="await a stable state">awaiting a stable state</dfn>, then the user
   agent must run their <dfn id=synchronous-section>synchronous section</dfn> and then resume running their asynchronous
@@ -72116,9 +72158,22 @@
 
   <hr><p>When an algorithm says to <dfn id=spin-the-event-loop>spin the event loop</dfn> until a condition <var title="">goal</var> is met, the user agent must run the following steps:</p>
 
-  <ol><li><p>Let <var title="">task source</var> be the <a href=#task-source>task source</a> of the currently
-   running <a href=#concept-task title=concept-task>task</a>.</li>
+  <ol><li>
 
+    <p>Let <var title="">task</var> be the <a href=#event-loop>event loop</a>'s <a href=#currently-running-task>currently running
+    task</a>.</p>
+
+    <p class=note>This might be a <a href=#microtask>microtask</a>, in which case it is a <a href=#solitary-callback-microtask>solitary
+    callback microtask</a>. It could also be a <a href=#compound-microtask-subtask>compound microtask subtask</a>, or a
+    regular <a href=#concept-task title=concept-task>task</a> that is not a <a href=#microtask>microtask</a>. It will
+    <em>not</em> be a <a href=#compound-microtask>compound microtask</a>.</p> <!-- well, not unless we messed up in the
+    speccing, anyway... -->
+
+   </li>
+
+   <li><p>Let <var title="">task source</var> be <var title="">task</var>'s <a href=#task-source>task
+   source</a>.</li>
+
    <li><p>Let <var title="">old stack of script settings objects</var> be a copy of the <a href=#stack-of-script-settings-objects>stack
    of script settings objects</a>.</li>
 
@@ -72130,20 +72185,20 @@
 
    <li>
 
-    <p>Stop the currently running <a href=#concept-task title=concept-task>task</a>, allowing the <a href=#event-loop>event
-    loop</a> to resume, but continue these steps asynchronously.</p>
+    <p>Stop <var title="">task</var>, allowing whatever algorithm that invoked it to resume, but
+    continue these steps asynchronously.</p>
 
-    <p class=note>This either causes the <a href=#event-loop>event loop</a> to move on to the second step of
-    its processing model, or causes the <a href=#perform-a-microtask-checkpoint>perform a microtask checkpoint</a> algorithm to
-    move on to its next step, depending on how the <a href=#concept-task title=concept-task>task</a> came to be
-    run.</p>
+    <p class=note>This causes one of the following algorithms to continue: the <a href=#event-loop>event
+    loop</a>'s main set of steps, the <a href=#perform-a-microtask-checkpoint>perform a microtask checkpoint</a> algorithm, or
+    the <a href=#execute-a-compound-microtask-subtask>execute a compound microtask subtask</a> algorithm to continue.</p>
 
    </li>
 
    <li><p>Wait until the condition <var title="">goal</var> is met.</li>
 
+<!--CLEANUP-->
    <li><p><a href=#queue-a-task>Queue a task</a> to continue running these steps, using the <a href=#task-source>task
-   source</a> <var title="">task source</var>. Wait until this task runs before continuing these
+   source</a> <var title="">task source</var>. Wait until this new task runs before continuing these
    steps.</li>
 
    <li><p>Replace the <a href=#stack-of-script-settings-objects>stack of script settings objects</a> with the <var title="">old
@@ -81189,10 +81244,10 @@
 
     </dl></li>
 
-  </ol><hr><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn> attribute must
+  </ol><hr><!--CLEANUP--><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn> attribute must
   return the number of bytes of application data (UTF-8 text and binary data) that have been queued
   using <code title=dom-WebSocket-send><a href=#dom-websocket-send>send()</a></code> but that, as of the last time the <a href=#event-loop>event
-  loop</a> started executing a <a href=#concept-task title=concept-task>task</a>, had not yet been
+  loop</a> reached step 1, had not yet been
   transmitted to the network. (This thus includes any text sent during the execution of the current
   task, regardless of whether the user agent is able to transmit text asynchronously with script
   execution.) This does not include framing overhead incurred by the protocol, or buffering done by
@@ -81579,20 +81634,23 @@
 
   <h4 id=garbage-collection-1><span class=secno>9.3.7 </span>Garbage collection</h4>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-CONNECTING><a href=#dom-websocket-connecting>CONNECTING</a></code> (0) as of
-  the last time the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must not be garbage collected if there are any event listeners
+  the last time the <a href=#event-loop>event loop</a> started reached step 1 must not be garbage collected if there are any event listeners
   registered for <code title=event-open><a href=#event-open>open</a></code> events, <code title=event-message><a href=#event-message>message</a></code> events, <code title=event-error><a href=#event-error>error</a></code> events, or
   <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1) as of the last time
-  the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must not be
+  the <a href=#event-loop>event loop</a> reached step 1 must not be
   garbage collected if there are any event listeners registered for <code title=event-message><a href=#event-message>message</a></code> events, <code title=event-error><a href=#event-error>error</a></code>, or <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code><a href=#websocket>WebSocket</a></code> object whose <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
   attribute's value was set to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2) as of the last
-  time the <a href=#event-loop>event loop</a> started executing a <a href=#concept-task title=concept-task>task</a> must
+  time the <a href=#event-loop>event loop</a> reached step 1 must
   not be garbage collected if there are any event listeners registered for <code title=event-error><a href=#event-error>error</a></code> or <code title=event-close><a href=#event-close>close</a></code> events.</p>
 
   <p>A <code><a href=#websocket>WebSocket</a></code> object with <i title="the WebSocket connection is established"><a href=#the-websocket-connection-is-established>an

Modified: source
===================================================================
--- source	2014-02-24 22:53:41 UTC (rev 8509)
+++ source	2014-02-25 03:53:16 UTC (rev 8510)
@@ -14597,7 +14597,7 @@
   If the style sheet referenced no other resources (e.g. it was an internal style sheet given by a
   <code>style</code> element with no <code data-x="">@import</code> rules), then the style rules must
   be synchronously made available to script; otherwise, the style rules must only be made available
-  to script once the <span>event loop</span> reaches its "update the rendering" step.</p>
+  to script once the <span>event loop</span> reaches its <i>update the rendering</i> step.</p>
 
   <p>A style sheet in the context of the <code>Document</code> of an <span>HTML parser</span> or
   <span>XML parser</span> is said to be <dfn>a style sheet that is blocking scripts</dfn> if the
@@ -29186,8 +29186,7 @@
    doesn't fire in the loop case). -->
 
    <li><p>As defined above, the <code data-x="dom-media-ended">ended</code> IDL attribute starts
-   returning true once the <span>event loop</span>'s current <span data-x="concept-task">task</span>
-   ends.</p></li>
+   returning true once the <span>event loop</span> returns to step 1.</p></li>
 
    <li><p><span>Queue a task</span> to <span>fire a simple event</span> named <code
    data-x="event-media-timeupdate">timeupdate</code> at the <span>media element</span>.</p></li>
@@ -34043,9 +34042,10 @@
 
   <hr>
 
+<!--CLEANUP-->
   <p>When a <span>media element</span> that is paused is <span data-x="remove an element from a
   document">removed from a document</span> and not reinserted before the next time the <span>event
-  loop</span> spins, implementations that are resource constrained are encouraged to take that
+  loop</span> reaches step 1, implementations that are resource constrained are encouraged to take that
   opportunity to release all hardware resources (like video planes, networking resources, and data
   buffers) used by the <span>media element</span>. (User agents still have to keep track of the
   playback position and so forth, though, in case playback is later restarted.)</p>
@@ -64519,7 +64519,7 @@
 
      <dd><p><a href="#inform">Inform the user</a> that the focus is at the location given by the
      intended path. User agents may wait until the next time the <span>event loop</span> reaches its
-     "update the rendering" step to optionally inform the user.</p></dd>
+     <i>update the rendering</i> step to optionally inform the user.</p></dd>
 
      <dt>Otherwise</dt>
 
@@ -64572,7 +64572,7 @@
 
      <dd><p><a href="#inform">Inform the user</a> that the focus is at the location given by the
      intended path. The user agent may wait until the next time the <span>event loop</span> reaches
-     its "update the rendering" step to optionally inform the user.</p></dd>
+     its <i>update the rendering</i> step to optionally inform the user.</p></dd>
 
      <dt>Otherwise</dt>
 
@@ -64623,7 +64623,7 @@
    <code>CanvasRenderingContext2D</code> object's <span
    data-x="concept-canvas-context-bitmap-mode">context bitmap mode</span> was <span
    data-x="concept-canvas-fixed">fixed</span> when the method was invoked, the user agent may wait
-   until the next time the <span>event loop</span> reaches its "update the rendering" step to
+   until the next time the <span>event loop</span> reaches its <i>update the rendering</i> step to
    optionally inform the user.</p></li>
 
   </ol>
@@ -80270,7 +80270,7 @@
 
   <div class="impl">
 
-  <h4>Event loops</h4>
+  <h4>Event loops</h4> <!-- <dfn>event loop</dfn> -->
 
   <h5>Definitions</h5>
 
@@ -80375,6 +80375,9 @@
   the time, keeping the interface responsive but not starving other task queues, and never
   processing events from any one <span>task source</span> out of order.</p>
 
+  <p>Each <span>event loop</span> has a <dfn>currently running task</dfn>. Initially, this is null.
+  It is used to handle reentrancy.</p>
+
   <hr>
 
   <p>A user agent may have one <dfn>storage mutex</dfn>. This mutex is used to control access to
@@ -80410,22 +80413,28 @@
 
   <ol>
 
-   <!-- if you add a step here, make sure to go through the spec updating references to the "first
-   step" or "step 1" of the event loop -->
+   <!-- lots of places in the spec refer to "step 1" -->
 
 <!--CLEANUP-->
-   <li><p>Run the oldest <span data-x="concept-task">task</span> on one of the <span>event
+   <li><p>Select the oldest <span data-x="concept-task">task</span> on one of the <span>event
    loop</span>'s <span data-x="task queue">task queues</span>, if any, ignoring, in the case of a <span>browsing context</span> <span>event loop</span>, tasks whose
    associated <code>Document</code>s are not <span>fully active</span>. The user agent may pick any
    <span>task queue</span>.</p></li>
 
-   <!-- warning! if you renumber these steps, make sure to update the "spin the event loop"
-   algorithm below! -->
+   <!-- note: reference to 'previous step' below -->
 
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> to the <span
+   data-x="concept-task">task</span> selected in the previous step.</p></li>
+
+   <li><p><i>Run</i>: Run the selected <span data-x="concept-task">task</span>.</p></li>
+
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> back to
+   null.</p></li>
+
    <li><p>If the <span>storage mutex</span> is now owned by the <span>event loop</span>, release it
    so that it is once again free.</p></li>
 
-   <li><p>If a task was run in the first step above, remove that task from its <span>task
+   <li><p>If a task was run in the <i>run</i> step above, remove that task from its <span>task
    queue</span>.</p></li>
 
    <li>
@@ -80439,7 +80448,8 @@
 
      <li><p><span>Provide a stable state</span>.</p></li>
 
-     <li><p>If necessary, update the rendering or user interface of any <code>Document</code> or
+<!--CLEANUP-->
+     <li><p><i>Update the rendering</i>: If necessary, update the rendering or user interface of any <code>Document</code> or
      <span>browsing context</span> to reflect the current state.</p></li>
 
     </ol>
@@ -80461,11 +80471,21 @@
 
   <p>Each <span>event loop</span> has a <dfn>microtask queue</dfn>. A <dfn>microtask</dfn> is a
   <span data-x="concept-task">task</span> that is originally to be queued on the <span>microtask
-  queue</span> rather than a <span>task queue</span>. When an algorithm requires a
-  <span>microtask</span> to be <dfn data-x="queue a microtask">queued</dfn>, it must be appended
-  to the relevant <span>event loop</span>'s <span>microtask queue</span>; the <span>task
-  source</span> of such a <span>microtask</span> is the <dfn>microtask task source</dfn>.</p>
+  queue</span> rather than a <span>task queue</span>. There are two kinds of <span
+  data-x="microtask">microtasks</span>: <dfn data-x="solitary callback microtask">solitary callback
+  microtasks</dfn>, and <dfn data-x="compound microtask">compound microtasks</dfn>.</p>
 
+  <p class="note">This specification only has <span data-x="solitary callback microtask">solitary
+  callback microtasks</span>. Specifications that use <span data-x="compound microtask">compound
+  microtasks</span> have to take extra care to <span data-x="execute a compound microtask
+  subtask">wrap callbacks</span> to handle <span data-x="spin the event loop">spinning the event
+  loop</span>.</p>
+
+  <p>When an algorithm requires a <span>microtask</span> to be <dfn data-x="queue a
+  microtask">queued</dfn>, it must be appended to the relevant <span>event loop</span>'s
+  <span>microtask queue</span>; the <span>task source</span> of such a <span>microtask</span> is the
+  <dfn>microtask task source</dfn>.</p>
+
   <p class="note">It is possible for a <span>microtask</span> to be moved to a regular <span>task
   queue</span>, if, during its initial execution, it <span data-x="spin the event loop">spins the
   event loop</span>. In that case, the <span>microtask task source</span> is the <span>task
@@ -80511,10 +80531,15 @@
    <li><p><i>Microtask queue handling</i>: If the <span>event loop</span>'s <span>microtask
    queue</span> is empty, jump to the <i>done</i> step below.</p></li>
 
+   <li><p>Select the oldest <span>microtask</span> on the <span>event loop</span>'s <span>microtask
+   queue</span>.</p></li>
+
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> to the <span
+   data-x="concept-task">task</span> selected in the previous step.</p></li>
+
    <li>
 
-    <p>Run the oldest <span>microtask</span> on the <span>event loop</span>'s <span>microtask
-    queue</span>.</p>
+    <p><i>Run</i>: Run the selected <span data-x="concept-task">task</span>.</p>
 
     <p class="note">This will typically invoke scripted callbacks, which eventually calls the
     <span>clean up after running a callback</span> steps, which call this <span>perform a microtask
@@ -80523,6 +80548,9 @@
 
    </li>
 
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> back to
+   null.</p></li>
+
    <li><p>If the <span>storage mutex</span> is now owned by the <span>event loop</span>, release it
    so that it is once again free.</p></li>
 
@@ -80534,6 +80562,30 @@
 
   </ol>
 
+  <p>If, while a <span>compound microtask</span> is running, the user agent is required to
+  <dfn>execute a compound microtask subtask</dfn> to run a series of steps, the user agent must run
+  the following steps:</p>
+
+  <ol>
+
+   <li><p>Let <var data-x="">parent</var> be the <span>event loop</span>'s <span>currently running
+   task</span> (the currently running <span>compound microtask</span>).</p></li>
+
+   <li><p>Let <var data-x="">subtask</var> be a new <span data-x="concept-task">task</span> that
+   consists of running the given series of steps. The <span>task source</span> of such a
+   <span>microtask</span> is the <span>microtask task source</span>. This is a <dfn>compound
+   microtask subtask</dfn>.</p></li>
+
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> to <var
+   data-x="">subtask</var>.</p></li>
+
+   <li><p>Run <var data-x="">subtask</var>.</p></li>
+
+   <li><p>Set the <span>event loop</span>'s <span>currently running task</span> back to <var
+   data-x="">parent</var>.</p></li>
+
+  </ol>
+
   <hr>
 
   <p>When the user agent is to <dfn>provide a stable state</dfn>, if any asynchronously-running
@@ -80556,9 +80608,22 @@
 
   <ol>
 
-   <li><p>Let <var data-x="">task source</var> be the <span>task source</span> of the currently
-   running <span data-x="concept-task">task</span>.</p></li>
+   <li>
 
+    <p>Let <var data-x="">task</var> be the <span>event loop</span>'s <span>currently running
+    task</span>.</p>
+
+    <p class="note">This might be a <span>microtask</span>, in which case it is a <span>solitary
+    callback microtask</span>. It could also be a <span>compound microtask subtask</span>, or a
+    regular <span data-x="concept-task">task</span> that is not a <span>microtask</span>. It will
+    <em>not</em> be a <span>compound microtask</span>.</p> <!-- well, not unless we messed up in the
+    speccing, anyway... -->
+
+   </li>
+
+   <li><p>Let <var data-x="">task source</var> be <var data-x="">task</var>'s <span>task
+   source</span>.</p></li>
+
    <li><p>Let <var data-x="">old stack of script settings objects</var> be a copy of the <span>stack
    of script settings objects</span>.</p></li>
 
@@ -80570,20 +80635,20 @@
 
    <li>
 
-    <p>Stop the currently running <span data-x="concept-task">task</span>, allowing the <span>event
-    loop</span> to resume, but continue these steps asynchronously.</p>
+    <p>Stop <var data-x="">task</var>, allowing whatever algorithm that invoked it to resume, but
+    continue these steps asynchronously.</p>
 
-    <p class="note">This either causes the <span>event loop</span> to move on to the second step of
-    its processing model, or causes the <span>perform a microtask checkpoint</span> algorithm to
-    move on to its next step, depending on how the <span data-x="concept-task">task</span> came to be
-    run.</p>
+    <p class="note">This causes one of the following algorithms to continue: the <span>event
+    loop</span>'s main set of steps, the <span>perform a microtask checkpoint</span> algorithm, or
+    the <span>execute a compound microtask subtask</span> algorithm to continue.</p>
 
    </li>
 
    <li><p>Wait until the condition <var data-x="">goal</var> is met.</p></li>
 
+<!--CLEANUP-->
    <li><p><span>Queue a task</span> to continue running these steps, using the <span>task
-   source</span> <var data-x="">task source</var>. Wait until this task runs before continuing these
+   source</span> <var data-x="">task source</var>. Wait until this new task runs before continuing these
    steps.</p></li>
 
    <li><p>Replace the <span>stack of script settings objects</span> with the <var data-x="">old
@@ -91042,10 +91107,11 @@
 
   <hr>
 
+<!--CLEANUP-->
   <p>The <dfn data-x="dom-WebSocket-bufferedAmount"><code>bufferedAmount</code></dfn> attribute must
   return the number of bytes of application data (UTF-8 text and binary data) that have been queued
   using <code data-x="dom-WebSocket-send">send()</code> but that, as of the last time the <span>event
-  loop</span> started executing a <span data-x="concept-task">task</span>, had not yet been
+  loop</span> reached step 1, had not yet been
   transmitted to the network. (This thus includes any text sent during the execution of the current
   task, regardless of whether the user agent is able to transmit text asynchronously with script
   execution.) This does not include framing overhead incurred by the protocol, or buffering done by
@@ -91526,24 +91592,26 @@
 
   <h4>Garbage collection</h4>
 
+<!--CLEANUP-->
   <p>A <code>WebSocket</code> object whose <code data-x="dom-WebSocket-readyState">readyState</code>
   attribute's value was set to <code data-x="dom-WebSocket-CONNECTING">CONNECTING</code> (0) as of
-  the last time the <span>event loop</span> started executing a <span
-  data-x="concept-task">task</span> must not be garbage collected if there are any event listeners
+  the last time the <span>event loop</span> started reached step 1 must not be garbage collected if there are any event listeners
   registered for <code data-x="event-open">open</code> events, <code
   data-x="event-message">message</code> events, <code data-x="event-error">error</code> events, or
   <code data-x="event-close">close</code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code>WebSocket</code> object whose <code data-x="dom-WebSocket-readyState">readyState</code>
   attribute's value was set to <code data-x="dom-WebSocket-OPEN">OPEN</code> (1) as of the last time
-  the <span>event loop</span> started executing a <span data-x="concept-task">task</span> must not be
+  the <span>event loop</span> reached step 1 must not be
   garbage collected if there are any event listeners registered for <code
   data-x="event-message">message</code> events, <code data-x="event-error">error</code>, or <code
   data-x="event-close">close</code> events.</p>
 
+<!--CLEANUP-->
   <p>A <code>WebSocket</code> object whose <code data-x="dom-WebSocket-readyState">readyState</code>
   attribute's value was set to <code data-x="dom-WebSocket-CLOSING">CLOSING</code> (2) as of the last
-  time the <span>event loop</span> started executing a <span data-x="concept-task">task</span> must
+  time the <span>event loop</span> reached step 1 must
   not be garbage collected if there are any event listeners registered for <code
   data-x="event-error">error</code> or <code data-x="event-close">close</code> events.</p>
 




More information about the Commit-Watchers mailing list