Skip to content

Commit

Permalink
Editorial: prepare create a notification for Declarative Web Push
Browse files Browse the repository at this point in the history
This makes the following changes:

- Instead of making create a notification deal directly with a service worker registration, we leave that to the callers. We also make service worker registration always present on a notification as "can have" fields are confusing and buggy.
- Stop requiring an environment settings object for create a notification as that won't necessarily be around for Declarative Web Push.
- Sprinkle some `<div algorithm>` around to reduce variable errors and make variables easier to track in user agents with JavaScript enabled.
  • Loading branch information
annevk authored Aug 23, 2024
1 parent bd0b2dc commit 9a8242e
Showing 1 changed file with 76 additions and 44 deletions.
120 changes: 76 additions & 44 deletions notifications.bs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ IDL, Service Workers, URL, and Vibration API Standards.
<p>A <dfn id=concept-notification>notification</dfn> is an abstract
representation of something that happened, such as the delivery of a message.

<p>A <a>notification</a> <em>can</em> have an associated
<dfn for=notification id=service-worker-registration>service worker registration</dfn>.
<p>A <a>notification</a> has an associated
<dfn for=notification id=service-worker-registration>service worker registration</dfn> (null
or a <a for=/>service worker registration</a>). It is initially null.

<p>A <a>notification</a> has an associated
<dfn for=notification id=concept-title>title</dfn> which is a string.
Expand Down Expand Up @@ -156,35 +157,45 @@ corners or painting it in a specific color. Developers are encouraged to use an
such cases gracefully and does not lose important information through, e.g., loss of color or
clipped corners.

<p>A <dfn>non-persistent notification</dfn> is a
<a>notification</a> without an associated
<a for=notification>service worker registration</a>.
<p>A <dfn>non-persistent notification</dfn> is a <a>notification</a> whose
<a for=notification>service worker registration</a> is null.

<p>A <dfn>persistent notification</dfn> is a
<a>notification</a> with an associated
<a for=notification>service worker registration</a>.
<p>A <dfn>persistent notification</dfn> is a <a>notification</a> whose
<a for=notification>service worker registration</a> is non-null.

<!-- XXX https://html.spec.whatwg.org/#fingerprinting-vector -->

<hr>

<p>To <dfn lt="create a notification|creating a notification">create a notification</dfn>, given a
string <var>title</var>, {{NotificationOptions}} <a for=/>dictionary</a> <var>options</var>,
<a for=/>environment settings object</a> <var>settings</var>, and optionally a
{{ServiceWorkerRegistration}} object <var>serviceWorkerRegistration</var>, run these steps:
<div algorithm>
<p>To <dfn>create a notification with a settings object</dfn>, given a string <var>title</var>,
{{NotificationOptions}} <a for=/>dictionary</a> <var>options</var>, and
<a for=/>environment settings object</a> <var>settings</var>:

<ol>
<li><p>Let <var>notification</var> be a new <a>notification</a>.
<li><p>Let <var>origin</var> be <var>settings</var>'s
<a for="environment settings object">origin</a>.

<li><p>Let <var>baseURL</var> be <var>settings</var>'s
<a for="environment settings object">API base URL</a>.

<li><p>If a <var>serviceWorkerRegistration</var> was provided, then set <var>notification</var>'s
<a for=notification>service worker registration</a> to <var>serviceWorkerRegistration</var>.
<li><p>Let <var>fallbackTimestamp</var> be the number of milliseconds from the <a>Unix epoch</a> to
<var>settings</var>'s <a for="environment settings object">current wall time</a>, rounded to the
nearest integer.

<li>
<p>If a <var>serviceWorkerRegistration</var> was not provided and
<var>options</var>["{{NotificationOptions/actions}}"] is not <a for=list>empty</a>, then
<a>throw</a> a {{TypeError}}.
<li><p>Return the result of <a>creating a notification</a> given <var>title</var>,
<var>options</var>, <var>origin</var>, <var>baseURL</var>, and <var>fallbackTimestamp</var>.
</ol>
</div>

<p class=note><a>Actions</a> are only currently supported for <a>persistent notifications</a>.
<div algorithm>
<p>To <dfn export>create a notification</dfn>, given a string <var>title</var>,
{{NotificationOptions}} <a for=/>dictionary</a> <var>options</var>, an <a for=/>origin</a>
<var>origin</var>, a <a for=/>URL</a> <var>baseURL</var>, and an {{EpochTimeStamp}}
<var>fallbackTimestamp</var>:

<ol>
<li><p>Let <var>notification</var> be a new <a>notification</a>.

<li><p>If <var>options</var>["{{NotificationOptions/silent}}"] is true and
<var>options</var>["{{NotificationOptions/vibrate}}"] <a for=map>exists</a>, then <a>throw</a> a
Expand All @@ -205,18 +216,14 @@ string <var>title</var>, {{NotificationOptions}} <a for=/>dictionary</a> <var>op
<li><p>Set <var>notification</var>'s <a for=notification>language</a> to
<var>options</var>["{{NotificationOptions/lang}}"].

<li><p>Set <var>notification</var>'s <a for=notification>origin</a> to <var>settings</var>'s
<a for="environment settings object">origin</a>.
<li><p>Set <var>notification</var>'s <a for=notification>origin</a> to <var>origin</var>.

<li><p>Set <var>notification</var>'s <a for=notification>body</a> to
<var>options</var>["{{NotificationOptions/body}}"].

<li><p>Set <var>notification</var>'s <a for=notification>tag</a> to
<var>options</var>["{{NotificationOptions/tag}}"].

<li><p>Let <var>baseURL</var> be <var>settings</var>'s
<a for="environment settings object">API base URL</a>.

<li><p>If <var>options</var>["{{NotificationOptions/image}}"] <a for=map>exists</a>, then
<a lt="URL parser">parse</a> it using <var>baseURL</var>, and if that does not return failure, set
<var>notification</var>'s <a>image URL</a> to the return value. (Otherwise
Expand All @@ -238,9 +245,7 @@ string <var>title</var>, {{NotificationOptions}} <a for=/>dictionary</a> <var>op

<li><p>If <var>options</var>["{{NotificationOptions/timestamp}}"] <a for=map>exists</a>, then set
<var>notification</var>'s <a for=notification>timestamp</a> to the value. Otherwise, set
<var>notification</var>'s <a for=notification>timestamp</a> to the number of milliseconds from the
<a>Unix epoch</a> to <var>settings</var>'s
<a for="environment settings object">current wall time</a>, rounded to the nearest integer.
<var>notification</var>'s <a for=notification>timestamp</a> to <var>fallbackTimestamp</var>.

<li><p>Set <var>notification</var>'s <a for=notification>renotify preference</a> to
<var>options</var>["{{NotificationOptions/renotify}}"].
Expand Down Expand Up @@ -276,6 +281,7 @@ string <var>title</var>, {{NotificationOptions}} <a for=/>dictionary</a> <var>op

<li><p>Return <var>notification</var>.
</ol>
</div>


<h3 id=lifetime-and-ui-integrations>Lifetime and UI integration</h3>
Expand Down Expand Up @@ -692,6 +698,7 @@ object and can be created through {{Notification}}'s

<h3 id=constructors>Constructors</h3>

<div algorithm>
<p>The
<dfn constructor for=Notification lt="Notification(title, options)"><code>new Notification(<var>title</var>, <var>options</var>)</code></dfn>
constructor steps are:
Expand All @@ -700,8 +707,15 @@ constructor steps are:
<li><p>If <a>this</a>'s <a>relevant global object</a> is a {{ServiceWorkerGlobalScope}} object,
then <a>throw</a> a {{TypeError}}.

<li><p>Let <var>notification</var> be the result of <a>creating a notification</a> given
<var>title</var>, <var>options</var>, and <a>this</a>'s <a>relevant settings object</a>.
<li>
<p>If <var>options</var>["{{NotificationOptions/actions}}"] is not <a for=list>empty</a>, then
<a>throw</a> a {{TypeError}}.

<p class=note><a>Actions</a> are only supported for <a>persistent notifications</a>.

<li><p>Let <var>notification</var> be the result of
<a>creating a notification with a settings object</a> given <var>title</var>, <var>options</var>,
and <a>this</a>'s <a>relevant settings object</a>.

<li><p>Associate <a>this</a> with <var>notification</var>.

Expand All @@ -718,12 +732,15 @@ constructor steps are:
<li><p>Run the <a>show steps</a> for <var>notification</var>.
</ol>
</ol>
</div>


<h3 id=static-members>Static members</h3>

<div algorithm>
<p>The static <dfn attribute for=Notification><code>permission</code></dfn> getter steps are to
return the result of <a>getting the notifications permission state</a>.
</div>

<div class=note>
<p>If you edit standards please refrain from copying the above. Synchronous permissions are like
Expand All @@ -740,6 +757,7 @@ return the result of <a>getting the notifications permission state</a>.
</pre>
</div>

<div algorithm>
<p>The static
<dfn method for=Notification><code>requestPermission(<var>deprecatedCallback</var>)</code></dfn>
method steps are:
Expand Down Expand Up @@ -770,6 +788,7 @@ method steps are:

<li><p>Return <var>promise</var>.
</ol>
</div>

<p class="warning">Notifications are the one instance thus far where asking the end user upfront
makes sense. Specifications for other APIs should not use this pattern and instead employ one of the
Expand Down Expand Up @@ -1029,7 +1048,9 @@ partial interface ServiceWorkerGlobalScope {
};
</pre>

<p>The <dfn method for=ServiceWorkerRegistration><code>showNotification(title, options)</code></dfn>
<div algorithm>
<p>The
<dfn method for=ServiceWorkerRegistration><code>showNotification(<var>title</var>, <var>options</var>)</code></dfn>
method steps are:

<ol>
Expand All @@ -1042,12 +1063,13 @@ method steps are:
<!-- We might have to throw directly here and below, see
https://github.com/web-platform-tests/wpt/pull/24601 -->

<li><p>Let <var>serviceWorkerRegistration</var> be <a>this</a>.
<li><p>Let <var>notification</var> be the result of
<a>creating a notification with a settings object</a> given <var>title</var>, <var>options</var>,
and <a>this</a>'s <a>relevant settings object</a>. If this threw an exception, then
<a for=/>reject</a> <var>promise</var> with that exception and return <var>promise</var>.

<li><p>Let <var>notification</var> be the result of <a>creating a notification</a> given
<var>title</var>, <var>options</var>, <a>this</a>'s <a>relevant settings object</a>, and
<var>serviceWorkerRegistration</var>. If this threw an exception, then <a for=/>reject</a>
<var>promise</var> with that exception and return <var>promise</var>.
<li><p>Set <var>notification</var>'s <a for=notification>service worker registration</a> to
<a>this</a>.

<li>
<p>Run these steps <a>in parallel</a>:
Expand All @@ -1068,7 +1090,9 @@ method steps are:

<li><p>Return <var>promise</var>.
</ol>
</div>

<div algorithm>
<p>The
<dfn method for=ServiceWorkerRegistration><code>getNotifications(<var>filter</var>)</code></dfn>
method steps are:
Expand Down Expand Up @@ -1116,26 +1140,34 @@ method steps are:

<p class=note>This method returns zero or more new {{Notification}} objects which might represent
the same underlying <a>notification</a> of {{Notification}} objects already in existence.
</div>

<hr>

<p>To <dfn>fire a service worker notification event</dfn> named <var>name</var> given
<var>notification</var> (a <a>notification</a>), and an optional <var>action</var> (a DOMString,
defaulting to the empty string), <a>Fire Functional Event</a> <var>name</var> using
{{NotificationEvent}} on <var>notification</var>'s
<a for=notification>service worker registration</a> with the following properties:
<div algorithm>
<p>To <dfn>fire a service worker notification event</dfn> named <var>name</var> given a
<a for=/>notification</a> <var>notification</var>, and an optional string <var>action</var> (default
the empty string): run <a>Fire Functional Event</a> given <var>name</var>, {{NotificationEvent}},
<var>notification</var>'s <a for=notification>service worker registration</a>, and the following
initialization:

<dl>
<dt>{{NotificationEvent/notification}}
<dd>A new {{Notification}} object representing <var>notification</var>.
<dt>{{NotificationEvent/action}}
<dd><var>action</var>
</dl>
</div>

<p>The {{NotificationEvent/notification}} getter steps are to return the value it was initialized
to.
<div algorithm>
<p>The <dfn attribute for=NotificationEvent><code>notification</code></dfn> getter steps are to
return the value it was initialized to.
</div>

<p>The {{NotificationEvent/action}} getter steps are to return the value it was initialized to.
<div algorithm>
<p>The <dfn attribute for=NotificationEvent><code>action</code></dfn> getter steps are to return the
value it was initialized to.
</div>

<p>The following is the <a>event handler</a> (and its corresponding
<a>event handler event type</a>) that must be supported as attribute by the
Expand Down

0 comments on commit 9a8242e

Please sign in to comment.