-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Ensure that 'noopener' does not reuse a browsing context #1842
Conversation
<p><dfn>The rules for choosing a browsing context given a browsing context name</dfn> are as | ||
follows. The rules assume that they are being applied in the context of a <span>browsing | ||
context</span>, as part of the execution of a <span data-x="concept-task">task</span>.</p> | ||
<p><dfn>The rules for choosing a browsing context</dfn> given a browsing context name and disown |
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 old ID should be preserved somehow.
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.
Is there an existing pattern for maintaining old IDs?
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.
This looks good to me in general, but there are some edge cases that may not have been considered (mentioned below) that I would like to make sure we have agreement on before I spend more time on implementation....
source
Outdated
@@ -18647,8 +18647,8 @@ interface <dfn>HTMLAnchorElement</dfn> : <span>HTMLElement</span> { | |||
<span>triggered by user activation</span>; or, if the user has not indicated a specific | |||
<span>browsing context</span> for following the link, and the element's <code | |||
data-x="attr-hyperlink-target">target</code> attribute is present, and applying <span>the rules | |||
for choosing a browsing context given a browsing context name</span>, using the value of the | |||
<code data-x="attr-hyperlink-target">target</code> attribute as the browsing context name, would | |||
for choosing a browsing context</span>, using the value of the <code |
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.
Doesn't this need to pass a value for the disown opener flag?
source
Outdated
context name, would result in there not being a chosen browsing context, then run these | ||
substeps:</p> | ||
<span>the rules for choosing a browsing context</span>, using the value of the <code | ||
data-x="attr-hyperlink-target">target</code> attribute as the browsing context name, would |
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.
And need to pass disown opener flag value here too...
source
Outdated
context</var> as the context in which the algorithm is executed, and let <var>target | ||
browsing context</var> be the resulting <span>browsing context</span>.</p></li> | ||
Otherwise, apply <span>the rules for choosing a browsing context</span> using <var>target</var> | ||
as the name and <var>form browsing context</var> as the context in which the algorithm is |
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.
And here.
source
Outdated
given browsing context name (otherwise, it has no name). The chosen browsing context must be | ||
this new browsing context.</p> | ||
<p>A new <span>top-level browsing context</span> must be created. Its <span>opener | ||
browsing context</span> is the current one if the disown opener flag is false, and empty |
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.
Is "empty" the right terminology?
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.
Reworded to avoid the question, since it's not answered anywhere else in the document. :)
<p><dfn>The rules for choosing a browsing context</dfn> given a browsing context name and disown | ||
opener flag are as follows. The rules assume that they are being applied in the context of a | ||
<span>browsing context</span>, as part of the execution of a <span | ||
data-x="concept-task">task</span>.</p> |
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.
OK, so let's think about edge cases:
window.open("", "_self", "noopener");
window.open("", "_top", "noopener");
window.open("", "_parent", "noopener");
source
Outdated
<p>Otherwise, apply <span>the rules for choosing a browsing context</span> using | ||
<var>target</var> as the name, <var>disown opener</var>, and <var>source browsing context</var> | ||
as the context in which the algorithm is executed. If this results in there not being a chosen | ||
browsing context, then throw an <span>"<code>InvalidAccessError</code>"</span> |
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.
Huh, really? This is not what any browser does. Filed #1845 on this, but for purposes of this review I guess this is a preexisting issue.
source
Outdated
<li><p>If the result of <span data-x="split a string on commas">splitting <var>features</var> | ||
on commas</span> contains the token "<code data-x="">noopener</code>", <span data-x="disowned | ||
its opener">disown <var>target browsing context</var>'s opener</span>, and return <code | ||
<li><p>If <var>disown opener</var> is true, <span data-x="disowned its opener">disown |
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.
OK, so this is the thing we need to sort out for _self and company. Should a window be able to disown its own opener by doing open("", "_self", "noopener")
, for example? Should such a call return null?
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.
Hrm, looking at this again, I don't think we actually need to disown the opener here since we're not setting the owner browsing context when choosing a browsing context. Changing this to something like "if disown opener is true, and target browsing context was just created, return null" should be enough.
@mikewest So I'd like to make a concrete proposal, because shipping noopener in Firefox is currently blocked on this being resolved, unless we were to just make something up and ship it...
|
|
WIP: All of this would benefit from more substantial refactoring, but let's decide that this is the right way to approach things first. #1826
It's totally observable. Off the top of my head, some ways:
It can totally happen, per spec. See https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name step 5 the "If the user agent has been configured such that in this instance it will reuse the current browsing context" case. That basically says "If the UA is set up to treat _blank as a synonym for _self". Note also the "User agent implementors are encouraged to provide a way for users to configure the user agent to always reuse the current browsing context." bit after that point. What probably makes the most sense is to just do the noopener disowning thing in the existing "If the chosen browsing context picked above, if any, is a new browsing context" section that currently does sandbox flag propagation. |
You're right. I hadn't considered something like
sigh I would dearly love to remove navigation to |
I don't actually think we need to actively disown the opener if we never set the "opener browsing context". Does disowning have side-effects other than removing that relationship? https://html.spec.whatwg.org/#disowned-its-opener is a bit light on expectations. |
Disowning is somewhat underspecified right now, yes. I think the main question is what the impact of never setting (as opposed to disowning) the opener is on the https://html.spec.whatwg.org/multipage/browsers.html#script-closable concept. For that matter, it's not clear to me whether the thing opened via noopener should be script-closable, conceptually. Looks like in Chrome it is, both in the window.open case and in the |
Hrm. They're script-closable because they're "a top-level browsing context whose session history contains only one Document." I guess I wouldn't be terribly sad if they were no longer script-closable, but it doesn't seem obviously wrong that they are. Do you think we need to address that in this patch? |
Ah, interesting. I did verify that if I use the testcase from #1866 but rel="noopener" in test.html then the close button does not work in Chrome (but does in Firefox and Safari, at least). For the same testcase without rel="noopener" the button works in Chrome, even if I add a So it certainly looks like at least in Chrome the behavior of rel="noopener" on a link is different from the same link without noopener followed by disowning the opener...
I think what we should do in this patch is not set the opener at all, rather than disowning it. And we can sort out the script-closable behavior in general in #1866 because the current spec seems pretty broken to me (e.g. doesn't match UAs). |
What I plan to implement in Gecko is that noopener does NOT return null in the _self/_parent/_top cases, and will write tests accordingly. |
Closing this as this is not the correct fix and the specification has changed quite a bit (noopener is being passed around these days). Probably best to first figure out what everyone wants to align on and go from there. |
WIP: All of this would benefit from more substantial refactoring, but
let's decide that this is the right way to approach things first.
#1826