Skip to content
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

Currently, knowing when a portal can be activated is guesswork #191

Open
jakearchibald opened this issue May 6, 2020 · 12 comments
Open
Labels
design work needed An acknowledged gap in the proposal that needs design work to resolve

Comments

@jakearchibald
Copy link
Collaborator

From #185, an activation can fail if:

no document was yet loaded in the portal, e.g. because the fetch isn't far enough along to commit, or because the UA chose to block it for some reason (incl. but not limited to CSP)

Do developers have a way to detect when the fetch is far enough along?

They have a way to detect later events, like load. I don't know whether we can reasonably expose this information. This is necessary because the entire load could end up being blocked and then we have nothing to show the user. This could have already happened, or we could be sitting waiting on a request which will ultimately result in a redirect to an invalid URL, a response with a CSP that prevents loading, or something similar.

This doesn't feel right. The load event is far too long to delay a navigation, and the only other choice we're leaving developers with is taking a punt and calling activate() early.

If exposing an earlier point is a leak, then we're kinda already leaking it though activate() rejecting.


When the developer calls activate(), we could wait until the fetch is far enough along, before deciding whether to fulfill or reject. This is generally how promise-based APIs work – they don't fail if the thing is in-progress.

Also, it'd be great to provide a portal.contentPainted promise, which is a signal for "you can start the transition now". But yeah, I'm unsure of the security implications here.

@jeremyroman
Copy link
Collaborator

We could make activate() wait, though it's kinda suboptimal if the developer did an animation already. Perhaps better than the current behavior, though. :)

activate() rejecting is less of a leak when/if we require a user gesture, though, which we seem likely to.

@jakearchibald
Copy link
Collaborator Author

We could make activate() wait, though it's kinda suboptimal if the developer did an animation already. Perhaps better than the current behavior, though. :)

Agreed, this is why I think we need something like portal.contentPainted to avoid animating a transparent portal.

@jeremyroman
Copy link
Collaborator

I do like this idea. I wonder if we'd want it to be a promise or an event. If a promise, I think I would expect it to be replaced with a new promise when I set src (but not when navigations occur internally to the portal context), but I haven't given it much thought.

@jakearchibald
Copy link
Collaborator Author

I wonder if we'd want it to be a promise or an event.

Even though it can happen many times, I think a promise is more usable as it can't be 'missed' (see the libraries that try to solve this for DOMContentLoaded).

I think I would expect it to be replaced with a new promise when I set src

Agreed. That was also the conclusion in whatwg/html#127.

(but not when navigations occur internally to the portal context)

Also agree, for security reasons.

I'm still not sure if it's safe to expose this for cross-origin cases. Don't we hold-back document swaps in regular navigations until first paint? Maybe this stuff is already exposed. Although I have a vague feeling the rules might be different for cross-origin navigations. I guess we should find someone who worked on this stuff.

@jakearchibald
Copy link
Collaborator Author

Don't we hold-back document swaps in regular navigations until first paint? Maybe this stuff is already exposed. Although I have a vague feeling the rules might be different for cross-origin navigations

https://bugs.chromium.org/p/chromium/issues/detail?id=805798 - this is only applied to same-origin navigations. I suspect it's for security/privacy reasons, but reason isn't given.

@jakearchibald
Copy link
Collaborator Author

jakearchibald commented May 7, 2020

From @mikewest

That seems like it would leak timing information that we otherwise wouldn't want to leak (e.g. cross-site search: interesting result takes longer to paint than non-interesting result). Same-origin less problematic than cross-origin.

Ok, so we need something else.

We already expose the time between setting location.href, and the page switching. Maybe that timing is good enough.

@mikewest
Copy link
Member

mikewest commented May 7, 2020

Rather than debating which point in time the browser can reveal readyness, and arguing about what period of time is potentially available via other means, why not provide the portaled page with the ability to notify its portaler that it's ready to be activated? That seems to me to mitigate the risk of inadvertently revealing information about user activity in frames/portals, and developers can presumably be trusted to make reasonable decisions about when they're ready that (in the best case) would be even more accurate than whatever heuristic we could produce.

It's a 1-bit leak from the portaled page to the portaler, which is perhaps something to worry about? I'm not sure what the privacy model is that y'all are working within...

@jakearchibald
Copy link
Collaborator Author

I'm worry is it isn't easy for developers to understand what information they're exposing by providing that, vs CORS where it's easier to explain (and folks still struggle with that).

@mikewest
Copy link
Member

mikewest commented May 7, 2020

I'm suggesting something like window.thisPageIsTotallyReadyToBeActivatedByWhomeverIsPortalingIt(), which doesn't seem on the face of it to be terribly difficult to explain. Unlike CORS, which people continually tell me is difficult to explain.

@jakearchibald
Copy link
Collaborator Author

Doesn't thisPageIsTotallyReadyToBeActivatedByWhomeverIsPortalingIt mean explaining timing attacks?

@mikewest
Copy link
Member

mikewest commented May 7, 2020

I guess? It doesn't seem to require less explanation (at least to ourselves) than the various points in time suggested above? I'm assuming most folks won't use it, which minimizes the impact.

@jakearchibald
Copy link
Collaborator Author

@mikewest if you have time, it might be worth thinking about #192 (comment). We're trying to come up with a way of using a portal as part of a regular navigation, so pages don't have to do special things to get a good experience. This idea is to make this as close to a regular navigation as possible, but with the opportunity to add a little animation.

This is why I was asking if real navigations were less problematic, since you can't just create 100s of them. We're trying to make the same guarantees here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design work needed An acknowledged gap in the proposal that needs design work to resolve
Projects
None yet
Development

No branches or pull requests

4 participants