1. Introduction
This section is non-normative.
This specification extends [HTML] to define a new kind of top-level browsing context, which can be embedded in another document, and a mechanism for replacing the contents of another top-level browsing context with the previously embedded context.
It is structured as a series of patches to HTML and other specifications, with each major section indicating where each it would be placed in the event of eventual graduation from incubation.
See also the explainer for more background and motivation.
2. Portal browsing contexts
The following section would be added as a new sub-section of [HTML]'s Browsing contexts section.
Every browsing context has a portal state, which may be "none
" (the default), "portal
" or "orphaned
".
A nested browsing context always has the portal state "none
".
-
"
portal
": top-level browsing contexts embedded in aportal
element -
"
orphaned
": top-level browsing contexts which have runactivate
but have not (yet) been adopted -
"
none
": all other browsing contexts
A top-level "none
" context can become "orphaned
" by activating another context. An "orphaned
" context can be adopted to
become a "portal
" context. A "portal
" context can become a "none
" context by being activated by its host browsing context.
A browsing context can be closed while in any of these states.
A portal browsing context is a browsing context whose portal state is "portal
".
The host element of a portal browsing context is a portal
element which embeds its rendered output and receives messages sent from the
portal browsing context.
portal
element may only be a host element while it is browsing-context connected or during the dispatch of the portalactivate
event from which it was obtained
using adoptPredecessor()
. The host browsing context of a portal browsing context is its host element's node document's browsing context.
The portal task source is a task source used for tasks related to the portal lifecycle and communication between a portal browsing context and its host browsing context.
-
Assert: The portal state of predecessorBrowsingContext is "
none
". -
If successorBrowsingContext’s only entry in its session history is the initial
about:blank
Document
, then wait until either this is no longer true, or successorBrowsingContext’s host element becomes null.This means that the initial load is still happening in successorBrowsingContext. We wait for it to complete, either successfully or unsuccessfully, before continuing.
-
If successorBrowsingContext’s host element is null, then:
-
Queue a global task on the portal task source given predecessorBrowsingContext’s active window to reject promise with an "
InvalidStateError
"DOMException
. -
Return.
-
-
Set the host element of successorBrowsingContext to null.
User agents should, however, attempt to preserve the rendering of the guest browsing context until predecessorBrowsingContext has been replaced with successorBrowsingContext in the rendering.
Note: This is intended to avoid a visual glitch, such as a "white flash", where the guest browsing context briefly disappears.
-
Set the portal state of predecessorBrowsingContext to "
orphaned
". -
Update the user interface to replace predecessorBrowsingContext with successorBrowsingContext (e.g., by updating the tab/window contents and browser chrome).
-
Let successorWindow be successorBrowsingContext’s associated
WindowProxy
's [[Window]] internal slot value. -
Queue a global task on the portal task source given successorWindow to run the following steps:
-
Assert: The portal state of successorBrowsingContext is "
portal
". -
Set the portal state of successorBrowsingContext to "
none
". -
Let targetRealm be successorWindow’s realm.
-
Let dataClone be null.
-
If serializeWithTransferResult is given and successorBrowsingContext’s active document's origin is same origin with sourceOrigin, then:
-
Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm), and set dataClone to deserializeRecord.[[Deserialized]].
If this throws an exception, catch it and do nothing.
-
-
Let event be the result of creating an event using
PortalActivateEvent
and targetRealm. -
Initialize event’s
type
attribute toportalactivate
. -
Initialize event’s
data
attribute to dataClone. -
Set event’s predecessor browsing context to predecessorBrowsingContext.
-
Set event’s successor window to successorWindow.
-
Set event’s activation promise to promise, if it is given, and null otherwise.
-
Dispatch event to successorWindow.
-
Let adoptedPredecessorElement be event’s adopted predecessor element.
-
If adoptedPredecessorElement is not null, then:
-
Set adoptedPredecessorElement’s just-adopted flag to false.
-
If adoptedPredecessorElement may not have a guest browsing context and its guest browsing context is not null, then discard it.
This unceremoniously discards the browsing context, as if the element had been removed from the document after previously being attached. This is distinct from the case where the predecessor was never adopted, below, which closes the browsing context. Closing unloads the predecessor’s document, somewhat similarly to if it had performed an ordinary navigation.Typically authors would not call
adoptPredecessor()
unless they intend to insert it into the document before the just-adopted flag becomes false.
-
-
Otherwise:
-
If promise is given, queue a global task on the portal task source given predecessorBrowsingContext’s active window to resolve promise with undefined.
-
Close predecessorBrowsingContext.
The user agent should not ask the user for confirmation during the prompt to unload step (and so the browsing context should be discarded).
Authors should not expect theunload
event to be dispatched consistently following portal activation. In addition to adoption of the predecessor, where the predecessor would not be unloaded at all, the predecessor could also enter bfcache (back forward cache) where the unload event would not be dispatched.Determine how to treat unload/beforeunload handlers. See issue #225 for discussion.
-
-
- portal-activate-event.html (live test) (source)
- portals-host-hidden-after-activation.html (live test) (source)
-
Let document be the document of successorWindow.
-
Let portalElement be the result of creating an element given document,
portal
, and the HTML namespace. -
Set portalElement’s just-adopted flag to true.
-
Assert: portalElement is an
HTMLPortalElement
. -
Queue a global task on the portal task source given predecessorBrowsingContext’s active window to run the following steps:
-
Assert: The portal state of predecessorBrowsingContext is "
orphaned
". -
Set the portal state of predecessorBrowsingContext to "
portal
", and set the host element of predecessorBrowsingContext to portalElement.
-
-
Return portalElement.
PortalHost
object, is queued first, and from the same task source,
it is exposed at the time the activation promise returned from activate(options)
is resolved.
// In the successor document. onportalactivate= event=> { // The predecessor document is adopted into a <portal> element... document. body. appendChild( event. adoptPredecessor()); }); // In the predecessor document. portalElement. activate(). then(() => { // ...and it is guaranteed to observe that change by the time the // activation promise resolves. console. assert( window. portalHostinstanceof PortalHost); });
3. The portal
element
The following section would be added as a new subsection of [HTML]'s Embedded content section.
A portal
element allows for a portal browsing context to be embedded in an HTML document.
A portal
element portalElement has a guest
browsing context, which is the portal browsing context whose host
element is portalElement, or null if no such browsing context exists.
A portal
element has a just-adopted
flag, which is a boolean and is initially false. It is set during
dispatch of the portalactivate
event.
The src
attribute gives the URL of a
page that the guest browsing context is to contain. The attribute, if
present, must be a valid non-empty URL potentially surrounded by spaces.
The referrerpolicy
attribute is a referrer policy attribute.
Its purpose is to set the referrer policy used when setting the source URL of a portal element. [REFERRER-POLICY]
A portal
is similar to an iframe
, in that it allows another
browsing context to be embedded. However, the portal browsing context hosted by a portal
is part of a separate browsing context group,
and thus a separate agent. The user agent therefore uses a
separate event loop for the browsing contexts, even if they are same
origin-domain.
[Exposed =Window ]interface :
HTMLPortalElement HTMLElement { [HTMLConstructor ](); [
constructor CEReactions ]attribute USVString src ; [CEReactions ]attribute DOMString referrerPolicy ; [NewObject ]Promise <undefined >activate (optional PortalActivateOptions = {});
options undefined postMessage (any ,
message optional PostMessageOptions = {});
options attribute EventHandler ;
onmessage attribute EventHandler ; };
onmessageerror dictionary :
PortalActivateOptions PostMessageOptions {any ; };
data
The src
IDL attribute must reflect the src
content attribute.
The referrerPolicy
IDL attribute must reflect the referrerpolicy
content attribute, limited to only known values.
activate(options)
method must run these steps:
-
Let portalBrowsingContext be the guest browsing context of this.
-
If portalBrowsingContext is null, throw an "
InvalidStateError
"DOMException
. -
Let predecessorBrowsingContext be the browsing context of this's node document.
-
If predecessorBrowsingContext is null, throw an "
InvalidStateError
"DOMException
. -
If the portal state of predecessorBrowsingContext is not "
none
", throw an "InvalidStateError
"DOMException
.Note: This means that a
portal
element inside a portal browsing context cannot be activated. -
Let serializeWithTransferResult be StructuredSerializeWithTransfer(options["
data
"], options["transfer
"]). Rethrow any exceptions. -
Let promise be a new promise.
-
Let sourceOrigin be this's relevant settings object's origin.
-
Run the steps to activate portalBrowsingContext in place of predecessorBrowsingContext with sourceOrigin, serializeWithTransferResult, and promise.
-
Return promise.
postMessage(message, options)
method must run these steps:
-
Let portalBrowsingContext be the guest browsing context of this.
-
If portalBrowsingContext is null, throw an "
InvalidStateError
"DOMException
. -
Let sourceOrigin be this's relevant settings object's origin.
-
Let transfer be options["
transfer
"]. -
Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
-
Queue a global task on the portal task source given portalBrowsingContext’s active window to run the following steps:
-
If portalBrowsingContext’s active document's origin is not same origin with sourceOrigin, then abort these steps.
-
Let origin be the serialization of sourceOrigin.
-
Let targetWindow be portalBrowsingContext’s associated
WindowProxy
's [[Window]] internal slot value. -
Let portalHost be the targetWindow’s portal host object.
-
Let targetRealm be the targetWindow’s realm.
-
Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
If this throws an exception, catch it, fire an event named
messageerror
at portalHost usingMessageEvent
with theorigin
attribute initialized to origin and thesource
attribute initialized to portalHost, then abort these steps. -
Let messageClone be deserializeRecord.[[Deserialized]].
-
Let newPorts be a new frozen array consisting of all
MessagePort
objects in deserializeRecord.[[TransferredValues]], if any, maintaining their relative order. -
Fire an event named
message
at portalHost usingMessageEvent
, with theorigin
attribute initialized to origin, thesource
attribute initialized to portalHost, thedata
attribute initialized to messageClone, and theports
attribute initialized to newPorts.
-
portal
element may have a guest browsing context, run the following steps:
-
If element’s node document's browsing context is not a top-level browsing context, then return false.
The user agent may choose to emit a warning if the author attempts to use a
portal
element in a nested browsing context, as this is not supported. -
If element’s node document's URL's scheme is not an HTTP(S) scheme, then return false.
This is to prevent problems later, if the portaled content attempts to adopt its predecessor. Since portaled content can only have a HTTP(S) scheme, adoption would fail, and so its simpler to restrict things at this stage.
-
If element’s node document's active sandboxing flag set is not empty, then return false.
Since portals cannot be created in child browsing contexts anyway, this step is about preventing portal uses in auxiliary browsing contexts spawned by sandboxed
iframe
s, or pages using CSP’s sandbox directive.This restriction is largely added for simplicity. If there are use cases for portals inside sandboxed documents, we can enable them in the future, with appropriate opt-in. See issue #207 for discussion.
-
If element is browsing-context connected, then return true.
-
If element’s just-adopted flag is true, then return true.
-
Return false.
portal
element element, run the following steps:
-
If element’s guest browsing context is not null, then close it.
The user agent should not ask the user for confirmation during the prompt to unload step (and so the browsing context should be discarded).
portal
element element, run the following steps:
-
Assert: element may have a guest browsing context.
-
Let hostBrowsingContext be element’s node document's browsing context.
-
Assert: hostBrowsingContext is a top-level browsing context.
-
Close element.
-
If element has no
src
attribute specified, or its value is the empty string, then return. -
Parse the value of the
src
attribute. If that is not successful, then return.Otherwise, let url be the resulting URL record.
-
Assert: element’s guest browsing context is null.
-
Let guestBrowsingContext be the result of creating a new top-level browsing context.
-
Set the portal state of guestBrowsingContext to "
portal
", and set the host element of guestBrowsingContext to element. -
Let resource be a new request whose url is url and whose referrer policy is the current state of element’s
referrerpolicy
content attribute. -
Navigate guestBrowsingContext to resource.
iframe
element, a portal
element supports a state where it has no associated
browsing context. This is the initial state of a portal
element. That is, the portal
browsing context has no web-developer-visible initial about:blank
Document
; instead it navigates directly to the first parsable URL assigned to it, and if the navigation cannot
finish successfully, it closes the browsing context before the
navigation algorithm finishes.
Similarly, a portal
element responds to an unparsable src
URL by closing its browsing context, rather than by navigating to about:blank
.
- portals-cross-origin-load.sub.html (live test) (source)
- portals-referrer.html (live test) (source)
- portals-referrer-inherit-header.html (live test) (source)
- portals-referrer-inherit-meta.html (live test) (source)
Whenever a portal
element element has its src
attribute set,
changed, or removed, run the following steps:
-
If element may have a guest browsing context, then set the source URL of element.
Whenever a portal
element element becomes
browsing-context connected, run the following steps:
-
If element may not have a guest browsing context, then abort these steps.
-
If element’s guest browsing context is not null, then abort these steps.
-
Set the source URL of element.
Whenever a portal
element element becomes
browsing-context connected, run the following steps:
-
If element may not have a guest browsing context and its guest browsing context is not null, then discard it.
portal
element without losing
its browsing context. Whenever a portal
element element is adopted, run the following steps:
-
Let guestBrowsingContext be element’s guest browsing context.
-
If guestBrowsingContext is null, then abort these steps.
-
Discard guestBrowsingContext.
portal
element loses its guest browsing
context if it is moved to the active document of a nested browsing
context.
Similarly, the steps when a portal
element’s source URL is set prevent
elements from creating a new guest browsing context while inside such
documents.
It is therefore impossible to embed a portal browsing context in a nested browsing context.
Whenever a Document
object document whose browsing context is a portal browsing context is marked as completely loaded, run the following steps as part of
the queued task:
-
Let element be document’s browsing context's host element.
-
Fire an event named
load
at element.
- portal-onload-event.html (live test) (source)
- portals-cross-origin-load.sub.html (live test) (source)
portal
element el’s activation behavior is to run the following steps:
-
Let portalBrowsingContext be the guest browsing context of el.
-
If portalBrowsingContext is null, return.
-
Let predecessorBrowsingContext be the browsing context of el’s node document.
-
If predecessorBrowsingContext is null, return.
-
If the portal state of predecessorBrowsingContext is not "
none
", return. -
Let sourceOrigin be el’s relevant settings object's origin.
-
Run the steps to activate portalBrowsingContext in place of predecessorBrowsingContext with sourceOrigin.
activate(options)
, with default options.
User agents might wish to display suitable console messages under the same conditions that would
result in promise rejection in those steps. The following events are dispatched on HTMLPortalElement
objects:
Event name | Interface | Dispatched when |
---|---|---|
message
| MessageEvent
| A message is received by the object, and deserialization does not throw an exception. |
messageerror
| MessageEvent
| A message is received by the object, but deserialization throws an exception. |
The portal
element exposes onmessage
and onmessageerror
as event handler content attributes.
3.1. Portal hosts
Every Window
has a portal host object, which is a PortalHost
. It is exposed
through the portalHost
attribute getter at times when the window may be in a portal browsing context.
window.portalHost
getter will return null. partial interface Window {readonly attribute PortalHost ?portalHost ; };
portalHost
attribute’s getter must run the following steps:
-
Let context be this's browsing context.
-
If context is null or the portal state of context is not "
portal
", then return null. -
Return this's portal host object.
The PortalHost
interface definition is as follows:
[Exposed =Window ]interface :
PortalHost EventTarget {undefined postMessage (any ,
message optional PostMessageOptions = {});
options attribute EventHandler ;
onmessage attribute EventHandler ; };
onmessageerror
postMessage(message, options)
method must run these steps:
-
Let browsingContext be this's relevant global object's browsing context.
-
If browsingContext has a portal state other than "
portal
", throw an "InvalidStateError
"DOMException
.Note: This roughly means that it has not yet been activated, as far as this event loop has been told. It is possible that this browsing context will be activated in parallel to this message being sent; in such cases, messages may not be delivered.
-
Let sourceOrigin be this's relevant settings object's origin.
-
Let transfer be options["
transfer
"]. -
Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
-
Let hostElement be the host element of browsingContext.
-
Queue an element task on the portal task source given hostElement to run the following steps:
-
If browsingContext is not the guest browsing context of hostElement, then abort these steps.
Note: This might happen if this event loop had a queued task to deliver a message, but it was not executed before the portal was activated. In such cases, the message is not delivered.
-
Let targetSettings be the relevant settings object of hostElement.
-
If targetSettings’s origin is not same origin with sourceOrigin, then abort these steps.
-
Let origin be the serialization of sourceOrigin.
-
Let targetRealm be targetSettings’s realm.
-
Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
If this throws an exception, catch it, fire an event named
messageerror
at element usingMessageEvent
with theorigin
attribute initialized to origin and thesource
attribute initialized to element. -
Let messageClone be deserializeRecord.[[Deserialized]].
-
Let newPorts be a new frozen array consisting of all
MessagePort
objects in deserializeRecord.[[TransferredValues]], if any, maintaining their relative order. -
Fire an event named
message
at the element usingMessageEvent
, with theorigin
attribute initialized to origin, thesource
attribute initialized to element, thedata
attribute initialized to messageClone, and theports
attribute initialized to newPorts.
-
The following events are dispatched on PortalHost
objects:
Event name | Interface | Dispatched when |
---|---|---|
message
| MessageEvent
| A message is received by the object, and deserialization does not throw an exception. |
messageerror
| MessageEvent
| A message is received by the object, but deserialization throws an exception. |
3.2. The PortalActivateEvent
interface
[Exposed =Window ]interface :
PortalActivateEvent Event {(
constructor DOMString ,
type optional PortalActivateEventInit = {});
eventInitDict readonly attribute any ;
data HTMLPortalElement adoptPredecessor (); };dictionary :
PortalActivateEventInit EventInit {any =
data null ; };
ports
attribute on PortalActivateEvent
, despite it being
used for data transfer in a similar way to MessageEvent
. This omission is for simplicity,
and could be reconsidered if a use case is found. (See also whatwg/html#4521 for a potential
expansion.) A PortalActivateEvent
has an associated predecessor browsing context,
which is a top-level browsing context or null, a successor window, which is
a Window
, an activation promise, which is a promise or null, and a adopted predecessor element, which is a portal
element or null.
PortalActivateEvent
, given an event, are as follows:
-
Set event’s predecessor browsing context to null.
-
Set event’s successor window to null.
-
Set event’s adopted predecessor element to null.
adoptPredecessor()
method must run these steps:
-
If this's adopted predecessor element is not null, throw an "
InvalidStateError
"DOMException
. -
Let predecessorBrowsingContext be this's predecessor browsing context.
-
Let successorWindow be this's successor window.
-
Run the steps to adopt the predecessor browsing context predecessorBrowsingContext in successorWindow, and let adoptedPredecessorElement be the result.
-
Set this's adopted predecessor element to adoptedPredecessorElement.
-
If this's activation promise is not null, queue a global task on the portal task source given predecessorBrowsingContext’s active window to resolve it with undefined.
Note: Queuing this immediately makes it possible to send messages to the adopted portal during dispatch of the
portalactivate
event without ordering issues between the task to resolve the activation promise and the task to deliver the message. -
Return adoptedPredecessorElement.
4. Miscellaneous HTML updates
This section contains various small patches to miscellaneous areas of the HTML Standard.
4.1. The MessageEvent
interface
The MessageEventSource
union is extended to include the new interfaces
which can produce MessageEvent
events.
typedef (WindowProxy or MessagePort or ServiceWorker or HTMLPortalElement or PortalHost );
MessageEventSource
4.2. Event handlers
The table of event handlers which must be supported by Window
objects, as event handler
IDL attributes on the Window
objects themselves (i.e. the table containing onafterprint
),
gets extended with the following row:
Event handler | Event handler event type |
---|---|
onportalactivate
| portalactivate
|
The corresponding WindowEventHandlers
mixin gets extended as follows:
partial interface mixin WindowEventHandlers {attribute EventHandler ; };
onportalactivate
The Events index is also updated with the following additional row:
Event | Interface | Interesting targets | Description |
---|---|---|---|
portalactivate
| PortalActivateEvent
| Window
| Fired at the Window of a portal browsing context when that portal browsing
context is activated.
|
4.3. APIs for creating and navigating browsing contexts by name
Modify the definition of script-closable to prevent window closing while in a portal browsing context:
A browsing context is script-closable if either of the following is true:
-
it is an auxiliary browsing context that was created by script (as opposed to by an action of the user); or
-
it is a top-level browsing context whose portal state is "
none
" and whose session history contains only oneDocument
.
4.4. Navigation
Patch the navigate algorithm to prevent certain navigations in a portal as follows:
-
If browsingContext’s portal state is not "
none
", and any of the following hold:-
failure is true;
-
navigationParams’s request is null;
-
navigationParams’s request's current URL's scheme is not a HTTP(S) scheme;
-
response has a `
Content-Disposition
` header specifying theattachment
disposition type; or -
response’s status is 204 or 205,
then:
-
If browsingContext’s only entry in its session history is the initial
about:blank
Document
, then:-
Close browsingContext’s host element.
-
Run the environment discarding steps for navigationParam’s reserved environment.
-
-
Return.
-
-
Otherwise, if browsingContext’s portal state is not "
none
", then close browsingContext’s host element.
4.5. Downloading resources
Modify the allowed to download algorithm to ensure that portaled content never performs downloads, by prepending the following steps:
-
If initiator browsing context’s portal state is not "
none
", then return false. -
If instantiator browsing context’s portal state is not "
none
", then return false.
5. Updates to other specifications
5.1. Content Security Policy
This specification integrates with [CSP] as follows.
Although navigate-to
works as expected while the content is portaled, we also
need to apply it to prevent activation (which is basically a navigation). This is not yet specced,
pending spec updates to the navigation and session history handling.
The following new subsection of Content Security Policy §6.1 Fetch Directives is added:
5.1.1. portal-src
The portal-src directive restricts the URLs which may be loaded into portal browsing contexts. The syntax for the directive’s name and value is described by the following ABNF:
directive-name = "portal-src" directive-value = serialized-source-list
Content-Security-Policy: portal-src https://example.com/
Fetches for the following code will return a network errors, and thus result in closing the portal, as the URL provided does not match portal-src
's source list:
< portal src = "https://example.org/" ></ portal >
5.1.1.1. portal-src
Pre-request check
This directive’s pre-request check is as follows:
-
Let name be the result of executing Content Security Policy §6.7.1 Get the effective directive for request on request.
-
If the result of executing Content Security Policy §6.7.4 Should fetch directive execute on name,
portal-src
and policy is "No
", return "Allowed
". -
If the result of executing Content Security Policy §6.6.2.3 Does request match source list? on request, this directive’s value, and policy is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
5.1.1.2. portal-src
Post-request check
This directive’s post-request check is as follows:
-
Let name be the result of executing Content Security Policy §6.7.1 Get the effective directive for request on request.
-
If the result of executing Content Security Policy §6.7.4 Should fetch directive execute on name,
portal-src
and policy is "No
", return "Allowed
". -
If the result of executing Content Security Policy §6.6.2.4 Does response to request match source list? on response, request, this directive’s value, and policy is "
Does Not Match
", return "Blocked
". -
Return "
Allowed
".
5.1.2. default-src
The informative example text which expands it into all other fetch directives in Content Security Policy §6.1.3 default-src will need updating to include portal-src.
5.1.3. Get fetch directive fallback list
The algorithm in Content Security Policy §6.7.3 Get fetch directive fallback list needs updating to account for the new portal-src fetch directive. Add a new case to step 1:
- "
portal-src
" -
-
Return « "
portal-src
", "prefetch-src
", "default-src
" ».
-
5.2. Fetch Metadata Request Headers
This specification integrates with [FETCH-METADATA] as follows.
-
Where the algorithm checks whether r’s reserved client's target browsing context is a nested browsing context, check instead whether it is a nested browsing context or a portal browsing context.
Sec-Fetch-Mode: nested-navigate
iframe
element, with no
spec updates needed. 6. Security Considerations
6.1. Overview
This section is non-normative.
In general, a portal browsing context should respect policies that would apply to a nested browsing context, e.g. that would restrict whether a document can be embedded in a document from another origin.
7. Untriaged tests
In order to get this spec to build without warnings, we need to include all the web platform tests explicitly. This section contains all the tests which we haven’t yet written spec text for, or haven’t triaged into the appropriate sections.
- history-manipulation-inside-portal-with-subframes.html (live test) (source)
- history-manipulation-inside-portal.html (live test) (source)
- portal-activate-default.html (live test) (source)
- portals-activate-empty-browsing-context.html (live test) (source)
- portals-activate-network-error.html (live test) (source)
- portals-activate-while-unloading.html (live test) (source)
- portals-no-frame-crash.html (live test) (source)
- portals-focus.sub.html (live test) (source)
- portals-navigate-after-adoption.html (live test) (source)
- portals-repeated-activate.html (live test) (source)
- portals-set-src-after-activate.html (live test) (source)
- predecessor-fires-unload.html (live test) (source)
The following tests are actively incorrect and need to get updated: