Chromium Code Reviews| 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..8eef89b49e8272afcae4607131da2d006263f98d 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,7 +171,56 @@ chrome.notifications.create = function(opt_notificationId, options, |
| if (opt_callback) |
| opt_callback(opt_notificationId); |
| - }); |
| + }) |
| +}; |
| + |
| +/** |
| + * Gets the service worker registration. |
| + * |
| + * @returns {Promise} Promise resolving to the service worker registration. |
| + * Rejects if no registration is available. |
| + */ |
| +chrome.caterpillar.notifications.getRegistration = function() { |
| + // Exported so we can override for testing. |
| + if (self.registration) |
| + return Promise.resolve(self.registration); |
| + |
| + if (navigator.serviceWorker && |
| + navigator.serviceWorker.getRegistration) { |
|
raymes
2016/01/28 04:36:56
nit: 4 space indent, or in-line with the ( on the
Matthew Alger
2016/01/28 05:18:02
Not sure what happened here - fixed!
|
| + return navigator.serviceWorker.getRegistration().then(function(reg) { |
| + if (reg === undefined) |
|
raymes
2016/01/28 04:36:56
if (!reg)
Matthew Alger
2016/01/28 05:18:02
Done.
|
| + 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. |
| + */ |
| +var createNotification = function(title, notificationOptions) { |
|
raymes
2016/01/28 04:36:56
function createNotification(title, ...
Matthew Alger
2016/01/28 05:18:02
Done. Is this syntax preferred?
raymes
2016/02/01 00:14:23
It's just a bit simpler
Matthew Alger
2016/02/01 00:50:42
Acknowledged.
|
| + 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)]); |
|
raymes
2016/01/28 04:36:56
Is this useful?
Matthew Alger
2016/01/28 05:18:02
Yes, I think so - new Notification was part of the
|
| + }) |
| + .then(function(notifications) { |
| + // Notifications are in creation order, so get the last notification. |
| + return Promise.resolve(notifications[notifications.length - 1]); |
|
raymes
2016/01/28 04:36:56
It should be easy to inline this .then() and just
Matthew Alger
2016/01/28 05:18:02
I'm not sure how to do that without adding a .then
raymes
2016/02/01 00:14:23
Oh right, I didn't realise it returned a promise.
Matthew Alger
2016/02/01 00:50:42
Acknowledged.
|
| + }); |
| }; |
| /** |
| @@ -230,4 +294,4 @@ chrome.notifications.onClicked.addListener = function(callback) { |
| onClickHandlers.push(callbackWrapper); |
| }; |
| -}).call(this); |
| +}).call(this); |