1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/sync/modules/notifications.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,128 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +this.EXPORTED_SYMBOLS = ["Notifications", "Notification", "NotificationButton"]; 1.9 + 1.10 +const Cc = Components.classes; 1.11 +const Ci = Components.interfaces; 1.12 +const Cr = Components.results; 1.13 +const Cu = Components.utils; 1.14 + 1.15 +Cu.import("resource://services-common/observers.js"); 1.16 +Cu.import("resource://gre/modules/Log.jsm"); 1.17 +Cu.import("resource://services-sync/util.js"); 1.18 + 1.19 +this.Notifications = { 1.20 + // Match the referenced values in toolkit/content/widgets/notification.xml. 1.21 + get PRIORITY_INFO() 1, // PRIORITY_INFO_LOW 1.22 + get PRIORITY_WARNING() 4, // PRIORITY_WARNING_LOW 1.23 + get PRIORITY_ERROR() 7, // PRIORITY_CRITICAL_LOW 1.24 + 1.25 + // FIXME: instead of making this public, dress the Notifications object 1.26 + // to behave like an iterator (using generators?) and have callers access 1.27 + // this array through the Notifications object. 1.28 + notifications: [], 1.29 + 1.30 + _observers: [], 1.31 + 1.32 + // XXX Should we have a helper method for adding a simple notification? 1.33 + // I.e. something like |function notify(title, description, priority)|. 1.34 + 1.35 + add: function Notifications_add(notification) { 1.36 + this.notifications.push(notification); 1.37 + Observers.notify("weave:notification:added", notification, null); 1.38 + }, 1.39 + 1.40 + remove: function Notifications_remove(notification) { 1.41 + let index = this.notifications.indexOf(notification); 1.42 + 1.43 + if (index != -1) { 1.44 + this.notifications.splice(index, 1); 1.45 + Observers.notify("weave:notification:removed", notification, null); 1.46 + } 1.47 + }, 1.48 + 1.49 + /** 1.50 + * Replace an existing notification. 1.51 + */ 1.52 + replace: function Notifications_replace(oldNotification, newNotification) { 1.53 + let index = this.notifications.indexOf(oldNotification); 1.54 + 1.55 + if (index != -1) 1.56 + this.notifications.splice(index, 1, newNotification); 1.57 + else { 1.58 + this.notifications.push(newNotification); 1.59 + // XXX Should we throw because we didn't find the existing notification? 1.60 + // XXX Should we notify observers about weave:notification:added? 1.61 + } 1.62 + 1.63 + // XXX Should we notify observers about weave:notification:replaced? 1.64 + }, 1.65 + 1.66 + /** 1.67 + * Remove all notifications that match a title. If no title is provided, all 1.68 + * notifications are removed. 1.69 + * 1.70 + * @param title [optional] 1.71 + * Title of notifications to remove; falsy value means remove all 1.72 + */ 1.73 + removeAll: function Notifications_removeAll(title) { 1.74 + this.notifications.filter(function(old) old.title == title || !title). 1.75 + forEach(function(old) this.remove(old), this); 1.76 + }, 1.77 + 1.78 + // replaces all existing notifications with the same title as the new one 1.79 + replaceTitle: function Notifications_replaceTitle(notification) { 1.80 + this.removeAll(notification.title); 1.81 + this.add(notification); 1.82 + } 1.83 +}; 1.84 + 1.85 + 1.86 +/** 1.87 + * A basic notification. Subclass this to create more complex notifications. 1.88 + */ 1.89 +this.Notification = 1.90 + function Notification(title, description, iconURL, priority, buttons) { 1.91 + this.title = title; 1.92 + this.description = description; 1.93 + 1.94 + if (iconURL) 1.95 + this.iconURL = iconURL; 1.96 + 1.97 + if (priority) 1.98 + this.priority = priority; 1.99 + 1.100 + if (buttons) 1.101 + this.buttons = buttons; 1.102 +} 1.103 + 1.104 +// We set each prototype property individually instead of redefining 1.105 +// the entire prototype to avoid blowing away existing properties 1.106 +// of the prototype like the the "constructor" property, which we use 1.107 +// to bind notification objects to their XBL representations. 1.108 +Notification.prototype.priority = Notifications.PRIORITY_INFO; 1.109 +Notification.prototype.iconURL = null; 1.110 +Notification.prototype.buttons = []; 1.111 + 1.112 +/** 1.113 + * A button to display in a notification. 1.114 + */ 1.115 +this.NotificationButton = 1.116 + function NotificationButton(label, accessKey, callback) { 1.117 + function callbackWrapper() { 1.118 + try { 1.119 + callback.apply(this, arguments); 1.120 + } catch (e) { 1.121 + let logger = Log.repository.getLogger("Sync.Notifications"); 1.122 + logger.error("An exception occurred: " + Utils.exceptionStr(e)); 1.123 + logger.info(Utils.stackTrace(e)); 1.124 + throw e; 1.125 + } 1.126 + } 1.127 + 1.128 + this.label = label; 1.129 + this.accessKey = accessKey; 1.130 + this.callback = callbackWrapper; 1.131 +}