1. 术语
本规范中使用的一些术语取自DOM、Fetch、HTML、IDL、URL 和 振动 API 标准。 [DOM] [FETCH] [HTML] [WEBIDL] [URL] [VIBRATION]
2. Notifications
notification 是事件发生的抽象表示,如信息发出。
一个 notification 有一个关联的 DOMString 类型的 title。
一个 notification 有一个关联的 DOMString 类型的 body。
一个 notification 有一个关联的 direction 其值是 auto, ltr, and rtl三者之一。
一个 notification 有一个关联的 DOMString 类型的 language ,其值是一个有效的 BCP 47 语言标记或空字符串。
一个 notification 有一个关联的 DOMString 类型的 tag。
一个 notification 有一个关联的 data。
一个 notification 有一个关联的 origin。
一个 notification 有一个关联的未被设置的 renotify preference flag。 设置该标志表示运行replace steps后,最终用户会被警告。
一个 notification 有一个关联的未被设置的 silent preference flag。设置该标志表示不接收声音或者振动通知。
一个 notification 有一个关联的未被设置的 screen off preference flag。设置该标志表示设备屏幕不会被启用。
一个 notification 有一个关联的未被设置的 sticky preference flag。设置该标志表示最终用户将不能很容易地清除 notification 仅适用于persistent notifications.
一个 notification 可以 有关联的 icon URL, icon resource, sound URL, sound resource, vibration pattern,和 service worker registration.
不鼓励开发者通过图标、声音或振动模式来给最终用户传达信息;除非这些信息 是最终用户可以访问的。
一个 non-persistent notification 是没有关联 service worker registration 的 notification。
一个 persistent notification 是关联了 service worker registration 的 notification。
为 create a notification,给定一个title 和 options,执行这些步骤:
-
设 notification 是一个新的 notification.
-
如果 options 的
silent
为 true, 那么 options 的sound
出现时或者 options 的vibrate
出现时, throw 一个TypeError
异常。 -
如果 options 的
renotify
为 true 并且 options 的tag
为空字符串,那么 throw 一个TypeError
异常。 -
设置 notification 的 data 为一个options 的
data
的 structured clone。重新抛出任何异常。 -
设置 notification 的 title 为 options 的
title
. -
设置 notification 的 direction 为 options 的
dir
. -
如果 options 的
lang
是一个有效的 BCP 47 语言标记或空字符串, 设置 notification 的 language 为 options的lang
;否则将之设置为空字符串。 [LANG] -
设置 notification 的 origin 为 entry settings object 的 origin。
-
设置 notification 的 body 为 options 的
body
. -
设置notification 的 tag 为 options 的
tag
. -
设 baseURL 为 entry settings object 指定的 API 基础 URL。 或现任?
-
如果 options 存在
icon
,用 baseURL parse 它;解析无误时,设置 notification 的 icon URL 为该解析值。(否则 icon URL 未设置。) -
如果 options 的
sound
存在, 用 baseURL parse 它;解析无误时,设置 notification 的 sound URL 为该解析值。(否则 sound URL 未设置。) -
如果 options 的
vibrate
存在, validate and normalize 它, 并设置 notification 的 vibration pattern 为该规范化值。 (否则vibration pattern未设置。) -
如果 options 的
renotify
为 true,设置 notification 的 renotify preference flag. -
如果 options 的
silent
为 true,设置 notification 的 silent preference flag. -
如果 options 的
noscreen
为 true,设置 notification 的 screen off preference flag. -
如果 options 的
sticky
为 true,设置 notification 的 sticky preference flag. -
返回 notification.
2.1. 生命周期与 UI 整合
用户代理必须保留一个由零或多个 notifications 组成的 list of notifications。
用户代理应该在创建 non-persistent notification 之后的几秒种内执行close steps。
用户代理不应该在平台的“通知中心”(如果有的话)显示 non-persistent notification。
用户代理应该保持 persistent notifications,直至被移除出list of notifications。
一个 persistent notification 可通过其 Notification
对象来调用
close()
方法。
用户代理应该在平台的“通知中心”(如果有的话)显示 persistent notification 。
2.2. 许可模式
Notifications 当且仅当被用户(或用户代理)授予permission时,才能被显示。 为给定 origin 显示 notifications 的 permission 是下面三个字符串之一:
- "
default
" -
相当于 "
denied
",但用户没有作出明确的选择。 - "
denied
" -
意味着用户不希望被 notifications.
- "
granted
" -
意味着可以显示 notifications。
"default
" 从不会等同于 "granted
"。如果那样
的话,
"granted
" 会被滥用,应用程序再也不必请求 permission。
2.3. 方向
本节所使用的术语等同于 HTML 规范中渲染部分所使用的。 [HTML]
期望用户代理使用 Unicode 语义来解析
notification 的
title 和 body中的文本。展示它们时,应视之为由双向
算法规则P1、P2和P3所定义的一个或多个双向算法段落组成的独立集合,例如包括支持换行
符 U+000A (LF) 带来的段落分割。对
title 和 body中的
每一段,notification 的
direction
属性在其值非 "auto
"时,将覆盖双向算法P2和P3规则。 [BIDI]
2.4. 语言
notification 的 language 属性指定了 notification 的 title 和 body的主要语言。语言属性值要么是一个有效的 BCP 47 语言标记,要么是一个空 字符串。空字符串表示主要语言是未知的。 [LANG]
2.5. 资源
对给定 notification notification 的 fetch steps 是:
-
如果通知平台支持图标,并且通知设置了icon URL,则 fetch notification 的 icon URL。
然后, in parallel:
-
等待 response.
-
如果 response 的 internal response 的 type 是 default,试图作为图像解码该资源。
-
如果平台支持该图像格式,设置 notification 的 icon resource 为该解码后的资源。(否则 notification 没有 icon resource。)
-
-
如果通知平台支持声音,并且通知设置了 sound URL ,则 fetch notification的 sound URL 。
然后, in parallel:
-
等待 response。
-
如果 response 的 internal response 的 type 是 default,试图作为声音解码该资源。
-
如果平台支持该声音格式,设置 notification 的 sound resource 为解码后的资源。(否则, notification 没有 sound resource。)
-
2.6. 显示通知
对给定 notification notification ,其show steps是:
-
如果 list of notifications 里存在某一 notification, 其 tag 非空字符串且等于 notification的 tag,其 origin 和 notification 的 origin 是 same origin, 那么对该 notification 执行 replace steps,而后终止这些步骤。
-
否则,对 notification 执行 display steps。
2.7. 激活通知
当用户激活 notification notification 时,假设底层通知平台支持激活,用户代理必须(除非另有规定)执行这些步骤:
-
如果 notification 是 persistent notification,执行这些子步骤:
-
设 callback 是 global 所调用的一种算法,对给定 global 上的 notification fires a service worker notification event 命名为
notificationclick
。 -
而后对 notification 的 service worker registration 和 callback 运行 Handle Functional Event。
-
-
否则,queue a task 来执行这些子步骤:
-
在表示 notification 的
Notification
对象上 Fire an event 属性为click
,其cancelable
属性初始化为 true。鼓励用户代理在
click
事件监听器中使用window.focus()
。 -
如果没有设置该 event 的 canceled flag,用户 代理应该聚焦 notification 相关的 browsing context 的 viewport。
-
纵观整个网络平台,“激活”被故意名不副实地称为“点击”。
2.8. 关闭通知
不论是底层通知平台还是用户,在关闭 notification 时, 都必须执行 close steps。
对给定 notification ,其 close steps 是:
-
如果 notification 不在 中,终止这些步骤。
-
从 list of notifications 中删除 notification。
2.9. 展示通知
对给定 given notification,其display steps 是:
-
等待所有的 fetches 完成,并且如果有的话,设置好 notification 的 icon resource 和 sound resource。
-
在设备上展示 notification(例如通过调用相应的通知平台)。
同时,如果有的话,播放 notification 的 sound resource,使用 notification 的 vibration pattern perform vibration。
-
追加 notification 到 list of notifications。
2.10. 更换通知
将 old notification 更换为 new 到, replace steps 是:
-
等待所有的 fetches 完成,并且如果有的话,设置好 notification 的 icon resource 和 sound resource。
-
在 list of notifications 相同的位置,将 old 更换为 new。
如果通知平台不支持更换要求,那么可对 old 运行 close steps 而后对 new 运行 display steps。
强烈建议通知平台支持原生更换,它要好得多。
3. API
[Constructor(DOMString title, optional NotificationOptions options), Exposed=(Window,Worker)] interface Notification : EventTarget { static readonly attribute NotificationPermission permission; [Exposed=Window] static void requestPermission(optional NotificationPermissionCallback callback); attribute EventHandler onclick; attribute EventHandler onerror; readonly attribute DOMString title; readonly attribute NotificationDirection dir; readonly attribute DOMString lang; readonly attribute DOMString body; readonly attribute DOMString tag; readonly attribute USVString icon; readonly attribute USVString sound; // 目前还没有暴露振动属性;见 bug 23682 readonly attribute boolean renotify; readonly attribute boolean silent; readonly attribute boolean noscreen; readonly attribute boolean sticky; [SameObject] readonly attribute any data; void close(); }; dictionary NotificationOptions { NotificationDirection dir = "auto"; DOMString lang = ""; DOMString body = ""; DOMString tag = ""; USVString icon; USVString sound; VibratePattern vibrate; boolean renotify = false; boolean silent = false; boolean noscreen = false; boolean sticky = false; any data = null; }; enum NotificationPermission { "default", "denied", "granted" }; callback NotificationPermissionCallback = void (NotificationPermission permission); enum NotificationDirection { "auto", "ltr", "rtl" };
一个 non-persistent notification 由一个 Notification
对象来表示,并且可以通过 Notification
的
constructor来创建
一个 persistent notification 由零或多个
Notification
对象来表示,并且可以通过
showNotification()
方法来创建。
3.1. 垃圾回收
当 Notification
对象相对应的 notification 在
list of notifications 时,该对象有一个 type 为
click
或 error
的 event listener,那么该 Notification
对象
一定不能被垃圾回收。
3.2. 构造函数
当调用 Notification(title, options)
构造函数时,必须(除非另有说明)执行这些步骤:
-
如果 options 存在
sticky
,throwTypeError
异常。 -
如果 entry settings object 的 global object 是一个
ServiceWorkerGlobalScope
对象, throw 一个TypeError
异常。 -
设 notification 是给定 title 和 options 之后 creating a notification 的。重新抛出任一异常。
-
设 n 是与 notification 相关联的新
Notification
. -
in parallel 执行这些子步骤:
-
如果对 notification 的 origin 的 permission 不是 "
granted
",在 n 上 queue a task 来 fire an event 命名为error
,并终止这些步骤。 -
对 notification 执行 fetch steps。
-
对 notification 执行 show steps。
-
-
返回 n.
3.3. 静态成员
获取静态属性 permission
的值必须返回对
entry settings object 的 origin 的 permission。
当调用静态方法 requestPermission(callback)
时,必须执行这些步骤:
-
返回,但依然 in parallel 执行这些子步骤:
-
设 permission 是对 entry settings object 的 originpermission。
-
如果 permission 是 "
default
",询问用户对 entry settings object 的 origin 进行显示通知是否可接受。如果可接受,设置许可为 "granted
",否则设置许可为 "denied
" 。 -
Queue a task 来设置 permission 为 entry settings object 的 origin 的 permission,并且当存在 callback 时将 permission 作为参数调用该 callback 。如果有任何异常抛出, report the exception.
设计时,通知平台是迄今为止询问用户许可比较有意义的实例。其他 API 的规范没有必要使用该模式,相反可使用 更多合适的替代品之一。
3.4. 对象成员
Notification
对象必须作为属性支持下列 event handlers (及其相应的
event handler event types)。
事件处理程序 | 事件处理事件类型 |
---|---|
onclick
| click
|
onerror
| error
|
当调用 close()
方法时,
必须对 notification 执行 close steps。
获取 title
属性值必须
返回 notification 的
title。
获取 dir
属性值必须
返回 notification 的
direction。
获取 lang
属性值必须
返回 notification 的
language。
获取 body
属性值必须
返回 notification 的
body。
获取 tag
属性值必须
返回 notification 的 tag。
获取 icon
属性值必须
返回 notification 的
icon URL, serialized, ,或者当 notification 没有 icon URL
时返回空字符串。
获取 sound
属性值必须
返回 notification’s
sound URL, serialized,或者当 notification 的 sound URL时
返回空字符串。
获取 renotify
属性值必须
返回
notification’s renotify preference flag。
获取 silent
属性值必须
返回 notification 的
silent preference flag。
获取 noscreen
属性值必须
返回
notification 的
screen off preference flag.
获取 sticky
属性值必须
返回 notification 的
sticky preference flag。
获取 data
属性值必须
返回
notification 的 data 的 structured clone。
3.5. 示例
3.5.1. 使用事件
开发者可以使用 Notification
对象在其生命周期内发出的事件来产生所需要的行为。
当用户激活一个通知时会触发 click
事件。
var not = new Notification("Gebrünn Gebrünn by Paul Kalkbrenner", { icon: "newsong.svg", tag: "song" }) notification.onclick = function() { displaySong(this) }
3.5.2. 多实例使用 tag
成员
Web 应用程序常常在多实例中进行并发操作,比如用户在多个浏览器标签中打开一个邮件
应用程序。由于桌面是一种共享资源,通知 API 通过 tag
成员提供一种很
容易协调的方式进行通知。
表示相同概念的事件可以使用相同的标记,当两个通知同时显示时,用户只会收到一个通知。
实例 1 | 实例 2 | // 有个新邮件的通知实例 | new Notification("New mail from John Doe", | { tag: 'message1' }); | | | // 稍后该实例通知有个新邮件。 | new Notification("New mail from John Doe", | { tag: 'message1' });
如果用户代理遵循这里的算法,这种情况的结果就是,用户收到 单一的 通知 "New mail from John Doe".
3.5.3. 单实例使用 tag
成员
单实例应用程序也可以使用 tag
成员来尽可能保持其通知的最新状态变化。
例如,Alice 和 Bob 正在使用一个聊天应用程序,当 Alice 空闲时 Bob 发送了多条信息, 应用程序可能更倾向于 Alice 没有看到每个消息的通知界面。
// Bob 说 "Hi" new Notification("Bob: Hi", { tag: 'chat_Bob' }); // Bob 说 "Are you free this afternoon?" new Notification("Bob: Hi / Are you free this afternoon?", { tag: 'chat_Bob' });
这种情况的结果就是单一的通知;第二条消息会替换第一条消息,因为它们具有
相同的标签。在该队列通知(先进先出)平台,使用标签允许通知保持其在队列中的位置。
在总是最先显示最新通知的平台里,也可以使用 close()
方法实现类似的结果。
4. 服务线程 API
dictionary GetNotificationOptions { DOMString tag = ""; }; partial interface ServiceWorkerRegistration { Promise<void> showNotification(DOMString title, optional NotificationOptions options); Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter); }; [Constructor(DOMString type, optional NotificationEventInit eventInitDict), Exposed=ServiceWorker] interface NotificationEvent : ExtendableEvent { readonly attribute Notification notification; }; dictionary NotificationEventInit : ExtendableEventInit { required Notification notification; }; partial interface ServiceWorkerGlobalScope { attribute EventHandler onnotificationclick; };
当调用
showNotification(title, options)
方法时,必须执行这些步骤:
-
设 promise 是一个新的 promise.
-
设notification 是给定 title 和 options 以后所 creating a notification的。重新抛出任何异常。
-
如果 context object 的 active worker 是 null,拒绝 promise 并抛出
TypeError
异常。 -
设置 notification 的 service worker registration 为该 context object。
-
in parallel 执行这些子步骤:
-
如果对 notification 的 originpermission 不是 "
granted
",拒绝 promise 并抛出TypeError
异常,而后终止这些子步骤。 -
否则,用 undefined 处理 promise。
-
对 notification 执行 fetch steps。
-
对 notificationshow steps 执行 。
-
-
返回 promise。
当调用
getNotifications(filter)
方法时,必须执行这些步骤:
-
设 promise 是一个新的 promise。
-
in parallel执行这些子步骤:
-
设 tag 是 filter 的
tag
。 -
设 notifications 是所有那些在 list of notifications 中, 其 origin 是 entry settings object 的 origin,其 service worker registration 是 context object,并且如果 tag 非空字符串 的话,其 tag 是 tag 的 notifications。
-
设 objects 是一空的 JavaScript 数组。
-
对 notifications 中每一个 notification, 按照其创建的顺序,来创建
Notification
对象表示 notification 并且将该对象压入 objects. -
用 objects 处理 promise。
-
-
返回 promise。
该方法返回零或多个新的 Notification
对象可能表示已然存在的相同底层 Notification
对象的 notification。
为给定 notification fire a service worker notification event named e,使用 NotificationEvent
属性初始化为新的 notification
对象表示 notification 的 Notification
接口来
fire an event named e 的服务线程通知 event。
获取 notification
属性值必须返回其所初始化的值。
ServiceWorkerGlobalScope
对象必须作为属性支持下列 event handler (及其相应的
event handler event type) :
事件处理程序 | 事件处理事件类型 |
---|---|
onnotificationclick
| notificationclick
|
Acknowledgments
感谢牛人: Aharon (Vladimir) Lanin, Alex Russell, Arkadiusz Michalski, Boris Zbarsky, David Håsäther, Doug Turner, Drew Wilson, Edward O’Connor, Frederick Hirsch, Ian Hickson, Jake Archibald, James Graham, John Mellor, Jon Lee, Jonas Sicking, Michael Cooper, Michael Henretty, Olli Pettay, Peter Beverloo, Reuben Morais, and Simon Pieters for being awesome.
本标准由 Anne van Kesteren (Mozilla, annevk@annevk.nl)编写。 前几版由 John Gregg (Google, johnnyg@google.com)编写。
根据 CC0, 在法律允许的范围内,编辑们放弃所有版权及与之相关或邻接的权利。