-
Notifications
You must be signed in to change notification settings - Fork 67
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
What happens if activate is called while the portal is navigating #227
Comments
Related: If a portal is navigated while it's activating (either via the host page, or itself), what happens? My gut here is that those navigations are no-ops. |
One parallel here: const img = new Image();
img.src = url;
await img.decode();
|
Potential issue:
What happens? If the redirect is allowed through, then it's a CSP bypass. I guess we'd have to block the redirect. Is it weird to do that after the portal has activated? Maybe it's fine. |
My preferred solution here, in the spirit of #191, is that the code in the OP should try to activate the current context. That context may be absent, causing a failure, or it might be something that exists, in which case it will activate while the navigation is ongoing. If the developer wants to wait for portal.src = otherURL;
portal.onready = () => portal.activate();
Similarly, this should activate while the navigation is ongoing. I.e., the previous page should become a TLBC, but the navigation is happening and so soon that TLBC might transition to a new page.
In my mind activation is atomic; it synchronously commits to activating once you call the method. This is supported by the spec in that step 4 ("update the user interface") happens synchronously from However, I realize that the spec doesn't actually switch the portal state until the posted task comes around, and there are of course implementation issues here; activating involves things happening in another process. From that point of view I'm not sure if step 4 happening synchronously is accurate... But I think we can still maintain the mental model of
Why is it a CSP bypass? After step 4, |
The comparison to
I'm a little worried that
Yeah, I'm proposing to make it async either way. If the portal activates by moving a browsing context, but the portal navigation also changes browsing context, that feels like a fun race condition 😄 .
I think the problem is, although Think of this this way: Malicious code on Page A wants to navigate the page to But then, the malicious code realises they can bypass this rule: const portal = document.createElement('portal');
portal.src = '/slowly-redirects-x-origin?example.com';
document.body.append(portal);
portal.activate(); Maybe being able to bypass |
An alternative: portal.src = otherURL;
portal.activate(); …would activate the current browsing context, which would navigate to Although I'm still unsure how that would work if portal navigations may cause a change of browsing context. |
For others reading along, TLBC = top level browsing context. |
No. I don't think image decoding and portal activation have anything really in common.
I think we have to decide whether or not we want activation to be a matter of guesswork. If we don't, then we need
I still don't think page A's rules matter anymore. Page A is out of the picture by that point.
How does |
Hm, fair enough. They both have this pattern. el.src = url;
await el.performAction(); With image decoding, it waits for the src to load enough to decode or fail, but with portals you have to get the timing right yourself.
I don't think we can release something where the core API involves guesswork like that. But I disagree with Mike that it's an information leak too, since you can get the same timing by polling the document of an iframe until it throws. If we can have a ready promise that means "navigated" (and maybe also event?) then I guess it's fine. If we can have it for portals, we can have it for
Yeah. It wouldn't even need to be that slow either, just as long as the redirect is processed after activation. |
As you point out, I think it'd be the same as using iframes (or |
Yes, that seems reasonable. Basically proposing the same event for iframes, I guess. |
I don't think so: const portal = document.createElement('portal');
portal.src = url;
setTimeout(() => {
portal.activate();
}, 1000); The above resolves if So whether it rejects or not depends how fast your connection is, and how quick |
|
I think using the context is associated with the |
Is that synchronous, or would it be racey? |
Teardown of an old context and creation of a new one is not synchronous, but reassociation with a new context can be. The element just requests a new one and as long as everything that actually changes the context itself happens asynchronously, it's fine. You'd run into trouble if you wanted to synchronously access that context, or if you wanted to allow the existing page in the portal to prevent this via |
We decided in #191 that the timing of activating a portal shouldn't be down to guesswork.
What should happen here? Should it wait for
otherURL
to fetch, or should it try and activate the current context (which may be absent)?Similarly, what should we do if the portal is undergoing a navigation that was triggered internally?
If the src is set, it feels like activation should wait for that action to settle.
If the portal is navigating by some other means, waiting seems like an information leak. The alternative would be to abort that navigation, and activate the current document. This is giving the host page some control over an action stated within the portal, but it seems
window.stop()
can already do that? Thoughts @jyasskin?The text was updated successfully, but these errors were encountered: