@@ -2933,6 +2933,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
2933
2933
<li><dfn data-x-href="https://tc39.es/ecma262/#sec-built-in-function-objects">NewTarget</dfn></li>
2934
2934
<li><dfn data-x-href="https://tc39.es/ecma262/#running-execution-context">running JavaScript execution context</dfn></li>
2935
2935
<li><dfn data-x-href="https://tc39.es/ecma262/#surrounding-agent">surrounding agent</dfn></li>
2936
+ <li><dfn data-x-href="https://tc39.es/ecma262/#sec-abstract-closure">abstract closure</dfn></li>
2936
2937
<li><dfn data-x-href="https://tc39.es/ecma262/#sec-well-known-symbols">Well-Known Symbols</dfn>, including
2937
2938
<dfn>@@hasInstance</dfn>,
2938
2939
<dfn>@@isConcatSpreadable</dfn>,
@@ -2974,14 +2975,14 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
2974
2975
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-createbytedatablock">CreateByteDataBlock</dfn> abstract operation</li>
2975
2976
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-createdataproperty">CreateDataProperty</dfn> abstract operation</li>
2976
2977
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-detacharraybuffer">DetachArrayBuffer</dfn> abstract operation</li>
2977
- <li>The <dfn data-x="js-EnqueueJob" data-x-href="https://tc39.es/ecma262/#sec-enqueuejob">EnqueueJob</dfn> abstract operation</li>
2978
2978
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-enumerableownproperties">EnumerableOwnProperties</dfn> abstract operation</li>
2979
2979
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-finishdynamicimport">FinishDynamicImport</dfn> abstract operation</li>
2980
2980
<li>The <dfn data-x="js-OrdinaryFunctionCreate" data-x-href="https://tc39.es/ecma262/#sec-ordinaryfunctioncreate">OrdinaryFunctionCreate</dfn> abstract operation</li>
2981
2981
<li>The <dfn data-x="js-Get" data-x-href="https://tc39.es/ecma262/#sec-get-o-p">Get</dfn> abstract operation</li>
2982
2982
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-getactivescriptormodule">GetActiveScriptOrModule</dfn> abstract operation</li>
2983
2983
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-getfunctionrealm">GetFunctionRealm</dfn> abstract operation</li>
2984
2984
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-hasownproperty">HasOwnProperty</dfn> abstract operation</li>
2985
+ <li>The <dfn data-x="js-HostEnqueuePromiseJob" data-x-href="https://tc39.es/ecma262/#sec-hostenqueuepromisejob">HostEnqueuePromiseJob</dfn> abstract operation</li>
2985
2986
<li>The <dfn data-x="js-HostEnsureCanCompileStrings" data-x-href="https://tc39.es/ecma262/#sec-hostensurecancompilestrings">HostEnsureCanCompileStrings</dfn> abstract operation</li>
2986
2987
<li>The <dfn data-x="js-HostImportModuleDynamically" data-x-href="https://tc39.es/proposal-dynamic-import/#sec-hostimportmoduledynamically">HostImportModuleDynamically</dfn> abstract operation</li>
2987
2988
<li>The <dfn data-x="js-HostPromiseRejectionTracker" data-x-href="https://tc39.es/ecma262/#sec-host-promise-rejection-tracker">HostPromiseRejectionTracker</dfn> abstract operation</li>
@@ -3009,8 +3010,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
3009
3010
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-objectcreate">ObjectCreate</dfn> abstract operation</li>
3010
3011
<li>The <dfn data-x="js-ParseModule" data-x-href="https://tc39.es/ecma262/#sec-parsemodule">ParseModule</dfn> abstract operation</li>
3011
3012
<li>The <dfn data-x="js-ParseScript" data-x-href="https://tc39.es/ecma262/#sec-parse-script">ParseScript</dfn> abstract operation</li>
3012
- <li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-promisereactionjob">PromiseReactionJob </dfn> abstract operation</li>
3013
- <li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-promiseresolvethenablejob">PromiseResolveThenableJob </dfn> abstract operation</li>
3013
+ <li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-newpromisereactionjob">NewPromiseReactionJob </dfn> abstract operation</li>
3014
+ <li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob">NewPromiseResolveThenableJob </dfn> abstract operation</li>
3014
3015
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-regexpbuiltinexec">RegExpBuiltinExec</dfn> abstract operation</li>
3015
3016
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-regexpcreate">RegExpCreate</dfn> abstract operation</li>
3016
3017
<li>The <dfn data-x-href="https://tc39.es/ecma262/#sec-runjobs">RunJobs</dfn> abstract operation</li>
@@ -90832,8 +90833,8 @@ interface <dfn>ApplicationCache</dfn> : <span>EventTarget</span> {
90832
90833
spec="WEBIDL"></p>
90833
90834
90834
90835
<p>When Web IDL is used to <span data-x="es-invoking-callback-functions">invoke</span> author
90835
- code, or when <span>EnqueueJob </span> invokes a promise job, they use the following algorithms to
90836
- track relevant data for determining the <span>incumbent settings object</span>:</p>
90836
+ code, or when <span>HostEnqueuePromiseJob </span> invokes a promise job, they use the following
90837
+ algorithms to track relevant data for determining the <span>incumbent settings object</span>:</p>
90837
90838
90838
90839
<p>To <dfn data-export="">prepare to run a callback</dfn> with an <span>environment settings
90839
90840
object</span> <var>settings</var>:</p>
@@ -91142,65 +91143,35 @@ document.querySelector("button").addEventListener("click", bound);
91142
91143
user with a mechanism to just close the page entirely, without running any <code
91143
91144
data-x="event-unload">unload</code> event handlers.</p>
91144
91145
91145
- <h5>Integration with the JavaScript job queue</h5>
91146
+ <span id="integration-with-the-javascript-job-queue"></span>
91147
+ <span id="enqueuejob(queuename,-job,-arguments)"></span>
91148
+ <h5 id="hostenqueuepromisejob"><dfn>HostEnqueuePromiseJob</dfn>(<var>job</var>,
91149
+ <var>realm</var>)</h5>
91146
91150
91147
- <p>The JavaScript specification defines the JavaScript job and job queue abstractions in order to
91148
- specify certain invariants about how promise operations execute with a clean <span>JavaScript
91149
- execution context stack</span> and in a certain order. However, as of the time of this writing
91150
- the definition of <span data-x="js-EnqueueJob">EnqueueJob</span> in that specification is not
91151
- sufficiently flexible to integrate with HTML as a host environment. <ref spec=JAVASCRIPT></p>
91152
-
91153
- <p class="note">This is not strictly true. It is in fact possible, by taking liberal advantage of
91154
- the many "implementation defined" sections of the algorithm, to contort it to our purposes.
91155
- However, the end result is a mass of messy indirection and workarounds that essentially bypasses
91156
- the job queue infrastructure entirely, albeit in a way that is technically sanctioned within the
91157
- bounds of implementation-defined behavior. We do not take this path, and instead introduce the
91158
- following <span>willful violation</span>.</p>
91159
-
91160
- <p>As such, user agents must instead use the following definition in place of that in the
91161
- JavaScript specification. These ensure that the promise jobs enqueued by the JavaScript
91162
- specification are properly integrated into the user agent's <span data-x="event loop">event
91163
- loops</span>.</p>
91164
-
91165
- <p>The <span>RunJobs</span> abstract operation from the JavaScript specification must
91166
- not be used by user agents.</p>
91167
-
91168
- <h6><dfn>EnqueueJob</dfn>(<var>queueName</var>, <var>job</var>, <var>arguments</var>)</h6>
91169
-
91170
- <p>When the JavaScript specification says to call the EnqueueJob abstract operation, the
91171
- following algorithm must be used in place of JavaScript's <span
91172
- data-x="js-EnqueueJob">EnqueueJob</span>:</p>
91151
+ <p>JavaScript contains an implementation-defined <span
91152
+ data-x="js-HostEnqueuePromiseJob">HostEnqueuePromiseJob</span>(<var>job</var>, <var>realm</var>)
91153
+ abstract operation to schedule Promise-related operations. HTML schedules these operations in the
91154
+ microtask queue. User agents must use the following implementation: <ref spec=JAVASCRIPT></p>
91173
91155
91174
91156
<ol>
91175
- <li><p>Assert: <var>queueName</var> is <code data-x="">"PromiseJobs"</code>. (<code
91176
- data-x="">"ScriptJobs"</code> must not be used by user agents.)</p></li>
91177
-
91178
- <li><p>Assert: <var>job</var> is either <span>PromiseResolveThenableJob</span> or
91179
- <span>PromiseReactionJob</span>. (The following steps would need to be updated if another type of
91180
- promise job were introduced.)</p></li>
91181
-
91182
91157
<li>
91183
- <p>Let <var>job settings</var> be determined by switching on <var>job</var>:</p>
91158
+ <p>If <var>realm</var> is not null, then let <var>job settings</var> be the <span
91159
+ data-x="concept-realm-settings-object">settings object</span> for <var>realm</var>. Otherwise,
91160
+ let <var>job settings</var> be null.</p>
91184
91161
91185
- <dl class="switch">
91186
- <dt><span>PromiseResolveThenableJob</span></dt>
91187
- <dd>
91188
- <p>The <span data-x="concept-realm-settings-object">settings object</span> for
91189
- <var>arguments</var>[2].[[Realm]]. (I.e., the <span data-x="JavaScript realm">Realm</span> of
91190
- the <code data-x="">then</code> function.)</p>
91191
- </dd>
91192
-
91193
- <dt><span>PromiseReactionJob</span></dt>
91194
- <dd>
91195
- <p>If <var>arguments</var>[0].[[Handler]] is not undefined, then the <span
91196
- data-x="concept-realm-settings-object">settings object</span> of
91197
- <var>arguments</var>[0].[[Handler]].[[Realm]]; otherwise, null.</p>
91162
+ <div class="note">
91163
+ <p>If <var>realm</var> is not null, it is the <span data-x="JavaScript realm">Realm</span> of
91164
+ the author code that will run. When <var>job</var> is returned by
91165
+ <span>NewPromiseReactionJob</span>, it is the realm of the promise's handler function. When
91166
+ <var>job</var> is returned by <span>NewPromiseResolveThenableJob</span>, it is the realm of
91167
+ the <code data-x="">then</code> function.
91198
91168
91199
- <p class="note">If the handler is undefined, then we are in a case like <code
91200
- data-x="">promise.then(null, null)</code>. In this case, no author code will run, so all of
91201
- the steps below that would otherwise use <var>job settings</var> get skipped.</p>
91202
- </dd>
91203
- </dl>
91169
+ <p>If <var>realm</var> is null, either no author code will run or author code is guaranteed to
91170
+ throw. For the former, the author may not have passed in code to run, such as in <code
91171
+ data-x="">promise.then(null, null)</code>. For the latter, it is because a revoked Proxy was
91172
+ passed. In both cases, all the steps below that would otherwise use <var>job settings</var>
91173
+ get skipped.</p>
91174
+ </div>
91204
91175
</li>
91205
91176
91206
91177
<li><p>Let <var>incumbent settings</var> be the <span>incumbent settings object</span>.</p></li>
@@ -91244,7 +91215,8 @@ document.querySelector("button").addEventListener("click", bound);
91244
91215
handler</span> will be created by the <span data-x="getting the current value of the event
91245
91216
handler">get the current value of the event handler</span> algorithm, which creates a function
91246
91217
with null [[ScriptOrModule]] value. Thus, when the promise machinery calls
91247
- <span>EnqueueJob</span>, there will be no <span>active script</span> to pass along.</p>
91218
+ <span>HostEnqueuePromiseJob</span>, there will be no <span>active script</span> to pass
91219
+ along.</p>
91248
91220
91249
91221
<p>As a consequence, this means that when the <code>import()</code> expression is evaluated,
91250
91222
there will still be no <span>active script</span>. Fortunately that is handled by our
@@ -91286,8 +91258,12 @@ document.querySelector("button").addEventListener("click", bound);
91286
91258
runs.</p>
91287
91259
</li>
91288
91260
91289
- <li><p>Let <var>result</var> be the result of performing the abstract operation specified by
91290
- <var>job</var>, using the elements of <var>arguments</var> as its arguments.</p></li>
91261
+ <li>
91262
+ <p>Let <var>result</var> be <var>job</var>().</p>
91263
+
91264
+ <p class="note"><var>job</var> is an <span>abstract closure</span> returned by
91265
+ <span>NewPromiseReactionJob</span> or <span>NewPromiseResolveThenableJob</span>.</p>
91266
+ </li>
91291
91267
91292
91268
<li><p>If <var>script execution context</var> is not null, then <span data-x="stack
91293
91269
pop">pop</span> <var>script execution context</var> from the <span>JavaScript execution context
0 commit comments