Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: src/js/polyfills/notifications.polyfill.js

Issue 1646633003: Notifications work in service workers. Resolves #14. (Closed) Base URL: git@github.com:chromium/caterpillar.git@master
Patch Set: Response to CR Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/js/polyfills/notifications.polyfill.test.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/polyfills/notifications.polyfill.js
diff --git a/src/js/polyfills/notifications.polyfill.js b/src/js/polyfills/notifications.polyfill.js
index 2063c80915a02cea75fadee91aa4d53da74f71c8..1e839e568ca2b22c04a4729b12715fa52b081f42 100644
--- a/src/js/polyfills/notifications.polyfill.js
+++ b/src/js/polyfills/notifications.polyfill.js
@@ -22,6 +22,8 @@
if (!chrome.notifications)
chrome.notifications = {};
+chrome.caterpillar.notifications = {};
+
(function() {
// Private object to map notification IDs to their notification.
@@ -125,29 +127,42 @@ chrome.notifications.create = function(opt_notificationId, options,
opt_notificationId = Math.round(Math.random() * MAX_NOTIFICATION_ID) + '';
}
- // TODO(alger): This uses a deprecated callback since the callback is
- // supported on both Chrome and Firefox but the not-deprecated Promise return
- // is only currently supported on Chrome.
- Notification.requestPermission(function() {
- var title = options.title;
- var body = options.message;
- if (options.contextMessage)
- body += '\n\n' + options.contextMessage;
- if (options.type === chrome.notifications.TemplateType.PROGRESS) {
- body += '\n\nProgress: ' + options.progress + '%';
- } else if (options.type !== chrome.notifications.TemplateType.BASIC) {
- console.warn('Notification type', options.type, 'not supported.',
- 'Falling back to basic.');
- }
- var notification_options = {
- 'body': body,
- 'tag': opt_notificationId,
- 'icon': options.iconUrl,
- 'data': options,
- };
+ var title = options.title;
+ var body = options.message;
+ if (options.contextMessage)
+ body += '\n\n' + options.contextMessage;
+ if (options.type === chrome.notifications.TemplateType.PROGRESS) {
+ body += '\n\nProgress: ' + options.progress + '%';
+ } else if (options.type !== chrome.notifications.TemplateType.BASIC) {
+ console.warn('Notification type', options.type, 'not supported.',
+ 'Falling back to basic.');
+ }
+ var notificationOptions = {
+ 'body': body,
+ 'tag': opt_notificationId,
+ 'icon': options.iconUrl,
+ 'data': options,
+ };
- var notification = new Notification(title, notification_options);
+ // Service workers can't request permission, so request permission if we can
+ // or just assume we have permission if we can't.
+ var notificationPromise;
+ if (!Notification.requestPermission) {
+ notificationPromise = createNotification(title, notificationOptions);
+ } else {
+ notificationPromise = new Promise(function(resolve, reject) {
+ // TODO(alger): This uses a deprecated callback since the callback is
+ // supported on both Chrome and Firefox but the not-deprecated Promise
+ // return is only currently supported on Chrome.
+ Notification.requestPermission(function() {
+ createNotification(title, notificationOptions)
+ .then(resolve)
+ .catch(reject);
+ });
+ });
+ }
+ notificationPromise.then(function(notification) {
for (var i = 0; i < onClickHandlers.length; i++) {
notification.addEventListener('click', onClickHandlers[i]);
}
@@ -156,10 +171,58 @@ chrome.notifications.create = function(opt_notificationId, options,
if (opt_callback)
opt_callback(opt_notificationId);
- });
+ })
};
/**
+ * Gets the service worker registration.
+ *
+ * Exported so we can override for testing.
+ *
+ * @returns {Promise} Promise resolving to the service worker registration.
+ * Rejects if no registration is available.
+ */
+chrome.caterpillar.notifications.getRegistration = function() {
+ if (self.registration)
+ return Promise.resolve(self.registration);
+
+ if (navigator.serviceWorker &&
+ navigator.serviceWorker.getRegistration) {
+ return navigator.serviceWorker.getRegistration().then(function(reg) {
+ if (!reg)
+ return Promise.reject();
+ return Promise.resolve(reg);
+ });
+ }
+
+ return Promise.reject();
+}
+
+
+/**
+ * Creates a notification.
+ *
+ * Internal helper function.
+ *
+ * @param {string} title
+ * @param {object} notificationOptions Object with properties body, tag, icon,
+ * and data. All properties are expected to be defined.
+ * @returns {Promise} Promise resolving to a Notification.
+ */
+function createNotification(title, notificationOptions) {
+ return chrome.caterpillar.notifications.getRegistration()
+ .then(function(registration) {
+ registration.showNotification(title, notificationOptions);
+ return registration.getNotifications({ tag: notificationOptions.tag });
+ }).catch(function() {
+ return Promise.resolve([new Notification(title, notificationOptions)]);
+ }).then(function(notifications) {
+ // Notifications are in creation order, so get the last notification.
+ return Promise.resolve(notifications[notifications.length - 1]);
+ });
+}
+
+/**
* Clears the specified notification.
*
* @param {string} notificationId
@@ -230,4 +293,4 @@ chrome.notifications.onClicked.addListener = function(callback) {
onClickHandlers.push(callbackWrapper);
};
-}).call(this);
+}).call(this);
« no previous file with comments | « no previous file | tests/js/polyfills/notifications.polyfill.test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698