1 importScripts('/resources/testharness-helpers.js');
3 // For copying Notification.data. Currently a deep copy algorithm is used. Note
4 // that the robustness of this function (and also |assert_object_equals| in
5 // testharness.js) affects the types of possible testing can be done.
6 // TODO(peter): change this to a structured clone algorithm.
7 function cloneObject(src) {
8 if (typeof src != 'object' || src === null)
10 var dst = Array.isArray(src) ? [] : {};
11 for (var property in src) {
12 if (src.hasOwnProperty(property))
13 dst[property] = cloneObject(src[property]);
18 // Copies the serializable attributes of |notification|.
19 function cloneNotification(notification) {
20 var copiedNotification = JSON.parse(stringifyDOMObject(notification));
21 copiedNotification.data = cloneObject(notification.data);
22 return copiedNotification;
25 // Allows a document to exercise the Notifications API within a service worker by sending commands.
26 var messagePort = null;
28 addEventListener('message', function(workerEvent) {
29 messagePort = workerEvent.data;
31 // Listen to incoming commands on the message port.
32 messagePort.onmessage = function(event) {
33 if (typeof event.data != 'object' || !event.data.command)
36 switch (event.data.command) {
38 messagePort.postMessage({ command: event.data.command,
39 value: Notification.permission });
43 registration.showNotification(event.data.title, event.data.options).then(function() {
44 messagePort.postMessage({ command: event.data.command,
47 messagePort.postMessage({ command: event.data.command,
49 message: error.message });
55 if (typeof (event.data.filter) !== 'undefined')
56 filter = event.data.filter;
58 registration.getNotifications(filter).then(function(notifications) {
59 var clonedNotifications = [];
60 for (var notification of notifications)
61 clonedNotifications.push(cloneNotification(notification));
63 messagePort.postMessage({ command: event.data.command,
65 notifications: clonedNotifications });
67 messagePort.postMessage({ command: event.data.command,
69 message: error.message });
73 case 'request-permission-exists':
74 messagePort.postMessage({ command: event.data.command,
75 value: 'requestPermission' in Notification });
79 messagePort.postMessage({ command: 'error', message: 'Invalid command: ' + event.data.command });
84 // Notify the controller that the worker is now available.
85 messagePort.postMessage('ready');
88 addEventListener('notificationclick', function(event) {
89 var notificationCopy = cloneNotification(event.notification);
91 // Notifications containing "ACTION:CLOSE" in their message will be closed
92 // immediately by the Service Worker.
93 if (event.notification.body.indexOf('ACTION:CLOSE') != -1)
94 event.notification.close();
96 // Notifications containing "ACTION:OPENWINDOW" in their message will attempt
97 // to open a new window for an example URL.
98 if (event.notification.body.indexOf('ACTION:OPENWINDOW') != -1)
99 event.waitUntil(clients.openWindow('https://example.com/'));
101 messagePort.postMessage({ command: 'click',
102 notification: notificationCopy,
103 action: event.action });