This section describes features that apply most directly to Web browsers. Having said that, except where specified otherwise, the requirements defined in this section do apply to all user agents, whether they are Web browsers or not.
A browsing context is an environment in which Document
objects
are presented to the user.
A tab or window in a web browser typically contains a browsing
context, as does an iframe
or frame
s in a
frameset
.
A browsing context has a corresponding WindowProxy
object.
A browsing context has an opener browsing context, which is null or a browsing context. It is initially null.
A browsing context has a disowned boolean. It is initially false.
A browsing context has an is closing boolean. It is initially false.
The following example illustrates the various possibilities of a browsing context. It can be disowned, is closing, neither, or both.
// Neither disowned nor is closing:
const popup1 = window.open();
// Disowned, but not is closing:
const popup2 = window.open();
popup2.opener = null;
// Not disowned, but is closing:
const popup3 = window.open();
popup3.close();
// Disowned, is closing:
const popup4 = window.open();
popup4.opener = null;
popup4.close();
A browsing context has a session history, which lists the
Document
objects that the browsing context has presented, is presenting,
or will present. A Document
's browsing context is the browsing
context whose session history contains the Document
, if any such
browsing context exists and has not been discarded, and null otherwise.
A Document
does not necessarily have a non-null browsing context. In particular, data mining tools are likely
to never instantiate browsing contexts. A Document
created using an API such as createDocument()
never has a non-null browsing context. And the Document
originally
created for an iframe
element, which has since been removed from the document, has no associated browsing context, since that
browsing context was discarded.
A browsing context's active window is its
WindowProxy
object's [[Window]]
internal slot value. A browsing context's active document is its
active window's associated
Document
.
In general, there is a 1-to-1 mapping from the Window
object to the
Document
object, as long as the Document
object has a non-null browsing context. There is one exception. A
Window
can be reused for the presentation of a second Document
in the
same browsing context, such that the mapping is then 1-to-2. This occurs when a
browsing context is navigated from the initial
about:blank
Document
to another, with historyHandling set to "replace
".
To set the active document of a browsing context
browsingContext to a Document
object document, run these
steps:
Let window be document's relevant global object.
Per this standard document can be created before window, which does not make much sense. See issue #2688.
Set browsingContext's active window to window.
Set window's associated
Document
to document.
Set window's relevant settings object's execution ready flag.
A browsing context has an associated creator origin (null or returns an origin), creator URL (null or returns a URL), and creator base URL (null or returns a URL). These are all initially null.
To determine the origin, given browsing context browsingContext, URL url, sandboxing flag set sandboxFlags, and two origins invocationOrigin and activeDocumentNavigationOrigin:
If sandboxFlags has its sandboxed origin browsing context flag set, then return a new opaque origin.
If url is null, then return a new opaque origin.
If activeDocumentNavigationOrigin is not null, and url's scheme is "javascript
", then return
activeDocumentNavigationOrigin.
If invocationOrigin is non-null and url is about:blank
,
then return invocationOrigin.
The result here is that two documents end up with the same underlying
origin, meaning that document.domain
affects both.
If url is about:srcdoc
, then return the origin of
browsingContext's container
document.
Return url's origin.
To create a new browsing context, given
null or a Document
object creator, null or an element embedder,
and a browsing context group group, run these steps:
Let browsingContext be a new browsing context.
If creator is non-null, then set browsingContext's creator origin to return creator's origin, browsingContext's creator URL to return creator's URL, and browsingContext's creator base URL to return creator's base URL.
Let sandboxFlags be the result of determining the creation sandboxing flags given browsingContext and embedder.
Let origin be the result of determining the
origin given browsingContext, about:blank
,
sandboxFlags, browsingContext's creator origin, and
null.
Let permissionsPolicy be the result of creating a permissions policy given browsingContext and origin. [PERMISSIONSPOLICY]
This needs to use embedder.
Let agent be the result of obtaining a similar-origin window agent given origin, group, and false.
Let realm execution context be the result of creating a new JavaScript realm given agent and the following customizations:
For the global object, create a new Window
object.
For the global this binding, use browsingContext's
WindowProxy
object.
Let topLevelCreationURL be about:blank
if embedder is
null; otherwise embedder's relevant settings object's top-level
creation URL.
Let topLevelOrigin be origin if embedder is null; otherwise embedder's relevant settings object's top-level origin.
Let settingsObject be the result of setting up a window environment settings object with realm execution context, null, topLevelCreationURL, and topLevelOrigin.
Let coop be "unsafe-none
".
If creator is non-null and creator's origin is same origin with creator's relevant settings object's top-level origin, then set coop to creator's browsing context's top-level browsing context's active document's cross-origin opener policy.
Let document be a new Document
, marked as an HTML document in quirks mode, whose content type is "text/html
",
origin is origin, active sandboxing flag set is
sandboxFlags, permissions
policy is permissionsPolicy, cross-origin
opener policy is coop, and which is ready for post-load
tasks.
Ensure that document has a single child html
node, which itself
has two empty child nodes: a head
element, and a body
element.
Set the active document of browsingContext to document.
If browsingContext's creator URL is non-null, then set document's referrer to the serialization of it.
If creator is non-null, then set document's referrer policy to creator's referrer policy.
If creator is non-null, then set document's embedder policy to creator's embedder policy.
Add document to browsingContext's session history.
Completely finish loading document.
Return browsingContext.
To create a new top-level browsing context:
Let group be the result of creating a new browsing context group.
Return group's browsing context set[0].
This creates a top-level browsing context.
To create a new auxiliary browsing context, given a browsing context opener:
Let group be opener's top-level browsing context's group
Assert: group is non-null, as navigating invokes this directly.
Let browsingContext be the result of creating a new browsing context with opener's active document, null, and group.
Append browsingContext to group.
Set browsingContext's opener browsing context to opener.
Legacy-clone a browsing session storage shed with opener's browsing session and browsingContext's browsing session. [STORAGE]
Return browsingContext.
This creates a top-level browsing context that is also an auxiliary browsing context.
To create a new nested browsing context, given an element element:
Let group be element's node document's browsing context's top-level browsing context's group.
Let browsingContext be the result of creating a new browsing context with element's node document, element, and group.
Set element's nested browsing context to browsingContext.
If element has a name
attribute, then set
browsingContext's name to the value of
this attribute.
Certain elements (for example, iframe
elements) can instantiate further browsing contexts. These elements are called browsing context
containers.
Each browsing context container has a nested browsing context, which is either a browsing context or null. It is initially null.
The container of a browsing context bc is the browsing context container whose nested browsing context is bc, or null if there is no such element.
Each browsing context bc has a container document, which is the result of running these steps:
If bc's container is null, then return null.
Return bc's container's node document.
This is equal to bc's container's shadow-including root as bc's container has to be connected.
A browsing context child is said to be a child browsing context of another browsing context parent, if child's container document is non-null and child's container document's browsing context is parent.
A browsing context child is a document-tree child browsing context of parent if child is a child browsing context and child's container is in a document tree.
A browsing context child may have a parent browsing context. This is the unique browsing context that has child as a child browsing context, if any such browsing context exists. Otherwise, the browsing context has no parent browsing context.
A browsing context A is said to be an ancestor of a browsing context B if there exists a browsing context A' that is a child browsing context of A and that is itself an ancestor of B, or if the browsing context A is the parent browsing context of B.
A browsing context that has no parent browsing context is the top-level browsing context for itself and all of the browsing contexts for which it is an ancestor browsing context.
A top-level browsing context has an associated group (null or a browsing context group). It is initially null.
It is possible to create new browsing contexts that are related to a top-level browsing context while their container is null. Such browsing contexts are called auxiliary browsing contexts. Auxiliary browsing contexts are always top-level browsing contexts.
The transitive closure of parent browsing contexts for a browsing context that is a child browsing context gives the list of ancestor browsing contexts.
The list of the descendant browsing contexts of a Document
d
is the (ordered) list returned by the following algorithm:
Let list be an empty list.
For each browsing context container container, whose nested browsing context is non-null and whose shadow-including root is d, in shadow-including tree order:
Let nestedBC be container's nested browsing context.
Append nestedBC to list.
Extend list with the list of the descendant browsing contexts of nestedBC's active document.
Return list.
A Document
d is said to be fully
active when d's browsing context is
non-null, d's browsing context's active
document is d, and either d's browsing context is a top-level browsing context,
or d's container document is fully
active.
Because they are associated with an element, child
browsing contexts are always tied to a specific Document
in their parent
browsing context. User agents must not allow the user to interact with child browsing contexts of elements that are in Document
s
that are not themselves fully active.
The following example illustrates the differences between active and fully active Document
objects. Here a.html
is loaded into a browser window, b-1.html
starts
out loaded into an iframe
as shown, and b-2.html
and c.html
are omitted (they can simply be an empty document).
<!-- a.html -->
<!DOCTYPE html>
<html lang="en">
<title>Browsing context A</title>
<iframe src="b-1.html"></iframe>
<button onclick="frames[0].location.href = 'b-2.html'">Click me</button>
<!-- b-1.html -->
<!DOCTYPE html>
<html lang="en">
<title>Browsing context B</title>
<iframe src="c.html"></iframe>
At this point, the documents given by a.html
, b-1.html
, and c.html
are all the active documents of their respective browsing
contexts. They are also all fully active.
After clicking on the button
, and thus loading a new Document
from
b-2.html
into browsing context B, we have the following results:
The a.html
Document
remains both the active
document of browsing context A, and fully active.
The b-1.html
Document
is now not the
active document of browsing context B. As such it is also not fully
active.
The new b-2.html
Document
is now the active
document of browsing context B, and is also fully active.
The c.html
Document
is still the active
document of browsing context C. However, since C's container document is the b-1.html
Document
, which is itself not fully active, this means the c.html
Document
is now not fully active (even though
it is active).
For more explorations of the complexities involved here, especially as it impacts the session history, see A Model of Navigation History. [NAVMODEL]
A child browsing context can be put into a delaying load
events mode. This is used when it is navigated, to delay the load event of its
container before the new Document
is created.
The document family of a browsing context consists of the union of all
the Document
objects in that browsing context's session
history and the document families of all those
Document
objects. The document family of a Document
object
consists of the union of all the document families of the
browsing contexts in the list of the descendant
browsing contexts of the Document
object.
The content document of a browsing context container container is the result of the following algorithm:
If container's nested browsing context is null, then return null.
Let context be container's nested browsing context.
Let document be context's active document.
If document's origin and container's node document's origin are not same origin-domain, then return null.
Return document.
top
Support in all current engines.
Returns the WindowProxy
for the top-level browsing context.
opener
[ = value ]Support in all current engines.
Returns the WindowProxy
for the opener browsing context.
Returns null if there isn't one or if it has been set to null.
Can be set to null.
parent
Support in all current engines.
Returns the WindowProxy
for the parent browsing context.
frameElement
Support in all current engines.
Returns the Element
for the browsing context container.
Returns null if there isn't one, and in cross-origin situations.
The top
attribute's getter must
run these steps:
If this Window
object's browsing context is
null, then return null.
Return this Window
object's browsing
context's top-level browsing context's WindowProxy
object.
The opener
attribute's
getter must run these steps:
Let current be this Window
object's browsing context.
If current is null, then return null.
If current's disowned is true, then return null.
If current's opener browsing context is null, then return null.
Return current's opener browsing context's
WindowProxy
object.
The opener
attribute's setter must run these steps:
If the given value is null and this Window
object's browsing context is non-null, then set this Window
object's browsing context's disowned to true.
If the given value is non-null, then return ? OrdinaryDefineOwnProperty(this
Window
object, "opener
", { [[Value]]: the given value,
[[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }).
If a browsing context's disowned is true, its window.opener
attribute is null. That prevents scripts in the
browsing context from changing any properties of its opener browsing
context's Window
object (i.e., the Window
object from which the
browsing context was created).
Otherwise, if a browsing context's disowned is false, then scripts
in that browsing context can use window.opener
to
change properties of its opener browsing context's Window
object. For
example, a script running in the browsing context can change the value of window.opener.location
, causing the opener browsing context to
navigate to a completely different document.
The parent
attribute's
getter must run these steps:
Let current be this Window
object's browsing context.
If current is null, then return null.
If current is a child browsing context of another browsing
context parent, then return parent's WindowProxy
object.
Assert: current is a top-level browsing context.
Return current's WindowProxy
object.
The frameElement
attribute's getter must run
these steps:
Let current be this Window
object's browsing context.
If current is null, then return null.
Let container be current's container.
If container is null, then return null.
If container's node document's origin is not same origin-domain with the current settings object's origin, then return null.
Return container.
An example of when these IDL attributes can return null is as follows:
<!DOCTYPE html>
<iframe></iframe>
<script>
"use strict";
const element = document.querySelector("iframe");
const iframeWindow = element.contentWindow;
element.remove();
console.assert(iframeWindow.top === null);
console.assert(iframeWindow.parent === null);
console.assert(iframeWindow.frameElement === null);
</script>
Here the browsing context corresponding to iframeWindow
was discarded when element
was removed from the document.
A browsing context A is familiar with a second browsing context B if one of the following conditions is true:
A browsing context A is allowed to navigate a second browsing context B if the following algorithm returns true:
If A is not the same browsing context as B, and A is not one of the ancestor browsing contexts of B, and B is not a top-level browsing context, and A's active document's active sandboxing flag set has its sandboxed navigation browsing context flag set, then return false.
Otherwise, if B is a top-level browsing context, and is one of the ancestor browsing contexts of A, then:
If A's active window has transient activation and A's active document's active sandboxing flag set has its sandboxed top-level navigation with user activation browsing context flag set, then return false.
Otherwise, if A's active window does not have transient activation and A's active document's active sandboxing flag set has its sandboxed top-level navigation without user activation browsing context flag set, then return false.
Otherwise, if B is a top-level browsing context, and is
neither A nor one of the ancestor
browsing contexts of A, and A's
Document
's active sandboxing flag set has its sandboxed
navigation browsing context flag set, and A is not the one
permitted sandboxed navigator of B, then return false.
Return true.
An element has a browsing context scope origin if its Document
's
browsing context is a top-level browsing
context or if all of its Document
's ancestor browsing contexts all have active
documents whose origin are the same origin as the element's
node document's origin. If an element has a browsing context scope
origin, then its value is the origin of the element's node
document.
用户代理持有 浏览上下文分组的集合 (一个 浏览上下文分组 的 集合)。
浏览上下文分组 持有 浏览上下文集合 (一个 顶级浏览上下文 的 集合)。
创建分组时 把 顶级浏览上下文 添加到 组内。 所有后续添加到 组内 的 顶级浏览上下文 都是 附属浏览上下文。
浏览上下文组 有一个关联的 代理群映射 (一个 代理群的键 到 代理群 的弱 映射)。 用户代理负责收集已经没有地方能访问的代理群。
浏览上下文组 有一个 跨域隔离 布尔,初始为 false。
浏览上下文组 有一个关联的 历史代理群键映射,是一个 源 到 代理群键 的 映射。 通过记录哪些代理群键之前用于给定的源,这个映射用于确保 域隔离 特性的一致性。
历史代理群键映射 的条目只能在浏览上下文组的生命期内获得。
创建浏览上下文组 要执行以下步骤:
令 group 为一个新的 浏览上下文组。
令 browsingContext 为用 null, null 和 group 创建新的浏览上下文 的结果。
把 browsingContext 加 到 group。
返回 group。
把 顶级浏览上下文 browsingContext 加 到 浏览上下文组 group 的步骤如下:
移除 顶级浏览上下文 browsingContext 的步骤如下:
追加 和 移除 是定义 浏览上下文组 生命期的基本操作, 会被 创建浏览上下文组, 创建附属浏览上下文 和 丢弃浏览上下文 调用。
HTML 标准层定义过 "
" 和 " "。 因为它们不够充分已经被移除。Browsing contexts can have a browsing context name. Unless stated otherwise, it is the empty string.
A valid browsing context name is any string with at least one character that does not start with a U+005F LOW LINE character. (Names starting with an underscore are reserved for special keywords.)
A valid browsing context name or keyword is any string that is either a valid
browsing context name or that is an ASCII case-insensitive match for one of:
_blank
, _self
, _parent
, or
_top
.
These values have different meanings based on whether the page is sandboxed or not, as
summarized in the following (non-normative) table. In this table, "current" means the
browsing context that the link or script is in, "parent" means the parent
browsing context of the one the link or script is in, "top" means the top-level
browsing context of the one the link or script is in, "new" means a new top-level
browsing context or auxiliary browsing context is to be created, subject to
various user preferences and user agent policies, "none" means that nothing will happen, and
"maybe new" means the same as "new" if the "allow-popups
" keyword is also specified on the
sandbox
attribute (or if the user overrode the
sandboxing), and the same as "none" otherwise.
Keyword | Ordinary effect | Effect in an iframe with...
| |
---|---|---|---|
sandbox=""
| sandbox="allow-top-navigation"
| ||
none specified, for links and form submissions | current | current | current |
empty string | current | current | current |
_blank
| new | maybe new | maybe new |
_self
| current | current | current |
_parent if there isn't a parent
| current | current | current |
_parent if parent is also top
| parent/top | none | parent/top |
_parent if there is one and it's not top
| parent | none | none |
_top if top is current
| current | current | current |
_top if top is not current
| top | none | top |
name that doesn't exist | new | maybe new | maybe new |
name that exists and is a descendant | specified descendant | specified descendant | specified descendant |
name that exists and is current | current | current | current |
name that exists and is an ancestor that is top | specified ancestor | none | specified ancestor/top |
name that exists and is an ancestor that is not top | specified ancestor | none | none |
other name that exists with common top | specified | none | none |
name that exists with different top, if familiar and one permitted sandboxed navigator | specified | specified | specified |
name that exists with different top, if familiar but not one permitted sandboxed navigator | specified | none | none |
name that exists with different top, not familiar | new | maybe new | maybe new |
Most of the restrictions on sandboxed browsing contexts are applied by other algorithms, e.g. the navigation algorithm, not the rules for choosing a browsing context given below.
The rules for choosing a browsing context, given a browsing context name name, a browsing context current, and a boolean noopener are as follows:
Let chosen be null.
Let windowType be "existing or none
".
Let sandboxingFlagSet be current's active document's active sandboxing flag set.
If name is the empty string or an ASCII case-insensitive match for
"_self
", then set chosen to current.
Otherwise, if name is an ASCII case-insensitive match for "_parent
", set chosen to current's parent browsing
context, if any, and current otherwise.
Otherwise, if name is an ASCII case-insensitive match for "_top
", set chosen to current's top-level browsing
context, if any, and current otherwise.
Otherwise, if name is not an ASCII case-insensitive match for "_blank
", there exists a browsing context whose name is the same as name, current is familiar
with that browsing context, and the user agent determines that the two browsing contexts
are related enough that it is ok if they reach each other, set chosen to that
browsing context. If there are multiple matching browsing contexts, the user agent should set
chosen to one in some arbitrary consistent manner, such as the most recently opened,
most recently focused, or more closely related.
This will be made more precise in issue #313.
Otherwise, a new browsing context is being requested, and what happens depends on the user agent's configuration and abilities — it is determined by the rules given for the first applicable option from the following list:
The user agent may inform the user that a popup has been blocked.
The user agent may report to a developer console that a popup has been blocked.
Set windowType to "new and unrestricted
".
If current's top-level browsing context's active
document's cross-origin opener policy is
"same-origin
" or "same-origin-plus-COEP
", then:
Let currentDocument be current's active document.
If currentDocument's origin is not same origin
with currentDocument's relevant settings object's top-level
origin, then set noopener to true, name to "_blank
", and windowType to "new with no
opener
".
In the presence of a cross-origin opener policy, nested documents that are cross-origin with their top-level browsing context's active document always set noopener to true.
If noopener is true, then set chosen to the result of creating a new top-level browsing context.
Otherwise:
Set chosen to the result of creating a new auxiliary browsing context with current.
If sandboxingFlagSet's sandboxed navigation browsing context flag is set, then current must be set as chosen's one permitted sandboxed navigator.
If sandboxingFlagSet's sandbox propagates to auxiliary browsing contexts flag is set, then all the flags that are set in sandboxingFlagSet must be set in chosen's popup sandboxing flag set.
If name is not an ASCII case-insensitive match for "_blank
", then set chosen's name to name.
If the newly created browsing context is immediately navigated, then the navigation will be done with historyHandling set to "replace
".
Set chosen to current.
Do nothing.
User agents are encouraged to provide a way for users to configure the user agent to always reuse current.
Return chosen and windowType.
Window
,
WindowProxy
, 和 Location
对象的安全基础设施 尽管通常不可以跨 域 访问对象, 但 Web 平台必须考虑遗留的那些例外情况。
When perform a security check is invoked, with a platformObject, identifier, and type, run these steps:
If platformObject is not a Window
or Location
object,
then return.
For each e of ! CrossOriginProperties(platformObject):
If SameValue(e.[[Property]], identifier) is true, then:
If type is "method
" and e has neither
[[NeedsGet]] nor [[NeedsSet]], then return.
Otherwise, if type is "getter
" and
e.[[NeedsGet]] is true, then return.
Otherwise, if type is "setter
" and
e.[[NeedsSet]] is true, then return.
If ! IsPlatformObjectSameOrigin(platformObject) is false, then
throw a "SecurityError
" DOMException
.
Window
and Location
objects both have a
[[CrossOriginPropertyDescriptorMap]] internal slot, whose value is initially an empty
map.
The [[CrossOriginPropertyDescriptorMap]] internal slot contains a map
with entries whose keys are (currentGlobal, objectGlobal,
propertyKey)-tuples and values are property descriptors, as a memoization of what is
visible to scripts when currentGlobal inspects a Window
or
Location
object from objectGlobal. It is filled lazily by
CrossOriginGetOwnPropertyHelper, which consults it on future lookups.
User agents should allow a value held in the map to be garbage collected along with its corresponding key when nothing holds a reference to any part of the value. That is, as long as garbage collection is not observable.
For example, with const href =
Object.getOwnPropertyDescriptor(crossOriginLocation, "href").set
the value and its
corresponding key in the map cannot be garbage collected as that would be observable.
User agents may have an optimization whereby they remove key-value pairs from the map when
document.domain
is set. This is not observable as document.domain
cannot revisit an earlier value.
For example, setting document.domain
to "example.com
" on www.example.com means user agents can remove all
key-value pairs from the map where part of the key is www.example.com, as that can never be part
of the origin again and therefore the corresponding value could never be retrieved
from the map.
If O is a Location
object, then return «
{ [[Property]]: "href
", [[NeedsGet]]: false, [[NeedsSet]]: true },
{ [[Property]]: "replace
" } ».
Return «
{ [[Property]]: "window
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "self
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "location
", [[NeedsGet]]: true, [[NeedsSet]]: true },
{ [[Property]]: "close
" },
{ [[Property]]: "closed
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "focus
" },
{ [[Property]]: "blur
" },
{ [[Property]]: "frames
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "length
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "top
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "opener
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "parent
", [[NeedsGet]]: true, [[NeedsSet]]: false },
{ [[Property]]: "postMessage
" } ».
Indexed properties do not need to be safelisted as they are handled directly by
the WindowProxy
object.
If P is "then
", @@toStringTag,
@@hasInstance, or @@isConcatSpreadable, then return
PropertyDescriptor{
[[Value]]: undefined,
[[Writable]]: false,
[[Enumerable]]: false,
[[Configurable]]: true }.
Throw a "SecurityError
" DOMException
.
Return true if the current settings object's origin is same origin-domain with O's relevant settings object's origin, and false otherwise.
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 w.document
, this
step is invoked before the document
getter is reached as part
of the [[Get]] algorithm for the WindowProxy
w.
If this abstract operation returns undefined and there is no custom behavior, the
caller needs to throw a "SecurityError
" DOMException
. In
practice this is handled by the caller calling CrossOriginPropertyFallback.
Let crossOriginKey be a tuple consisting of the current settings object, O's relevant settings object, and P.
For each e of ! CrossOriginProperties(O):
If SameValue(e.[[Property]], P) is true, then:
If the value of the [[CrossOriginPropertyDescriptorMap]] internal slot of O contains an entry whose key is crossOriginKey, then return that entry's value.
Let originalDesc be OrdinaryGetOwnProperty(O, P).
Let crossOriginDesc be undefined.
If e.[[NeedsGet]] and e.[[NeedsSet]] are absent, then:
Let value be originalDesc.[[Value]].
If ! IsCallable(value) is true, then set value to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the IDL operation P on object O.
Set crossOriginDesc to PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }.
Otherwise:
Let crossOriginGet be undefined.
If e.[[NeedsGet]] is true, then set crossOriginGet to an anonymous built-in function, created in the current Realm Record, 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 Record, that performs the same steps as the setter of the IDL attribute P on object O.
Set crossOriginDesc to PropertyDescriptor{ [[Get]]: crossOriginGet, [[Set]]: crossOriginSet, [[Enumerable]]: false, [[Configurable]]: true }.
Create an entry in the value of the [[CrossOriginPropertyDescriptorMap]] internal slot of O with key crossOriginKey and value crossOriginDesc.
Return crossOriginDesc.
Return undefined.
The reason that the property descriptors produced here are configurable is to preserve the invariants of the essential internal methods required by the JavaScript specification. In particular, since the value of the property can change as a consequence of navigation, it is required that the property be configurable. (However, see tc39/ecma262 issue #672 and references to it elsewhere in this specification for cases where we are not able to preserve these invariants, for compatibility with existing web content.) [JAVASCRIPT]
The reason the property descriptors are non-enumerable, despite this mismatching the same-origin behavior, is for compatibility with existing web content. See issue #3183 for details.
Let desc be ? O.[[GetOwnProperty]](P).
Assert: desc is not undefined.
If ! IsDataDescriptor(desc) is true, then return desc.[[Value]].
Assert: IsAccessorDescriptor(desc) is true.
Let getter be desc.[[Get]].
If getter is undefined, then throw a "SecurityError
"
DOMException
.
Return ? Call(getter, Receiver).
Let desc be ? O.[[GetOwnProperty]](P).
Assert: desc is not undefined.
If desc.[[Set]] is present and its value is not undefined, then:
Perform ? Call(setter, Receiver, «V»).
Return true.
Throw a "SecurityError
" DOMException
.
Let keys be a new empty List.
For each e of ! CrossOriginProperties(O), append e.[[Property]] to keys.
Return the concatenation of keys and « "then
",
@@toStringTag, @@hasInstance, @@isConcatSpreadable
».