Skip to content

Allow each window to handle notification click without service worker #224

@saschanaz

Description

@saschanaz

What problem are you trying to solve?

During internal discussion about declarative notification activation handling, we thought it could be useful to let webpages handle notification click without having to depend on service worker, as we are interested in reducing service worker use (to reduce complexity).

What solutions exist today?

Webpages need to deploy a service worker to listen on notificationclick and iterate on window clients to navigate/focus/open window.

e.g in Mastodon: https://github.com/mastodon/mastodon/blob/37bcbeab4aead09c4884827b8a7625c5070ab192/app/javascript/mastodon/service_worker/web_push_notifications.js#L175-L184

const openUrl = url =>
  self.clients.matchAll({ type: 'window' }).then(clientList => {
    if (clientList.length !== 0 && 'navigate' in clientList[0]) { // Chrome 42-48 does not support navigate
      const client = findBestClient(clientList);

      return client.navigate(url).then(client => client.focus());
    }

    return self.clients.openWindow(url);
  });

How would you solve it?

(rough idea) Define a notification event handler on window, on which the event can request navigation:

// the opt-in version
window.onnotificationclick = ev => {
  if (/* should I be navigated */) {
    ev.navigateAndFocus();
    // would only work if navigation URL was given
    // only one call would be accepted. If multiple windows call this, the one who won the IPC race would be selected
  }
};

// If nobody responds, a new tab will be opened.

or the event can be a signal that the page will soon be navigated:

// the opt-out version
window.onnotificationclick = ev => {
  if (/* should I not be navigated */) {
    ev.preventDefault();
  }
};

// Any window that didn't call preventDefault should expect navigation. (Only one of them would be navigated)
// If everyone called preventDefault, a new tab will be opened.

Anything else?

It's kinda parallel to the current version of #213 as it doesn't fire click event at all if navigation URL is given and depends on unspecified browser internal algorithm to select which tab is to be navigated. This one would provide a way for each website to decide where the navigation should happen.

It could also be solved with SW notificationclick, if we set the default behavior to "open new tab" and let "preventDefault()" to not open a new tab and let SW customize the behavior as websites already do.

// (on the service worker)
self.onnotificationclick = ev => {
  ev.preventDefault(); // don't open a new tab
  
  // some custom client selection
  openUrl(ev.navigate /* the URL given to the notification */);
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express interest

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions