Intent to Implement: Service Worker-based event delivery for Web Notifications

201 views
Skip to first unread message

Peter Beverloo

unread,
Oct 23, 2014, 12:34:01 PM10/23/14
to blink-dev
Contact emails

Spec

Summary
Enabling delivery of Web Notification-generated events to a Service Worker.

Motivation
Notifications play a prominent role of informing the user of activities and events on mobile, but the expected lifetime of a document on a mobile device would make them very unreliable at best. This causes the page to lose the event handlers, making it impossible for the user to respond to a shown notification.

Instead, it will be possible to create Service Worker-bound notifications. These will be created using a method on the ServiceWorkerRegistration instead of the Notification constructor, and will move event delivery of the "click" and "error" events to the Service Worker rather than event handlers on the Notification event itself. Such notifications can safely outlive the page or worker they were created by, without rendering them useless.

When the user clicks on a Service Worker-bound notification, the browser will activate the Service Worker and invoke the "onnotificationclick" event. It's got full access to the Notification object from here.

Example
// index.html
navigator.serviceWorker.ready.then(function (registration) {
  registration.showNotification('Hello, world!', {
    body: 'This is a notification.',
    icon: 'notification.png'
  });
});

// service_worker.js
onnotificationclick = function(event) {
  if (event.notification.title == 'Hello, world!') {
    // do something with it.
    event.notification.close();
  }
};

Compatibility Risk
Small. Mozilla is pushing for the Service Worker event delivery as well. Neither Microsoft nor Apple have participated in discussions.

Will this feature be supported on all five Blink platforms?
Yes.

OWP launch tracking bug?

Link to entry on the feature dashboard

Requesting approval to ship?
No.

Elliott Sprehn

unread,
Oct 23, 2014, 9:23:26 PM10/23/14
to Peter Beverloo, blink-dev
I don't think we should implement this as described here, ServiceWorkerRegistration should not need to know all the features in the engine. This is how Element and Window ended up with an ever growing number of properties.


More abstractly, the method "showNotification" doesn't make sense on a registration object, it's also weird that SW's global scope is growing on* properties for every feature.

Why doesn't new Notification take a SW instead?

Peter Beverloo

unread,
Oct 24, 2014, 6:03:45 AM10/24/14
to Elliott Sprehn, blink-dev
On Fri, Oct 24, 2014 at 2:22 AM, Elliott Sprehn <esp...@chromium.org> wrote:
I don't think we should implement this as described here, ServiceWorkerRegistration should not need to know all the features in the engine. This is how Element and Window ended up with an ever growing number of properties.


More abstractly, the method "showNotification" doesn't make sense on a registration object, it's also weird that SW's global scope is growing on* properties for every feature.

Why doesn't new Notification take a SW instead?

While I agree that ServiceWorkerRegistration shouldn't become a dumping ground, it is a sane place for features with a strict dependency on the registration to reside. In case of Notifications, it allows us to distinguish between persistent notifications and non-persistent notifications, which have different lifetime and event-delivery semantics. This would be less obvious if it were passed in as a parameter (which is something we considered).

Regarding events on the ServiceWorkerGlobalScope -- this pretty much is the way Service Workers have been designed. I don't have strong feelings in this regard.

Peter

PhistucK

unread,
Oct 24, 2014, 8:12:00 AM10/24/14
to Peter Beverloo, Elliott Sprehn, blink-dev
I also agree that having onX (versus addEventListener, at least) in new APIs is a serious step back to the wild wild nineties.


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Anne van Kesteren

unread,
Oct 24, 2014, 8:15:56 AM10/24/14
to PhistucK, Peter Beverloo, Elliott Sprehn, blink-dev
On Fri, Oct 24, 2014 at 2:11 PM, PhistucK <phis...@gmail.com> wrote:
> I also agree that having onX (versus addEventListener, at least) in new APIs
> is a serious step back to the wild wild nineties.

Contrasted to addEventListener, on* is much easier if you want to do
something simple. And it's definitely not nineties, every event-based
API has them.


--
https://annevankesteren.nl/

PhistucK

unread,
Oct 24, 2014, 8:21:32 AM10/24/14
to Anne van Kesteren, Peter Beverloo, Elliott Sprehn, blink-dev
"much easier" would be an exaggeration.
onbla = listener versus addEventListener("bla", listener) is not "much easier" in my view.
Even if it is, it is too easily overridable (and the web - or web development - had, or has, so many bugs because of that).


PhistucK

Anne van Kesteren

unread,
Oct 24, 2014, 8:29:58 AM10/24/14
to PhistucK, Peter Beverloo, Elliott Sprehn, blink-dev
On Fri, Oct 24, 2014 at 2:20 PM, PhistucK <phis...@gmail.com> wrote:
> onbla = listener versus addEventListener("bla", listener) is not "much
> easier" in my view.

If you want to clear the latter approach requires you to keep a
reference to listener.


> Even if it is, it is too easily overridable (and the web - or web
> development - had, or has, so many bugs because of that).

[citation needed]


--
https://annevankesteren.nl/

PhistucK

unread,
Oct 24, 2014, 8:40:19 AM10/24/14
to Anne van Kesteren, Peter Beverloo, Elliott Sprehn, blink-dev
Right, you should manage your references anyway. If you set a listener using the legacy method (onbla), it is a reference nonetheless and a less obvious one when you look at your globals/variables.

They mostly never end up in production, but it is common to have, for example, two window.onload = function () {} in the same file, or in (bad) third party code and they overrode each other. Some login checker script with which I worked had one, for example and it broke during development or testing because it was overridden. I sent the author the fix and it was soon deployed. The bugs are not always obvious and may take a while to be discovered, or even traced to the event being overridden.


PhistucK

Chris Harrelson

unread,
Oct 30, 2014, 1:14:05 AM10/30/14
to Elliott Sprehn, Peter Beverloo, blink-dev
I agree with Elliott. ServiceWorkerRegistration is an illogical place for showNotification. I can see the idea though - the ServiceWorkerRegistration is a queue of current and upcoming service workers for a path, so you want the Notification to go to whichever SW is alive at the time the user activates the Notification.

Elliott's suggestion of passing a SW to the notification as the handler of the notification also makes sense to me. All notifications can then have an optional EventTarget argument, which could be a service worker or other object.

Or even better, get rid of this special case and and force all Notifications to be created and handled only within the lifetime of some JS execution world (either main document, regular Worker or a SW). Then expect the developer to postMessage the notification content to the SW and have the SW create its own Notification. This allows the SW to close the Notification whenever it wants, and also allows the User Agent to detect that the Notification is tied to the SW, and keep the SW around for a time in order to have the chance to process it. The document can also postMessage a request to kill notifications to the SW.

On top of the above, (and going beyond the scope of this thread if I may) I'd say perhaps get rid of the difference between a persistent and non-persistent Notification unless there is some web trust permissions reason to prefer the distinction (and even then just pass an enum to the constructor to hint to the User Agent). The developer can dismiss their own Notifications when desired, or they can be cleaned up when the document or SW is killed or the Notification sits unactivated too long.

addEventListener is also preferable to on*, for the reasons PhistucK and others stated.

Chris




Peter Beverloo

unread,
Nov 11, 2014, 12:06:58 PM11/11/14
to Chris Harrelson, Elliott Sprehn, blink-dev
Based on discussion with Chris I think there is one important misunderstanding here: the intent is that these notifications can outlive the service worker, and even the browser itself if the platform supports that.

Using Android as an example, you can imagine the following scenario:
- The user visits FancyAirline.com and books a flight, and signs up for delay notifications.
- The flight is delayed. FancyAirline sends a Push Message to the client, which wakes up the Service Worker and fires the "onpush" event. In here, they show a notification.
- [The Android framework kills Chrome because of memory presure.]
- The user clicks on the shown Notification, which fires an intent, which starts up Chrome, launches the Service Worker associated with the registration (even when updated) and allows the developer to handle this, e.g. create or focus a tab.

The reasoning for binding to the ServiceWorkerRegistration is that it's the Service Worker that will be woken up if necessary for delivering the event, irrespective of the version (it may have been updated in between).

Attaching the event listener can of course be done using attachEventListener.

Thanks,
Peter

Peter Beverloo

unread,
Nov 11, 2014, 12:09:31 PM11/11/14
to Chris Harrelson, Elliott Sprehn, blink-dev
On Tue, Nov 11, 2014 at 5:06 PM, Peter Beverloo <pe...@chromium.org> wrote:
Based on discussion with Chris I think there is one important misunderstanding here: the intent is that these notifications can outlive the service worker, and even the browser itself if the platform supports that.

Using Android as an example, you can imagine the following scenario:
- The user visits FancyAirline.com and books a flight, and signs up for delay notifications.
- The flight is delayed. FancyAirline sends a Push Message to the client, which wakes up the Service Worker and fires the "onpush" event. In here, they show a notification.
- [The Android framework kills Chrome because of memory presure.]
- The user clicks on the shown Notification, which fires an intent, which starts up Chrome, launches the Service Worker associated with the registration (even when updated) and allows the developer to handle this, e.g. create or focus a tab.

The reasoning for binding to the ServiceWorkerRegistration is that it's the Service Worker that will be woken up if necessary for delivering the event, irrespective of the version (it may have been updated in between).

Attaching the event listener can of course be done using attachEventListener.

That should read addEventListener of course :-).

Peter

Chris Harrelson

unread,
Nov 11, 2014, 12:39:49 PM11/11/14
to Peter Beverloo, Elliott Sprehn, blink-dev
On Tue, Nov 11, 2014 at 9:06 AM, Peter Beverloo <pe...@chromium.org> wrote:
Based on discussion with Chris I think there is one important misunderstanding here: the intent is that these notifications can outlive the service worker, and even the browser itself if the platform supports that.

Using Android as an example, you can imagine the following scenario:
- The user visits FancyAirline.com and books a flight, and signs up for delay notifications.
- The flight is delayed. FancyAirline sends a Push Message to the client, which wakes up the Service Worker and fires the "onpush" event. In here, they show a notification.
- [The Android framework kills Chrome because of memory presure.]
- The user clicks on the shown Notification, which fires an intent, which starts up Chrome, launches the Service Worker associated with the registration (even when updated) and allows the developer to handle this, e.g. create or focus a tab.

The reasoning for binding to the ServiceWorkerRegistration is that it's the Service Worker that will be woken up if necessary for delivering the event, irrespective of the version (it may have been updated in between).

Attaching the event listener can of course be done using attachEventListener.

That makes sense. Thanks for clarifying.
Reply all
Reply to author
Forward
0 new messages