- 7.3 Infrastructure for sequences of documents
- 7.3.1 Navigables
- 7.3.1.1 Traversable navigables
- 7.3.1.2 Top-level traversables
- 7.3.1.3 Child navigables
- 7.3.1.4 Jake diagrams
- 7.3.1.5 Related navigable collections
- 7.3.1.6 Navigable destruction
- 7.3.1.7 Navigable target names
- 7.3.2 Browsing contexts
- 7.3.2.1 Creating browsing contexts
- 7.3.2.2 Related browsing contexts
- 7.3.2.3 Groupings of browsing contexts
- 7.3.3 Fully active documents
7.3 Infrastructure for sequences of documents
This standard contains several related concepts for grouping sequences of documents. As a
brief, non-normative summary:
Navigables are a user-facing representation of a sequence
of documents, i.e., they represent something that can be navigated between documents. Typical
examples are tabs or windows in a web browser, or iframes, or
frames in a frameset.
Traversable navigables are a special type of
navigable which control the session history of themselves and of their descendant navigables.
That is, in addition to their own series of documents, they represent a tree of further series
of documents, plus the ability to linearly traverse back and forward through a flattened view of
this tree.
Browsing contexts are a developer-facing
representation of a series of documents. They correspond 1:1 with WindowProxy
objects. Each navigable can present a series of browsing contexts, with switches between
those browsing contexts occurring under certain well-defined circumstances.
Most of this standard works in the language of navigables, but certain APIs expose the
existence of browsing context switches, and so some parts of the standard need to work in terms
of browsing contexts.
7.3.1 Navigables
A navigable presents a Document to the user via its active session history entry. Each navigable has:
The current session history entry and the
active session history entry are usually the same,
but they get out of sync when:
This can be safely read from within the session history traversal queue of the
navigable's top-level traversable. Although a
navigable's active history entry can
change synchronously, the new entry will always have the same Document.
This will always equal the navigable's active
document's relevant global object; this is kept in sync by the make
active algorithm.
7.3.1.1 Traversable navigables
A traversable navigable is a navigable that also controls which
session history entry should be the current
session history entry and active session history
entry for itself and its descendant navigables.
In addition to the properties of a navigable, a traversable
navigable has:
To get the traversable navigable of
a navigable inputNavigable:
Let navigable be inputNavigable.
While navigable is not a traversable navigable, set
navigable to navigable's parent.
Return navigable.
7.3.1.2 Top-level traversables
Currently, all traversable navigables
are top-level traversables. Future proposals envision
introducing non-top-level traversables.
A user agent holds a top-level traversable set (a
set of top-level traversables). These are
typically presented to the user in the form of browser windows or browser tabs.
To get the top-level traversable of a
navigable inputNavigable:
Let navigable be inputNavigable.
While navigable's parent is not null, set
navigable to navigable's parent.
Return navigable.
To create a fresh top-level traversable given a URL
initialNavigationURL and an optional POST resource-or-null
initialNavigationPostResource (default null):
Let traversable be the result of creating a new top-level
traversable given null and the empty string.
-
Navigate traversable to initialNavigationURL using
traversable's active document, with documentResource set to
initialNavigationPostResource.
We treat these initial navigations as traversable navigating itself,
which will ensure all relevant security checks pass.
Return traversable.
7.3.1.3 Child navigables
Certain elements (for example, iframe elements)
can present a navigable to the user. These elements are called navigable containers.
Each navigable container has a content navigable, which is either a navigable or
null. It is initially null.
A navigable navigable is a child navigable of another navigable potentialParent when
navigable's parent is potentialParent. We
can also just say that a navigable "is a child navigable", which means
that its parent is non-null.
All child navigables are the content
navigable of their container.
7.3.1.4 Jake diagrams
A useful method for visualizing sequences of documents, and in particular navigables and their session
history entries, is the Jake diagram. A typical Jake diagram is the
following:
| 0 | 1 | 2 | 3 | 4 |
|---|
top | /t-a | /t-a#foo | /t-b |
|---|
frames[0] | /i-0-a | /i-0-b |
|---|
frames[1] | /i-1-a | /i-1-b |
|---|
Here, each numbered column denotes a possible value for the traversable's session history step. Each labeled row depicts a
navigable, as it transitions between different URLs and documents. The first,
labeled top, being the top-level traversable, and the others
being child navigables. The documents are given by the
background color of each cell, with a new background color indicating a new document in that
navigable. The URLs are given by the text content of the cells; usually they are
given as relative URLs for brevity, unless a cross-origin case
is specifically under investigation. A given navigable might not exist at a given step, in which
case the corresponding cells are empty. The bold-italic step number depicts the current session history step of the traversable,
and all cells with bold-italic URLs represent the current session history entry for that row's
navigable.
Thus, the above Jake diagram depicts the following sequence of events:
A top-level traversable is created, starting at the URL /t-a, with two child navigables
starting at /i-0-a and /i-1-a
respectively.
The first child navigable is navigated to another
document, with URL /i-0-b.
The second child navigable is navigated to another
document, with URL /i-1-b.
The top-level traversable is navigated to the
same document, updating its URL to /t-a#foo.
The top-level traversable is navigated to another
document, with URL /t-b. (Notice how this document, of course, does not
carry over the old document's child navigables.)
The traversable was traversed by a
delta of −3, back to step 1.
Jake diagrams are a powerful tool for visualizing the
interactions of multiple navigables, navigations, and traversals. They cannot capture every
possible interaction — for example, they only work with a single level of nesting —
but we will have occasion to use them to illustrate several complex situations throughout this
standard.
Jake diagrams are named after their creator,
the inimitable Jake Archibald.
7.3.1.5 Related navigable collections
It is often helpful in this standard's algorithms to look at collections of navigables starting at a given Document. This section
contains a curated set of algorithms for collecting those navigables.
The return values of these algorithms are ordered so that parents appears before
their children. Callers rely on this ordering.
Starting with a Document, rather than a navigable, is
generally better because it makes the caller cognizant of whether they are starting with a
fully active Document or not. Although non-fully active
Documents do have ancestor and descendant navigables, they often behave as if they
don't (e.g., in the window.parent getter).
The ancestor navigables of a Document
document are given by these steps:
Let navigable be document's node navigable's parent.
Let ancestors be an empty list.
-
While navigable is not null:
Prepend navigable to
ancestors.
Set navigable to navigable's parent.
Return ancestors.
These descendant-collecting algorithms are described as looking at the DOM tree
of descendant Document objects. In reality, this is often not feasible since the DOM
tree can be in another process from the caller of the algorithm. Instead, implementations
generally replicate the appropriate trees across processes.
7.3.1.6 Navigable destruction
User agents may destroy a top-level traversable at any time (typically, in response to user requests).
The close vs. definitely close separation allows other
specifications to call close and have it be a
no-op if the top-level traversable is already closing due to JavaScript code calling window.close().
7.3.1.7 Navigable target names
Navigables can be given target
names, which are strings allowing certain APIs (such as window.open() or the a element's target attribute) to target navigations at that navigable.
A valid navigable target name is any string with at
least one character that does not contain both an ASCII tab or newline and a U+003C
(<), and it does not start with a U+005F (_). (Names starting with a U+005F (_) are reserved
for special keywords.)
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
navigable that the link or script is in, "parent" means the parent of the navigable that the link or script is in,
"top" means the top-level traversable of the navigable
that the link or script is in, "new" means a new traversable navigable with a null
parent (which may use an auxiliary browsing
context, 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 navigable given below.
To find a navigable by target name given a string name and a
navigable currentNavigable:
Let currentDocument be currentNavigable's active document.
Let sourceSnapshotParams be the result of snapshotting source snapshot
params given currentDocument.
-
Let subtreesToSearch be an implementation-defined choice of one of
the following:
Issue #10848 tracks
settling on one of these two possibilities, to achieve interoperability.
-
For each subtreeToSearch of
subtreesToSearch, in reverse order:
Let documentToSearch be subtreeToSearch's active document.
-
For each navigable of the inclusive
descendant navigables of documentToSearch:
-
If currentNavigable is not allowed by sandboxing to navigate
navigable given sourceSnapshotParams, then optionally
continue.
Issue #10849 tracks
making this check required, to achieve interoperability.
If navigable's target name is
name, then return navigable.
Let currentTopLevelBrowsingContext be currentNavigable's active browsing context's top-level browsing
context.
Let group be currentTopLevelBrowsingContext's group.
-
For each topLevelBrowsingContext of
group's browsing context set, in an implementation-defined
order (the user agent should pick a consistent ordering, such as the most recently opened, most
recently focused, or more closely related):
Issue #10850 tracks
picking a specific ordering, to achieve interoperability.
If currentTopLevelBrowsingContext is topLevelBrowsingContext, then
continue.
Let documentToSearch be topLevelBrowsingContext's active
document.
-
For each navigable of the inclusive
descendant navigables of documentToSearch:
If currentNavigable's active browsing context
is not familiar with navigable's active
browsing context, then continue.
-
If currentNavigable is not allowed by sandboxing to navigate
navigable given sourceSnapshotParams, then optionally
continue.
Issue #10849 tracks
making this check required, to achieve interoperability.
If navigable's target name is
name, then return navigable.
Return null.
The rules
for choosing a navigable, given a string name, a navigable
currentNavigable, and a boolean noopener are as follows:
Let chosen be null.
Let windowType be "existing or none".
Let sandboxingFlagSet be currentNavigable'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
currentNavigable.
Otherwise, if name is an ASCII case-insensitive match for "_parent", set chosen to currentNavigable's parent, if any, and currentNavigable otherwise.
Otherwise, if name is an ASCII case-insensitive match for "_top", set chosen to currentNavigable's traversable navigable.
Otherwise, if name is not an ASCII case-insensitive match for
"_blank", then set chosen to the result of finding a navigable by target name given
name and currentNavigable.
-
If chosen is null, then a new top-level traversable 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:
- If currentNavigable's active
window does not have transient activation and the user agent has been
configured to not show popups (i.e., the user agent has a "popup blocker" enabled)
The user agent may inform the user that a popup has been blocked.
- If sandboxingFlagSet has the sandboxed auxiliary
navigation browsing context flag set
The user agent may report to a developer console that a popup has been blocked.
- If the user agent has been configured such that in this instance it will create a new top-level traversable
-
Consume user activation of currentNavigable's active window.
Set windowType to "new and unrestricted".
Let currentDocument be currentNavigable's active document.
-
If currentDocument's opener
policy's value is "same-origin" or "same-origin-plus-COEP", and
currentDocument's origin is not
same origin with currentDocument's relevant settings
object's top-level origin:
Set noopener to true.
Set name to "_blank".
Set windowType to "new with no opener".
In the presence of an opener policy, nested documents that are
cross-origin with their top-level browsing context's active document always set
noopener to true.
Let targetName be the empty string.
If name is not an ASCII case-insensitive match for "_blank", then set targetName to name.
If noopener is true, then set chosen to the
result of creating a new top-level traversable given null,
targetName, and currentNavigable.
-
Otherwise:
Set chosen to the result of creating a new top-level
traversable given currentNavigable's active
browsing context, targetName, and currentNavigable.
If sandboxingFlagSet's sandboxed navigation browsing context
flag is set, then set chosen's active browsing
context's one permitted sandboxed navigator to
currentNavigable's active browsing
context.
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 active browsing context's
popup sandboxing flag set.
Set chosen's is created by web content to true.
If the newly created navigable chosen is immediately
navigated, then the navigation will be done as a "replace" navigation.
- If the user agent has been configured such that in this instance it will choose currentNavigable
Set chosen to currentNavigable.
- If the user agent has been configured such that in this instance it will not find a navigable
Do nothing.
User agents are encouraged to provide a way for users to configure the user
agent to always choose currentNavigable.
Return chosen and windowType.
7.3.2 Browsing contexts
A browsing context is a programmatic representation of a series of documents,
multiple of which can live within a single navigable. Each browsing
context has a corresponding WindowProxy object, as well as the following:
An active document, a Document or null, initially null.
An opener browsing context, a browsing context or null,
initially null.
An opener origin at creation, an
origin or null, initially null.
-
An is popup boolean, initially false.
The only mandatory impact in this specification of is popup is on
the visible getter of the relevant
BarProp objects. However, user agents might also use it for user interface considerations.
An is auxiliary boolean, initially false.
An initial URL, a URL or
null, initially null.
A virtual browsing context group ID
integer, initially 0. This is used by opener policy
reporting, to keep track of the browsing context group switches that would have happened
if the report-only policy had been enforced.
It's unclear whether a separate is auxiliary concept is necessary. In
issue #5680, it is indicated that we may
be able to simplify this by using whether or not the opener browsing context is
null.
Modern specifications should avoid using the
browsing context concept in most cases, unless they are dealing with the subtleties
of browsing context
group switches and agent cluster allocation. Instead,
the Document and navigable concepts are usually more appropriate.
A Document's browsing context is a browsing context or null,
initially null.
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 nulled out.
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, which will be done with replacement.
7.3.2.1 Creating browsing contexts
To create a new browsing context and document, given null or a Document
object creator, null or an element embedder, and a browsing context
group group:
Let browsingContext be a new browsing context.
Let unsafeContextCreationTime be the
unsafe shared current time.
Let creatorOrigin be null.
Let creatorBaseURL be null.
-
If creator is non-null:
Set creatorOrigin to creator's origin.
Set creatorBaseURL to creator's document base
URL.
Set browsingContext's virtual browsing context group ID to
creator's browsing context's top-level browsing context's virtual browsing context group ID.
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 about:blank, sandboxFlags, and
creatorOrigin.
-
Let permissionsPolicy be the result of creating a permissions policy
given embedder and origin. [PERMISSIONSPOLICY]
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 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 the return value of running these steps:
If embedder is non-null, then return embedder's relevant
settings object's top-level creation URL.
If creator is non-null, then return creator's relevant
settings object's top-level creation URL.
Return about:blank.
Let topLevelOrigin be origin if embedder is null;
otherwise embedder's relevant settings object's top-level
origin.
Set up a window environment settings object with about:blank,
realm execution context, null, topLevelCreationURL, and
topLevelOrigin.
Let loadTimingInfo be a new document load timing info with
its navigation start time set to the result of calling coarsen time
with unsafeContextCreationTime and the new environment settings object's
cross-origin isolated
capability.
-
Let document be a new Document, with:
- type
- "
html" - content type
- "
text/html" - mode
- "
quirks" - origin
- origin
- browsing context
- browsingContext
- permissions policy
- permissionsPolicy
- active sandboxing flag set
- sandboxFlags
- load timing info
- loadTimingInfo
- is initial
about:blank - true
- about base URL
- creatorBaseURL
- allow declarative shadow
roots
- true
- custom element registry
- a new
CustomElementRegistry object
Let iframeReferrerPolicy be the result of determining the
iframe element referrer policy given embedder.
Set document's internal ancestor origin objects
list to the result of running the internal ancestor origin objects list creation
steps given document and iframeReferrerPolicy.
Set document's ancestor
origins list to the result of running the ancestor origins list creation
steps given document.
-
If creator is non-null:
Set document's referrer to the
serialization of creator's URL.
Set document's policy
container to a clone of
creator's policy
container.
If creator's origin is
same origin with creator's relevant settings object's
top-level origin, then set document's opener policy to creator's browsing context's top-level
browsing context's active document's opener policy.
Assert: document's URL
and document's relevant settings object's creation URL are
about:blank.
Mark document as ready for post-load tasks.
Populate with html/head/body given
document.
Make active document.
Completely finish loading document.
Return browsingContext and document.
7.3.2.2 Related browsing contexts
A browsing context potentialDescendant is said to be an ancestor of a browsing context
potentialAncestor if the following algorithm returns true:
Let potentialDescendantDocument be potentialDescendant's
active document.
If potentialDescendantDocument is not fully active, then return
false.
Let ancestorBCs be the list obtained by taking the browsing context of the active
document of each member of potentialDescendantDocument's ancestor
navigables.
If ancestorBCs contains
potentialAncestor, then return true.
Return false.
It is not required to be a top-level traversable.
7.3.2.3 Groupings of browsing contexts
A top-level browsing context has an associated group (null or a browsing context group). It is initially null.
A user agent holds a browsing context group set (a set of browsing context groups).
A browsing context group holds a browsing context set (a set
of top-level browsing contexts).
A top-level browsing context is added to the group when the group is created. All subsequent top-level
browsing contexts added to the group will be
auxiliary browsing contexts.
A browsing context group has an associated agent cluster map (a weak
map of agent cluster
keys to agent clusters). User agents are responsible
for collecting agent clusters when it is deemed that nothing can access them anymore.
A browsing context group has an associated historical agent cluster key
map, which is a map of origins to agent cluster keys. This
map is used to ensure the consistency of the origin-keyed
agent clusters feature by recording what agent cluster keys were previously used for a given
origin.
The historical agent cluster key map only ever gains entries over the
lifetime of the browsing context group.
A browsing context group has a cross-origin isolation mode, which is a
cross-origin isolation mode. It is initially "none".
A cross-origin isolation mode is one of three possible values: "none", "logical", or "concrete".
"logical" and "concrete" are similar. They are both used for
browsing context groups where:
On some platforms, it is difficult to provide the security properties required to grant safe
access to the APIs gated by the cross-origin isolated
capability. As a result, only "concrete" can grant access that capability.
"logical" is used on platform not supporting
this capability, where various restrictions imposed by cross-origin isolation will still apply,
but the capability is not granted.
Append and remove are primitive operations that help define the lifetime of a browsing
context group. They are called by higher-level creation and destruction operations for
Documents and browsing contexts.
7.3.3 Fully active documents
Because they are associated with an element, child
navigables are always tied to a specific Document, their container document, in their parent navigable. User agents must not allow the user to interact with
child navigables whose container documents are not themselves fully
active.
The following example illustrates how a Document can be the active document of its node navigable, while not being
fully active. 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>Navigable 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>Navigable 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 node navigables. They are also all fully active.
After clicking on the button, and thus loading a new Document from
b-2.html into navigable B, we have the following results: