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 a session history, which lists the
Document
objects that the browsing context has presented, is presenting,
or will present. A browsing context's active document is
its WindowProxy
object's [[Window]]
internal slot value's associated
Document
. 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.
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 browsing context. There are two exceptions. First, 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 replacement enabled.
Second, a Document
can end up being reused for several Window
objects
when the document.open()
method is used, such that the
mapping is then many-to-1.
A Document
does not necessarily have a browsing context associated with it. In particular, data
mining tools are likely to never instantiate browsing contexts. A Document
created
using an API such as createDocument()
never has a 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.
To set the active document of a browsing context
browsingContext to a Document
object document, optionally with
a Window
object window, run these steps:
If window is not given, 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 WindowProxy
object's [[Window]] internal slot value to
window.
Set window's associated
Document
to document.
Set window's relevant settings object's execution ready flag.
A browsing context can have a creator browsing context, the browsing context that was responsible for its creation. If a browsing context has a parent browsing context, then that is its creator browsing context. Otherwise, if the browsing context has an opener browsing context, then that is its creator browsing context. Otherwise, the browsing context has no creator browsing context.
If a browsing context context has a creator browsing context creator, it also has the following properties. In what follows, let creator document be creator's active document at the time context is created:
To create a new browsing context, optionally given noopener:
If noopener was not given, let it be false.
Let browsingContext be a new browsing context.
Call the JavaScript InitializeHostDefinedRealm() abstract operation with the following customizations:
For the global object, create a new Window
object
window.
For the global this value, use browsingContext's
WindowProxy
object.
Let realm execution context be the created JavaScript execution context.
Set up a window environment settings object with realm execution context, and let settingsObject be the result.
Let document be a new Document
, marked as an HTML document in quirks mode, whose content type is "text/html
",
and which is both ready for post-load tasks and completely loaded
immediately.
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.
Set the origin of document:
If browsingContext has a creator browsing context, then the origin of document is the creator origin.
Otherwise, the origin of document is a unique opaque origin.
If browsingContext has a creator browsing context, then set document's referrer to the serialization of creator URL.
If browsingContext has a creator browsing context, then set document's referrer policy to the creator referrer policy.
Implement the sandboxing for document.
Set the allow* flags for document.
Add document to browsingContext's session history.
If noopener is false, browsingContext is a
top-level browsing context, and creator origin is same
origin with document's origin, then copy the sessionStorage
storage area of the creator origin
from the creator browsing context into browsingContext's set of session
storage areas. These areas must be considered separate, not affecting each other in any
way.
Return browsingContext.
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.
If a browsing context is the nested browsing context of a browsing context container, then the browsing context is said to be nested through the browsing context container's node document.
A browsing context child is said to be a child browsing context of another browsing context parent, if all of the following conditions hold:
child is a nested browsing context of a browsing context container element
element is connected
element's shadow-including root's browsing context is parent
A browsing context child is then a document-tree child browsing context of parent if it is a child browsing context and its browsing context container is not just connected, but also 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 is not a nested browsing context has no parent browsing context, and is the top-level browsing context of all the browsing contexts for which it is an ancestor browsing context.
The transitive closure of parent browsing contexts for a browsing context that is a nested 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 child browsing context of d that is nested through an element that is in
the Document
d, in the tree order of the elements
nesting those browsing contexts, run these substeps:
Append that child browsing context to the list list.
Append the list of the descendant browsing contexts of the active document of that child browsing context to the list list.
Return the constructed list.
A Document
is said to be fully
active when it has a browsing context and it is
the active document of that browsing context, and either its browsing
context is a top-level browsing context, or it has a parent browsing
context and the Document
through which it is nested is itself
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.
A browsing context that is a nested 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
browsing context 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 that are nested through 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 the origin specified by the current settings object are not same origin-domain, then return null.
Return document.
top
Returns the WindowProxy
for the top-level browsing context.
parent
Returns the WindowProxy
for the parent browsing context.
frameElement
Returns the Element
for the browsing context container.
Returns null if there isn't one, and in cross-origin situations.
The top
IDL attribute, on getting, must run the
following algorithm:
Let windowProxy be this Window
object's WindowProxy
object.
If there is no browsing context with windowProxy as its
WindowProxy
object, then return null.
Let context be that browsing context.
If context is a top-level browsing context, then return
context's WindowProxy
object.
Otherwise, context must have a top-level browsing context (i.e. an
ancestor browsing context with no parent browsing context). Return that
top-level browsing context's WindowProxy
object.
The parent
IDL attribute, on getting, must run the
following algorithm:
Let windowProxy be this Window
object's WindowProxy
object.
If there is no browsing context with windowProxy as its
WindowProxy
object, then return null.
Let context be that browsing context.
If context is a child browsing context of another browsing
context parent, then return parent's WindowProxy
object.
Otherwise, context must be a top-level browsing context. Return
context's WindowProxy
object.
The frameElement
IDL attribute, on getting,
must run the following algorithm:
Let windowProxy be this Window
object's WindowProxy
object.
If there is no browsing context with windowProxy as its
WindowProxy
object, then return null.
Let context be that browsing context.
If context is not a nested browsing context, then return null.
Let container be context's browsing context container.
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.
It is possible to create new browsing contexts that are related to a top-level browsing context without being nested through an element. Such browsing contexts are called auxiliary browsing contexts. Auxiliary browsing contexts are always top-level browsing contexts.
An auxiliary browsing context has an opener browsing context, which is the browsing context from which the auxiliary browsing context was created.
The opener
IDL attribute on the Window
object, on getting, must return the WindowProxy
object of the browsing
context from which the current browsing context was created (its opener
browsing context), if there is one, if it is still available, and if the current
browsing context has not disowned its opener;
otherwise, it must return null. On setting, if the new value is null then the current
browsing context must disown its
opener; if the new value is anything else then the user agent must
call the [[DefineOwnProperty]] internal method of the Window
object, passing the
property name "opener
" as the property key, and the Property Descriptor {
[[Value]]: value, [[Writable]]: true, [[Enumerable]]: true,
[[Configurable]]: true } as the property descriptor,
where value is the new value.
If a browsing context has disowned its
opener, the value of its window.opener
is null
. That prevents scripts in the browsing context from changing
any properties of its opener browsing context's Window
(i.e., the window
from which the browsing context was created).
Otherwise, if a browsing context has not disowned its
opener, then scripts in that browsing context can use window.opener
to change properties of its opener browsing
context's Window
. 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.
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 terminates positively:
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 abort these steps negatively.
Otherwise, if B is a top-level browsing context, and is one of the ancestor browsing contexts of A, then:
If this algorithm is triggered by user 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 abort these steps negatively.
Otherwise, If this algorithm is not triggered by user 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 abort these steps negatively.
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 abort these steps
negatively.
Otherwise, terminate positively!
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.
Each browsing context is defined as having a list of one or more directly reachable browsing contexts. These are:
The transitive closure of all the browsing contexts that are directly reachable browsing contexts forms a unit of related browsing contexts.
Each unit of related browsing contexts is then further divided into the smallest
number of groups such that every member of each group has an active document with an
origin that, through appropriate manipulation of the document.domain
attribute, could be made to be same
origin-domain with other members of the group, but could not be made the same as members of
any other group. Each such group is a unit of related similar-origin browsing
contexts.
There is also at most one event loop per unit of related similar-origin browsing contexts (though several units of related similar-origin browsing contexts can have a shared event loop).
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 null or a browsing context name name, a browsing context current, and a boolean noopener are as follows:
Let chosen be null.
Let new be false.
If name is the empty string or an ASCII case-insensitive match for
"_self
", then set chosen to current.
If name is an ASCII case-insensitive match for "_parent
", then set chosen to current's parent
browsing context, if any, and current otherwise.
If name is an ASCII case-insensitive match for "_top
", then set chosen to current's top-level
browsing context, if any, and current otherwise.
If name is not an ASCII case-insensitive match for "_blank
" and there exists a browsing context whose name is the same as name, and 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, then 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 #1440.
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 offer the user one of:
Set chosen to a new top-level browsing context given noopener, and set new to true.
Set chosen to an existing top-level browsing context.
If this case occurs, it means that an author has explicitly sandboxed the document that is trying to open a link.
If the user declines or the user agent doesn't offer the above, the variables remain unchanged.
Set chosen to a new
auxiliary browsing context given noopener with the opener
browsing context being current, and set new to true. If
name is not an ASCII case-insensitive match for "_blank
", then chosen's name must be set to name (otherwise, it has no name).
If the newly created browsing context is immediately navigated, then the navigation will be done with replacement enabled.
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.
If new is true, then:
Let flagSet be current's active document's active sandboxing flag set.
If flagSet's sandboxed navigation browsing context flag is set, then current must be set as chosen's one permitted sandboxed navigator.
If flagSet's sandbox propagates to auxiliary browsing contexts flag is set, then all the flags that are set in flagSet must be set in chosen's popup sandboxing flag set.
Return chosen and new.
Window
,
WindowProxy
, and Location
objectsAlthough typically objects cannot be accessed across origins, the web platform would not be true to itself if it did not have some legacy exceptions to that rule that the web depends upon.
When perform a security check is invoked, with a platformObject, identifier, and type, run these steps:
If platformObject is a Window
or Location
object,
then:
Repeat for each e that is an element 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
" } ».
Let crossOriginWindowProperties be «
{ [[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
" } ».
Repeat for each e that is an element of O's document-tree child browsing context name property set:
Add { [[Property]]: e, [[HideFromKeys]]: true } as the last element of crossOriginWindowProperties.
Return crossOriginWindowProperties.
Indexed properties do not need to be safelisted as they are handled directly by
the WindowProxy
object.
Return true if the current settings object's origin is same origin-domain with O's relevant settings object's origin, and false otherwise.
If this abstract operation returns undefined and there is no custom behavior, the
caller needs to throw a "SecurityError
" DOMException
.
If P is @@toStringTag, @@hasInstance, or @@isConcatSpreadable, then return PropertyDescriptor{ [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
Let crossOriginKey be a tuple consisting of the current settings object, O's relevant settings object, and P.
Repeat for each e that is an element 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.
Repeat for each e that is an element of ! CrossOriginProperties(O):
If e.[[HideFromKeys]] is not true, append e.[[Property]] to keys.
Return the concatenation of keys and « @@toStringTag, @@hasInstance, @@isConcatSpreadable ».