Despite the use case in Jake's comment for issue #993, there is another interesting case in this manifest issue about _singleton_ apps. Perhaps something like:
self.onnavigation = event => {
const clients = await self.clients.matchAll({ type: 'window' });
if (clients.length === 1) {
clients[0].navigate(event.request.url);
clients[0].focus();
event.preventDefault();
}
};
If the app is a SPA, then SW could use # routes or post a message to the client to start an in-site navigation.
How is this different than a FetchEvent with a "navigate" RequestMode?
addEventListener('fetch', evt => {
if (evt.request.mode === 'navigate') {
// navigation event stuff here
}
});
Consider navigating from someotherplace.com to mysite.com which is already open. The link to mysite.com is a target="_blank" one but I want that navigation to be communicated to the already open instance of mysite.com
How do you actually prevent the opening of a new browser / tab with the fetch event? You are forced to use respondWith or get an error.
Hmm, ok. Although I'm not sure I agree if its a good idea.
What are your main concerning points? I have my own but I was waiting to receive some feedback so your comments are more than welcome.
We've talked about this before, as a "launch" event. https://github.com/w3c/ServiceWorker/issues/720#issuecomment-141021310
We should define the lidlfecycle of documents and browsing contexts a whole lot better first. And also the integration with history might be hard.
Actually, I remember reading it in a different issue, recently. Although _launch_ seems to have the correct connotations when tapping on a notification, it seems to not fit completely with "following a link" which is actually "navigation".
I agree with @annevk in defining such a lifecycle will help to clarify the problem.
My main concerns are about how _navigation_ relates with _fetch_ (should it be triggered before? after? does cancelling navigation cancel fetch?) and the overhead introduced by this new event (perhaps it makes more sense just triggering on _foreign navigations_, i.e. navigations from outside the origin/scope should be considered).
The reason I don't think "navigation" is the answer for this case is the page may express how it wants to handle the navigation.
We see this happening in native. If I click a link, a native app may take over. If I long-press and select "open in new tab" the native app does not take over, as I (the user) have specifically asked for a new tab.
I went with "launch" as it feels like the service worker would be controlling a subset of navigations.
(...) perhaps it makes more sense just triggering on foreign navigations (...)
I went with "launch" as it feels like the service worker would be controlling a subset of navigations.
I think we are saying the same here. Although, in my opinion, "launch" does not seem to convey the proper meaning but I agree on the name of the event should reflect intentionality.
So, @jakearchibald, in your opinion, which user intents should trigger the _launch_ event? For my _foreign navigation_ thing, I think it would be triggered every time you navigate into a URL controlled by a service worker from outside the scope.
I agree with your definition but add "鈥nless the user has expressed how they would like the navigation to behave". If I say "open in new tab", it'd be weird if that didn't happen.
Perhaps you could trigger _foreign navigation_ but not prevent default behaviour if the user has explicitly expressed an intention.
self.onforeignnavigation = evt => {
/* Log the event... */
if (evt.navigationMode === 'default') {
evt.preventDefault(); // OK
} else {
evt.preventDefault(); // throws
}
};
There is a similar discussion happening in w3c/manifest#597
I'm very interested in this (coming from w3c/manifest#597). I agree with Jake about the semantics: that it should have an (unspecified, user-agent-defined) condition on whether it fires or not, with the intention being that if the user has clearly signalled their intention to open a browser tab, then it does not fire and the app has no opportunity to intercept. But that it would fire for normal link clicks and the like.
I would vaguely suggest the following events would trigger / not trigger the event:
This is just a suggestion and would be UA-defined behaviour, but the idea would be to capture "plain" navigations but not navigations that are directly intended to be shown inside a browser tab.
As for the name, I am fine with "launch" but I agree there's something a bit funny about it.
How do we move forward on this?
I don't personally have enough knowledge about the SW spec or implementation to make some headway on this. I'm going to contact some of the SW team at Google to see if they are interested in implementing it.
OK, keep us posted
Did I ever mention anywhere that I created an explainer and polyfill for this?
https://wicg.github.io/sw-launch/
(Edit: Now on WICG)