annevk@1: annevk@1: annevk@1: annevk@1: Web Notifications annevk@1: annevk@1: annevk@1:
annevk@1: annevk@1: annevk@1: annevk@1:

Web Notifications

annevk@1:

[LONGSTATUS] [DATE: 01 Jan 1901]

annevk@1: annevk@1:
annevk@1:
This Version: annevk@1:
http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html annevk@1:
[VERSION] annevk@1: annevk@1:
Latest Version: annevk@1:
[LATEST] annevk@1: annevk@1:
Latest Editors Draft: annevk@1:
http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html annevk@1: annevk@1:
Participate:
annevk@1:
Send feedback to annevk@1: public-web-notification@w3.org annevk@1: (archives) annevk@1: annevk@1:
Version History: annevk@1:
http://dvcs.w3.org/hg/notifications/shortlog
annevk@1: annevk@10:
Previous Version:
annevk@10:
http://www.w3.org/TR/2011/WD-notifications-20110301/ annevk@10: annevk@11:
Editors: annevk@1:
Anne van Kesteren annevk@1: (Opera Software ASA) annevk@1: <annevk@annevk.nl>
annevk@1:
John Gregg (Google) annevk@1: <johnnyg@google.com> annevk@1:
annevk@1: annevk@1: annevk@1: annevk@1:
annevk@1: annevk@1:
annevk@1: annevk@1:

Abstract

annevk@1: annevk@14:

Web notifications defines an API for end-user notifications. A annevk@14: notification allows alerting the user outside the context of a web page of annevk@14: an occurrence, such as the delivery of email. annevk@1: annevk@1:

Status of this document

annevk@1: annevk@11:

This section describes the status of this document at the time of its annevk@11: publication. Other documents may supersede this document. A list of current annevk@11: W3C publications and the latest revision of this technical report can be annevk@11: found in the W3C technical reports index annevk@11: at http://www.w3.org/TR/. annevk@11: annevk@11:

This is the [DATE: 3 August 2002] [LONGSTATUS] of Web Notifications. annevk@11: Please send comments to annevk@12: public-web-notification@w3.org annevk@11: (archived). annevk@11: annevk@11:

This document was developed by the annevk@11: Web Notification Working Group. annevk@11: The Working Group expects to advance this Working Draft to Recommendation Status. annevk@11: annevk@11:

Publication as a Working Draft does not imply endorsement by the W3C annevk@11: Membership. This is a draft document and may be updated, replaced or annevk@11: obsoleted by other documents at any time. It is inappropriate to cite this annevk@11: document as other than work in progress. annevk@11: annevk@11:

This document was produced by a group operating under the annevk@11: 5 February 2004 W3C Patent Policy. annevk@11: W3C maintains a annevk@11: public list of any patent disclosures annevk@11: made in connection with the deliverables of the group; that page also annevk@11: includes instructions for disclosing a patent. An individual who has actual annevk@11: knowledge of a patent which the individual believes contains annevk@11: Essential Claim(s) annevk@11: must disclose the information in accordance with annevk@11: section 6 of the W3C Patent Policy. annevk@11: annevk@1: annevk@1:

Table of contents

annevk@1: annevk@1: annevk@1: annevk@1: annevk@1:

Introduction

annevk@1: annevk@1:

This specification provides an API to display notifications to alert annevk@1: users outside the context of a web page. It does not specify exactly how a annevk@1: user agent should display these notifications; the best presentation depends annevk@1: on the device where the user agent is run. When this specification refers annevk@1: to displaying notifications on the "desktop", it generally refers to some annevk@1: static display area outside the web page, but may take several forms, annevk@1: including: annevk@1: annevk@1:

annevk@1: annevk@1:

This specification does not define exactly how the user agent should annevk@1: display the notification, and the API is designed to be flexible with annevk@1: respect to presentation options. annevk@1: annevk@1:

This specification is designed to be compatible with existing annevk@1: notification platforms as much as possible, but also to be annevk@1: platform-independent. Since the common platforms do not provide the same annevk@1: functionality, this spec will indicate what events are guaranteed and annevk@1: which are not. In particular, notifications as specified here only can annevk@1: contain text and icon content. In the future, notifications generated from annevk@1: web content may wish to contain web content themselves, but that is outside annevk@1: the scope of this document. annevk@1: annevk@1:

In general, the event model for notifications is best-effort; while the annevk@1: Notification object offers a click event, annevk@1: applications may enhance their functionality by listening for that event, annevk@1: but must not depend on receiving it, in case the underlying annevk@1: notification platform does not provide that capability. annevk@1: annevk@1: annevk@1:

Conformance

annevk@1: annevk@1:

All diagrams, examples, and notes in this specification are annevk@1: non-normative, as are all sections explicitly marked non-normative. annevk@1: Everything else in this specification is normative. annevk@1: annevk@1:

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and annevk@1: "OPTIONAL" in the normative parts of this specification are to be annevk@1: interpreted as described in RFC2119. For readability, these words do annevk@1: not appear in all uppercase letters in this specification. annevk@1: RFC2119 annevk@1: annevk@1: annevk@1: annevk@1:

Security

annevk@1: annevk@1:

Notifications should only be presented when the user has indicated they annevk@1: are desired; without this they could create a negative experience for the annevk@1: user. annevk@1: annevk@1: annevk@1:

Terminology

annevk@1: annevk@1:

Most terminology used in this specification is from DOM and HTML. annevk@1: DOM annevk@1: HTML annevk@1: annevk@1: annevk@1: annevk@1:

Model

annevk@1: annevk@1:

A notification allows alerting the annevk@6: user outside the context of a web page of an occurrence, such as the annevk@1: delivery of email. annevk@1: annevk@1:

Each notification has a annevk@16: title (string). For specification simplicity each annevk@1: notification also has a annevk@1: title direction and body direction, both of which are annevk@1: initially "auto". annevk@1: annevk@1:

Each notification can annevk@16: have an associated body (string), annevk@16: tag ((string, origin) tuple), annevk@16: and icon URL (URL). annevk@1: annevk@1: annevk@1:

Permission

annevk@1: annevk@1:

Notifications can only be annevk@1: displayed if the user (or user agent on behalf of the user) has granted annevk@1: permission. The permission to display annevk@1: notifications for a given annevk@1: origin can be one of three strings: annevk@1: annevk@1:

annevk@1:
"default" annevk@1:

This is equivalent to "denied", but the user has annevk@1: made no explicit choice thus far. annevk@1: annevk@1:

"denied" annevk@1:

This means the user does not want annevk@1: notifications. annevk@1: annevk@1:

"granted" annevk@1:

This means notifications can annevk@1: be displayed. annevk@1:

annevk@1: annevk@2:

There is no equivalent to "default" annevk@2: meaning "granted". In that case annevk@1: "granted" is simply returned as there would be no reason annevk@1: for the application to ask for permission. annevk@1: annevk@1: annevk@1:

Notification lists

annevk@1: annevk@1:

The user agent must keep a list of pending notifications and annevk@1: a list of active notifications. annevk@1: annevk@1:

Showing a notification

annevk@1: annevk@1:

The show steps for a given notification are: annevk@1: annevk@1:

    annevk@2:
  1. If permission for the current annevk@2: origin is not annevk@2: "granted", cancel any ongoing annevk@1: fetch for annevk@1: notification's icon URL, annevk@1: queue a task to annevk@1: fire an event named annevk@1: error on notification, and terminate annevk@1: these steps. annevk@1: annevk@1:

  2. If there is a notification annevk@1: in the list of pending notifications or the annevk@1: list of active notifications whose tag equals annevk@1: notification's tag, run the annevk@1: replace steps and terminate these steps. annevk@1: annevk@1:

  3. If the device allows notifications to be displayed immediately annevk@1: without limitations on the number of concurrent notifications, run annevk@1: the display steps and terminate these steps. annevk@1: annevk@1:

  4. If the device has limitations on the number of concurrent annevk@1: notifications, either immediately call to a notifications platform which annevk@1: natively supports queueing, or append notification to the annevk@1: list of pending notifications. annevk@1:

annevk@1: annevk@1:

Closing a notification

annevk@1: annevk@1:

When a notification is closed, annevk@1: either by the underlying notifications platform or by the user, the annevk@3: close steps for it must be run. annevk@1: annevk@3:

The close steps for a given notification are: annevk@1: annevk@1:

    annevk@3:
  1. If notification is neither in the annevk@3: list of pending notifications nor in the annevk@1: list of active notifications, terminate these steps. annevk@1: annevk@1:

  2. Queue a task to remove annevk@3: notification from either the annevk@1: list of pending notifications or the annevk@1: list of active notifications, and annevk@1: fire an event annevk@3: named close on notification. annevk@1:

annevk@1: annevk@1:

Pending notifications

annevk@1: annevk@1:

Whenever the list of pending notifications is not empty, the annevk@1: user agent must wait and monitor changes in the available notification space annevk@1: on the device. annevk@1: annevk@1:

When the available display space changes on the device such that a new annevk@1: notification can be displayed, for example due to a previous notification annevk@1: being dismissed, the user agent should run the display steps annevk@1: for the first notification in the annevk@1: list of pending notifications and then remove it from the annevk@1: list of pending notifications. annevk@1: annevk@1:

Displaying notifications

annevk@1: annevk@1:

The display steps for a given notification annevk@1: are: annevk@1: annevk@1:

    annevk@1:
  1. If the notification platform supports icons and annevk@1: notification's icon URL has not yet been annevk@1: fetched, annevk@1: fetch it and wait for the resource to be annevk@1: fully downloaded. annevk@1: annevk@1:

  2. If fetching annevk@1: notification's icon URL failed for some annevk@1: reason or the image format is not supported, annevk@1: queue a task to annevk@1: fire an event annevk@1: named error on notification and terminate annevk@1: these steps. annevk@1: annevk@1:

  3. Queue a task to display annevk@1: notification on the device (e.g. by calling the annevk@1: appropriate notification platform), append notification to the annevk@1: list of active notifications, and annevk@1: fire an event annevk@1: named show on notification. annevk@1:

annevk@1: annevk@1: annevk@1:

Replacing a notification

annevk@1: annevk@1:

The replace steps for replacing an old annevk@1: notification with a annevk@1: new one are: annevk@1: annevk@1:

    annevk@1:
  1. If the notification platform supports icons and annevk@1: new's icon URL has not yet been annevk@1: fetched, annevk@1: fetch it and wait for the resource to be annevk@1: fully downloaded. annevk@1: annevk@1:

  2. If fetching annevk@1: new's icon URL failed for some annevk@1: reason or the image format is not supported, annevk@1: queue a task to annevk@1: fire an event annevk@1: named error on new and terminate annevk@1: these steps. annevk@1: annevk@1:

  3. If old is in the annevk@1: list of pending notifications, annevk@1: queue a task to replace annevk@1: old with new, in the same position, in annevk@1: the list of pending notifications, and annevk@1: fire an event annevk@1: named close on old. annevk@1: annevk@1:

  4. annevk@1:

    Otherwise, annevk@1: queue a task to replace annevk@1: old with new, in the same position, in annevk@1: the list of active notifications, annevk@1: fire an event annevk@1: named close on old, and annevk@1: fire an event annevk@1: named show on new. annevk@1: annevk@1:

    If the notification platform does not support replacement this annevk@1: requirement may be addressed by removal and addition instead. annevk@1:

annevk@1: annevk@1: annevk@1: annevk@1:

API

annevk@1: annevk@1:

A notification is represented by annevk@1: a Notification object and can be created by its annevk@1: constructor. annevk@1: annevk@1:

[Constructor(DOMString title, optional NotificationOptions options)]
annevk@1: interface Notification : EventTarget {
annevk@1:   static readonly attribute NotificationPermission permission;
annevk@1:   static void requestPermission(NotificationPermissionCallback callback);
annevk@1: 
annevk@1:   [TreatNonCallableAsNull] attribute Function? onclick;
annevk@1:   [TreatNonCallableAsNull] attribute Function? onshow;
annevk@1:   [TreatNonCallableAsNull] attribute Function? onerror;
annevk@1:   [TreatNonCallableAsNull] attribute Function? onclose;
annevk@1: 
annevk@1:   void close();
annevk@1: };
annevk@1: 
annevk@1: dictionary NotificationOptions {
annevk@1:   NotificationDirection titleDir;
annevk@1:   DOMString body;
annevk@1:   NotificationDirection bodyDir;
annevk@1:   DOMString tag;
annevk@1:   DOMString iconUrl;
annevk@1: };
annevk@1: 
annevk@1: enum NotificationPermission {
annevk@1:   "default",
annevk@1:   "denied",
annevk@1:   "granted"
annevk@1: };
annevk@1: 
annevk@1: callback NotificationPermissionCallback = void (NotificationPermission permission);
annevk@1: 
annevk@1: enum NotificationDirection {
annevk@1:   "auto",
annevk@1:   "ltr",
annevk@1:   "rtl"
annevk@1: };
annevk@1: annevk@8:

Web IDL is annevk@8: not yet updated annevk@8: to allow for static attributes. annevk@8: annevk@1:

The annevk@1: Notification(title, options) annevk@1: constructor must run these steps: annevk@1: annevk@1:

    annevk@1:
  1. Let notification be a new annevk@1: notification represented by a annevk@1: Notification object. annevk@1: annevk@1:

  2. Set notification's title to annevk@1: title, annevk@1: converted to Unicode. annevk@1: annevk@1:

  3. If options is not omitted and its annevk@1: titleDir member is not null, set annevk@1: notification's title direction to annevk@1: titleDir. annevk@1: annevk@1:

  4. If options is not omitted and its annevk@1: body is not null, set notification's annevk@1: body to body, annevk@1: converted to Unicode. annevk@1: annevk@1:

  5. If options is not omitted and its annevk@1: bodyDir member is not null, set annevk@1: notification's body direction to annevk@1: bodyDir. annevk@1: annevk@1:

  6. If options is not omitted and its annevk@1: tag is not null, set notification's annevk@16: tag to annevk@16: (tag, current origin). annevk@1: annevk@1:

  7. If options is not omitted and its annevk@1: iconUrl is not null, set notification's annevk@1: icon URL to iconUrl. annevk@1: annevk@1:

  8. Return notification, but continue running these annevk@1: steps asynchronouusly. annevk@1: annevk@1:

  9. If the notification platform supports icons, the user agent may annevk@1: start fetching annevk@1: notification's icon URL at this point. annevk@1: annevk@1:

  10. Run the show steps for notification. annevk@1:

annevk@1: annevk@1:

The static annevk@1: permission annevk@1: attribute must return permission. annevk@1: annevk@1:

The static annevk@1: requestPermission(callback) annevk@1: method must run these steps: annevk@1: annevk@1:

    annevk@1:
  1. Return, but continue running these steps asynchronously. annevk@1: annevk@1:

  2. Let permission be permission. annevk@1: annevk@1:

  3. If permission is "default", annevk@1: ask the user whether showing notifications for the current annevk@1: origin is acceptable. If it is, set annevk@1: permission to "granted", or annevk@1: "denied" otherwise. annevk@1: annevk@1:

  4. Queue a task to set annevk@9: permission to permission and invoke annevk@9: callback with permission as single annevk@9: argument. annevk@1:

annevk@1: annevk@8:

In designing the platform notifications are the one annevk@8: instance thus far where asking the user upfront makes sense. Specifications annevk@8: for other APIs should not use this pattern and instead employ one of the annevk@8: many more suitable alternatives. annevk@8: annevk@1:

The following are the event handlers annevk@1: (and their corresponding annevk@1: event handler event types) annevk@1: that must be supported as attributes by the Notification object. annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1:
event handler annevk@1: event handler event type annevk@1:
onclick annevk@1: click annevk@1:
onshow annevk@1: show annevk@1:
onerror annevk@1: error annevk@1:
onclose annevk@1: close annevk@1:
annevk@1: annevk@1:

The close() method annevk@1: must run the close steps for the annevk@1: notification. annevk@1: annevk@1: annevk@1: annevk@1: annevk@1: annevk@1:

Rendering

annevk@1: annevk@4:

This section is written in terms equivalent to those used in the annevk@4: Rendering section of HTML. HTML annevk@4: annevk@4: annevk@4: annevk@4:

User agents are expected to honor the Unicode semantics of the text of a annevk@4: notification's title annevk@5: and body. Each is expected to be treated as an independent set annevk@5: of one or more bidirectional algorithm paragraphs when displayed, as defined annevk@5: by the bidirectional algorithm's rules P1, P2, and P3, including, for annevk@5: instance, supporting the paragraph-breaking behaviour of annevk@5: U+000A LINE FEED (LF) characters. For each paragraph of the annevk@5: title and body, the annevk@4: notification's annevk@5: title direction and body direction respectively annevk@5: provide the higher-level override of rules P2 and P3 if they have a value annevk@5: other than "auto". annevk@4: BIDI annevk@1: annevk@1: annevk@1:

Examples

annevk@1: annevk@1:

Using events

annevk@1: annevk@13:

Notification objects dispatch events during their lifecycle, annevk@13: which developers can use to generate desired behaviors. annevk@1: annevk@13:

The show event dispatches when the annevk@13: notification is shown to the user annevk@13: — this may be at some time after the notification is created in the annevk@13: case of limited display space and a queue. annevk@1: annevk@13:

In the following example, this event is used to guarantee that regardless annevk@13: of when the notification is shown, it is displayed for only 15 seconds. annevk@1: annevk@13:

var notification = new Notification("New Email Received", { iconUrl: "mail.png" })
annevk@15: notification.onshow = function() { setTimeout(notification.close, 15000) }
annevk@13: annevk@13:

The close events dispatches when the annevk@13: notification is dismissed by the user. Developers may use this event to annevk@13: perform actions when notifications are acknowledged. annevk@13: annevk@13:

In the following example, when a meeting reminder notification is annevk@13: acknowledged, the application suppresses other forms of reminders. annevk@13: annevk@13:

var notification = new Notification("Meeting about to begin", { iconUrl: "calendar.gif", body: "Room 101" })
annevk@13: notification.onclose = function(event) { cancelReminders(event) }
annevk@1: annevk@1: annevk@7:

Using the tag member for multiple instances

annevk@1: annevk@1:

Web applications frequently operate concurrently in multiple instances, such as when a annevk@1: user opens a mail application in multiple browser tabs. Since the desktop is a shared annevk@1: resource, Web Notifications provides a way for these instances to easily coordinate, by annevk@7: using the tag member. annevk@1: annevk@1:

Notifications which represent the same conceptual event can be tagged in the same way, annevk@1: and when both are shown, the user will only receive one notification. annevk@1:

annevk@1: annevk@1:
Instance 1                                   | Instance 2
annevk@1:                                              |
annevk@1: // Instance notices there is new mail.       |
annevk@1: new Notification("New mail from John Doe",   |
annevk@1:                  { tag: 'message1' });       |
annevk@1:                                              |
annevk@1:                                              |  // Slightly later, this instance notices
annevk@1:                                              |  // there is new mail.
annevk@1:                                              |  new Notification("New mail from John Doe",
annevk@1:                                              |                   { tag: 'message1' });
annevk@1: annevk@1:

annevk@1: The result of this situation, if the user agent follows the algorithms here, is a single notification "New mail from John Doe". annevk@1: annevk@7:

Using the tag member for a single instance

annevk@1: annevk@7:

The tag member can also be used by a single instance of an application to keep its annevk@1: notifications as current as possible as state changes. annevk@1: annevk@1:

For example, if Alice is using a chat application with Bob, and Bob sends multiple annevk@1: messages while Alice is idle, the application may prefer that Alice not see a annevk@1: desktop notification for each message. annevk@1: annevk@1:

// Bob says "Hi"
annevk@1: new Notification("Bob: Hi", { tag: 'chat_Bob' });
annevk@1: 
annevk@1: // Bob says "Are you free this afternoon?"
annevk@1: new Notification("Bob: Hi / Are you free this afternoon?", { tag: 'chat_Bob' });
annevk@1: annevk@1:

The result of this situation is a single notification; the second one annevk@1: replaces the first having the same tag. In a platform that queues notifications annevk@1: (first-in-first-out), using the tag allows the notification to also maintain its annevk@1: position in the queue. Platforms where the newest notifications are shown first, annevk@1: a similar result could be achieved using the annevk@1: close() method. annevk@1: annevk@1:

References

annevk@1: annevk@1:
annevk@1: annevk@1:

Acknowledgments

annevk@1: annevk@1:

Thanks to annevk@5: Aharon (Vladimir) Lanin, annevk@1: Alex Russell, annevk@15: David Håsäther, annevk@1: Doug Turner, annevk@1: Drew Wilson, annevk@1: Edward O'Connor, annevk@1: Ian Hickson, annevk@1: James Graham, annevk@16: Jon Lee, annevk@16: Jonas Sicking, and annevk@16: Olli Pettay, annevk@1: for being awesome.