|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 this.EXPORTED_SYMBOLS = ["Notifications", "Notification", "NotificationButton"]; |
|
6 |
|
7 const Cc = Components.classes; |
|
8 const Ci = Components.interfaces; |
|
9 const Cr = Components.results; |
|
10 const Cu = Components.utils; |
|
11 |
|
12 Cu.import("resource://services-common/observers.js"); |
|
13 Cu.import("resource://gre/modules/Log.jsm"); |
|
14 Cu.import("resource://services-sync/util.js"); |
|
15 |
|
16 this.Notifications = { |
|
17 // Match the referenced values in toolkit/content/widgets/notification.xml. |
|
18 get PRIORITY_INFO() 1, // PRIORITY_INFO_LOW |
|
19 get PRIORITY_WARNING() 4, // PRIORITY_WARNING_LOW |
|
20 get PRIORITY_ERROR() 7, // PRIORITY_CRITICAL_LOW |
|
21 |
|
22 // FIXME: instead of making this public, dress the Notifications object |
|
23 // to behave like an iterator (using generators?) and have callers access |
|
24 // this array through the Notifications object. |
|
25 notifications: [], |
|
26 |
|
27 _observers: [], |
|
28 |
|
29 // XXX Should we have a helper method for adding a simple notification? |
|
30 // I.e. something like |function notify(title, description, priority)|. |
|
31 |
|
32 add: function Notifications_add(notification) { |
|
33 this.notifications.push(notification); |
|
34 Observers.notify("weave:notification:added", notification, null); |
|
35 }, |
|
36 |
|
37 remove: function Notifications_remove(notification) { |
|
38 let index = this.notifications.indexOf(notification); |
|
39 |
|
40 if (index != -1) { |
|
41 this.notifications.splice(index, 1); |
|
42 Observers.notify("weave:notification:removed", notification, null); |
|
43 } |
|
44 }, |
|
45 |
|
46 /** |
|
47 * Replace an existing notification. |
|
48 */ |
|
49 replace: function Notifications_replace(oldNotification, newNotification) { |
|
50 let index = this.notifications.indexOf(oldNotification); |
|
51 |
|
52 if (index != -1) |
|
53 this.notifications.splice(index, 1, newNotification); |
|
54 else { |
|
55 this.notifications.push(newNotification); |
|
56 // XXX Should we throw because we didn't find the existing notification? |
|
57 // XXX Should we notify observers about weave:notification:added? |
|
58 } |
|
59 |
|
60 // XXX Should we notify observers about weave:notification:replaced? |
|
61 }, |
|
62 |
|
63 /** |
|
64 * Remove all notifications that match a title. If no title is provided, all |
|
65 * notifications are removed. |
|
66 * |
|
67 * @param title [optional] |
|
68 * Title of notifications to remove; falsy value means remove all |
|
69 */ |
|
70 removeAll: function Notifications_removeAll(title) { |
|
71 this.notifications.filter(function(old) old.title == title || !title). |
|
72 forEach(function(old) this.remove(old), this); |
|
73 }, |
|
74 |
|
75 // replaces all existing notifications with the same title as the new one |
|
76 replaceTitle: function Notifications_replaceTitle(notification) { |
|
77 this.removeAll(notification.title); |
|
78 this.add(notification); |
|
79 } |
|
80 }; |
|
81 |
|
82 |
|
83 /** |
|
84 * A basic notification. Subclass this to create more complex notifications. |
|
85 */ |
|
86 this.Notification = |
|
87 function Notification(title, description, iconURL, priority, buttons) { |
|
88 this.title = title; |
|
89 this.description = description; |
|
90 |
|
91 if (iconURL) |
|
92 this.iconURL = iconURL; |
|
93 |
|
94 if (priority) |
|
95 this.priority = priority; |
|
96 |
|
97 if (buttons) |
|
98 this.buttons = buttons; |
|
99 } |
|
100 |
|
101 // We set each prototype property individually instead of redefining |
|
102 // the entire prototype to avoid blowing away existing properties |
|
103 // of the prototype like the the "constructor" property, which we use |
|
104 // to bind notification objects to their XBL representations. |
|
105 Notification.prototype.priority = Notifications.PRIORITY_INFO; |
|
106 Notification.prototype.iconURL = null; |
|
107 Notification.prototype.buttons = []; |
|
108 |
|
109 /** |
|
110 * A button to display in a notification. |
|
111 */ |
|
112 this.NotificationButton = |
|
113 function NotificationButton(label, accessKey, callback) { |
|
114 function callbackWrapper() { |
|
115 try { |
|
116 callback.apply(this, arguments); |
|
117 } catch (e) { |
|
118 let logger = Log.repository.getLogger("Sync.Notifications"); |
|
119 logger.error("An exception occurred: " + Utils.exceptionStr(e)); |
|
120 logger.info(Utils.stackTrace(e)); |
|
121 throw e; |
|
122 } |
|
123 } |
|
124 |
|
125 this.label = label; |
|
126 this.accessKey = accessKey; |
|
127 this.callback = callbackWrapper; |
|
128 } |