Index: lib/notification.js |
=================================================================== |
--- a/lib/notification.js |
+++ b/lib/notification.js |
@@ -25,15 +25,23 @@ |
let {Prefs} = require("prefs"); |
let {Downloader, Downloadable, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); |
let {Utils} = require("utils"); |
+let {Matcher} = require("matcher"); |
+let {Filter} = require("filterClasses"); |
let INITIAL_DELAY = 12 * MILLIS_IN_MINUTE; |
let CHECK_INTERVAL = 1 * MILLIS_IN_HOUR; |
let EXPIRATION_INTERVAL = 1 * MILLIS_IN_DAY; |
+let SEVERITY = { |
+ information: 0, |
+ question: 1, |
+ critical: 2 |
+}; |
+ |
+let listeners = []; |
function getNumericalSeverity(notification) |
{ |
- let levels = {information: 0, critical: 1}; |
- return (notification.severity in levels ? levels[notification.severity] : levels.information); |
+ return (notification.severity in SEVERITY ? SEVERITY[notification.severity] : SEVERITY.information); |
Felix Dahlke
2014/02/12 15:09:27
I actually thought it's fine to call this TYPE, ju
Thomas Greiner
2014/02/12 18:28:02
Done.
|
} |
function saveNotificationData() |
@@ -60,6 +68,7 @@ |
* @type Downloader |
*/ |
let downloader = null; |
+let localData = []; |
/** |
* Regularly fetches notifications and decides which to show. |
@@ -142,10 +151,10 @@ |
/** |
* Determines which notification is to be shown next. |
- * @param {Array of Object} notifications active notifications |
+ * @param {String} url URL to match notifications to |
Felix Dahlke
2014/02/12 15:09:27
Would be nice to point out here that it's optional
Thomas Greiner
2014/02/12 18:28:02
Done.
|
* @return {Object} notification to be shown, or null if there is none |
*/ |
- getNextToShow: function() |
+ getNextToShow: function(url) |
{ |
function checkTarget(target, parameter, name, version) |
{ |
@@ -154,11 +163,11 @@ |
return !((parameter in target && target[parameter] != name) || |
(minVersionKey in target && Services.vc.compare(version, target[minVersionKey]) < 0) || |
(maxVersionKey in target && Services.vc.compare(version, target[maxVersionKey]) > 0)); |
- |
} |
- if (typeof Prefs.notificationdata.data != "object" || !(Prefs.notificationdata.data.notifications instanceof Array)) |
- return null; |
+ let remoteData = []; |
+ if (typeof Prefs.notificationdata.data == "object" && Prefs.notificationdata.data.notifications instanceof Array) |
+ remoteData = Prefs.notificationdata.data.notifications; |
if (!(Prefs.notificationdata.shown instanceof Array)) |
{ |
@@ -166,15 +175,32 @@ |
saveNotificationData(); |
} |
+ let notifications = localData.concat(remoteData); |
+ if (notifications.length === 0) |
+ return null; |
+ |
let {addonName, addonVersion, application, applicationVersion, platform, platformVersion} = require("info"); |
- let notifications = Prefs.notificationdata.data.notifications; |
let notificationToShow = null; |
for each (let notification in notifications) |
{ |
- if ((typeof notification.severity === "undefined" || notification.severity === "information") |
+ if ((typeof notification.severity === "undefined" || notification.severity !== "critical") |
&& Prefs.notificationdata.shown.indexOf(notification.id) !== -1) |
continue; |
+ if (typeof url === "string" || notification.urlFilters instanceof Array) |
+ { |
+ if (typeof url === "string" && notification.urlFilters instanceof Array) |
+ { |
+ let matcher = new Matcher(); |
+ for each (let urlFilter in notification.urlFilters) |
+ matcher.add(Filter.fromText(urlFilter)); |
+ if (!matcher.matchesAny(url, "DOCUMENT", url)) |
+ continue; |
+ } |
+ else |
+ continue; |
+ } |
+ |
if (notification.targets instanceof Array) |
{ |
let match = false; |
@@ -192,20 +218,28 @@ |
continue; |
} |
- if (!notificationToShow |
- || getNumericalSeverity(notification) > getNumericalSeverity(notificationToShow)) |
+ if (!notificationToShow || getNumericalSeverity(notification) > getNumericalSeverity(notificationToShow)) |
Felix Dahlke
2014/02/12 15:09:27
Can you restore the line break? To avoid unrelated
Thomas Greiner
2014/02/12 18:28:02
Done.
|
notificationToShow = notification; |
} |
if (notificationToShow && "id" in notificationToShow) |
{ |
- Prefs.notificationdata.shown.push(notificationToShow.id); |
- saveNotificationData(); |
+ if (notificationToShow.severity !== "question") |
+ this.markAsShown(notificationToShow.id); |
} |
return notificationToShow; |
}, |
+ markAsShown: function(id) |
+ { |
+ if (Prefs.notificationdata.shown.indexOf(id) > -1) |
+ return; |
+ |
+ Prefs.notificationdata.shown.push(id); |
+ saveNotificationData(); |
+ }, |
+ |
/** |
* Localizes the texts of the supplied notification. |
* @param {Object} notification notification to translate |
@@ -221,9 +255,65 @@ |
for each (let key in textKeys) |
{ |
if (key in notification) |
- localizedTexts[key] = localize(notification[key], locale); |
+ { |
+ if (typeof notification[key] == "string") |
+ localizedTexts[key] = notification[key]; |
+ else |
+ localizedTexts[key] = localize(notification[key], locale); |
+ } |
} |
return localizedTexts; |
+ }, |
+ |
+ /** |
+ * Adds a local notification. |
+ * @param {Object} notification notification to add |
+ */ |
+ addNotification: function(notification) |
+ { |
+ if (localData.indexOf(notification) == -1) |
+ localData.push(notification); |
+ }, |
+ |
+ /** |
+ * Removes an existing local notification. |
+ * @param {Object} notification notification to remove |
+ */ |
+ removeNotification: function(notification) |
+ { |
+ let index = localData.indexOf(notification); |
+ if (index > -1) |
+ localData.splice(index, 1); |
+ }, |
+ |
+ /** |
+ * Adds a listener |
+ */ |
+ addListener: function(/**function(id, approved)*/ listener) |
Felix Dahlke
2014/02/12 15:09:27
I think it'd make more sense to register listeners
Thomas Greiner
2014/02/12 18:28:02
Done. Although from a consistency standpoint I'm m
|
+ { |
+ if (listeners.indexOf(listener) === -1) |
+ listeners.push(listener); |
+ }, |
+ |
+ /** |
+ * Removes a listener that was previously added via addListener |
+ */ |
+ removeListener: function(/**function(id, approved)*/ listener) |
+ { |
+ let index = listeners.indexOf(listener); |
+ if (index > -1) |
+ listeners.splice(index, 1); |
+ }, |
+ |
+ /** |
+ * Notifies listeners about interactions with a notification |
+ * @param {String} id notification ID |
+ * @param {Boolean} approved indicator whether notification has been approved or not |
+ */ |
+ triggerListeners: function(id, approved) |
+ { |
+ for each (let listener in listeners) |
+ listener(id, approved); |
} |
}; |
Notification.init(); |