Overview.src.html
author Anne van Kesteren <annevk@opera.com>
Thu, 07 Jun 2012 12:58:20 +0200
changeset 5 ce7609323bc7
parent 4 efe6a33eaa55
child 6 2fb089113c31
permissions -rw-r--r--
bidi: http://lists.w3.org/Archives/Public/public-web-notification/2012Jun/0003.html
<!doctype html>
<html lang=en-US>
<meta charset=utf-8>
<title>Web Notifications</title>
<style>
 pre.idl { border:solid thin; background:#eee; color:#000; padding:0.5em 1em }
 pre.idl :link, pre.idl :visited { color:inherit; background:transparent }
 pre code { color:inherit; background:transparent }
 pre.css { border: solid 0.0625em; background: #FFFFEE; color: black; padding: 0.5em 1em; }
 .example { margin-left:1em; padding-left:1em; border-left:double; color:#222; background:#fcfcfc }
 .note { margin-left:2em; font-weight:bold; font-style:italic; color:#008000 }
 p.note::before { content:"Note: " }
 .XXX { padding:.5em; border:solid #f00 }
 p.XXX::before { content:"Issue: " }
 dl.switch { padding-left:2em }
 dl.switch > dt { text-indent:-1.5em }
 dl.switch > dt:before { content:'\21AA'; padding:0 0.5em 0 0; display:inline-block; width:1em; text-align:right; line-height:0.5em }
 dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; }
 dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; }
 dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; }
 dl.domintro dd p { margin: 0.5em 0; }
 dl.domintro:before { display: table; margin: -1em -0.5em -0.5em auto; width: auto; content: 'This box is non-normative. Implementation requirements are given below this box.'; color: red; border: solid 2px; background: white; padding: 0 0.25em; }
 em.ct { text-transform:lowercase; font-variant:small-caps; font-style:normal }
 dfn { font-weight:bold; font-style:normal }
 code { color:orangered }
 code :link, code :visited { color:inherit }
 hr:not(.top) { display:block; background:none; border:none; padding:0; margin:2em 0; height:auto }
 table { border-collapse:collapse; border-style:hidden hidden none hidden }
 table thead { border-bottom:solid }
 table tbody th:first-child { border-left:solid }
 table td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em }

 .warning { color: red; background: transparent; font-weight: bolder; font-style: italic; }
 .warning p:first-child { margin-top: 0; }
 .warning p:last-child { margin-bottom: 0; }
 .warning:before { font-style: normal; }
 p.warning:before { content: '\26A0 Warning! '; }

 @media print {
   [data-anolis-spec]::after { content:"[" attr(data-anolis-spec) "]"; font-size:.6em; vertical-align:super; text-transform:uppercase }
 }
</style>
<link rel=stylesheet href="http://www.w3.org/StyleSheets/TR/W3C-[STATUS]">
<div class=head>

<!-- logo -->

<h1>Web Notifications</h1>
<h2 class="no-num no-toc">[LONGSTATUS] [DATE: 01 Jan 1901]</h2>

<dl>
 <dt>This Version:
 <dd class=dontpublish><a href="http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html">http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html</a>
 <dd class=publish><a href="[VERSION]">[VERSION]</a>

 <dt class=publish>Latest Version:
 <dd class=publish><a href="[LATEST]">[LATEST]</a>

 <dt class=publish>Latest Editors Draft:
 <dd class=publish><a href="http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html">http://dvcs.w3.org/hg/notifications/raw-file/tip/Overview.html</a>

 <dt class=dontpublish>Participate:</dt>
 <dd class=dontpublish>Send feedback to
  <a href="mailto:public-web-notification@w3.org">public-web-notification@w3.org</a>
  (<a href=http://lists.w3.org/Archives/Public/public-web-notification/>archives</a>)

 <dt>Version History:
 <dd><a href="http://dvcs.w3.org/hg/notifications/shortlog">http://dvcs.w3.org/hg/notifications/shortlog</a></dd>

 <dt>Editor:
 <dd><a href="http://annevankesteren.nl/">Anne van Kesteren</a>
 (<a href="http://www.opera.com/">Opera Software ASA</a>)
 &lt;<a href="mailto:annevk@annevk.nl">annevk@annevk.nl</a>&gt;</dd>
 <dd>John Gregg (<a href="http://www.google.com/">Google</a>)
 &lt;<a href="mailto:johnnyg@google.com">johnnyg@google.com</a>>
</dl>

<!-- copyright -->

</div>

<hr>

<h2 class="no-num no-toc">Abstract</h2>

<p>This document defines an API for displaying simple notifications to the user.

<h2 class="no-num no-toc" id="sotd">Status of this document</h2>

<p>This document is an Editor's Draft and is not suitable for purposes other than reviewing the specification being developed.

<h2 class="no-num no-toc">Table of contents</h2>

<!-- toc -->


<h2>Introduction</h2>

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

<ul>
 <li>A corner of the user's display.
 <li>An area within the chrome of the user agent.
 <li>The "home" screen of a mobile device.
</ul>

<p>This specification does not define exactly how the user agent should
display the notification, and the API is designed to be flexible with
respect to presentation options.

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

<p>In general, the event model for notifications is best-effort; while the
<code>Notification</code> object offers a <code title>click</code> event,
applications may enhance their functionality by listening for that event,
but <em>must not depend on receiving it</em>, in case the underlying
notification platform does not provide that capability.


<h2>Conformance</h2>

<p>All diagrams, examples, and notes in this specification are
non-normative, as are all sections explicitly marked non-normative.
Everything else in this specification is normative.

<p>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
NOT",--> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in the normative parts of this specification are to be
interpreted as described in RFC2119. For readability, these words do
not appear in all uppercase letters in this specification.
<span data-anolis-ref>RFC2119</span>



<h3>Security</h3>

<p>Notifications should only be presented when the user has indicated they
are desired; without this they could create a negative experience for the
user.


<h2>Terminology</h2>

<p>Most terminology used in this specification is from DOM and HTML.
<span data-anolis-ref>DOM</span>
<span data-anolis-ref>HTML</span>



<h2>Model</h2>

<p>A <dfn title=concept-notification>notification</dfn> allows alerting the
user outside a the context of a web page of an occurrence, such as the
delivery of email.

<p>Each <span title=concept-notification>notification</span> has a
<dfn>title</dfn>. For specification simplicity each
<span title=concept-notification>notification</span> also has a
<dfn>title direction</dfn> and <dfn>body direction</dfn>, both of which are
initially "<code title>auto</code>".

<p>Each <span title=concept-notification>notification</span> <em>can</em>
have an associated <dfn>body</dfn>, <dfn>tag</dfn>, and <dfn>icon URL</dfn>.


<h3>Permission</h3>

<p><span title=concept-notification>Notifications</span> can only be
displayed if the user (or user agent on behalf of the user) has granted
<dfn>permission</dfn>. The <span>permission</span> to display
<span title=concept-notification>notifications</span> for a given
<span data-anolis-spec=origin>origin</span> can be one of three strings:

<dl>
 <dt>"<code title>default</code>"
 <dd><p>This is equivalent to "<code title>denied</code>", but the user has
 made no explicit choice thus far.

 <dt>"<code title>denied</code>"
 <dd><p>This means the user does not want
 <span title=concept-notification>notifications</span>.

 <dt>"<code title>granted</code>"
 <dd><p>This means <span title=concept-notification>notifications</span> can
 be displayed.
</dl>

<p class=note>There is no equivalent to "<code title>default</code>"
meaning "<code title>granted</code>". In that case
"<code title>granted</code>" is simply returned as there would be no reason
for the application to ask for <span>permission</span>.


<h3>Notification lists</h3>

<p>The user agent must keep a <dfn>list of pending notifications</dfn> and
a <dfn>list of active notifications</dfn>.

<h3>Showing a notification</h3>

<p>The <dfn>show steps</dfn> for a given <var title>notification</var> are:

<ol>
 <li><p>If <span>permission</span> for the current
 <span data-anolis-spec=origin>origin</span> is not
 "<code title>granted</code>", cancel any ongoing
 <span data-anolis-spec=html>fetch</span> for
 <var title>notification</var>'s <span>icon URL</span>,
 <span data-anolis-spec=html>queue a task</span> to
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span> named
 <code title>error</code> on <var title>notification</var>, and terminate
 these steps.

 <li><p>If there is a <span title=concept-notification>notification</span>
 in the <span>list of pending notifications</span> or the
 <span>list of active notifications</span> whose <span>tag</span> equals
 <var title>notification</var>'s <span>tag</span>, run the
 <span>replace steps</span> and terminate these steps.

 <li><p>If the device allows notifications to be displayed immediately
 without limitations on the number of concurrent notifications, run
 the <span>display steps</span> and terminate these steps.

 <li><p>If the device has limitations on the number of concurrent
 notifications, either immediately call to a notifications platform which
 natively supports queueing, or append <var title>notification</var> to the
 <span>list of pending notifications</span>.
</ol>

<h3>Closing a notification</h3>

<p>When a <span title=concept-notification>notification</span> is closed,
either by the underlying notifications platform or by the user, the
<span>close steps</span> for it must be run.

<p>The <dfn>close steps</dfn> for a given <var title>notification</var> are:

<ol>
 <li><p>If <var title>notification</var> is neither in the
 <span>list of pending notifications</span> nor in the
 <span>list of active notifications</span>, terminate these steps.

 <li><p><span data-anolis-spec=html>Queue a task</span> to remove
 <var title>notification</var> from either the
 <span>list of pending notifications</span> or the
 <span>list of active notifications</span>, and
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
 named <code title>close</code> on <var title>notification</var>.
</ol>

<h3>Pending notifications</h3>

<p>Whenever the <span>list of pending notifications</span> is not empty, the
user agent must wait and monitor changes in the available notification space
on the device.

<p>When the available display space changes on the device such that a new
notification can be displayed, for example due to a previous notification
being dismissed, the user agent should run the <span>display steps</span>
for the first <span title=concept-notification>notification</span> in the
<span>list of pending notifications</span> and then remove it from the
<span>list of pending notifications</span>.

<h3>Displaying notifications</h3>

<p>The <dfn>display steps</dfn> for a given <var title>notification</var>
are:

<ol>
 <li><p>If the notification platform supports icons and
 <var title>notification</var>'s <span>icon URL</span> has not yet been
 <span data-anolis-spec=html title=fetch>fetched</span>,
 <span data-anolis-spec=html>fetch</span> it and wait for the resource to be
 fully downloaded.

 <li><p>If <span data-anolis-spec=html title=fetch>fetching</span>
 <var title>notification</var>'s <span>icon URL</span> failed for some
 reason or the image format is not supported,
 <span data-anolis-spec=html>queue a task</span> to
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
 named <code title>error</code> on <var title>notification</var> and terminate
 these steps.

 <li><p><span data-anolis-spec=html>Queue a task</span> to display
 <var title>notification</var> on the device (e.g. by calling the
 appropriate notification platform), append <var title>notification</var> to the
 <span>list of active notifications</span>, and
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
 named <code title>show</code> on <var title>notification</var>.
</ol>


<h3>Replacing a notification</h3>

<p>The <dfn>replace steps</dfn> for replacing an <var title>old</var>
<span title=concept-notification>notification</span> with a
<var title>new</var> one are:

<ol>
 <li><p>If the notification platform supports icons and
 <var title>new</var>'s <span>icon URL</span> has not yet been
 <span data-anolis-spec=html title=fetch>fetched</span>,
 <span data-anolis-spec=html>fetch</span> it and wait for the resource to be
 fully downloaded.

 <li><p>If <span data-anolis-spec=html title=fetch>fetching</span>
 <var title>new</var>'s <span>icon URL</span> failed for some
 reason or the image format is not supported,
 <span data-anolis-spec=html>queue a task</span> to
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
 named <code title>error</code> on <var title>new</var> and terminate
 these steps.

 <li><p>If <var title>old</var> is in the
 <span>list of pending notifications</span>,
 <span data-anolis-spec=html>queue a task</span> to replace
 <var title>old</var> with <var title>new</var>, in the same position, in
 the <span>list of pending notifications</span>, and
 <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
 named <code title>close</code> on <var title>old</var>.

 <li>
  <p>Otherwise,
  <span data-anolis-spec=html>queue a task</span> to replace
  <var title>old</var> with <var title>new</var>, in the same position, in
  the <span>list of active notifications</span>,
  <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
  named <code title>close</code> on <var title>old</var>, and
  <span data-anolis-spec=dom title=concept-event-fire>fire an event</span>
  named <code title>show</code> on <var title>new</var>.

  <p>If the notification platform does not support replacement this
  requirement may be addressed by removal and addition instead.
</ol>



<h2>API</h2>

<p>A <span title=concept-notification>notification</span> is represented by
a <code>Notification</code> object and can be created by its
<span title=dom-Notification>constructor</span>.

<pre class="idl">[<span title=dom-Notification>Constructor</span>(DOMString <var title>title</var>, optional <span>NotificationOptions</span> <var title>options</var>)]
interface <dfn>Notification</dfn> : <span data-anolis-spec=dom>EventTarget</span> {
  static readonly attribute <span>NotificationPermission</span> <span title=dom-Notification-permission>permission</span>;
  static void <span title=dom-Notification-requestPermission>requestPermission</span>(<span>NotificationPermissionCallback</span> <var title>callback</var>);

  [TreatNonCallableAsNull] attribute <span data-anolis-spec=html>Function</span>? <span title=handler-onclick>onclick</span>;
  [TreatNonCallableAsNull] attribute <span data-anolis-spec=html>Function</span>? <span title=handler-onshow>onshow</span>;
  [TreatNonCallableAsNull] attribute <span data-anolis-spec=html>Function</span>? <span title=handler-onerror>onerror</span>;
  [TreatNonCallableAsNull] attribute <span data-anolis-spec=html>Function</span>? <span title=handler-onclose>onclose</span>;

  void <span title=dom-Notification-close>close</span>();
};

dictionary <dfn>NotificationOptions</dfn> {
  <span>NotificationDirection</span> titleDir;
  DOMString body;
  <span>NotificationDirection</span> bodyDir;
  DOMString tag;
  DOMString iconUrl;
};

enum <dfn>NotificationPermission</dfn> {
  "default",
  "denied",
  "granted"
};

callback <dfn>NotificationPermissionCallback</dfn> = void (<span>NotificationPermission</span> <var title>permission</var>);

enum <dfn>NotificationDirection</dfn> {
  "auto",
  "ltr",
  "rtl"
};</pre>

<p>The
<dfn title=dom-Notification><code>Notification(<var title>title</var>, <var title>options</var>)</code></dfn>
constructor must run these steps:

<ol>
 <li><p>Let <var title>notification</var> be a new
 <span title=concept-notification>notification</span> represented by a
 <code>Notification</code> object.

 <li><p>Set <var title>notification</var>'s <span>title</span> to
 <var title>title</var>,
 <span data-anolis-spec=webidl title="convert a DOMString to a sequence of Unicode characters">converted to Unicode</span>.

 <li><p>If <var title>options</var> is not omitted and its
 <code title>titleDir</code> member is not null, set
 <var title>notification</var>'s <span>title direction</span> to
 <code title>titleDir</code>.

 <li><p>If <var title>options</var> is not omitted and its
 <code title>body</code> is not null, set <var title>notification</var>'s
 <span>body</span> to <code title>body</code>,
 <span data-anolis-spec=webidl title="convert a DOMString to a sequence of Unicode characters">converted to Unicode</span>.

 <li><p>If <var title>options</var> is not omitted and its
 <code title>bodyDir</code> member is not null, set
 <var title>notification</var>'s <span>body direction</span> to
 <code title>bodyDir</code>.

 <li><p>If <var title>options</var> is not omitted and its
 <code title>tag</code> is not null, set <var title>notification</var>'s
 <span>tag</span> to <code title>tag</code>.

 <li><p>If <var title>options</var> is not omitted and its
 <code title>iconUrl</code> is not null, set <var title>notification</var>'s
 <span>icon URL</span> to <code title>iconUrl</code>.

 <li><p>Return <var title>notification</var>, but continue running these
 steps asynchronouusly.

 <li><p>If the notification platform supports icons, the user agent may
 start <span data-anolis-spec=html title=fetch>fetching</span>
 <var title>notification</var>'s <span>icon URL</span> at this point.

 <li><p>Run the <span>show steps</span> for <var title>notification</var>.
</ol>

<p>The static
<dfn title=dom-Notification-permission><code>permission</code></dfn>
attribute must return <span>permission</span>.

<p>The static
<dfn title=dom-Notification-requestPermission><code>requestPermission(<var title>callback</var>)</code></dfn>
method must run these steps:

<ol>
 <li><p>Return, but continue running these steps asynchronously.

 <li><p>Let <var title>permission</var> be <span>permission</span>.

 <li><p>If <var title>permission</var> is "<code title>default</code>",
 ask the user whether showing notifications for the current
 <span data-anolis-spec=origin>origin</span> is acceptable. If it is, set
 <var title>permission</var> to "<code title>granted</code>", or
 "<code title>denied</code>" otherwise.

 <li><p><span data-anolis-spec=html>Queue a task</span> to set
 <code title=dom-Notification-permission>permission</code> to
 <var title>permission</var> and invoke <var title>callback</var> with
 <var title>permission</var> as single argument.
</ol>

<p>The following are the <span data-anolis-spec=html>event handlers</span>
(and their corresponding
<span data-anolis-spec=html title="event handler event type">event handler event types</span>)
that must be supported as attributes by the <code>Notification</code> object.

<table>
 <thead>
  <tr>
   <th><span data-anolis-spec=html title="event handlers">event handler</span>
   <th><span data-anolis-spec=html>event handler event type</span>
 <tbody>
  <tr>
   <td><dfn title=handler-onclick><code>onclick</code></dfn>
   <td><code title=event-click>click</code>
  <tr>
   <td><dfn title=handler-onshow><code>onshow</code></dfn>
   <td><code title=event-show>show</code>
  <tr>
   <td><dfn title=handler-onerror><code>onerror</code></dfn>
   <td><code title=event-error>error</code>
  <tr>
   <td><dfn title=handler-onclose><code>onclose</code></dfn>
   <td><code title=event-close>close</code>
</table>

<p>The <dfn title=dom-Notification-close><code>close()</code></dfn> method
must run the <span>close steps</span> for the
<span title=concept-notification>notification</span>.





<h2>Rendering</h2>

<p>This section is written in terms equivalent to those used in the
Rendering section of HTML. <span data-anolis-ref>HTML</span>

<!-- keep this in sync with
     http://www.whatwg.org/specs/web-apps/current-work/#text-rendered-in-native-user-interfaces -->

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


<h2>Examples</h2>

<h3>Using events</h3>

<p>
	Notification objects dispatch events during their lifecycle, which authors can use
	to generate desired behaviors.
      </p>
      <p>
	The <code>show</code> event occurs when the notification is shown to the user --
	this may be at some time after the notification is created in the case
	of limited display space and a queue.
      </p>

      <p>
	In the following example, this event is used to guarantee that regardless of when
	the notification is shown, it is displayed for only 15 seconds.
      </p>

<pre class="example">new Notification("New Email Received",
                 { iconUrl: "mail.png",
                   onshow: function() { setTimeout(notification.close(), 15000); }
                 });</pre>

<p>The <code>close</code> events occurs when the notification is dismissed by the user.
	Authors may use this event to perform actions when notifications are acknowledged.

<p>
	In the following example, when a meeting reminder notification is acknowledged, the
	application suppresses other forms of reminders.
      </p>

<pre class="example">new Notification("Meeting about to begin",
                 { iconUrl: "calendar.gif",
                   body: "Room 101",
                   onclose: function() { cancelReminders(event); }
                 });</pre>


<h3 id="tags-example">Using the tag attribute for multiple instances</h3>

<p>Web applications frequently operate concurrently in multiple instances, such as when a
	user opens a mail application in multiple browser tabs.  Since the desktop is a shared
	resource, Web Notifications provides a way for these instances to easily coordinate, by
	using the <code>tag</code> attribute.

<p>Notifications which represent the same conceptual event can be tagged in the same way,
	and when both are shown, the user will only receive one notification.
      </p>

<pre class="example" title="">Instance 1                                   | Instance 2
                                             |
// Instance notices there is new mail.       |
new Notification("New mail from John Doe",   |
                 { tag: 'message1' });       |
                                             |
                                             |  // Slightly later, this instance notices
                                             |  // there is new mail.
                                             |  new Notification("New mail from John Doe",
                                             |                   { tag: 'message1' });</pre>

<p>
	The result of this situation, if the user agent follows the algorithms here, is a <strong>single</strong> notification "New mail from John Doe".

<h3>Using the tag attribute for a single instance</h3>

<p>The tag attribute can also be used by a single instance of an application to keep its
	notifications as current as possible as state changes.

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

<pre class="example">// Bob says "Hi"
new Notification("Bob: Hi", { tag: 'chat_Bob' });

// Bob says "Are you free this afternoon?"
new Notification("Bob: Hi / Are you free this afternoon?", { tag: 'chat_Bob' });</pre>

<p>The result of this situation is a <em>single</em> notification; the second one
	replaces the first having the same tag.  In a platform that queues notifications
	(first-in-first-out), using the tag allows the notification to also maintain its
	position in the queue.  Platforms where the newest notifications are shown first,
	a similar result could be achieved using the
	<code title=dom-Notification-close>close()</code> method.

<h2 class=no-num>References</h2>

<div id=anolis-references></div>

<h2 class=no-num>Acknowledgments</h2>

<p>Thanks to
Aharon (Vladimir) Lanin,
Alex Russell,
Doug Turner,
Drew Wilson,
Edward O'Connor,
Ian Hickson,
James Graham,
Jon Lee, and
Jonas Sicking
for being awesome.