| 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-2016 Eyeo GmbH | 3  * Copyright (C) 2006-2016 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 | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
|  | 18 "use strict"; | 
|  | 19 | 
| 18 /** | 20 /** | 
| 19  * @fileOverview Definition of Subscription class and its subclasses. | 21  * @fileOverview Definition of Subscription class and its subclasses. | 
| 20  */ | 22  */ | 
| 21 | 23 | 
| 22 let {ActiveFilter, BlockingFilter, WhitelistFilter, ElemHideBase} = require("fil
     terClasses"); | 24 const {ActiveFilter, BlockingFilter, | 
| 23 let {FilterNotifier} = require("filterNotifier"); | 25        WhitelistFilter, ElemHideBase} = require("filterClasses"); | 
| 24 let {desc, extend} = require("coreUtils"); | 26 const {FilterNotifier} = require("filterNotifier"); | 
|  | 27 const {desc, extend} = require("coreUtils"); | 
| 25 | 28 | 
| 26 /** | 29 /** | 
| 27  * Abstract base class for filter subscriptions | 30  * Abstract base class for filter subscriptions | 
| 28  * | 31  * | 
| 29  * @param {String} url    download location of the subscription | 32  * @param {string} url    download location of the subscription | 
| 30  * @param {String} [title]  title of the filter subscription | 33  * @param {string} [title]  title of the filter subscription | 
| 31  * @constructor | 34  * @constructor | 
| 32  */ | 35  */ | 
| 33 function Subscription(url, title) | 36 function Subscription(url, title) | 
| 34 { | 37 { | 
| 35   this.url = url; | 38   this.url = url; | 
| 36   this.filters = []; | 39   this.filters = []; | 
| 37   if (title) | 40   if (title) | 
| 38     this._title = title; | 41     this._title = title; | 
| 39   Subscription.knownSubscriptions[url] = this; | 42   Subscription.knownSubscriptions[url] = this; | 
| 40 } | 43 } | 
| 41 exports.Subscription = Subscription; | 44 exports.Subscription = Subscription; | 
| 42 | 45 | 
| 43 Subscription.prototype = | 46 Subscription.prototype = | 
| 44 { | 47 { | 
| 45   /** | 48   /** | 
| 46    * Download location of the subscription | 49    * Download location of the subscription | 
| 47    * @type String | 50    * @type {string} | 
| 48    */ | 51    */ | 
| 49   url: null, | 52   url: null, | 
| 50 | 53 | 
| 51   /** | 54   /** | 
| 52    * Filters contained in the filter subscription | 55    * Filters contained in the filter subscription | 
| 53    * @type Filter[] | 56    * @type {Filter[]} | 
| 54    */ | 57    */ | 
| 55   filters: null, | 58   filters: null, | 
| 56 | 59 | 
| 57   _title: null, | 60   _title: null, | 
| 58   _fixedTitle: false, | 61   _fixedTitle: false, | 
| 59   _disabled: false, | 62   _disabled: false, | 
| 60 | 63 | 
| 61   /** | 64   /** | 
| 62    * Title of the filter subscription | 65    * Title of the filter subscription | 
| 63    * @type String | 66    * @type {string} | 
| 64    */ | 67    */ | 
| 65   get title() | 68   get title() | 
| 66   { | 69   { | 
| 67     return this._title; | 70     return this._title; | 
| 68   }, | 71   }, | 
| 69   set title(value) | 72   set title(value) | 
| 70   { | 73   { | 
| 71     if (value != this._title) | 74     if (value != this._title) | 
| 72     { | 75     { | 
| 73       let oldValue = this._title; | 76       let oldValue = this._title; | 
| 74       this._title = value; | 77       this._title = value; | 
| 75       FilterNotifier.triggerListeners("subscription.title", this, value, oldValu
     e); | 78       FilterNotifier.triggerListeners("subscription.title", | 
|  | 79                                       this, value, oldValue); | 
| 76     } | 80     } | 
| 77     return this._title; | 81     return this._title; | 
| 78   }, | 82   }, | 
| 79 | 83 | 
| 80   /** | 84   /** | 
| 81    * Determines whether the title should be editable | 85    * Determines whether the title should be editable | 
| 82    * @type Boolean | 86    * @type {boolean} | 
| 83    */ | 87    */ | 
| 84   get fixedTitle() | 88   get fixedTitle() | 
| 85   { | 89   { | 
| 86     return this._fixedTitle; | 90     return this._fixedTitle; | 
| 87   }, | 91   }, | 
| 88   set fixedTitle(value) | 92   set fixedTitle(value) | 
| 89   { | 93   { | 
| 90     if (value != this._fixedTitle) | 94     if (value != this._fixedTitle) | 
| 91     { | 95     { | 
| 92       let oldValue = this._fixedTitle; | 96       let oldValue = this._fixedTitle; | 
| 93       this._fixedTitle = value; | 97       this._fixedTitle = value; | 
| 94       FilterNotifier.triggerListeners("subscription.fixedTitle", this, value, ol
     dValue); | 98       FilterNotifier.triggerListeners("subscription.fixedTitle", | 
|  | 99                                       this, value, oldValue); | 
| 95     } | 100     } | 
| 96     return this._fixedTitle; | 101     return this._fixedTitle; | 
| 97   }, | 102   }, | 
| 98 | 103 | 
| 99   /** | 104   /** | 
| 100    * Defines whether the filters in the subscription should be disabled | 105    * Defines whether the filters in the subscription should be disabled | 
| 101    * @type Boolean | 106    * @type {boolean} | 
| 102    */ | 107    */ | 
| 103   get disabled() | 108   get disabled() | 
| 104   { | 109   { | 
| 105     return this._disabled; | 110     return this._disabled; | 
| 106   }, | 111   }, | 
| 107   set disabled(value) | 112   set disabled(value) | 
| 108   { | 113   { | 
| 109     if (value != this._disabled) | 114     if (value != this._disabled) | 
| 110     { | 115     { | 
| 111       let oldValue = this._disabled; | 116       let oldValue = this._disabled; | 
| 112       this._disabled = value; | 117       this._disabled = value; | 
| 113       FilterNotifier.triggerListeners("subscription.disabled", this, value, oldV
     alue); | 118       FilterNotifier.triggerListeners("subscription.disabled", | 
|  | 119                                       this, value, oldValue); | 
| 114     } | 120     } | 
| 115     return this._disabled; | 121     return this._disabled; | 
| 116   }, | 122   }, | 
| 117 | 123 | 
| 118   /** | 124   /** | 
| 119    * Serializes the subscription to an array of strings for writing out on the d
     isk. | 125    * Serializes the subscription to an array of strings for writing | 
|  | 126    * out on the disk. | 
| 120    * @param {string[]} buffer  buffer to push the serialization results into | 127    * @param {string[]} buffer  buffer to push the serialization results into | 
| 121    */ | 128    */ | 
| 122   serialize: function(buffer) | 129   serialize(buffer) | 
| 123   { | 130   { | 
| 124     buffer.push("[Subscription]"); | 131     buffer.push("[Subscription]"); | 
| 125     buffer.push("url=" + this.url); | 132     buffer.push("url=" + this.url); | 
| 126     if (this._title) | 133     if (this._title) | 
| 127       buffer.push("title=" + this._title); | 134       buffer.push("title=" + this._title); | 
| 128     if (this._fixedTitle) | 135     if (this._fixedTitle) | 
| 129       buffer.push("fixedTitle=true"); | 136       buffer.push("fixedTitle=true"); | 
| 130     if (this._disabled) | 137     if (this._disabled) | 
| 131       buffer.push("disabled=true"); | 138       buffer.push("disabled=true"); | 
| 132   }, | 139   }, | 
| 133 | 140 | 
| 134   serializeFilters: function(buffer) | 141   serializeFilters(buffer) | 
| 135   { | 142   { | 
| 136     for (let filter of this.filters) | 143     for (let filter of this.filters) | 
| 137       buffer.push(filter.text.replace(/\[/g, "\\[")); | 144       buffer.push(filter.text.replace(/\[/g, "\\[")); | 
| 138   }, | 145   }, | 
| 139 | 146 | 
| 140   toString: function() | 147   toString() | 
| 141   { | 148   { | 
| 142     let buffer = []; | 149     let buffer = []; | 
| 143     this.serialize(buffer); | 150     this.serialize(buffer); | 
| 144     return buffer.join("\n"); | 151     return buffer.join("\n"); | 
| 145   } | 152   } | 
| 146 }; | 153 }; | 
| 147 | 154 | 
| 148 /** | 155 /** | 
| 149  * Cache for known filter subscriptions, maps URL to subscription objects. | 156  * Cache for known filter subscriptions, maps URL to subscription objects. | 
| 150  * @type Object | 157  * @type {Object} | 
| 151  */ | 158  */ | 
| 152 Subscription.knownSubscriptions = Object.create(null); | 159 Subscription.knownSubscriptions = Object.create(null); | 
| 153 | 160 | 
| 154 /** | 161 /** | 
| 155  * Returns a subscription from its URL, creates a new one if necessary. | 162  * Returns a subscription from its URL, creates a new one if necessary. | 
| 156  * @param {String} url  URL of the subscription | 163  * @param {string} url | 
| 157  * @return {Subscription} subscription or null if the subscription couldn't be c
     reated | 164  *   URL of the subscription | 
|  | 165  * @return {Subscription} | 
|  | 166  *   subscription or null if the subscription couldn't be created | 
| 158  */ | 167  */ | 
| 159 Subscription.fromURL = function(url) | 168 Subscription.fromURL = function(url) | 
| 160 { | 169 { | 
| 161   if (url in Subscription.knownSubscriptions) | 170   if (url in Subscription.knownSubscriptions) | 
| 162     return Subscription.knownSubscriptions[url]; | 171     return Subscription.knownSubscriptions[url]; | 
| 163 | 172 | 
| 164   if (url[0] != "~") | 173   if (url[0] != "~") | 
| 165     return new DownloadableSubscription(url, null); | 174     return new DownloadableSubscription(url, null); | 
| 166   else | 175   return new SpecialSubscription(url); | 
| 167     return new SpecialSubscription(url); |  | 
| 168 }; | 176 }; | 
| 169 | 177 | 
| 170 /** | 178 /** | 
| 171  * Deserializes a subscription | 179  * Deserializes a subscription | 
| 172  * | 180  * | 
| 173  * @param {Object}  obj map of serialized properties and their values | 181  * @param {Object}  obj | 
| 174  * @return {Subscription} subscription or null if the subscription couldn't be c
     reated | 182  *   map of serialized properties and their values | 
|  | 183  * @return {Subscription} | 
|  | 184  *   subscription or null if the subscription couldn't be created | 
| 175  */ | 185  */ | 
| 176 Subscription.fromObject = function(obj) | 186 Subscription.fromObject = function(obj) | 
| 177 { | 187 { | 
| 178   let result; | 188   let result; | 
| 179   if (obj.url[0] != "~") | 189   if (obj.url[0] != "~") | 
| 180   { | 190   { | 
| 181     // URL is valid - this is a downloadable subscription | 191     // URL is valid - this is a downloadable subscription | 
| 182     result = new DownloadableSubscription(obj.url, obj.title); | 192     result = new DownloadableSubscription(obj.url, obj.title); | 
| 183     if ("downloadStatus" in obj) | 193     if ("downloadStatus" in obj) | 
| 184       result._downloadStatus = obj.downloadStatus; | 194       result._downloadStatus = obj.downloadStatus; | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 212   if ("fixedTitle" in obj) | 222   if ("fixedTitle" in obj) | 
| 213     result._fixedTitle = (obj.fixedTitle == "true"); | 223     result._fixedTitle = (obj.fixedTitle == "true"); | 
| 214   if ("disabled" in obj) | 224   if ("disabled" in obj) | 
| 215     result._disabled = (obj.disabled == "true"); | 225     result._disabled = (obj.disabled == "true"); | 
| 216 | 226 | 
| 217   return result; | 227   return result; | 
| 218 }; | 228 }; | 
| 219 | 229 | 
| 220 /** | 230 /** | 
| 221  * Class for special filter subscriptions (user's filters) | 231  * Class for special filter subscriptions (user's filters) | 
| 222  * @param {String} url see Subscription() | 232  * @param {string} url see Subscription() | 
| 223  * @param {String} [title]  see Subscription() | 233  * @param {string} [title]  see Subscription() | 
| 224  * @constructor | 234  * @constructor | 
| 225  * @augments Subscription | 235  * @augments Subscription | 
| 226  */ | 236  */ | 
| 227 function SpecialSubscription(url, title) | 237 function SpecialSubscription(url, title) | 
| 228 { | 238 { | 
| 229   Subscription.call(this, url, title); | 239   Subscription.call(this, url, title); | 
| 230 } | 240 } | 
| 231 exports.SpecialSubscription = SpecialSubscription; | 241 exports.SpecialSubscription = SpecialSubscription; | 
| 232 | 242 | 
| 233 SpecialSubscription.prototype = extend(Subscription, { | 243 SpecialSubscription.prototype = extend(Subscription, { | 
| 234   /** | 244   /** | 
| 235    * Filter types that should be added to this subscription by default | 245    * Filter types that should be added to this subscription by default | 
| 236    * (entries should correspond to keys in SpecialSubscription.defaultsMap). | 246    * (entries should correspond to keys in SpecialSubscription.defaultsMap). | 
| 237    * @type string[] | 247    * @type {string[]} | 
| 238    */ | 248    */ | 
| 239   defaults: null, | 249   defaults: null, | 
| 240 | 250 | 
| 241   /** | 251   /** | 
| 242    * Tests whether a filter should be added to this group by default | 252    * Tests whether a filter should be added to this group by default | 
| 243    * @param {Filter} filter filter to be tested | 253    * @param {Filter} filter filter to be tested | 
| 244    * @return {Boolean} | 254    * @return {boolean} | 
| 245    */ | 255    */ | 
| 246   isDefaultFor: function(filter) | 256   isDefaultFor(filter) | 
| 247   { | 257   { | 
| 248     if (this.defaults && this.defaults.length) | 258     if (this.defaults && this.defaults.length) | 
| 249     { | 259     { | 
| 250       for (let type of this.defaults) | 260       for (let type of this.defaults) | 
| 251       { | 261       { | 
| 252         if (filter instanceof SpecialSubscription.defaultsMap[type]) | 262         if (filter instanceof SpecialSubscription.defaultsMap[type]) | 
| 253           return true; | 263           return true; | 
| 254         if (!(filter instanceof ActiveFilter) && type == "blacklist") | 264         if (!(filter instanceof ActiveFilter) && type == "blacklist") | 
| 255           return true; | 265           return true; | 
| 256       } | 266       } | 
| 257     } | 267     } | 
| 258 | 268 | 
| 259     return false; | 269     return false; | 
| 260   }, | 270   }, | 
| 261 | 271 | 
| 262   /** | 272   /** | 
| 263    * See Subscription.serialize() | 273    * See Subscription.serialize() | 
|  | 274    * @inheritdoc | 
| 264    */ | 275    */ | 
| 265   serialize: function(buffer) | 276   serialize(buffer) | 
| 266   { | 277   { | 
| 267     Subscription.prototype.serialize.call(this, buffer); | 278     Subscription.prototype.serialize.call(this, buffer); | 
| 268     if (this.defaults && this.defaults.length) | 279     if (this.defaults && this.defaults.length) | 
| 269       buffer.push("defaults=" + this.defaults.filter((type) => type in SpecialSu
     bscription.defaultsMap).join(" ")); | 280     { | 
|  | 281       buffer.push("defaults=" + | 
|  | 282         this.defaults.filter( | 
|  | 283           type => type in SpecialSubscription.defaultsMap | 
|  | 284         ).join(" ") | 
|  | 285       ); | 
|  | 286     } | 
| 270     if (this._lastDownload) | 287     if (this._lastDownload) | 
| 271       buffer.push("lastDownload=" + this._lastDownload); | 288       buffer.push("lastDownload=" + this._lastDownload); | 
| 272   } | 289   } | 
| 273 }); | 290 }); | 
| 274 | 291 | 
| 275 SpecialSubscription.defaultsMap = Object.create(null, desc({ | 292 SpecialSubscription.defaultsMap = Object.create(null, desc({ | 
| 276   "whitelist": WhitelistFilter, | 293   whitelist: WhitelistFilter, | 
| 277   "blocking": BlockingFilter, | 294   blocking: BlockingFilter, | 
| 278   "elemhide": ElemHideBase | 295   elemhide: ElemHideBase | 
| 279 })); | 296 })); | 
| 280 | 297 | 
| 281 /** | 298 /** | 
| 282  * Creates a new user-defined filter group. | 299  * Creates a new user-defined filter group. | 
| 283  * @param {String} [title]  title of the new filter group | 300  * @param {string} [title]  title of the new filter group | 
| 284  * @result {SpecialSubscription} | 301  * @return {SpecialSubscription} | 
| 285  */ | 302  */ | 
| 286 SpecialSubscription.create = function(title) | 303 SpecialSubscription.create = function(title) | 
| 287 { | 304 { | 
| 288   let url; | 305   let url; | 
| 289   do | 306   do | 
| 290   { | 307   { | 
| 291     url = "~user~" + Math.round(Math.random()*1000000); | 308     url = "~user~" + Math.round(Math.random() * 1000000); | 
| 292   } while (url in Subscription.knownSubscriptions); | 309   } while (url in Subscription.knownSubscriptions); | 
| 293   return new SpecialSubscription(url, title); | 310   return new SpecialSubscription(url, title); | 
| 294 }; | 311 }; | 
| 295 | 312 | 
| 296 /** | 313 /** | 
| 297  * Creates a new user-defined filter group and adds the given filter to it. | 314  * Creates a new user-defined filter group and adds the given filter to it. | 
| 298  * This group will act as the default group for this filter type. | 315  * This group will act as the default group for this filter type. | 
|  | 316  * @param {Filter} filter | 
|  | 317  * @return {SpecialSubscription} | 
| 299  */ | 318  */ | 
| 300 SpecialSubscription.createForFilter = function(/**Filter*/ filter) /**SpecialSub
     scription*/ | 319 SpecialSubscription.createForFilter = function(filter) | 
| 301 { | 320 { | 
| 302   let subscription = SpecialSubscription.create(); | 321   let subscription = SpecialSubscription.create(); | 
| 303   subscription.filters.push(filter); | 322   subscription.filters.push(filter); | 
| 304   for (let type in SpecialSubscription.defaultsMap) | 323   for (let type in SpecialSubscription.defaultsMap) | 
| 305   { | 324   { | 
| 306     if (filter instanceof SpecialSubscription.defaultsMap[type]) | 325     if (filter instanceof SpecialSubscription.defaultsMap[type]) | 
| 307       subscription.defaults = [type]; | 326       subscription.defaults = [type]; | 
| 308   } | 327   } | 
| 309   if (!subscription.defaults) | 328   if (!subscription.defaults) | 
| 310     subscription.defaults = ["blocking"]; | 329     subscription.defaults = ["blocking"]; | 
| 311   return subscription; | 330   return subscription; | 
| 312 }; | 331 }; | 
| 313 | 332 | 
| 314 /** | 333 /** | 
| 315  * Abstract base class for regular filter subscriptions (both internally and ext
     ernally updated) | 334  * Abstract base class for regular filter subscriptions (both | 
| 316  * @param {String} url    see Subscription() | 335  * internally and externally updated) | 
| 317  * @param {String} [title]  see Subscription() | 336  * @param {string} url    see Subscription() | 
|  | 337  * @param {string} [title]  see Subscription() | 
| 318  * @constructor | 338  * @constructor | 
| 319  * @augments Subscription | 339  * @augments Subscription | 
| 320  */ | 340  */ | 
| 321 function RegularSubscription(url, title) | 341 function RegularSubscription(url, title) | 
| 322 { | 342 { | 
| 323   Subscription.call(this, url, title || url); | 343   Subscription.call(this, url, title || url); | 
| 324 } | 344 } | 
| 325 exports.RegularSubscription = RegularSubscription; | 345 exports.RegularSubscription = RegularSubscription; | 
| 326 | 346 | 
| 327 RegularSubscription.prototype = extend(Subscription, { | 347 RegularSubscription.prototype = extend(Subscription, { | 
| 328   _homepage: null, | 348   _homepage: null, | 
| 329   _lastDownload: 0, | 349   _lastDownload: 0, | 
| 330 | 350 | 
| 331   /** | 351   /** | 
| 332    * Filter subscription homepage if known | 352    * Filter subscription homepage if known | 
| 333    * @type String | 353    * @type {string} | 
| 334    */ | 354    */ | 
| 335   get homepage() | 355   get homepage() | 
| 336   { | 356   { | 
| 337     return this._homepage; | 357     return this._homepage; | 
| 338   }, | 358   }, | 
| 339   set homepage(value) | 359   set homepage(value) | 
| 340   { | 360   { | 
| 341     if (value != this._homepage) | 361     if (value != this._homepage) | 
| 342     { | 362     { | 
| 343       let oldValue = this._homepage; | 363       let oldValue = this._homepage; | 
| 344       this._homepage = value; | 364       this._homepage = value; | 
| 345       FilterNotifier.triggerListeners("subscription.homepage", this, value, oldV
     alue); | 365       FilterNotifier.triggerListeners("subscription.homepage", | 
|  | 366                                       this, value, oldValue); | 
| 346     } | 367     } | 
| 347     return this._homepage; | 368     return this._homepage; | 
| 348   }, | 369   }, | 
| 349 | 370 | 
| 350   /** | 371   /** | 
| 351    * Time of the last subscription download (in seconds since the beginning of t
     he epoch) | 372    * Time of the last subscription download (in seconds since the | 
| 352    * @type Number | 373    * beginning of the epoch) | 
|  | 374    * @type {number} | 
| 353    */ | 375    */ | 
| 354   get lastDownload() | 376   get lastDownload() | 
| 355   { | 377   { | 
| 356     return this._lastDownload; | 378     return this._lastDownload; | 
| 357   }, | 379   }, | 
| 358   set lastDownload(value) | 380   set lastDownload(value) | 
| 359   { | 381   { | 
| 360     if (value != this._lastDownload) | 382     if (value != this._lastDownload) | 
| 361     { | 383     { | 
| 362       let oldValue = this._lastDownload; | 384       let oldValue = this._lastDownload; | 
| 363       this._lastDownload = value; | 385       this._lastDownload = value; | 
| 364       FilterNotifier.triggerListeners("subscription.lastDownload", this, value, 
     oldValue); | 386       FilterNotifier.triggerListeners("subscription.lastDownload", | 
|  | 387                                       this, value, oldValue); | 
| 365     } | 388     } | 
| 366     return this._lastDownload; | 389     return this._lastDownload; | 
| 367   }, | 390   }, | 
| 368 | 391 | 
| 369   /** | 392   /** | 
| 370    * See Subscription.serialize() | 393    * See Subscription.serialize() | 
|  | 394    * @inheritdoc | 
| 371    */ | 395    */ | 
| 372   serialize: function(buffer) | 396   serialize(buffer) | 
| 373   { | 397   { | 
| 374     Subscription.prototype.serialize.call(this, buffer); | 398     Subscription.prototype.serialize.call(this, buffer); | 
| 375     if (this._homepage) | 399     if (this._homepage) | 
| 376       buffer.push("homepage=" + this._homepage); | 400       buffer.push("homepage=" + this._homepage); | 
| 377     if (this._lastDownload) | 401     if (this._lastDownload) | 
| 378       buffer.push("lastDownload=" + this._lastDownload); | 402       buffer.push("lastDownload=" + this._lastDownload); | 
| 379   } | 403   } | 
| 380 }); | 404 }); | 
| 381 | 405 | 
| 382 /** | 406 /** | 
| 383  * Class for filter subscriptions updated externally (by other extension) | 407  * Class for filter subscriptions updated externally (by other extension) | 
| 384  * @param {String} url    see Subscription() | 408  * @param {string} url    see Subscription() | 
| 385  * @param {String} [title]  see Subscription() | 409  * @param {string} [title]  see Subscription() | 
| 386  * @constructor | 410  * @constructor | 
| 387  * @augments RegularSubscription | 411  * @augments RegularSubscription | 
| 388  */ | 412  */ | 
| 389 function ExternalSubscription(url, title) | 413 function ExternalSubscription(url, title) | 
| 390 { | 414 { | 
| 391   RegularSubscription.call(this, url, title); | 415   RegularSubscription.call(this, url, title); | 
| 392 } | 416 } | 
| 393 exports.ExternalSubscription = ExternalSubscription; | 417 exports.ExternalSubscription = ExternalSubscription; | 
| 394 | 418 | 
| 395 ExternalSubscription.prototype = extend(RegularSubscription, { | 419 ExternalSubscription.prototype = extend(RegularSubscription, { | 
| 396   /** | 420   /** | 
| 397    * See Subscription.serialize() | 421    * See Subscription.serialize() | 
|  | 422    * @inheritdoc | 
| 398    */ | 423    */ | 
| 399   serialize: function(buffer) | 424   serialize(buffer) | 
| 400   { | 425   { | 
| 401     throw new Error("Unexpected call, external subscriptions should not be seria
     lized"); | 426     throw new Error( | 
|  | 427       "Unexpected call, external subscriptions should not be serialized" | 
|  | 428     ); | 
| 402   } | 429   } | 
| 403 }); | 430 }); | 
| 404 | 431 | 
| 405 /** | 432 /** | 
| 406  * Class for filter subscriptions updated externally (by other extension) | 433  * Class for filter subscriptions updated externally (by other extension) | 
| 407  * @param {String} url  see Subscription() | 434  * @param {string} url  see Subscription() | 
| 408  * @param {String} [title]  see Subscription() | 435  * @param {string} [title]  see Subscription() | 
| 409  * @constructor | 436  * @constructor | 
| 410  * @augments RegularSubscription | 437  * @augments RegularSubscription | 
| 411  */ | 438  */ | 
| 412 function DownloadableSubscription(url, title) | 439 function DownloadableSubscription(url, title) | 
| 413 { | 440 { | 
| 414   RegularSubscription.call(this, url, title); | 441   RegularSubscription.call(this, url, title); | 
| 415 } | 442 } | 
| 416 exports.DownloadableSubscription = DownloadableSubscription; | 443 exports.DownloadableSubscription = DownloadableSubscription; | 
| 417 | 444 | 
| 418 DownloadableSubscription.prototype = extend(RegularSubscription, { | 445 DownloadableSubscription.prototype = extend(RegularSubscription, { | 
| 419   _downloadStatus: null, | 446   _downloadStatus: null, | 
| 420   _lastCheck: 0, | 447   _lastCheck: 0, | 
| 421   _errors: 0, | 448   _errors: 0, | 
| 422 | 449 | 
| 423   /** | 450   /** | 
| 424    * Status of the last download (ID of a string) | 451    * Status of the last download (ID of a string) | 
| 425    * @type String | 452    * @type {string} | 
| 426    */ | 453    */ | 
| 427   get downloadStatus() | 454   get downloadStatus() | 
| 428   { | 455   { | 
| 429     return this._downloadStatus; | 456     return this._downloadStatus; | 
| 430   }, | 457   }, | 
| 431   set downloadStatus(value) | 458   set downloadStatus(value) | 
| 432   { | 459   { | 
| 433     let oldValue = this._downloadStatus; | 460     let oldValue = this._downloadStatus; | 
| 434     this._downloadStatus = value; | 461     this._downloadStatus = value; | 
| 435     FilterNotifier.triggerListeners("subscription.downloadStatus", this, value, 
     oldValue); | 462     FilterNotifier.triggerListeners("subscription.downloadStatus", | 
|  | 463                                     this, value, oldValue); | 
| 436     return this._downloadStatus; | 464     return this._downloadStatus; | 
| 437   }, | 465   }, | 
| 438 | 466 | 
| 439   /** | 467   /** | 
| 440    * Time of the last successful download (in seconds since the beginning of the | 468    * Time of the last successful download (in seconds since the beginning of the | 
| 441    * epoch). | 469    * epoch). | 
| 442    */ | 470    */ | 
| 443   lastSuccess: 0, | 471   lastSuccess: 0, | 
| 444 | 472 | 
| 445   /** | 473   /** | 
| 446    * Time when the subscription was considered for an update last time (in secon
     ds | 474    * Time when the subscription was considered for an update last time | 
| 447    * since the beginning of the epoch). This will be used to increase softExpira
     tion | 475    * (in seconds since the beginning of the epoch). This will be used | 
| 448    * if the user doesn't use Adblock Plus for some time. | 476    * to increase softExpiration if the user doesn't use Adblock Plus | 
| 449    * @type Number | 477    * for some time. | 
|  | 478    * @type {number} | 
| 450    */ | 479    */ | 
| 451   get lastCheck() | 480   get lastCheck() | 
| 452   { | 481   { | 
| 453     return this._lastCheck; | 482     return this._lastCheck; | 
| 454   }, | 483   }, | 
| 455   set lastCheck(value) | 484   set lastCheck(value) | 
| 456   { | 485   { | 
| 457     if (value != this._lastCheck) | 486     if (value != this._lastCheck) | 
| 458     { | 487     { | 
| 459       let oldValue = this._lastCheck; | 488       let oldValue = this._lastCheck; | 
| 460       this._lastCheck = value; | 489       this._lastCheck = value; | 
| 461       FilterNotifier.triggerListeners("subscription.lastCheck", this, value, old
     Value); | 490       FilterNotifier.triggerListeners("subscription.lastCheck", | 
|  | 491                                       this, value, oldValue); | 
| 462     } | 492     } | 
| 463     return this._lastCheck; | 493     return this._lastCheck; | 
| 464   }, | 494   }, | 
| 465 | 495 | 
| 466   /** | 496   /** | 
| 467    * Hard expiration time of the filter subscription (in seconds since the begin
     ning of the epoch) | 497    * Hard expiration time of the filter subscription (in seconds since | 
| 468    * @type Number | 498    * the beginning of the epoch) | 
|  | 499    * @type {number} | 
| 469    */ | 500    */ | 
| 470   expires: 0, | 501   expires: 0, | 
| 471 | 502 | 
| 472   /** | 503   /** | 
| 473    * Soft expiration time of the filter subscription (in seconds since the begin
     ning of the epoch) | 504    * Soft expiration time of the filter subscription (in seconds since | 
| 474    * @type Number | 505    * the beginning of the epoch) | 
|  | 506    * @type {number} | 
| 475    */ | 507    */ | 
| 476   softExpiration: 0, | 508   softExpiration: 0, | 
| 477 | 509 | 
| 478   /** | 510   /** | 
| 479    * Number of download failures since last success | 511    * Number of download failures since last success | 
| 480    * @type Number | 512    * @type {number} | 
| 481    */ | 513    */ | 
| 482   get errors() | 514   get errors() | 
| 483   { | 515   { | 
| 484     return this._errors; | 516     return this._errors; | 
| 485   }, | 517   }, | 
| 486   set errors(value) | 518   set errors(value) | 
| 487   { | 519   { | 
| 488     if (value != this._errors) | 520     if (value != this._errors) | 
| 489     { | 521     { | 
| 490       let oldValue = this._errors; | 522       let oldValue = this._errors; | 
| 491       this._errors = value; | 523       this._errors = value; | 
| 492       FilterNotifier.triggerListeners("subscription.errors", this, value, oldVal
     ue); | 524       FilterNotifier.triggerListeners("subscription.errors", this, | 
|  | 525                                       value, oldValue); | 
| 493     } | 526     } | 
| 494     return this._errors; | 527     return this._errors; | 
| 495   }, | 528   }, | 
| 496 | 529 | 
| 497   /** | 530   /** | 
| 498    * Version of the subscription data retrieved on last successful download | 531    * Version of the subscription data retrieved on last successful download | 
| 499    * @type Number | 532    * @type {number} | 
| 500    */ | 533    */ | 
| 501   version: 0, | 534   version: 0, | 
| 502 | 535 | 
| 503   /** | 536   /** | 
| 504    * Minimal Adblock Plus version required for this subscription | 537    * Minimal Adblock Plus version required for this subscription | 
| 505    * @type String | 538    * @type {string} | 
| 506    */ | 539    */ | 
| 507   requiredVersion: null, | 540   requiredVersion: null, | 
| 508 | 541 | 
| 509   /** | 542   /** | 
| 510    * Number indicating how often the object was downloaded. | 543    * Number indicating how often the object was downloaded. | 
| 511    * @type Number | 544    * @type {number} | 
| 512    */ | 545    */ | 
| 513   downloadCount: 0, | 546   downloadCount: 0, | 
| 514 | 547 | 
| 515   /** | 548   /** | 
| 516    * See Subscription.serialize() | 549    * See Subscription.serialize() | 
|  | 550    * @inheritdoc | 
| 517    */ | 551    */ | 
| 518   serialize: function(buffer) | 552   serialize(buffer) | 
| 519   { | 553   { | 
| 520     RegularSubscription.prototype.serialize.call(this, buffer); | 554     RegularSubscription.prototype.serialize.call(this, buffer); | 
| 521     if (this.downloadStatus) | 555     if (this.downloadStatus) | 
| 522       buffer.push("downloadStatus=" + this.downloadStatus); | 556       buffer.push("downloadStatus=" + this.downloadStatus); | 
| 523     if (this.lastSuccess) | 557     if (this.lastSuccess) | 
| 524       buffer.push("lastSuccess=" + this.lastSuccess); | 558       buffer.push("lastSuccess=" + this.lastSuccess); | 
| 525     if (this.lastCheck) | 559     if (this.lastCheck) | 
| 526       buffer.push("lastCheck=" + this.lastCheck); | 560       buffer.push("lastCheck=" + this.lastCheck); | 
| 527     if (this.expires) | 561     if (this.expires) | 
| 528       buffer.push("expires=" + this.expires); | 562       buffer.push("expires=" + this.expires); | 
| 529     if (this.softExpiration) | 563     if (this.softExpiration) | 
| 530       buffer.push("softExpiration=" + this.softExpiration); | 564       buffer.push("softExpiration=" + this.softExpiration); | 
| 531     if (this.errors) | 565     if (this.errors) | 
| 532       buffer.push("errors=" + this.errors); | 566       buffer.push("errors=" + this.errors); | 
| 533     if (this.version) | 567     if (this.version) | 
| 534       buffer.push("version=" + this.version); | 568       buffer.push("version=" + this.version); | 
| 535     if (this.requiredVersion) | 569     if (this.requiredVersion) | 
| 536       buffer.push("requiredVersion=" + this.requiredVersion); | 570       buffer.push("requiredVersion=" + this.requiredVersion); | 
| 537     if (this.downloadCount) | 571     if (this.downloadCount) | 
| 538       buffer.push("downloadCount=" + this.downloadCount); | 572       buffer.push("downloadCount=" + this.downloadCount); | 
| 539   } | 573   } | 
| 540 }); | 574 }); | 
| OLD | NEW | 
|---|