| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2015 Eyeo GmbH | 3  * Copyright (C) 2006-2015 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 23 | 23 | 
| 24 let {Prefs} = require("prefs"); | 24 let {Prefs} = require("prefs"); | 
| 25 let {Downloader, Downloadable, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} 
     = require("downloader"); | 25 let {Downloader, Downloadable, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} 
     = require("downloader"); | 
| 26 let {Utils} = require("utils"); | 26 let {Utils} = require("utils"); | 
| 27 let {Matcher} = require("matcher"); | 27 let {Matcher} = require("matcher"); | 
| 28 let {Filter} = require("filterClasses"); | 28 let {Filter} = require("filterClasses"); | 
| 29 | 29 | 
| 30 let INITIAL_DELAY = 12 * MILLIS_IN_MINUTE; | 30 let INITIAL_DELAY = 12 * MILLIS_IN_MINUTE; | 
| 31 let CHECK_INTERVAL = 1 * MILLIS_IN_HOUR; | 31 let CHECK_INTERVAL = 1 * MILLIS_IN_HOUR; | 
| 32 let EXPIRATION_INTERVAL = 1 * MILLIS_IN_DAY; | 32 let EXPIRATION_INTERVAL = 1 * MILLIS_IN_DAY; | 
|  | 33 let STARTUP_SHOW_DELAY = 3 * MILLIS_IN_MINUTE; | 
| 33 let TYPE = { | 34 let TYPE = { | 
| 34   information: 0, | 35   information: 0, | 
| 35   question: 1, | 36   question: 1, | 
| 36   critical: 2 | 37   critical: 2 | 
| 37 }; | 38 }; | 
| 38 | 39 | 
| 39 let listeners = {}; | 40 let showListeners = []; | 
|  | 41 let questionListeners = {}; | 
| 40 | 42 | 
| 41 function getNumericalSeverity(notification) | 43 function getNumericalSeverity(notification) | 
| 42 { | 44 { | 
| 43   return (notification.type in TYPE ? TYPE[notification.type] : TYPE.information
     ); | 45   return (notification.type in TYPE ? TYPE[notification.type] : TYPE.information
     ); | 
| 44 } | 46 } | 
| 45 | 47 | 
| 46 function saveNotificationData() | 48 function saveNotificationData() | 
| 47 { | 49 { | 
| 48   // HACK: JSON values aren't saved unless they are assigned a different object. | 50   // HACK: JSON values aren't saved unless they are assigned a different object. | 
| 49   Prefs.notificationdata = JSON.parse(JSON.stringify(Prefs.notificationdata)); | 51   Prefs.notificationdata = JSON.parse(JSON.stringify(Prefs.notificationdata)); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 74  * @class | 76  * @class | 
| 75  */ | 77  */ | 
| 76 let Notification = exports.Notification = | 78 let Notification = exports.Notification = | 
| 77 { | 79 { | 
| 78   /** | 80   /** | 
| 79    * Called on module startup. | 81    * Called on module startup. | 
| 80    */ | 82    */ | 
| 81   init: function() | 83   init: function() | 
| 82   { | 84   { | 
| 83     downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY
     , CHECK_INTERVAL); | 85     downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY
     , CHECK_INTERVAL); | 
| 84     onShutdown.add(function() |  | 
| 85     { |  | 
| 86       downloader.cancel(); |  | 
| 87     }); |  | 
| 88 |  | 
| 89     downloader.onExpirationChange = this._onExpirationChange.bind(this); | 86     downloader.onExpirationChange = this._onExpirationChange.bind(this); | 
| 90     downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); | 87     downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); | 
| 91     downloader.onDownloadError = this._onDownloadError.bind(this); | 88     downloader.onDownloadError = this._onDownloadError.bind(this); | 
|  | 89     onShutdown.add(() => downloader.cancel()); | 
|  | 90 | 
|  | 91     notificationTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); | 
|  | 92     notificationTimer.initWithCallback(Notification.showNext.bind(this), | 
|  | 93                                        STARTUP_SHOW_DELAY, | 
|  | 94                                        Ci.nsITimer.TYPE_ONE_SHOT); | 
|  | 95     onShutdown.add(() => notificationTimer.cancel()); | 
| 92   }, | 96   }, | 
| 93 | 97 | 
| 94   /** | 98   /** | 
| 95    * Yields a Downloadable instances for the notifications download. | 99    * Yields a Downloadable instances for the notifications download. | 
| 96    */ | 100    */ | 
| 97   _getDownloadables: function*() | 101   _getDownloadables: function*() | 
| 98   { | 102   { | 
| 99     let downloadable = new Downloadable(Prefs.notificationurl); | 103     let downloadable = new Downloadable(Prefs.notificationurl); | 
| 100     if (typeof Prefs.notificationdata.lastError === "number") | 104     if (typeof Prefs.notificationdata.lastError === "number") | 
| 101       downloadable.lastError = Prefs.notificationdata.lastError; | 105       downloadable.lastError = Prefs.notificationdata.lastError; | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 151   }, | 155   }, | 
| 152 | 156 | 
| 153   _onDownloadError: function(downloadable, downloadURL, error, channelStatus, re
     sponseStatus, redirectCallback) | 157   _onDownloadError: function(downloadable, downloadURL, error, channelStatus, re
     sponseStatus, redirectCallback) | 
| 154   { | 158   { | 
| 155     Prefs.notificationdata.lastError = Date.now(); | 159     Prefs.notificationdata.lastError = Date.now(); | 
| 156     Prefs.notificationdata.downloadStatus = error; | 160     Prefs.notificationdata.downloadStatus = error; | 
| 157     saveNotificationData(); | 161     saveNotificationData(); | 
| 158   }, | 162   }, | 
| 159 | 163 | 
| 160   /** | 164   /** | 
|  | 165    * Adds a listener for notifications to be shown. | 
|  | 166    * @param {Function} listener Listener to be invoked when a notification is | 
|  | 167    *                   to be shown | 
|  | 168    */ | 
|  | 169   addShowListener: function(listener) | 
|  | 170   { | 
|  | 171     if (showListeners.indexOf(listener) == -1) | 
|  | 172       showListeners.push(listener); | 
|  | 173   }, | 
|  | 174 | 
|  | 175   /** | 
|  | 176    * Removes the supplied listener. | 
|  | 177    * @param {Function} listener Listener that was added via addShowListener() | 
|  | 178    */ | 
|  | 179   removeShowListener: function(listener) | 
|  | 180   { | 
|  | 181     let index = showListeners.indexOf(listener); | 
|  | 182     if (index != -1) | 
|  | 183       showListeners.splice(index, 1); | 
|  | 184   }, | 
|  | 185 | 
|  | 186   /** | 
| 161    * Determines which notification is to be shown next. | 187    * Determines which notification is to be shown next. | 
| 162    * @param {String} url URL to match notifications to (optional) | 188    * @param {String} url URL to match notifications to (optional) | 
| 163    * @return {Object} notification to be shown, or null if there is none | 189    * @return {Object} notification to be shown, or null if there is none | 
| 164    */ | 190    */ | 
| 165   getNextToShow: function(url) | 191   _getNextToShow: function(url) | 
| 166   { | 192   { | 
| 167     function checkTarget(target, parameter, name, version) | 193     function checkTarget(target, parameter, name, version) | 
| 168     { | 194     { | 
| 169       let minVersionKey = parameter + "MinVersion"; | 195       let minVersionKey = parameter + "MinVersion"; | 
| 170       let maxVersionKey = parameter + "MaxVersion"; | 196       let maxVersionKey = parameter + "MaxVersion"; | 
| 171       return !((parameter in target && target[parameter] != name) || | 197       return !((parameter in target && target[parameter] != name) || | 
| 172                (minVersionKey in target && Services.vc.compare(version, target[m
     inVersionKey]) < 0) || | 198                (minVersionKey in target && Services.vc.compare(version, target[m
     inVersionKey]) < 0) || | 
| 173                (maxVersionKey in target && Services.vc.compare(version, target[m
     axVersionKey]) > 0)); | 199                (maxVersionKey in target && Services.vc.compare(version, target[m
     axVersionKey]) > 0)); | 
| 174     } | 200     } | 
| 175 | 201 | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 227         } | 253         } | 
| 228         if (!match) | 254         if (!match) | 
| 229           continue; | 255           continue; | 
| 230       } | 256       } | 
| 231 | 257 | 
| 232       if (!notificationToShow | 258       if (!notificationToShow | 
| 233           || getNumericalSeverity(notification) > getNumericalSeverity(notificat
     ionToShow)) | 259           || getNumericalSeverity(notification) > getNumericalSeverity(notificat
     ionToShow)) | 
| 234         notificationToShow = notification; | 260         notificationToShow = notification; | 
| 235     } | 261     } | 
| 236 | 262 | 
| 237     if (notificationToShow && "id" in notificationToShow) |  | 
| 238     { |  | 
| 239       if (notificationToShow.type !== "question") |  | 
| 240         this.markAsShown(notificationToShow.id); |  | 
| 241     } |  | 
| 242 |  | 
| 243     return notificationToShow; | 263     return notificationToShow; | 
| 244   }, | 264   }, | 
| 245 | 265 | 
|  | 266   /** | 
|  | 267    * Invokes the listeners added via addShowListener() with the next | 
|  | 268    * notification to be shown. | 
|  | 269    * @param {String} url URL to match notifications to (optional) | 
|  | 270    */ | 
|  | 271   showNext: function(url) | 
|  | 272   { | 
|  | 273     let notification = Notification._getNextToShow(url); | 
|  | 274     if (notification) | 
|  | 275       for (let showListener of showListeners) | 
|  | 276         showListener(notification); | 
|  | 277   }, | 
|  | 278 | 
|  | 279   /** | 
|  | 280    * Marks a notification as shown. | 
|  | 281    * @param {String} id ID of the notification to be marked as shown | 
|  | 282    */ | 
| 246   markAsShown: function(id) | 283   markAsShown: function(id) | 
| 247   { | 284   { | 
| 248     if (Prefs.notificationdata.shown.indexOf(id) > -1) | 285     if (Prefs.notificationdata.shown.indexOf(id) > -1) | 
| 249       return; | 286       return; | 
| 250 | 287 | 
| 251     Prefs.notificationdata.shown.push(id); | 288     Prefs.notificationdata.shown.push(id); | 
| 252     saveNotificationData(); | 289     saveNotificationData(); | 
| 253   }, | 290   }, | 
| 254 | 291 | 
| 255   /** | 292   /** | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 296     let index = localData.indexOf(notification); | 333     let index = localData.indexOf(notification); | 
| 297     if (index > -1) | 334     if (index > -1) | 
| 298       localData.splice(index, 1); | 335       localData.splice(index, 1); | 
| 299   }, | 336   }, | 
| 300 | 337 | 
| 301   /** | 338   /** | 
| 302    * Adds a listener for question-type notifications | 339    * Adds a listener for question-type notifications | 
| 303    */ | 340    */ | 
| 304   addQuestionListener: function(/**string*/ id, /**function(approved)*/ listener
     ) | 341   addQuestionListener: function(/**string*/ id, /**function(approved)*/ listener
     ) | 
| 305   { | 342   { | 
| 306     if (!(id in listeners)) | 343     if (!(id in questionListeners)) | 
| 307       listeners[id] = []; | 344       questionListeners[id] = []; | 
| 308     if (listeners[id].indexOf(listener) === -1) | 345     if (questionListeners[id].indexOf(listener) === -1) | 
| 309       listeners[id].push(listener); | 346       questionListeners[id].push(listener); | 
| 310   }, | 347   }, | 
| 311 | 348 | 
| 312   /** | 349   /** | 
| 313    * Removes a listener that was previously added via addQuestionListener | 350    * Removes a listener that was previously added via addQuestionListener | 
| 314    */ | 351    */ | 
| 315   removeQuestionListener: function(/**string*/ id, /**function(approved)*/ liste
     ner) | 352   removeQuestionListener: function(/**string*/ id, /**function(approved)*/ liste
     ner) | 
| 316   { | 353   { | 
| 317     if (!(id in listeners)) | 354     if (!(id in questionListeners)) | 
| 318       return; | 355       return; | 
| 319     let index = listeners[id].indexOf(listener); | 356     let index = questionListeners[id].indexOf(listener); | 
| 320     if (index > -1) | 357     if (index > -1) | 
| 321       listeners[id].splice(index, 1); | 358       questionListeners[id].splice(index, 1); | 
| 322     if (listeners[id].length === 0) | 359     if (questionListeners[id].length === 0) | 
| 323       delete listeners[id]; | 360       delete questionListeners[id]; | 
| 324   }, | 361   }, | 
| 325 | 362 | 
| 326   /** | 363   /** | 
| 327    * Notifies listeners about interactions with a notification | 364    * Notifies question listeners about interactions with a notification | 
| 328    * @param {String} id notification ID | 365    * @param {String} id notification ID | 
| 329    * @param {Boolean} approved indicator whether notification has been approved 
     or not | 366    * @param {Boolean} approved indicator whether notification has been approved 
     or not | 
| 330    */ | 367    */ | 
| 331   triggerQuestionListeners: function(id, approved) | 368   triggerQuestionListeners: function(id, approved) | 
| 332   { | 369   { | 
| 333     if (!(id in listeners)) | 370     if (!(id in questionListeners)) | 
| 334       return; | 371       return; | 
| 335     let questionListeners = listeners[id]; | 372     let listeners = questionListeners[id]; | 
| 336     for (let listener of questionListeners) | 373     for (let listener of listeners) | 
| 337       listener(approved); | 374       listener(approved); | 
| 338   }, | 375   }, | 
| 339 | 376 | 
| 340   /** | 377   /** | 
| 341    * Toggles whether notifications of a specific category should be ignored | 378    * Toggles whether notifications of a specific category should be ignored | 
| 342    * @param {String} category notification category identifier | 379    * @param {String} category notification category identifier | 
| 343    * @param {Boolean} [forceValue] force specified value | 380    * @param {Boolean} [forceValue] force specified value | 
| 344    */ | 381    */ | 
| 345   toggleIgnoreCategory: function(category, forceValue) | 382   toggleIgnoreCategory: function(category, forceValue) | 
| 346   { | 383   { | 
| 347     let categories = Prefs.notifications_ignoredcategories; | 384     let categories = Prefs.notifications_ignoredcategories; | 
| 348     let index = categories.indexOf(category); | 385     let index = categories.indexOf(category); | 
| 349     if (index == -1 && forceValue !== false) | 386     if (index == -1 && forceValue !== false) | 
| 350     { | 387     { | 
| 351       categories.push(category); | 388       categories.push(category); | 
| 352       Prefs.notifications_showui = true; | 389       Prefs.notifications_showui = true; | 
| 353     } | 390     } | 
| 354     else if (index != -1 && forceValue !== true) | 391     else if (index != -1 && forceValue !== true) | 
| 355       categories.splice(index, 1); | 392       categories.splice(index, 1); | 
| 356 | 393 | 
| 357     // HACK: JSON values aren't saved unless they are assigned a different objec
     t. | 394     // HACK: JSON values aren't saved unless they are assigned a different objec
     t. | 
| 358     Prefs.notifications_ignoredcategories = JSON.parse(JSON.stringify(categories
     )); | 395     Prefs.notifications_ignoredcategories = JSON.parse(JSON.stringify(categories
     )); | 
| 359   } | 396   } | 
| 360 }; | 397 }; | 
| 361 Notification.init(); | 398 Notification.init(); | 
| OLD | NEW | 
|---|