From d589ac8ff30bb7166018c31015177b997381f44a Mon Sep 17 00:00:00 2001
From: Ms2ger User agents that support JavaScript must also implement the ShadowRealm API
+ proposal. The following terms are defined there, and used in this specification:
+ JSSHADOWREALM
+
+
+
DOMHighResTimeStamp
- typedef. HRT
Performance
+ interface. HRT
@@ -9484,7 +9498,7 @@ interface DOMStringList {
If the current settings object's If the current principal settings object's cross-origin isolated
capability is false, then throw a "DataCloneError
"
DOMException
.
Let registry be the current global object's +
Let registry be the current principal global object's
CustomElementRegistry
object.
Let element be the result of internally creating a new object implementing the interface - to which the active function object corresponds, given the current + to which the active function object corresponds, given the current principal realm and NewTarget.
Set element's node document to the current global
- object's associated
+ Set element's node document to the current principal
+ global object's associated
Set element's namespace to
@@ -29387,7 +29401,7 @@ img.decode().then(() => {
the legacy factory function must perform the following steps: Let document be the current global object's Let document be the current principal global object's associated Let img be the result of creating an
@@ -34913,7 +34927,7 @@ interface HTMLAudioElement : HTMLMediaElement
must perform the following steps: Let document be the current global object's Let document be the current principal global object's associated Let audio be the result of creating an
@@ -53855,7 +53869,7 @@ interface HTMLOptionElement : HTMLElement {
function must perform the following steps: Let document be the current global object's Let document be the current principal global object's associated Let option be the result of creating an
@@ -87668,7 +87682,7 @@ dictionary DragEventInit : MouseEventInit {
Return true if the current settings object's Return true if the current principal settings object's origin is same origin-domain with
O's relevant settings object's origin, and false otherwise. This abstract operation does not return a Completion Record. Here the current settings object roughly corresponds to the "caller",
- because this check occurs before the execution
- context for the getter/setter/method in question makes its way onto the JavaScript
- execution context stack. For example, in the code Here the current principal settings object roughly corresponds to the
+ "caller", because this check occurs before the execution context for the getter/setter/method in question makes its way onto the
+ JavaScript execution context stack. For example, in the code Let crossOriginKey be a tuple consisting of the current settings
- object, O's relevant settings object, and P. Let crossOriginKey be a tuple consisting of the current principal
+ settings object, O's relevant settings object, and
+ P. For each e of CrossOriginProperties(O): Let value be originalDesc.[[Value]]. If IsCallable(value) is true, then set value to
- an anonymous built-in function, created in the current realm, that performs
- the same steps as the IDL operation P on object O.Document
.
-
Document
.
-
Document
.
-
Document
.IsPlatformObjectSameOrigin ( O )
-
w.document
, this
- step is invoked before the document
getter is reached as part
- of the [[Get]] algorithm for the WindowProxy
- w.w.document
, this step is invoked before the document
getter is reached as part of the [[Get]] algorithm for the WindowProxy
w.CrossOriginGetOwnPropertyHelper ( O, P )
@@ -87691,8 +87705,9 @@ dictionary DragEventInit : MouseEventInit {
practice this is handled by the caller calling CrossOriginPropertyFallback.
-
Set crossOriginDesc to PropertyDescriptor{ [[Value]]: value, @@ -87736,15 +87751,15 @@ dictionary DragEventInit : MouseEventInit {
Let crossOriginGet be undefined.
If e.[[NeedsGet]] is true, then set crossOriginGet to an - anonymous built-in function, created in the current realm, that performs the - same steps as the getter of the IDL attribute P on object + anonymous built-in function, created in the current principal realm, that + performs the same steps as the getter of the IDL attribute P on object O.
Let crossOriginSet be undefined.
If e.[[NeedsSet]] is true, then set crossOriginSet to an - anonymous built-in function, created in the current realm, that performs the - same steps as the setter of the IDL attribute P on object + anonymous built-in function, created in the current principal realm, that + performs the same steps as the setter of the IDL attribute P on object O.
Set crossOriginDesc to PropertyDescriptor{
@@ -88767,7 +88782,7 @@ dictionary WindowPostMessageOptions : StructuredSeri
If container's node document's origin is not same origin-domain with the
- current settings object's current principal settings object's origin, then return null. Return container.
Check if an access between two browsing contexts - should be reported, given the current global object's + should be reported, given the current principal global object's browsing context, W's browsing context, P, and the current settings - object.
If IsPlatformObjectSameOrigin(W) is true, then return ? OrdinaryGet(this, P, Receiver).
Check if an access between two browsing contexts - should be reported, given the current global object's browsing - context, W's browsing context, P, - and the current settings object.
If IsPlatformObjectSameOrigin(W) is true, then:
@@ -102803,8 +102819,8 @@ new PaymentRequest(…); // Allowed to use data-x="concept-relevant-realm">relevant realm's agent. -The agent equivalent of the current realm is the surrounding - agent.
+The agent equivalent of the current principal realm is the + surrounding agent.
@@ -103023,16 +103039,32 @@ new PaymentRequest(…); // Allowed to useThe JavaScript specification introduces the realm concept, representing a global - environment in which script is run. Each realm comes with an implementation-defined - global object; much of this specification is devoted to defining that global object - and its properties.
+ environment in which script is run. + +In the context of the JavaScript ShadowRealm API proposal, there are two kinds of realms: + JSSHADOWREALM
+ +A principal realm comes with an implementation-defined + global object; much of this specification is devoted to defining that global object + and its properties.
A synthetic realm is created by the ShadowRealm API and includes a reduced set + of properties.
For web specifications, it is often useful to associate values or algorithms with a
- realm/global object pair. When the values are specific to a particular type of realm, they are
- associated directly with the global object in question, e.g., in the definition of the
+ principal realm/global object pair. When the values are specific to a particular type of realm,
+ they are associated directly with the global object in question, e.g., in the definition of the
Window
or WorkerGlobalScope
interfaces. When the values have utility
across multiple realms, we use the environment settings object concept.
Each synthetic realm originates from a principal realm + (its settings object's + principal realm). + Generally, in contexts where the associated values or algorithms of a realm are needed, + the associated values and algorithms of this associated principal realm are used.
+Finally, in some cases it is necessary to track associated values before a realm/global object/environment settings object even comes into existence (for example, during navigation). These values are tracked in the @@ -103187,32 +103219,40 @@ new PaymentRequest(…); // Allowed to use
A global object is a JavaScript object that is the [[GlobalObject]] field of a realm.
-In this specification, all realms are created with global
+ A realm's global object is found in its [[GlobalObject]] field. A global
+ object's realm is the unique
+ realm whose global object is that object. A principal global object is a global object of a principal
+ realm. Similarly, a synthetic global object is a global object of a
+ synthetic realm. In this specification, all principal realms
+ are created with global
objects that are either There is always a 1-to-1-to-1 mapping between realms, global objects, and environment settings objects: There is always a 1-to-1-to-1 mapping between principal
+ realms, principal global objects, and environment settings objects: A realm has a [[HostDefined]] field, which contains A principal realm has a [[HostDefined]] field, which contains the realm's
settings object. A realm has a [[GlobalObject]] field, which contains the realm's global
- object. A principal realm has a global
+ object. Each global object in this specification is created during the creation of a corresponding realm, known as
- the global
- object's realm. Each principal global object in this specification is created during the
+ creation of a corresponding principal
+ realm, which is the global object's
+ realm. Each global object in this
- specification is created alongside a corresponding environment settings object,
- known as its relevant settings object. Each principal global object
+ in this specification is created alongside a corresponding environment settings
+ object, known as its relevant settings object. An environment settings object's realm execution context's
Realm component is Return realm execution context.Window
, WorkerGlobalScope
, or
WorkletGlobalScope
objects.
-
Each synthetic realm has an associated synthetic realm settings object + with the following fields:
+ +A principal realm
The principal realm which this synthetic realm exists within.
An underlying realm
The synthetic realm which this settings object represents.
A module map
A module map that is used when importing JavaScript modules.
+ +Synthetic realm settings objects' module map entries are copies of successfully
+ fetched modules found in the principal realm's module map, so this map never contains entries
+ which are null or "fetching
".
Synthetic realms are created with global objects which are initialized by the JavaScript specification's + SetDefaultGlobalBindings algorithm. Synthetic + global objects implement only certain specifically exposed interfaces.
+ +Analogously, there is always a 1-to-1-to-1 mapping between synthetic realms, synthetic global + objects, and synthetic realm settings + objects:
+ +A synthetic realm has a [[HostDefined]] field, which contains the synthetic realm's settings + object.
A synthetic realm has a global + object.
Each synthetic global object in this specification is created as part of the
+ ShadowRealm
constructor, which creates the global object's realm.
Each synthetic global object in this specification is created alongside a + corresponding synthetic realm settings object, known as its relevant synthetic + realm settings object.
A synthetic realm settings object's realm execution context's + Realm component is the synthetic realm settings object's realm.
A synthetic realm settings object's synthetic realm settings object's global object is its + realm's + global.
The principal realm of any + realm realm is defined by the following algorithm:
+ +If realm.[[HostDefined]] is a synthetic realm settings object, + then:
+ +Assert: realm is a synthetic realm.
Set realm to the principal realm of + realm.[[HostDefined]].
Assert: realm.[[HostDefined]] is an environment settings + object and realm is a principal realm.
Return realm.
The module map of a realm + realm is defined by the following algorithm:
+ +If realm is a principal realm, then return the module map of the + environment settings object of + realm.
Assert: realm is a synthetic realm.
Return the module map + of the synthetic realm settings + object of realm.
When defining algorithm steps throughout this specification, it is often important to indicate - what realm is to be used—or, equivalently, what global object or - environment settings object is to be used. In general, there are at least four - possibilities:
+ what principal realm is to be used—or, equivalently, what principal global + object or environment settings object is to be used. In general, there are at + least four possibilities:The incumbent realm is that of b.html
.
The current realm is that of c.html
(since it is the
- print()
method from c.html
whose code is
- running).
The current principal realm is that of c.html
(since it is the print()
method from
+ c.html
whose code is running).
The relevant realm of the object on which
the print()
method is being called is that of d.html
.
If the algorithm for the getBattery()
method
- had instead used the current realm, all the results would be reversed. That is,
- after the first call to getBattery()
in outer.html
, the Navigator
object in current principal realm, all the results would be reversed.
+ That is, after the first call to
function would thus return a promise from the "wrong" realm.
+ Since this is undesirable, the algorithm instead uses the relevant realm, giving the sensible results indicated in
the comments above.getBattery()
in
+ outer.html
, the Navigator
object in inner.html
would be permanently storing a Promise
object
created in outer.html
's realm, and calls like that inside the
- hello()
function would thus return a promise from the "wrong" realm. Since
- this is undesirable, the algorithm instead uses the hello()
With this in hand, we define the entry execution context to be the most recently pushed item in the JavaScript execution context stack that is a realm execution context. The entry - realm is the entry execution context's Realm component.
+ realm is the principal realm of the + entry execution context's Realm component.Then, the entry settings object is the environment settings object of the
Return context's Realm component's principal realm's settings object. The JavaScript specification defines the current realm, also known as the "current
Realm Record". JAVASCRIPT Then, the current settings object is the environment settings object of the current
+ The current principal realm is the principal realm of the current
realm. Similarly, the current global object is the global object of the current realm. Note that the current realm, unlike the entry, incumbent and
+ relevant concepts, can refer to a synthetic realm. Almost all uses of the "current"
+ concept in this document and other Web specifications need to refer to the current principal
+ realm as well. One exception is JavaScript module processing, as synthetic realms have a separate set of module instances (derived from a common
+ module map across the shared environment settings object). Then, the current principal settings object is the environment settings object of the current
+ principal realm. Similarly, the current principal global object is the global object of the current principal realm. An environment settings object, containing various settings that are shared
- with other scripts in the same context. A realm where the script is evaluated, which is shared with other
+ scripts in the same context. Note that, in the case of
+ module scripts (but not classic scripts), this realm can be a synthetic
+ realm.Relevant
@@ -103854,11 +104011,13 @@ document.querySelector("button").addEventListener("click", bound);
module script). All scripts have:
-
The settings object of a script is the + settings object of the + principal realm of the script's + realm.
A classic script is a type of script that has the following additional item:
@@ -104406,7 +104570,8 @@ document.querySelector("button").addEventListener("click", bound);Fetch a single module script given url, settingsObject,
- "script
", options, settingsObject, "script
", options, settingsObject's
+ realm, "client
", true, and with the following steps given result:
Fetch the descendants of
and link result given settingsObject, "script
", and onComplete.
Fetch a single module script given url, settingsObject,
- destination, options, settingsObject, "destination, options, settingsObject's
+ realm, "
client
", true, and with the following steps given result:
Fetch a single module script given url,
- fetchClient, destination, options, settingsObject,
+ fetchClient, destination, options, settingsObject's
+ realm,
"client
", true, and onSingleFetchComplete as defined below. If
performFetch was given, pass it along as well.
Fetch the descendants of and link result given fetchClient, - destination, and onComplete. If performFetch was given, pass - it along as well.
To fetch a single module script, given a URL url, an environment settings object fetchClient, a destination destination, a script - fetch options options, an environment settings object - settingsObject, a referrer - referrer, an optional ModuleRequest Record moduleRequest, a - boolean isTopLevel, an algorithm + fetch options options, a realm moduleMapRealm, + a referrer referrer, + an optional ModuleRequest Record moduleRequest, + a boolean isTopLevel, an algorithm onComplete, and an optional perform the fetch hook performFetch, run these steps. onComplete must be an algorithm accepting null (on failure) or a module script (on success).
@@ -104748,14 +104917,14 @@ document.querySelector("button").addEventListener("click", bound); moduleRequest.Assert: the result of running the module type allowed steps - given moduleType and settingsObject's realm is true. Otherwise we would not have reached this point because a - failure would have been raised when inspecting moduleRequest.[[Attributes]] in + given moduleType and moduleMapRealm is true. + Otherwise we would not have reached this point because a failure would have been raised when + inspecting moduleRequest.[[Attributes]] in create a JavaScript module script or fetch a single imported module script.
Let moduleMap be settingsObject's module map.
Let moduleMap be moduleMapRealm's module map.
If moduleMap[(url, moduleType)] is
"fetching
", wait in parallel until that entry's value
@@ -104766,6 +104935,23 @@ document.querySelector("button").addEventListener("click", bound);
data-x="map exists">exists, run onComplete given
moduleMap[(url, moduleType)], and return.
If moduleMapRealm is a synthetic realm, then:
+ +Let script be the result of + cloning a module + given url, moduleType and moduleMapRealm.
Set moduleMap[(url, + moduleType)] to script.
Run onComplete given script.
Return.
Set moduleMap[(url,
moduleType)] to "fetching
".
Let settingsObject be moduleMapRealm's settings object.
If mimeType is a JavaScript MIME type and moduleType
is "javascript
", then set moduleScript to the result of
creating a JavaScript module script given sourceText,
@@ -104871,13 +105060,92 @@ document.querySelector("button").addEventListener("click", bound);
To clone a module given a URL, moduleType, and + moduleMapRealm, perform the following steps.
+ +Assert: moduleMapRealm is a synthetic realm.
Let parentModuleMap be moduleMapRealm's + principal realm's settings object's module map.
Assert: parentModuleMap[(url, moduleType)] + exists.
Let parentModule be parentModuleMap[(url, + moduleType)].
Let childModule be a new module script that this algorithm will + subsequently initialize.
Set childModule's realm to + moduleMapRealm.
Set childModule's base URL to + parentModule's base URL.
Set childModule's fetch + options to parentModule's fetch options.
Set childModule's error to + rethrow to parentModule's error + to rethrow.
Should this be cloned? Can this be an arbitrary + value?Let parentRecord be parentModule's record.
If parentRecord is null, then:
+ +Let parentParseError be parentModule's parse error.
Assert: parentParseError is a SyntaxError
+ instance.
Set childModule's parse
+ error to a new SyntaxError
in moduleMapRealm with the same
+ message as parentParseError.
Set childModule's record to + null.
Return childModule.
Set childModule's error to + rethrow to null.
Can parentModule be a CSS or JSON module?
Set childModule's record to + a new Source Text Module Record { [[Realm]]: moduleMapRealm, + [[Environment]]: undefined, [[Namespace]]: undefined, [[Status]]: unlinked, [[EvaluationError]]: + undefined, [[HostDefined]]: childModule, [[ECMAScriptCode]]: + parentRecord.[[ECMAScriptCode]], [[Context]]: empty, [[ImportMeta]]: empty, + [[RequestedModules]]: parentRecord.[[RequestedModules]], + [[ImportEntries]]: parentRecord.[[ImportEntries]], + [[LocalExportEntries]]: parentRecord.[[LocalImportEntries]], + [[IndirectExportEntries]]: parentRecord.[[IndirectImportEntries]], + [[StarExportEntries]]: parentRecord.[[StarImportEntries]], [[DFSIndex]]: undefined, + [[DFSAncestorIndex]]: undefined }. Is 'unlinked' correct?
Return childModule.
To fetch a single imported module script, given a URL url, an environment settings object fetchClient, a destination destination, a script - fetch options options, environment settings object - settingsObject, a referrer - referrer, a ModuleRequest Record moduleRequest, an - algorithm onComplete, and an optional options, a realm moduleMapRealm, + a referrer referrer, + a ModuleRequest Record moduleRequest, + an algorithm onComplete, and an optional perform the fetch hook performFetch, run these steps. onComplete must be an algorithm accepting null (on failure) or a module script (on success).
@@ -104892,11 +105160,11 @@ document.querySelector("button").addEventListener("click", bound); request steps given moduleRequest.If the result of running the module type allowed steps given - moduleType and settingsObject's realm is false, then run onComplete given null, and return.
Fetch a single module script given url, fetchClient, - destination, options, settingsObject, referrer, + destination, options, moduleMapRealm, referrer, moduleRequest, false, and onComplete. If performFetch was given, pass it along as well.
Let script be a new classic script that this algorithm will subsequently initialize.
Set script's settings - object to settings.
Set script's realm to + settings's realm.
Set script's base URL to baseURL.
Let script be a new module script that this algorithm will subsequently initialize.
Set script's settings - object to settings.
Set script's realm to + settings's realm.
Set script's base URL to baseURL.
Assert: there is a current settings object.
Assert: there is a current principal settings object.
Set settingsObject to the current settings object.
Set settingsObject to the current principal settings + object.
Set baseURL to settingsObject's API base URL.
If script is a classic script and script's muted errors is true, then return.
-Let settings object be the current settings object.
Let settings object be the current principal settings + object. Should this work for synthetic realms?
If script is not null, then set settings object to
script's settings
@@ -106719,7 +106989,8 @@ dictionary PromiseRejectionEventInit : EventInit
If realm is not null, then let job settings be the settings object for realm. Otherwise,
+ data-x="concept-realm-settings-object">settings object
import()
expression is evaluated,
there will still be no active script. Fortunately that is handled by our
implementation of HostLoadImportedModule by falling back to using the
- current settings object's API base URL.
+ current principal settings object's API base URL.
Let settingsObject be the current settings object.
Let moduleMapRealm be the current realm.
+ +In the case of the ShadowRealm.prototype.importValue
API the
+ current realm is set to the appropriate synthetic realm.
If settingsObject's global
- object implements WorkletGlobalScope
or ServiceWorkerGlobalScope
+
If moduleMapRealm's principal
+ realm's (can we check moduleMapRealm directly?)
+ global object implements
+ WorkletGlobalScope
or ServiceWorkerGlobalScope
and loadState is undefined, then:
loadState is undefined when the current fetching process has been @@ -107102,9 +107380,6 @@ import "https://example.com/foo/../module2.mjs";
Set referencingScript to referrer.[[HostDefined]].
-Set settingsObject to referencingScript's settings object.
Set fetchOptions to the new descendant script fetch options for referencingScript's fetch options.
Set fetchReferrer to referrer's base URL.
Set moduleMapRealm to referencing script's realm
+ +In the case of a dynamic import nested within a module loaded through the
+ ShadowRealm.prototype.importValue
API, the realm of the script is set to the
+ appropriate synthetic realm.
Let settingsObject be moduleMapRealm's + principal realm's + settings object.
Disallow further import maps given settingsObject.
Let url be the result of resolving a
@@ -107170,7 +107458,7 @@ import "https://example.com/foo/../module2.mjs";
Fetch a single imported module script given url,
fetchClient, destination, fetchOptions,
- settingsObject, fetchReferrer, moduleRequest, and
+ moduleMapRealm, fetchReferrer, moduleRequest, and
onSingleFetchComplete as defined below. If loadState is not undefined and
loadState.[[PerformFetch]] is not null, pass loadState.[[PerformFetch]]
along as well.
JavaScript contains an implementation-defined HostInitializeShadowRealm(realm) + abstract operation. User agents must use the following implementation: + JSSHADOWREALM
+ +Let settings be a new synthetic realm settings object that this + algorithm will subsequently initialize.
Set settings's principal realm to the + current principal realm.
Set settings's underlying realm to + realm.
Set settings's module + map to a new module map, initially empty.
Set realm.[[HostDefined]] to settings.
Define the global property references on realm.[[GlobalObject]], + given realm.
Let selfSteps be the following series of steps:
+ +Let thisValue be the result of getting the ShadowRealm global object with realm and the this + value.
Return thisValue.
Let selfGetter be CreateBuiltinFunction(selfSteps, 0, + "get self", « », realm).
Let selfDescriptor be the PropertyDescriptor{[[Get]]: + selfGetter, [[Set]]: undefined, [[Enumerable]]: true, [[Configurable]]: + true}.
Perform ! DefinePropertyOrThrow(realm.[[GlobalObject]], "self", + selfDescriptor).
Assert: calleeRealm is a synthetic realm
If thisValue is null or undefined, return + calleeRealm.[[GlobalObject]].
If Type(thisValue) is not Object, then throw a + TypeError.
If thisValue is not a global object, then throw a + TypeError.
Assert: thisValue is + calleeRealm.[[GlobalObject]].
Return thisValue.
Let parsed be the result of encoding-parsing a URL given - string, relative to the current settings object.
If parsed is failure, then return a promise rejected with a
"SyntaxError
" DOMException
.
Let realm be the current realm.
Let realm be the current principal realm.
Let p be a new promise.
It does its URL parsing up front, on the event loop, before going to the in parallel steps. This is necessary, since parsing depends on the current - settings object, which would no longer be current after going in + principal settings object, which would no longer be current after going in parallel.
Alternately, it could have saved a reference to the current settings
+ Alternately, it could have saved a reference to the current principal settings
object's API base URL and used it during the in parallel steps;
that would have been equivalent. However, we recommend instead doing as much work as possible up
front, as this example does. Attempting to save the correct values can be error prone; for
- example, if we'd saved just the current settings object, instead of its API
- base URL, there would have been a potential race.
It implicitly passes a list of strings from the
initial steps to the in parallel steps. This is OK, as both OnBeforeUnloadEventHandlerNonNull? OnBeforeUnl
In practice, this only affects the resolution of relative URLs via import()
,
which consult the base URL of the associated
script. Nulling out [[ScriptOrModule]] means that HostLoadImportedModule will
- fall back to the current settings object's API base URL.
Let outside settings be the current settings object.
+Let outside settings be the current principal settings object.
Let worker URL be the result of encoding-parsing a URL given @@ -116477,7 +116831,8 @@ interface SharedWorker : EventTarget { data-x="">name member is set to the value of options and whose other members are set to their default values.
Let outside settings be the current settings object.
Let outside settings be the current principal settings + object.
Let urlRecord be the result of encoding-parsing a URL given @@ -116679,7 +117034,8 @@ interface SharedWorker : EventTarget { data-x="concept-WorkerGlobalScope-type">type
module
", throw a
TypeError
exception.
- Let settings object be the current settings object.
Let settings object be the current principal settings + object.
If urls is empty, return.