-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tie BC creation to availability of a valid src + BC connectedness. #138
Changes from all commits
ac51051
57d995f
394043b
87bb25d
1b2087d
772f647
c67ecaa
b2c5fcd
315b8a0
cc1abcb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,13 @@ spec:url; type:dfn; text:scheme | |
element which embeds its rendered output and receives messages sent from the | ||
portal browsing context. | ||
|
||
<div class="note"> | ||
A <{portal}> element may only be a [=host element=] while it is | ||
[=browsing-context connected=] or during the dispatch of the | ||
{{Window/portalactivate!!event}} event from which it was obtained | ||
using {{PortalActivateEvent/adoptPredecessor()}}. | ||
</div> | ||
|
||
The <dfn>host browsing context</dfn> of a [=portal browsing context=] is its | ||
[=host element=]'s [=node document|document=]'s [=browsing context=]. | ||
|
||
|
@@ -116,6 +123,15 @@ spec:url; type:dfn; text:scheme | |
|
||
1. [=Assert=]: The [=portal state=] of |predecessorBrowsingContext| is "`none`". | ||
|
||
1. 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 |portalBrowsingContext| in the rendering. | ||
|
||
Note: This is intended to avoid a visual glitch, such as a "white flash", where | ||
the guest browsing context briefly disappears. | ||
|
||
1. Set the [=portal state=] of |predecessorBrowsingContext| to "`orphaned`". | ||
|
||
1. Update the user interface to replace |predecessorBrowsingContext| with |successorBrowsingContext| | ||
|
@@ -151,16 +167,40 @@ spec:url; type:dfn; text:scheme | |
|
||
1. [=Dispatch=] |event| to |successorWindow|. | ||
|
||
1. If |event|'s [=PortalActivateEvent/predecessor browsing context=] is not null, then | ||
[=queue a task=] from the [=portal task source=] to the | ||
[=event loop=] associated with |predecessorBrowsingContext| to | ||
resolve |promise| with undefined. | ||
1. Let |adoptedPredecessorElement| be |event|'s [=PortalActivateEvent/adopted predecessor element=]. | ||
|
||
1. If |adoptedPredecessorElement| is not null, then: | ||
|
||
1. Set |adoptedPredecessorElement|'s [=just-adopted flag=] to false. | ||
|
||
1. If |element| [=may have a guest browsing context|may not have a guest browsing context=] and its [=guest browsing context=] is not null, then [=discard a browsing context|discard=] it. | ||
|
||
<div class="note"> | ||
This unceremoniously [=discard a browsing context|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 [=close a browsing context|closes=] the | ||
browsing context, which dispatches the | ||
{{Window/unload!!event}} event, somewhat similarly to if it | ||
had performed an ordinary navigation. | ||
|
||
1. If |predecessorBrowsingContext| is not a [=portal browsing context=], [=close a browsing context|close=] it. | ||
Typically authors would not call | ||
{{PortalActivateEvent/adoptPredecessor()}} unless they intend | ||
to insert it into the document before the [=just-adopted flag=] | ||
becomes false. | ||
</div> | ||
|
||
The user agent *should not* ask the user for confirmation during the | ||
[=prompt to unload=] step (and so the browsing context should be | ||
[=discard a browsing context|discarded=]). | ||
1. Otherwise: | ||
|
||
1. [=Queue a task=] from the [=portal task source=] to the [=event loop=] | ||
associated with |predecessorBrowsingContext| to resolve |promise| with undefined. | ||
|
||
1. [=Close a browsing context|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 | ||
[=discard a browsing context|discarded=]). | ||
</section> | ||
|
||
<wpt> | ||
|
@@ -186,6 +226,8 @@ spec:url; type:dfn; text:scheme | |
|
||
1. Let |portalElement| be the result of [=creating an element=] given |document|, `portal`, and the [=HTML namespace=]. | ||
|
||
1. Set |portalElement|'s [=just-adopted flag=] to true. | ||
|
||
1. [=Assert=]: |portalElement| is an {{HTMLPortalElement}}. | ||
|
||
1. [=Queue a task=] from the [=portal task source=] | ||
|
@@ -240,6 +282,10 @@ spec:url; type:dfn; text:scheme | |
browsing context</dfn>, which is the [=portal browsing context=] whose [=host | ||
element=] is |portalElement|, or null if no such browsing context exists. | ||
|
||
A <{portal}> element has a <dfn for="HTMLPortalElement">just-adopted | ||
flag</dfn>, which is a [=boolean=] and is initially false. It is set during | ||
dispatch of the {{Window/portalactivate!!event}} event. | ||
|
||
The <dfn element-attr for="portal">src</dfn> 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=]. | ||
|
@@ -308,14 +354,6 @@ spec:url; type:dfn; text:scheme | |
|options|["{{PortalActivateOptions/transfer}}"]). | ||
Rethrow any exceptions. | ||
|
||
1. Set the [=guest browsing context=] of [=this=] to null. | ||
User agents *should*, however, attempt to preserve the rendering of the | ||
guest browsing context until |predecessorBrowsingContext| has been replaced | ||
with |portalBrowsingContext| in the rendering. | ||
|
||
Note: This is intended to avoid a visual glitch, such as a "white flash", where | ||
the guest browsing context briefly disappears. | ||
|
||
1. Let |promise| be a new [=promise=]. | ||
|
||
1. Run the steps to [=activate a portal browsing context|activate=] |portalBrowsingContext| | ||
|
@@ -400,6 +438,28 @@ spec:url; type:dfn; text:scheme | |
</wpt> | ||
</section> | ||
|
||
<section algorithm="htmlportalelement-may-have-guest-browsing-context"> | ||
To determine whether a <{portal}> element <dfn for="HTMLPortalElement">may have a guest browsing context</dfn>, run the following steps: | ||
|
||
1. If |element|'s [=node document|document=]'s [=browsing context=] is not a [=top-level browsing context=], then return false. | ||
|
||
<wpt> | ||
portals-nested.html | ||
</wpt> | ||
|
||
<p class="note"> | ||
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. | ||
</p> | ||
|
||
1. If |element| is [=browsing-context connected=], then return true. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe also add "and its browsing context is top-level"? Maybe this will complicate the algorithm below, but it might be worth changing, as it expresses more clearly the situations where a portal may have a browsing context. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done; PTAL? |
||
|
||
1. If |element|'s [=just-adopted flag=] is true, then return true. | ||
|
||
1. Return false. | ||
</section> | ||
|
||
<section algorithm="htmlportalelement-close"> | ||
To <dfn for="HTMLPortalElement">close a <{portal}> element</dfn> |element|, run the following steps: | ||
|
||
|
@@ -408,25 +468,39 @@ spec:url; type:dfn; text:scheme | |
The user agent *should not* ask the user for confirmation during the | ||
[=prompt to unload=] step (and so the browsing context should be | ||
[=discard a browsing context|discarded=]). | ||
|
||
1. Set |element|'s [=guest browsing context=] to null. | ||
</section> | ||
|
||
<section algorithm="htmlportalelement-setsourceurl"> | ||
To <dfn for="HTMLPortalElement">set the source URL of a <{portal}> element</dfn> |element|, run the following steps: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "set the source URL" is feeling like a worse name for this algorithm now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what a better name is. It's principally used when the embedder directs the portal BC to navigate by changing the "Possibly navigate" sounds a little vague. Any suggestions? |
||
|
||
1. Let |guestBrowsingContext| be |element|'s [=guest browsing context=]. | ||
1. [=Assert=]: |element| [=may have a guest browsing context=]. | ||
|
||
1. [=Assert=]: |guestBrowsingContext| is not null. | ||
1. Let |hostBrowsingContext| be |element|'s [=node document|document=]'s [=browsing context=]. | ||
|
||
1. [=Assert=]: |hostBrowsingContext| is a [=top-level browsing context=]. | ||
|
||
1. If |element| has no <{portal/src}> attribute specified, or its value is the empty string, | ||
then [=close a portal element|close=] |element| and abort these steps. | ||
then [=close a portal element|close=] |element| and return. | ||
|
||
1. [=Parse a URL|Parse=] the value of the <{portal/src}> attribute. If that is not successful, | ||
then [=close a portal element|close=] |element| and abort these steps. | ||
then [=close a portal element|close=] |element| and return. | ||
|
||
Otherwise, let |url| be the [=resulting URL record=]. | ||
|
||
1. If the [=scheme=] of |url| is not an [=HTTP(S) scheme=], then abort these steps. | ||
1. If the [=scheme=] of |url| is not an [=HTTP(S) scheme=], then [=close a portal element|close=] | ||
|element| and return. | ||
|
||
1. If |element|'s [=guest browsing context=] is null, then run the following steps: | ||
|
||
1. Let |newBrowsingContext| be the result of | ||
[=create a new top-level browsing context|creating a new top-level browsing context=]. | ||
|
||
1. Set the [=portal state=] of |newBrowsingContext| to "`portal`", and set | ||
the [=host element=] of |newBrowsingContext| to |element|. | ||
|
||
1. Let |guestBrowsingContext| be |element|'s [=guest browsing context=]. | ||
|
||
1. [=Assert=]: |guestBrowsingContext| is not null. | ||
|
||
1. Let |resource| be a new [=request=] whose [=request URL|URL=] is |url| | ||
and whose [=request referrer policy|referrer policy=] is the current state of | ||
|
@@ -457,48 +531,25 @@ spec:url; type:dfn; text:scheme | |
Whenever a <{portal}> element |element| has its <{portal/src}> attribute set, | ||
changed, or removed, run the following steps: | ||
|
||
1. If |element|'s [=guest browsing context=] is null, abort these steps. | ||
|
||
1. [=set the source URL of a portal element|Set the source URL=] of |element|. | ||
1. If |element| [=may have a guest browsing context=], then [=set the source URL of a portal element|set the source URL=] of |element|. | ||
|
||
Whenever a <{portal}> element |element| [=becomes browsing-context connected=], run the following steps: | ||
|
||
1. If |element|'s [=guest browsing context=] is null, abort these steps. | ||
|
||
1. Let |hostBrowsingContext| be |element|'s [=node document|document=]'s [=browsing context=]. | ||
|
||
1. [=Assert=]: |hostBrowsingContext| is not null. | ||
|
||
1. If |hostBrowsingContext| is a nested browsing context, then abort these steps. | ||
|
||
<p class="note"> | ||
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. | ||
</p> | ||
1. If |element| [=may have a guest browsing context|may not have a guest browsing context=], then abort these steps. | ||
|
||
1. Let |newBrowsingContext| be the result of [=create a new top-level browsing context|creating a new top-level browsing context=]. | ||
1. If |element|'s [=guest browsing context=] is not null, then abort these steps. | ||
|
||
1. Set the [=portal state=] of |newBrowsingContext| to "`portal`", and set | ||
the [=host element=] of |newBrowsingContext| to |element|. | ||
|
||
1. Set |element|'s [=guest browsing context=] to |newBrowsingContext|. | ||
<div class="note"> | ||
This ensures that a newly [=adopt the predecessor browsing context|adopted=] | ||
<{portal}> element can be inserted into the document without navigating | ||
it. | ||
</div> | ||
|
||
1. [=set the source URL of a portal element|Set the source URL=] of |element|. | ||
|
||
<wpt> | ||
portals-nested.html | ||
</wpt> | ||
|
||
Whenever a <{portal}> element |element| [=becomes browsing-context disconnected=], run the following steps: | ||
|
||
1. Let |guestBrowsingContext| be |element|'s [=guest browsing context=]. | ||
|
||
1. If |guestBrowsingContext| is null, then abort these steps. | ||
|
||
1. [=discard a browsing context|Discard=] |guestBrowsingContext|. | ||
|
||
1. Set |element|'s [=guest browsing context=] to null. | ||
1. If |element| [=may have a guest browsing context|may not have a guest browsing context=] and its [=guest browsing context=] is not null, then [=discard a browsing context|discard=] it. | ||
|
||
<div class="issue"> | ||
It might be convenient to not immediately detach the portal element, but instead to do so | ||
|
@@ -514,16 +565,15 @@ spec:url; type:dfn; text:scheme | |
|
||
1. [=discard a browsing context|Discard=] |guestBrowsingContext|. | ||
|
||
1. Set |element|'s [=guest browsing context=] to null. | ||
|
||
<div class="note"> | ||
In particular, this means a <{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 [=becomes browsing-context | ||
connected=] prevent elements from creating a new [=guest browsing context=] | ||
while inside such documents. | ||
Similarly, the steps when a <{portal}> element's | ||
[=set the source URL of a portal element|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=]. | ||
|
@@ -701,14 +751,17 @@ spec:url; type:dfn; text:scheme | |
|
||
A {{PortalActivateEvent}} has an associated <dfn for="PortalActivateEvent">predecessor browsing context</dfn>, | ||
which is a [=top-level browsing context=] or null, a <dfn for="PortalActivateEvent">successor window</dfn>, which is | ||
a {{Window}}, and an <dfn for="PortalActivateEvent">activation promise</dfn>, which is a [=promise=]. | ||
a {{Window}}, an <dfn for="PortalActivateEvent">activation promise</dfn>, which is a [=promise=], and a | ||
<dfn for="PortalActivateEvent">adopted predecessor element</dfn>, which is a <{portal}> element or null. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fact that this is an element doesn't appear to be used. A boolean would work just as well. Right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used to clear the "just adopted" flag after There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, my bad. |
||
|
||
<section algorithm="portalactivateevent-event-constructing-steps"> | ||
The [=event constructing steps=] for {{PortalActivateEvent}}, given an |event|, are as follows: | ||
|
||
1. Set |event|'s [=PortalActivateEvent/predecessor browsing context=] to null. | ||
|
||
1. Set |event|'s [=PortalActivateEvent/successor window=] to null. | ||
|
||
1. Set |event|'s [=PortalActivateEvent/adopted predecessor element=] to null. | ||
</section> | ||
|
||
<wpt> | ||
|
@@ -718,15 +771,16 @@ spec:url; type:dfn; text:scheme | |
<section algorithm="portalactivateevent-adoptpredecessor"> | ||
The <dfn method for="PortalActivateEvent"><code>adoptPredecessor()</code></dfn> method *must* run these steps: | ||
|
||
1. Let |predecessorBrowsingContext| be [=this=]'s [=PortalActivateEvent/predecessor browsing context=]. | ||
1. If [=this=]'s [=PortalActivateEvent/adopted predecessor element=] is not null, throw an "{{InvalidStateError}}" {{DOMException}}. | ||
|
||
1. If |predecessorBrowsingContext| is null, throw an "{{InvalidStateError}}" {{DOMException}}. | ||
|
||
1. Clear [=this=]'s [=PortalActivateEvent/predecessor browsing context=]. | ||
1. Let |predecessorBrowsingContext| be [=this=]'s [=PortalActivateEvent/predecessor browsing context=]. | ||
|
||
1. Let |successorWindow| be [=this=]'s [=PortalActivateEvent/successor window=]. | ||
|
||
1. Run the steps to [=adopt the predecessor browsing context=] |predecessorBrowsingContext| in |successorWindow|, and return the result. | ||
1. Run the steps to [=adopt the predecessor browsing context=] |predecessorBrowsingContext| in |successorWindow|, | ||
and let |adoptedPredecessorElement| be the result. | ||
|
||
1. Set [=this=]'s [=PortalActivateEvent/adopted predecessor element=] to |adoptedPredecessorElement|. | ||
|
||
1. [=Queue a task=] from the [=portal task source=] to the [=event loop=] associated with | ||
|predecessorBrowsingContext| to resolve [=this=]'s [=activation promise=] with undefined. | ||
|
@@ -736,6 +790,8 @@ spec:url; type:dfn; text:scheme | |
ordering issues between the task to resolve the activation promise and the task | ||
to deliver the message. | ||
|
||
1. Return |adoptedPredecessorElement|. | ||
|
||
<wpt> | ||
portals-adopt-predecessor.html | ||
</wpt> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of discard here vs. close below warrants a note, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done; wdyt?