-
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
Reacting to changes in storage #184
Comments
Potential solution: With a cross origin portal activation from origin A to origin B, origin B must signal that it recognises the situation, and is prepared to handle it. Otherwise, on activation, origin B will be reloaded. addEventListener('portalactivate', async (event) => {
if (!event.hasStorageAccess) {
// The page doesn't have storage access, meaning it was a cross-origin activation.
// By default, this page will reload, unless…
await document.requestStorageAccess();
// If storage access is granted (if it's top-level, it'll be granted without permission UI)
// the page won't be reloaded.
}
});
Alternatively, if we can't integrate with addEventListener('portalactivate', (event) => {
if (event.storageChanged) {
// The page didn't have storage access, but now it does, meaning it was a cross-origin activation.
// By default, this page will reload, unless…
event.preventDefault();
}
}); As usual, |
Having
<meta name="storage-access" content="on-upgrade=none"> The
|
Is it magic? The rule is "if you remain third party after activation, your page will be reloaded", and
Yeah I feel the same. I guess there could be another method on the event object? But then, it feels like it'd just be the same as
I'm less keen on solutions that separate declaring an action will be performed, and performing the action. For example: <meta name="storage-access" content="on-upgrade=silent">
<script>
addEventListener('portalactivate', (event) => {
if (event.storageChanged) {
updateUI(appConfig.user?.whatever);
}
});
</script> Here, the app has declared it'll handle the storage change, whereas the script that actually handles it may hit a parse error in some browsers due to addEventListener('portalactivate', async (event) => {
if (!event.hasStorageAccess) {
await document.requestStorageAccess();
updateUI(appConfig.user?.whatever);
}
}); In this case, if the script fails to load, or it hits a parse error, the declaration of "I can handle this situation" is also lost, so the page refreshes. |
Taking a step back: to me, if a portal reloads on activation, then it's not really a portal. It's a restricted iframe with a convenience method for doing Instead, my takeaway from
is that it would make the most sense for cross-origin portals to be completely opt-in. That is, unless the cross-origin page provides the appropriate header, attempting to portal it would be a navigation error. In other words, if a site hasn't explicitly allowed themselves to be portaled, then you should really just iframe them, not portal them. |
Yeah, pretty much.
I'm still unsure about solutions that separate declaring an action will be performed, and performing the action. Also, headers seem to be a huge barrier to entry since they can't be set on some static hosts. But yeah, it seems better to fail early than force a reload. |
Maybe. It seems kinda frustrating because it means that no existing content works, even trivial static documents. And then there's the question of how they would opt-in. Would it be a response header evaluated at load time, or a |
Well, I guess I'm confused as to whether it's a goal for existing content to work or not. The OP points out that this might be undesired, since then origin A can load origin B as a top-level navigation without credentials. If we think it's desirable to allow existing content to work despite this drawback, then that does change the design space. But I think it also means we should stop considering designs like the OP's which cause any existing content to be reloaded. |
I think it's obviously desirable, but perhaps non-critical. If we want to drop that, then we should think about whether we can make this detectable in some way, or whether we are expecting authors to know in advance whether the content they are referring to can be loaded in a portal, bearing in mind that this might change. And then if it fails do we want it to fail into doing nothing, or fail into holding onto the request URL until activation and then using that to do an ordinary navigation then (so that preload scenarios degrade into navigation instead of brokenness, at a cost of the API looking kinda weird). I agree that implicit reload is not a great behavior to have if we can avoid it. |
fwiw, this is why I keep pushing a "navigate" event. Since the developer is hooking into an actual navigation, and the portal is somewhat browser-controlled, the portal can be created with first party access, even if it's cross-origin. It just works with existing content. You'd still need some kind of opt-in for the cross-origin prerender use-case, where the portal is created before the navigation. |
@jakearchibald summarized some thoughts on the ephemeral/deadlined portal idea in #192 since they're slightly separate from this issue (though of course everything is intertwined); apologies if I didn't do it justice or missed something critical |
Cross-origin portals will have no access to storage while portaled. However, they are eligible for first-party storage once activated.
But this creates the following new situation:
jakearchibald.com
contains a portal tosocial.example.com
. Due to a lack of storage access,social.example.com
appears logged out, or even broken.This is fine. Iframes already behave in a similar way in Safari. The URL bar says
jakearchibald.com
, so any broken UI should seem the responsibility ofjakearchibald.com
, notsocial.example.com
.social.example.com
is activated.This is problematic. The URL bar now says
social.example.com
, and unlesssocial.example.com
takes steps to update their page in reaction to the change in storage, the experience will be broken, and reflect badly onsocial.example.com
.This is a new capability. Until now, there was no way for origin A to load origin B as a top-level navigation without credentials. Similar things, like strict SameSite cookies, are opt-in from origin B.
The text was updated successfully, but these errors were encountered: