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.
2. Concepts
A portal browsing context is a browsing context created according to the steps in this specification. A portal browsing context cannot have a parent browsing context.
A portal browsing context has a host which is embeds its rendered output and
receives messages sent from the portal browsing context. This specification defines HTMLPortalElement
, which hosts a portal browsing context inside an HTML document.
A host defines steps to accept a message posted to the host.
This implies that every portal browsing context is a top-level browsing context. It is expected that a Web browser will not present a tab or window to display a portal browsing context, but rather that it will be presented only through a host element.
-
Let successorWindow be portalBrowsingContext’s associated
WindowProxy
's [[Window]] internal slot value. -
Update the user interface to replace predecessorBrowsingContext with portalBrowsingContext (e.g., by updating the tab/window contents and browser chrome).
From this point onward, portalBrowsingContext is no longer a portal browsing context and has no host.
-
Queue a task from the DOM manipulation task source to the event loop associated with successorWindow to run the following steps:
-
portal host object of portalBrowsingContext.
the -
Let targetRealm be successorWindow’s realm.
-
Let dataClone be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
If this throws an exception, catch it, and let dataClone be null instead.
-
Let event be the result of creating an event using
PortalActivateEvent
. -
Initialize event’s
type
attribute toportalactivate
. -
Initialize event’s
data
attribute to dataClone. -
Set event’s predecessor browsing context to predecessorBrowsingContext.
-
Dispatch event to successorWindow.
-
If predecessorBrowsingContext is not a portal browsing context, close it. The user agent should not refuse to allow the document to be unloaded.
-
-
Let portalElement be the result of creating an element given document,
portal
, and the HTML namespace. -
Assert: portalElement is an
HTMLPortalElement
. -
Set the guest browsing context of portalElement to predecessorBrowsingContext. From this point onward, predecessorBrowsingContext is a portal browsing context, with portalElement as its host.
-
Queue a task from the DOM manipulation task source to the event loop associated with predecessorBrowsingContext to run the following steps:
-
Expose the portal host object of predecessorBrowsingContext.
-
-
Return portalElement.
PortalHost
is queued before the task to complete portal activation,
from the same task source, it is exposed at the time the promise returned from activate()
is resolved. 3. API
3.1. The portal
element
A portal
element for a portal browsing context to be embedded in an HTML document.
A portal
element may have a guest browsing context, which is a portal browsing context. If so, the element is the host of its guest browsing context.
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 unit of related
browsing contexts. The user agent is thus free to use a separate event loop for the browsing
contexts, even if they are same origin-domain.
[HTMLConstructor] interfaceHTMLPortalElement
: HTMLElement { [CEReactions] attribute USVStringsrc
; [NewObject] Promise<void> activate(optional PortalActivateOptionsoptions
); void postMessage(anymessage
, DOMStringtargetOrigin
, optional sequence<object>transfer
= []); }; dictionaryPortalActivateOptions
{ anydata
= null; sequence<object>transfer
= []; };
PostMessageOptions
dictionary overload, to reflect the changes due to the user activation proposal. The following tasks may be queued by this standard. Unless otherwise specified, each task must be queued from the DOM manipulation task source.
-
complete portal activation
activate(options)
method must run these steps:
-
Let portalBrowsingContext be the guest browsing context of the context object.
If no such context exists, throw an "
InvalidStateError
"DOMException
. -
Let predecessorBrowsingContext be the browsing context of the context object's document.
If no such context exists, throw an "
InvalidStateError
"DOMException
. -
Let serializeWithTransferResult be StructuredSerializeWithTransfer(options["
data
"], options["transfer
"]). Rethrow any exceptions. -
Let promise be a new promise.
-
Run the steps to activate portalBrowsingContext in place of predecessorBrowsingContext with data serializeWithTransferResult.
To complete portal activation, run these steps:
-
Resolve promise with undefined.
-
-
Return promise.
postMessage(message, targetOrigin, transfer)
method must run these steps:
-
Let portalBrowsingContext be the guest browsing context of the context object.
If no such context exists, throw an "
InvalidStateError
"DOMException
. -
Let settings be the relevant settings object of the context object.
-
Let origin be the serialization of settings’s origin.
-
If targetOrigin is a single U+002F SOLIDUS character (/), then set targetOrigin to the origin of settings.
-
Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
-
Queue a task from the posted message task source to the event loop of portalBrowsingContext to run the following steps:
-
If targetOrigin is not a single literal U+002A ASTERISK character (*) and the origin of portalBrowsingContext’s active document is not same origin with targetOrigin, then abort these steps.
-
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 with serializeWithTransferResult, origin and targetOrigin, queue a task from the posted message task source to the event loop associated with the
element’s document's browsing
context to run the following steps:
-
Let settings be the relevant settings object of the context object.
-
If targetOrigin is not a single literal U+002A ASTERISK character (*) and settings’s origin is not same origin with targetOrigin, then abort these steps.
-
Let targetRealm be settings’s realm.
-
Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
If this throws an exception, catch it, fire an event named
messageerror
at the context object usingMessageEvent
with theorigin
attribute initialized to origin and thesource
attribute initialized to the context object, -
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 context object usingMessageEvent
, with theorigin
attribute initialized to origin, thesource
attribute initialized to the context object, thedata
attribute initialized to messageClone, and theports
attribute initialized to newPorts.
portal
element, run the following steps:
-
If the context object has a guest browsing context, then close it. The user agent should not refuse to allow the document to be unloaded.
-
Clear the context object's guest browsing context.
portal
element, run the following steps:
-
Assert: the context object has a guest browsing context.
-
If the context object has no
src
attribute specified, or its value is the empty string, then close the context object and abort these steps. -
Parse the value of the
src
attribute. If that is not successful, then close the context object and abort these steps. Otherwise, let url be the resulting URL record. -
Let resource be a new request whose URL is url and whose referrer policy is "
no-referrer
". -
Navigate the guest browsing context to resource.
no-referrer
the right referrer policy here, or should we send the document’s URL? Whenever a portal
element’s src
attribute is set, run the following steps:
-
If the context object does not have a guest browsing context, abort these steps.
-
Set the source URL of the context object.
Whenever a portal
element is inserted, run the following steps:
-
If the context object has a guest browsing context or is not connected, abort these steps.
-
Create a new browsing context with noopener, and let newBrowsingContext be the result.
-
Set the context object's guest browsing context to newBrowsingContext. newBrowsingContext is a portal browsing context from this point onward.
-
Expose the portal host object of newBrowsingContext.
-
Set the source URL of the context object.
Whenever a portal
element is removed, run the following steps:
-
If the context object does not have a guest browsing context, abort these steps.
-
Close the context object.
portal
element without losing
its browsing context. 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. |
3.2. The PortalHost
interface
The portal host object of a browsing context is a PortalHost
. It may be either exposed or hidden; by default it is .
interfacePortalHost
: EventTarget { void postMessage(anymessage
, DOMStringtargetOrigin
, optional sequence<object>transfer
= []); };
PostMessageOptions
dictionary overload, to reflect the changes due to the user activation proposal. postMessage(message, targetOrigin, transfer)
method must run these steps:
-
If the context object's associated browsing context is not a portal browsing context, throw an "
InvalidStateError
"DOMException
. -
Let settings be the relevant settings object of the context object.
-
Let origin be the serialization of settings’s origin.
-
If targetOrigin is a single U+002F SOLIDUS character (/), then set targetOrigin to the origin of settings.
-
Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
-
Run the steps to accept a message posted to the host for the host associated with the context object with serializeWithTransferResult, origin and targetOrigin.
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.3. The PortalActivateEvent
interface
interfacePortalActivateEvent
: Event { readonly attribute anydata
; HTMLPortalElement adoptPredecessor(Documentdocument
); };
A PortalActivateEvent
has an associated predecessor browsing context,
which is a top-level browsing context.
adoptPredecessor(document)
method must run these steps:
-
Let predecessorBrowsingContext be the context object's predecessor browsing context.
-
Run the steps to adopt the predecessor browsing context predecessorBrowsingContext in document, and return the result.
3.4. Miscellaneous extensions
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
;
A PortalHost
is exposed at times when the window may be in a portal browsing context.
partial interface Window { readonly attribute PortalHost? portalHost; };
portalHost
attribute must run the following steps:
-
Let windowProxy be the context 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.
-
Let portalHostObject be the portal host object of context.
-
If portalHostObject is
, then return null. -
Return portalHostObject.
The following events are dispatched on Window
objects:
Event name | Interface | Dispatched when |
---|---|---|
portalactivate
| PortalActivateEvent
| The window is associated with a new top-level browsing context due to activation of its portal browsing context. |