@@ -93968,7 +93968,7 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
9396893968 </ol>
9396993969 </li>
9397093970
93971- <li>
93971+ <li id="idle-deadline-computation" >
9397293972 <p>If all of the following are true
9397393973
9397493974 <ul class="brief">
@@ -96460,12 +96460,21 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9646096460
9646196461 <div w-nodev>
9646296462
96463- <p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn
96464- export>map of active timers</dfn>, which is a <span>map</span>, initially empty. Each
96465- <span data-x="map key">key</span> in this map is identified by a number, which must be unique
96466- within the list for the lifetime of the object that implements the
96467- <code>WindowOrWorkerGlobalScope</code> mixin, and each <span data-x="map value">value</span> is a
96468- <code>DOMHighResTimeStamp</code>, representing the expiry time for that timer.</p>
96463+ <p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn>map of
96464+ active timers</dfn>, which is a <span>map</span>, initially empty. Each <span data-x="map
96465+ key">key</span> in this map is an identifier for a timer, and each <span data-x="map
96466+ value">value</span> is a <code>DOMHighResTimeStamp</code>, representing the expiry time for that
96467+ timer.</p>
96468+
96469+ <p class="note">For entries put in the <span>map of active timers</span> by the <span>timer
96470+ initialization steps</span>, i.e., by <code data-x="dom-setTimeout">setTimeout()</code> and <code
96471+ data-x="dom-setInterval">setInterval()</code>, the keys are numbers. For other specifications
96472+ that use the <span>run steps after a timeout</span> algorithm, the identifier is a unique
96473+ non-numeric value. Only the numeric-keyed timers are affected by <code
96474+ data-x="dom-clearTimeout">clearTimeout()</code> and <code
96475+ data-x="dom-clearInterval">clearInterval()</code>, but all timers contribute to <a
96476+ href="#idle-deadline-computation">idle deadline computation</a>, and are cleared when the
96477+ relevant global is destroyed.</p>
9646996478
9647096479 <hr>
9647196480
@@ -96508,8 +96517,8 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9650896517
9650996518 <li><p>If <var>previousId</var> was given, let <var>id</var> be <var>previousId</var>;
9651096519 otherwise, let <var>id</var> be an <span>implementation-defined</span> integer that is greater
96511- than zero that will identify the timeout to be set by this call in <var>global</var>'s <span>map
96512- of active timers</span>.</p></li>
96520+ than zero and does not already <span data-x="map exists">exist</span> in <var>global</var>'s
96521+ <span>map of active timers</span>.</p></li>
9651396522
9651496523 <li>
9651596524 <p>If the <span>surrounding agent</span>'s <span data-x="concept-agent-event-loop">event
@@ -96623,50 +96632,19 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9662396632
9662496633 <li><p>Set <var>task</var>'s <dfn>timer nesting level</dfn> to <var>nesting level</var>.</p></li>
9662596634
96626- <li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li>
96627-
96628- <li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active
96629- timers</span>[<var>id</var>] to <var>startTime</var> plus <var>timeout</var>.</p></li>
96635+ <li><p>Let <var>completionStep</var> be an algorithm step which <span data-x="queue a global
96636+ task">queues a global task</span> on the <dfn export>timer task source</dfn> given
96637+ <var>global</var> to run <var>task</var>.</p></li>
9663096638
9663196639 <li>
96632- <p>Run the following steps <span>in parallel</span>:</p>
96633-
96634- <ol>
96635- <li>
96636- <p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span
96637- data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully
96638- active</span> for a further <var>timeout</var> milliseconds (not necessarily
96639- consecutively).</p>
96640-
96641- <p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait
96642- until <var>timeout</var> milliseconds have passed with the worker not suspended (not
96643- necessarily consecutively).</p>
96644- </li>
96645-
96646- <li><p>Wait until any invocations of this algorithm that had the same <var>global</var>, that
96647- started before this one, and whose <var>timeout</var> is equal to or less than this one's,
96648- have completed.</p></li>
96649-
96650- <li>
96651- <p>Optionally, wait a further <span>implementation-defined</span> length of time.</p>
96652-
96653- <p class="note">This is intended to allow user agents to pad timeouts as needed to optimize
96654- the power usage of the device. For example, some processors have a low-power mode where the
96655- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
96656- this schedule instead of requiring the processor to use the more accurate mode with its
96657- associated higher power usage.</p>
96658- </li>
96640+ <p><span>Run steps after a timeout</span> given <var>global</var>, "<code
96641+ data-x="">setTimeout/setInterval</code>", <var>timeout</var>, <var>completionStep</var>, and
96642+ <var>id</var>.</p>
9665996643
96660- <li>
96661- <p><span>Queue a global task</span> on the <dfn>timer task source</dfn> given
96662- <var>global</var> to run <var>task</var>.</p>
96663-
96664- <p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe
96665- to remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no
96666- way for the entry's existence to be detected past this point, so it does not technically
96667- matter one way or the other).</p>
96668- </li>
96669- </ol>
96644+ <p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe to
96645+ remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no way
96646+ for the entry's existence to be detected past this point, so it does not technically matter one
96647+ way or the other).</p>
9667096648 </li>
9667196649
9667296650 <li><p>Return <var>id</var>.</p></li>
@@ -96718,6 +96696,69 @@ function scheduleWork() {
9671896696scheduleWork(); // queues a task to do lots of work</code></pre>
9671996697 </div>
9672096698
96699+ <div w-nodev>
96700+
96701+ <p>To <dfn export>run steps after a timeout</dfn>, given a <code>WindowOrWorkerGlobalScope</code>
96702+ <var>global</var>, a string <var>orderingIdentifier</var>, a number <var>milliseconds</var>, a
96703+ set of steps <var>completionSteps</var>, and an optional value <var>timerKey</var>:</p>
96704+
96705+ <ol>
96706+ <li><p>Assert: if <var>timerKey</var> is given, then the caller of this algorithm is the
96707+ <span>timer initialization steps</span>. (Other specifications must not pass
96708+ <var>timerKey</var>.)</p></li>
96709+
96710+ <li><p>If <var>timerKey</var> is not given, then set it to a new unique non-numeric
96711+ value.</p></li>
96712+
96713+ <li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li>
96714+
96715+ <li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active
96716+ timers</span>[<var>timerKey</var>] to <var>startTime</var> plus
96717+ <var>milliseconds</var>.</p></li>
96718+
96719+ <li>
96720+ <p>Run the following steps <span>in parallel</span>:</p>
96721+
96722+ <ol>
96723+ <li>
96724+ <p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span
96725+ data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully
96726+ active</span> for a further <var>milliseconds</var> milliseconds (not necessarily
96727+ consecutively).</p>
96728+
96729+ <p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait until
96730+ <var>milliseconds</var> milliseconds have passed with the worker not suspended (not
96731+ necessarily consecutively).</p>
96732+ </li>
96733+
96734+ <li><p>Wait until any invocations of this algorithm that had the same <var>global</var> and
96735+ <var>orderingIdentifier</var>, that started before this one, and whose <var>milliseconds</var>
96736+ is equal to or less than this one's, have completed.</p></li>
96737+
96738+ <li>
96739+ <p>Optionally, wait a further <span>implementation-defined</span> length of time.</p>
96740+
96741+ <p class="note">This is intended to allow user agents to pad timeouts as needed to optimize
96742+ the power usage of the device. For example, some processors have a low-power mode where the
96743+ granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
96744+ this schedule instead of requiring the processor to use the more accurate mode with its
96745+ associated higher power usage.</p>
96746+ </li>
96747+
96748+ <li><p>Perform <var>completionSteps</var>.</p></li>
96749+ </ol>
96750+ </li>
96751+ </ol>
96752+
96753+ <p class="note"><span>Run steps after a timeout</span> is meant to be used by other
96754+ specifications that want to execute developer-supplied code after a developer-supplied timeout,
96755+ in a similar manner to <code data-x="dom-setTimeout">setTimeout()</code>. (Note, however, it does
96756+ not have the nesting and clamping behavior of <code data-x="dom-setTimeout">setTimeout()</code>.)
96757+ Such specifications can choose an <var>orderingIdentifier</var> to ensure ordering within their
96758+ specification's timeouts, while not constraining ordering with respect to other specification's
96759+ timeouts.</p>
96760+
96761+ </div>
9672196762
9672296763 <h3>Microtask queuing</h3>
9672396764
0 commit comments