| 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 /** | 18 /** | 
| 19  * @fileOverview Definition of Filter class and its subclasses. | 19  * @fileOverview Definition of Filter class and its subclasses. | 
| 20  */ | 20  */ | 
| 21 | 21 | 
| 22 let {FilterNotifier} = require("filterNotifier"); | 22 let {FilterNotifier} = require("filterNotifier"); | 
|  | 23 let {desc} = require("coreUtils"); | 
| 23 | 24 | 
| 24 /** | 25 /** | 
| 25  * Abstract base class for filters | 26  * Abstract base class for filters | 
| 26  * | 27  * | 
| 27  * @param {String} text   string representation of the filter | 28  * @param {String} text   string representation of the filter | 
| 28  * @constructor | 29  * @constructor | 
| 29  */ | 30  */ | 
| 30 function Filter(text) | 31 function Filter(text) | 
| 31 { | 32 { | 
| 32   this.text = text; | 33   this.text = text; | 
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 203  * @augments Filter | 204  * @augments Filter | 
| 204  */ | 205  */ | 
| 205 function InvalidFilter(text, reason) | 206 function InvalidFilter(text, reason) | 
| 206 { | 207 { | 
| 207   Filter.call(this, text); | 208   Filter.call(this, text); | 
| 208 | 209 | 
| 209   this.reason = reason; | 210   this.reason = reason; | 
| 210 } | 211 } | 
| 211 exports.InvalidFilter = InvalidFilter; | 212 exports.InvalidFilter = InvalidFilter; | 
| 212 | 213 | 
| 213 InvalidFilter.prototype = | 214 InvalidFilter.prototype = Object.create(Filter.prototype, desc({ | 
| 214 { |  | 
| 215   __proto__: Filter.prototype, |  | 
| 216 |  | 
| 217   type: "invalid", | 215   type: "invalid", | 
| 218 | 216 | 
| 219   /** | 217   /** | 
| 220    * Reason why this filter is invalid | 218    * Reason why this filter is invalid | 
| 221    * @type String | 219    * @type String | 
| 222    */ | 220    */ | 
| 223   reason: null, | 221   reason: null, | 
| 224 | 222 | 
| 225   /** | 223   /** | 
| 226    * See Filter.serialize() | 224    * See Filter.serialize() | 
| 227    */ | 225    */ | 
| 228   serialize: function(buffer) {} | 226   serialize: function(buffer) {} | 
| 229 }; | 227 })); | 
| 230 | 228 | 
| 231 /** | 229 /** | 
| 232  * Class for comments | 230  * Class for comments | 
| 233  * @param {String} text see Filter() | 231  * @param {String} text see Filter() | 
| 234  * @constructor | 232  * @constructor | 
| 235  * @augments Filter | 233  * @augments Filter | 
| 236  */ | 234  */ | 
| 237 function CommentFilter(text) | 235 function CommentFilter(text) | 
| 238 { | 236 { | 
| 239   Filter.call(this, text); | 237   Filter.call(this, text); | 
| 240 } | 238 } | 
| 241 exports.CommentFilter = CommentFilter; | 239 exports.CommentFilter = CommentFilter; | 
| 242 | 240 | 
| 243 CommentFilter.prototype = | 241 CommentFilter.prototype = Object.create(Filter.prototype, desc({ | 
| 244 { |  | 
| 245   __proto__: Filter.prototype, |  | 
| 246 |  | 
| 247   type: "comment", | 242   type: "comment", | 
| 248 | 243 | 
| 249   /** | 244   /** | 
| 250    * See Filter.serialize() | 245    * See Filter.serialize() | 
| 251    */ | 246    */ | 
| 252   serialize: function(buffer) {} | 247   serialize: function(buffer) {} | 
| 253 }; | 248 })); | 
| 254 | 249 | 
| 255 /** | 250 /** | 
| 256  * Abstract base class for filters that can get hits | 251  * Abstract base class for filters that can get hits | 
| 257  * @param {String} text see Filter() | 252  * @param {String} text see Filter() | 
| 258  * @param {String} [domains] Domains that the filter is restricted to separated 
      by domainSeparator e.g. "foo.com|bar.com|~baz.com" | 253  * @param {String} [domains] Domains that the filter is restricted to separated 
      by domainSeparator e.g. "foo.com|bar.com|~baz.com" | 
| 259  * @constructor | 254  * @constructor | 
| 260  * @augments Filter | 255  * @augments Filter | 
| 261  */ | 256  */ | 
| 262 function ActiveFilter(text, domains) | 257 function ActiveFilter(text, domains) | 
| 263 { | 258 { | 
| 264   Filter.call(this, text); | 259   Filter.call(this, text); | 
| 265 | 260 | 
| 266   this.domainSource = domains; | 261   this.domainSource = domains; | 
| 267 } | 262 } | 
| 268 exports.ActiveFilter = ActiveFilter; | 263 exports.ActiveFilter = ActiveFilter; | 
| 269 | 264 | 
| 270 ActiveFilter.prototype = | 265 ActiveFilter.prototype = Object.create(Filter.prototype, desc({ | 
| 271 { |  | 
| 272   __proto__: Filter.prototype, |  | 
| 273 |  | 
| 274   _disabled: false, | 266   _disabled: false, | 
| 275   _hitCount: 0, | 267   _hitCount: 0, | 
| 276   _lastHit: 0, | 268   _lastHit: 0, | 
| 277 | 269 | 
| 278   /** | 270   /** | 
| 279    * Defines whether the filter is disabled | 271    * Defines whether the filter is disabled | 
| 280    * @type Boolean | 272    * @type Boolean | 
| 281    */ | 273    */ | 
| 282   get disabled() | 274   disabled: { | 
| 283   { | 275     get: function() | 
| 284     return this._disabled; |  | 
| 285   }, |  | 
| 286   set disabled(value) |  | 
| 287   { |  | 
| 288     if (value != this._disabled) |  | 
| 289     { | 276     { | 
| 290       let oldValue = this._disabled; | 277       return this._disabled; | 
| 291       this._disabled = value; | 278     }, | 
| 292       FilterNotifier.triggerListeners("filter.disabled", this, value, oldValue); | 279     set: function(value) | 
|  | 280     { | 
|  | 281       if (value != this._disabled) | 
|  | 282       { | 
|  | 283         let oldValue = this._disabled; | 
|  | 284         this._disabled = value; | 
|  | 285         FilterNotifier.triggerListeners("filter.disabled", this, | 
|  | 286         value, oldValue); | 
|  | 287       } | 
|  | 288       return this._disabled; | 
| 293     } | 289     } | 
| 294     return this._disabled; |  | 
| 295   }, | 290   }, | 
| 296 | 291 | 
| 297   /** | 292   /** | 
| 298    * Number of hits on the filter since the last reset | 293    * Number of hits on the filter since the last reset | 
| 299    * @type Number | 294    * @type Number | 
| 300    */ | 295    */ | 
| 301   get hitCount() | 296   hitCount: { | 
| 302   { | 297     get: function() | 
| 303     return this._hitCount; |  | 
| 304   }, |  | 
| 305   set hitCount(value) |  | 
| 306   { |  | 
| 307     if (value != this._hitCount) |  | 
| 308     { | 298     { | 
| 309       let oldValue = this._hitCount; | 299       return this._hitCount; | 
| 310       this._hitCount = value; | 300     }, | 
| 311       FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); | 301     set: function(value) | 
|  | 302     { | 
|  | 303       if (value != this._hitCount) | 
|  | 304       { | 
|  | 305         let oldValue = this._hitCount; | 
|  | 306         this._hitCount = value; | 
|  | 307         FilterNotifier.triggerListeners("filter.hitCount", this, | 
|  | 308         value, oldValue); | 
|  | 309       } | 
|  | 310       return this._hitCount; | 
| 312     } | 311     } | 
| 313     return this._hitCount; |  | 
| 314   }, | 312   }, | 
| 315 | 313 | 
| 316   /** | 314   /** | 
| 317    * Last time the filter had a hit (in milliseconds since the beginning of the 
      epoch) | 315    * Last time the filter had a hit (in milliseconds since the beginning of the 
      epoch) | 
| 318    * @type Number | 316    * @type Number | 
| 319    */ | 317    */ | 
| 320   get lastHit() | 318   lastHit: { | 
| 321   { | 319     get: function() | 
| 322     return this._lastHit; |  | 
| 323   }, |  | 
| 324   set lastHit(value) |  | 
| 325   { |  | 
| 326     if (value != this._lastHit) |  | 
| 327     { | 320     { | 
| 328       let oldValue = this._lastHit; | 321       return this._lastHit; | 
| 329       this._lastHit = value; | 322     }, | 
| 330       FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue); | 323     set: function(value) | 
|  | 324     { | 
|  | 325       if (value != this._lastHit) | 
|  | 326       { | 
|  | 327         let oldValue = this._lastHit; | 
|  | 328         this._lastHit = value; | 
|  | 329         FilterNotifier.triggerListeners("filter.lastHit", this, | 
|  | 330         value, oldValue); | 
|  | 331       } | 
|  | 332       return this._lastHit; | 
| 331     } | 333     } | 
| 332     return this._lastHit; |  | 
| 333   }, | 334   }, | 
| 334 | 335 | 
| 335   /** | 336   /** | 
| 336    * String that the domains property should be generated from | 337    * String that the domains property should be generated from | 
| 337    * @type String | 338    * @type String | 
| 338    */ | 339    */ | 
| 339   domainSource: null, | 340   domainSource: null, | 
| 340 | 341 | 
| 341   /** | 342   /** | 
| 342    * Separator character used in domainSource property, must be overridden by su
      bclasses | 343    * Separator character used in domainSource property, must be overridden by su
      bclasses | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 355    * Determines whether domainSource is already upper-case, | 356    * Determines whether domainSource is already upper-case, | 
| 356    * can be overridden by subclasses. | 357    * can be overridden by subclasses. | 
| 357    * @type Boolean | 358    * @type Boolean | 
| 358    */ | 359    */ | 
| 359   domainSourceIsUpperCase: false, | 360   domainSourceIsUpperCase: false, | 
| 360 | 361 | 
| 361   /** | 362   /** | 
| 362    * Map containing domains that this filter should match on/not match on or nul
      l if the filter should match on all domains | 363    * Map containing domains that this filter should match on/not match on or nul
      l if the filter should match on all domains | 
| 363    * @type Object | 364    * @type Object | 
| 364    */ | 365    */ | 
| 365   get domains() | 366   domains: { | 
| 366   { | 367     get: function() | 
| 367     // Despite this property being cached, the getter is called | 368     { | 
| 368     // several times on Safari, due to WebKit bug 132872 | 369       // Despite this property being cached, the getter is called | 
| 369     let prop = Object.getOwnPropertyDescriptor(this, "domains"); | 370       // several times on Safari, due to WebKit bug 132872 | 
| 370     if (prop) | 371       let prop = Object.getOwnPropertyDescriptor(this, "domains"); | 
| 371       return prop.value; | 372       if (prop) | 
|  | 373         return prop.value; | 
| 372 | 374 | 
| 373     let domains = null; | 375       let domains = null; | 
| 374 | 376 | 
| 375     if (this.domainSource) | 377       if (this.domainSource) | 
| 376     { |  | 
| 377       let source = this.domainSource; |  | 
| 378       if (!this.domainSourceIsUpperCase) { |  | 
| 379         // RegExpFilter already have uppercase domains |  | 
| 380         source = source.toUpperCase(); |  | 
| 381       } |  | 
| 382       let list = source.split(this.domainSeparator); |  | 
| 383       if (list.length == 1 && list[0][0] != "~") |  | 
| 384       { | 378       { | 
| 385         // Fast track for the common one-domain scenario | 379         let source = this.domainSource; | 
| 386         domains = Object.create(null); | 380         if (!this.domainSourceIsUpperCase) { | 
| 387         domains[""] = false; | 381           // RegExpFilter already have uppercase domains | 
| 388         if (this.ignoreTrailingDot) | 382           source = source.toUpperCase(); | 
| 389           list[0] = list[0].replace(/\.+$/, ""); | 383         } | 
| 390         domains[list[0]] = true; | 384         let list = source.split(this.domainSeparator); | 
| 391       } | 385         if (list.length == 1 && list[0][0] != "~") | 
| 392       else |  | 
| 393       { |  | 
| 394         let hasIncludes = false; |  | 
| 395         for (let i = 0; i < list.length; i++) |  | 
| 396         { | 386         { | 
| 397           let domain = list[i]; | 387           // Fast track for the common one-domain scenario | 
|  | 388           domains = Object.create(null); | 
|  | 389           domains[""] = false; | 
| 398           if (this.ignoreTrailingDot) | 390           if (this.ignoreTrailingDot) | 
| 399             domain = domain.replace(/\.+$/, ""); | 391             list[0] = list[0].replace(/\.+$/, ""); | 
| 400           if (domain == "") | 392           domains[list[0]] = true; | 
| 401             continue; | 393         } | 
|  | 394         else | 
|  | 395         { | 
|  | 396           let hasIncludes = false; | 
|  | 397           for (let i = 0; i < list.length; i++) | 
|  | 398           { | 
|  | 399             let domain = list[i]; | 
|  | 400             if (this.ignoreTrailingDot) | 
|  | 401               domain = domain.replace(/\.+$/, ""); | 
|  | 402             if (domain == "") | 
|  | 403               continue; | 
| 402 | 404 | 
| 403           let include; | 405             let include; | 
| 404           if (domain[0] == "~") | 406             if (domain[0] == "~") | 
| 405           { | 407             { | 
| 406             include = false; | 408               include = false; | 
| 407             domain = domain.substr(1); | 409               domain = domain.substr(1); | 
|  | 410             } | 
|  | 411             else | 
|  | 412             { | 
|  | 413               include = true; | 
|  | 414               hasIncludes = true; | 
|  | 415             } | 
|  | 416 | 
|  | 417             if (!domains) | 
|  | 418               domains = Object.create(null); | 
|  | 419 | 
|  | 420             domains[domain] = include; | 
| 408           } | 421           } | 
| 409           else | 422           domains[""] = !hasIncludes; | 
| 410           { | 423         } | 
| 411             include = true; |  | 
| 412             hasIncludes = true; |  | 
| 413           } |  | 
| 414 | 424 | 
| 415           if (!domains) | 425         this.domainSource = null; | 
| 416             domains = Object.create(null); |  | 
| 417 |  | 
| 418           domains[domain] = include; |  | 
| 419         } |  | 
| 420         domains[""] = !hasIncludes; |  | 
| 421       } | 426       } | 
| 422 | 427 | 
| 423       this.domainSource = null; | 428       Object.defineProperty(this, "domains", {value: domains, enumerable: true})
      ; | 
|  | 429       return this.domains; | 
| 424     } | 430     } | 
| 425 |  | 
| 426     Object.defineProperty(this, "domains", {value: domains, enumerable: true}); |  | 
| 427     return this.domains; |  | 
| 428   }, | 431   }, | 
| 429 | 432 | 
| 430   /** | 433   /** | 
| 431    * Array containing public keys of websites that this filter should apply to | 434    * Array containing public keys of websites that this filter should apply to | 
| 432    * @type string[] | 435    * @type string[] | 
| 433    */ | 436    */ | 
| 434   sitekeys: null, | 437   sitekeys: null, | 
| 435 | 438 | 
| 436   /** | 439   /** | 
| 437    * Checks whether this filter is active on a domain. | 440    * Checks whether this filter is active on a domain. | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 508     { | 511     { | 
| 509       Filter.prototype.serialize.call(this, buffer); | 512       Filter.prototype.serialize.call(this, buffer); | 
| 510       if (this._disabled) | 513       if (this._disabled) | 
| 511         buffer.push("disabled=true"); | 514         buffer.push("disabled=true"); | 
| 512       if (this._hitCount) | 515       if (this._hitCount) | 
| 513         buffer.push("hitCount=" + this._hitCount); | 516         buffer.push("hitCount=" + this._hitCount); | 
| 514       if (this._lastHit) | 517       if (this._lastHit) | 
| 515         buffer.push("lastHit=" + this._lastHit); | 518         buffer.push("lastHit=" + this._lastHit); | 
| 516     } | 519     } | 
| 517   } | 520   } | 
| 518 }; | 521 })); | 
| 519 | 522 | 
| 520 /** | 523 /** | 
| 521  * Abstract base class for RegExp-based filters | 524  * Abstract base class for RegExp-based filters | 
| 522  * @param {String} text see Filter() | 525  * @param {String} text see Filter() | 
| 523  * @param {String} regexpSource filter part that the regular expression should b
      e build from | 526  * @param {String} regexpSource filter part that the regular expression should b
      e build from | 
| 524  * @param {Number} [contentType] Content types the filter applies to, combinatio
      n of values from RegExpFilter.typeMap | 527  * @param {Number} [contentType] Content types the filter applies to, combinatio
      n of values from RegExpFilter.typeMap | 
| 525  * @param {Boolean} [matchCase] Defines whether the filter should distinguish be
      tween lower and upper case letters | 528  * @param {Boolean} [matchCase] Defines whether the filter should distinguish be
      tween lower and upper case letters | 
| 526  * @param {String} [domains] Domains that the filter is restricted to, e.g. "foo
      .com|bar.com|~baz.com" | 529  * @param {String} [domains] Domains that the filter is restricted to, e.g. "foo
      .com|bar.com|~baz.com" | 
| 527  * @param {Boolean} [thirdParty] Defines whether the filter should apply to thir
      d-party or first-party content only | 530  * @param {Boolean} [thirdParty] Defines whether the filter should apply to thir
      d-party or first-party content only | 
| 528  * @param {String} [sitekeys] Public keys of websites that this filter should ap
      ply to | 531  * @param {String} [sitekeys] Public keys of websites that this filter should ap
      ply to | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 549     Object.defineProperty(this, "regexp", {value: regexp}); | 552     Object.defineProperty(this, "regexp", {value: regexp}); | 
| 550   } | 553   } | 
| 551   else | 554   else | 
| 552   { | 555   { | 
| 553     // No need to convert this filter to regular expression yet, do it on demand | 556     // No need to convert this filter to regular expression yet, do it on demand | 
| 554     this.regexpSource = regexpSource; | 557     this.regexpSource = regexpSource; | 
| 555   } | 558   } | 
| 556 } | 559 } | 
| 557 exports.RegExpFilter = RegExpFilter; | 560 exports.RegExpFilter = RegExpFilter; | 
| 558 | 561 | 
| 559 RegExpFilter.prototype = | 562 RegExpFilter.prototype = Object.create(ActiveFilter.prototype, desc({ | 
| 560 { |  | 
| 561   __proto__: ActiveFilter.prototype, |  | 
| 562 |  | 
| 563   /** | 563   /** | 
| 564    * @see ActiveFilter.domainSourceIsUpperCase | 564    * @see ActiveFilter.domainSourceIsUpperCase | 
| 565    */ | 565    */ | 
| 566   domainSourceIsUpperCase: true, | 566   domainSourceIsUpperCase: true, | 
| 567 | 567 | 
| 568   /** | 568   /** | 
| 569    * Number of filters contained, will always be 1 (required to optimize Matcher
      ). | 569    * Number of filters contained, will always be 1 (required to optimize Matcher
      ). | 
| 570    * @type Integer | 570    * @type Integer | 
| 571    */ | 571    */ | 
| 572   length: 1, | 572   length: 1, | 
| 573 | 573 | 
| 574   /** | 574   /** | 
| 575    * @see ActiveFilter.domainSeparator | 575    * @see ActiveFilter.domainSeparator | 
| 576    */ | 576    */ | 
| 577   domainSeparator: "|", | 577   domainSeparator: "|", | 
| 578 | 578 | 
| 579   /** | 579   /** | 
| 580    * Expression from which a regular expression should be generated - for delaye
      d creation of the regexp property | 580    * Expression from which a regular expression should be generated - for delaye
      d creation of the regexp property | 
| 581    * @type String | 581    * @type String | 
| 582    */ | 582    */ | 
| 583   regexpSource: null, | 583   regexpSource: null, | 
| 584   /** | 584   /** | 
| 585    * Regular expression to be used when testing against this filter | 585    * Regular expression to be used when testing against this filter | 
| 586    * @type RegExp | 586    * @type RegExp | 
| 587    */ | 587    */ | 
| 588   get regexp() | 588   regexp: { | 
| 589   { | 589     get: function() | 
| 590     // Despite this property being cached, the getter is called | 590     { | 
| 591     // several times on Safari, due to WebKit bug 132872 | 591       // Despite this property being cached, the getter is called | 
| 592     let prop = Object.getOwnPropertyDescriptor(this, "regexp"); | 592       // several times on Safari, due to WebKit bug 132872 | 
| 593     if (prop) | 593       let prop = Object.getOwnPropertyDescriptor(this, "regexp"); | 
| 594       return prop.value; | 594       if (prop) | 
|  | 595         return prop.value; | 
| 595 | 596 | 
| 596     let source = Filter.toRegExp(this.regexpSource); | 597       let source = Filter.toRegExp(this.regexpSource); | 
| 597     let regexp = new RegExp(source, this.matchCase ? "" : "i"); | 598       let regexp = new RegExp(source, this.matchCase ? "" : "i"); | 
| 598     Object.defineProperty(this, "regexp", {value: regexp}); | 599       Object.defineProperty(this, "regexp", {value: regexp}); | 
| 599     return regexp; | 600       return regexp; | 
|  | 601     } | 
| 600   }, | 602   }, | 
|  | 603 | 
| 601   /** | 604   /** | 
| 602    * Content types the filter applies to, combination of values from RegExpFilte
      r.typeMap | 605    * Content types the filter applies to, combination of values from RegExpFilte
      r.typeMap | 
| 603    * @type Number | 606    * @type Number | 
| 604    */ | 607    */ | 
| 605   contentType: 0x7FFFFFFF, | 608   contentType: 0x7FFFFFFF, | 
| 606   /** | 609   /** | 
| 607    * Defines whether the filter should distinguish between lower and upper case 
      letters | 610    * Defines whether the filter should distinguish between lower and upper case 
      letters | 
| 608    * @type Boolean | 611    * @type Boolean | 
| 609    */ | 612    */ | 
| 610   matchCase: false, | 613   matchCase: false, | 
| 611   /** | 614   /** | 
| 612    * Defines whether the filter should apply to third-party or first-party conte
      nt only. Can be null (apply to all content). | 615    * Defines whether the filter should apply to third-party or first-party conte
      nt only. Can be null (apply to all content). | 
| 613    * @type Boolean | 616    * @type Boolean | 
| 614    */ | 617    */ | 
| 615   thirdParty: null, | 618   thirdParty: null, | 
| 616 | 619 | 
| 617   /** | 620   /** | 
| 618    * String that the sitekey property should be generated from | 621    * String that the sitekey property should be generated from | 
| 619    * @type String | 622    * @type String | 
| 620    */ | 623    */ | 
| 621   sitekeySource: null, | 624   sitekeySource: null, | 
| 622 | 625 | 
| 623   /** | 626   /** | 
| 624    * Array containing public keys of websites that this filter should apply to | 627    * Array containing public keys of websites that this filter should apply to | 
| 625    * @type string[] | 628    * @type string[] | 
| 626    */ | 629    */ | 
| 627   get sitekeys() | 630   sitekeys: { | 
| 628   { | 631     get: function() | 
| 629     // Despite this property being cached, the getter is called | 632     { | 
| 630     // several times on Safari, due to WebKit bug 132872 | 633       // Despite this property being cached, the getter is called | 
| 631     let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | 634       // several times on Safari, due to WebKit bug 132872 | 
| 632     if (prop) | 635       let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | 
| 633       return prop.value; | 636       if (prop) | 
|  | 637         return prop.value; | 
| 634 | 638 | 
| 635     let sitekeys = null; | 639       let sitekeys = null; | 
| 636 | 640 | 
| 637     if (this.sitekeySource) | 641       if (this.sitekeySource) | 
| 638     { | 642       { | 
| 639       sitekeys = this.sitekeySource.split("|"); | 643         sitekeys = this.sitekeySource.split("|"); | 
| 640       this.sitekeySource = null; | 644         this.sitekeySource = null; | 
|  | 645       } | 
|  | 646 | 
|  | 647       Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true
      }); | 
|  | 648       return this.sitekeys; | 
| 641     } | 649     } | 
| 642 |  | 
| 643     Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true})
      ; |  | 
| 644     return this.sitekeys; |  | 
| 645   }, | 650   }, | 
| 646 | 651 | 
| 647   /** | 652   /** | 
| 648    * Tests whether the URL matches this filter | 653    * Tests whether the URL matches this filter | 
| 649    * @param {String} location URL to be tested | 654    * @param {String} location URL to be tested | 
| 650    * @param {number} typeMask bitmask of content / request types to match | 655    * @param {number} typeMask bitmask of content / request types to match | 
| 651    * @param {String} docDomain domain name of the document that loads the URL | 656    * @param {String} docDomain domain name of the document that loads the URL | 
| 652    * @param {Boolean} thirdParty should be true if the URL is a third-party requ
      est | 657    * @param {Boolean} thirdParty should be true if the URL is a third-party requ
      est | 
| 653    * @param {String} sitekey public key provided by the document | 658    * @param {String} sitekey public key provided by the document | 
| 654    * @return {Boolean} true in case of a match | 659    * @return {Boolean} true in case of a match | 
| 655    */ | 660    */ | 
| 656   matches: function(location, typeMask, docDomain, thirdParty, sitekey) | 661   matches: function(location, typeMask, docDomain, thirdParty, sitekey) | 
| 657   { | 662   { | 
| 658     if (this.contentType & typeMask && | 663     if (this.contentType & typeMask && | 
| 659         (this.thirdParty == null || this.thirdParty == thirdParty) && | 664         (this.thirdParty == null || this.thirdParty == thirdParty) && | 
| 660         this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 665         this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 
| 661     { | 666     { | 
| 662       return true; | 667       return true; | 
| 663     } | 668     } | 
| 664 | 669 | 
| 665     return false; | 670     return false; | 
|  | 671   }, | 
|  | 672 | 
|  | 673   // Required to optimize Matcher, see also RegExpFilter.prototype.length | 
|  | 674   0: { | 
|  | 675     get: function() { return this; } | 
| 666   } | 676   } | 
| 667 }; | 677 })); | 
| 668 |  | 
| 669 // Required to optimize Matcher, see also RegExpFilter.prototype.length |  | 
| 670 Object.defineProperty(RegExpFilter.prototype, "0", |  | 
| 671 { |  | 
| 672   get: function() { return this; } |  | 
| 673 }); |  | 
| 674 | 678 | 
| 675 /** | 679 /** | 
| 676  * Creates a RegExp filter from its text representation | 680  * Creates a RegExp filter from its text representation | 
| 677  * @param {String} text   same as in Filter() | 681  * @param {String} text   same as in Filter() | 
| 678  */ | 682  */ | 
| 679 RegExpFilter.fromText = function(text) | 683 RegExpFilter.fromText = function(text) | 
| 680 { | 684 { | 
| 681   let blocking = true; | 685   let blocking = true; | 
| 682   let origText = text; | 686   let origText = text; | 
| 683   if (text.indexOf("@@") == 0) | 687   if (text.indexOf("@@") == 0) | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 803  * @augments RegExpFilter | 807  * @augments RegExpFilter | 
| 804  */ | 808  */ | 
| 805 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thi
      rdParty, sitekeys, collapse) | 809 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thi
      rdParty, sitekeys, collapse) | 
| 806 { | 810 { | 
| 807   RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
      hirdParty, sitekeys); | 811   RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
      hirdParty, sitekeys); | 
| 808 | 812 | 
| 809   this.collapse = collapse; | 813   this.collapse = collapse; | 
| 810 } | 814 } | 
| 811 exports.BlockingFilter = BlockingFilter; | 815 exports.BlockingFilter = BlockingFilter; | 
| 812 | 816 | 
| 813 BlockingFilter.prototype = | 817 BlockingFilter.prototype = Object.create(RegExpFilter.prototype, desc({ | 
| 814 { |  | 
| 815   __proto__: RegExpFilter.prototype, |  | 
| 816 |  | 
| 817   type: "blocking", | 818   type: "blocking", | 
| 818 | 819 | 
| 819   /** | 820   /** | 
| 820    * Defines whether the filter should collapse blocked content. Can be null (us
      e the global preference). | 821    * Defines whether the filter should collapse blocked content. Can be null (us
      e the global preference). | 
| 821    * @type Boolean | 822    * @type Boolean | 
| 822    */ | 823    */ | 
| 823   collapse: null | 824   collapse: null | 
| 824 }; | 825 })); | 
| 825 | 826 | 
| 826 /** | 827 /** | 
| 827  * Class for whitelist filters | 828  * Class for whitelist filters | 
| 828  * @param {String} text see Filter() | 829  * @param {String} text see Filter() | 
| 829  * @param {String} regexpSource see RegExpFilter() | 830  * @param {String} regexpSource see RegExpFilter() | 
| 830  * @param {Number} contentType see RegExpFilter() | 831  * @param {Number} contentType see RegExpFilter() | 
| 831  * @param {Boolean} matchCase see RegExpFilter() | 832  * @param {Boolean} matchCase see RegExpFilter() | 
| 832  * @param {String} domains see RegExpFilter() | 833  * @param {String} domains see RegExpFilter() | 
| 833  * @param {Boolean} thirdParty see RegExpFilter() | 834  * @param {Boolean} thirdParty see RegExpFilter() | 
| 834  * @param {String} sitekeys see RegExpFilter() | 835  * @param {String} sitekeys see RegExpFilter() | 
| 835  * @constructor | 836  * @constructor | 
| 836  * @augments RegExpFilter | 837  * @augments RegExpFilter | 
| 837  */ | 838  */ | 
| 838 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, th
      irdParty, sitekeys) | 839 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, th
      irdParty, sitekeys) | 
| 839 { | 840 { | 
| 840   RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
      hirdParty, sitekeys); | 841   RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
      hirdParty, sitekeys); | 
| 841 } | 842 } | 
| 842 exports.WhitelistFilter = WhitelistFilter; | 843 exports.WhitelistFilter = WhitelistFilter; | 
| 843 | 844 | 
| 844 WhitelistFilter.prototype = | 845 WhitelistFilter.prototype = Object.create(RegExpFilter.prototype, desc({ | 
| 845 { |  | 
| 846   __proto__: RegExpFilter.prototype, |  | 
| 847 |  | 
| 848   type: "whitelist" | 846   type: "whitelist" | 
| 849 }; | 847 })); | 
| 850 | 848 | 
| 851 /** | 849 /** | 
| 852  * Base class for element hiding filters | 850  * Base class for element hiding filters | 
| 853  * @param {String} text see Filter() | 851  * @param {String} text see Filter() | 
| 854  * @param {String} [domains] Host names or domains the filter should be restrict
      ed to | 852  * @param {String} [domains] Host names or domains the filter should be restrict
      ed to | 
| 855  * @param {String} selector   CSS selector for the HTML elements that should be 
      hidden | 853  * @param {String} selector   CSS selector for the HTML elements that should be 
      hidden | 
| 856  * @constructor | 854  * @constructor | 
| 857  * @augments ActiveFilter | 855  * @augments ActiveFilter | 
| 858  */ | 856  */ | 
| 859 function ElemHideBase(text, domains, selector) | 857 function ElemHideBase(text, domains, selector) | 
| 860 { | 858 { | 
| 861   ActiveFilter.call(this, text, domains || null); | 859   ActiveFilter.call(this, text, domains || null); | 
| 862 | 860 | 
| 863   if (domains) | 861   if (domains) | 
| 864     this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "
      ").toLowerCase(); | 862     this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "
      ").toLowerCase(); | 
| 865   this.selector = selector; | 863   this.selector = selector; | 
| 866 } | 864 } | 
| 867 exports.ElemHideBase = ElemHideBase; | 865 exports.ElemHideBase = ElemHideBase; | 
| 868 | 866 | 
| 869 ElemHideBase.prototype = | 867 ElemHideBase.prototype = Object.create(ActiveFilter.prototype, desc({ | 
| 870 { |  | 
| 871   __proto__: ActiveFilter.prototype, |  | 
| 872 |  | 
| 873   /** | 868   /** | 
| 874    * @see ActiveFilter.domainSeparator | 869    * @see ActiveFilter.domainSeparator | 
| 875    */ | 870    */ | 
| 876   domainSeparator: ",", | 871   domainSeparator: ",", | 
| 877 | 872 | 
| 878   /** | 873   /** | 
| 879    * @see ActiveFilter.ignoreTrailingDot | 874    * @see ActiveFilter.ignoreTrailingDot | 
| 880    */ | 875    */ | 
| 881   ignoreTrailingDot: false, | 876   ignoreTrailingDot: false, | 
| 882 | 877 | 
| 883   /** | 878   /** | 
| 884    * Host name or domain the filter should be restricted to (can be null for no 
      restriction) | 879    * Host name or domain the filter should be restricted to (can be null for no 
      restriction) | 
| 885    * @type String | 880    * @type String | 
| 886    */ | 881    */ | 
| 887   selectorDomain: null, | 882   selectorDomain: null, | 
| 888   /** | 883   /** | 
| 889    * CSS selector for the HTML elements that should be hidden | 884    * CSS selector for the HTML elements that should be hidden | 
| 890    * @type String | 885    * @type String | 
| 891    */ | 886    */ | 
| 892   selector: null | 887   selector: null | 
| 893 }; | 888 })); | 
| 894 | 889 | 
| 895 /** | 890 /** | 
| 896  * Creates an element hiding filter from a pre-parsed text representation | 891  * Creates an element hiding filter from a pre-parsed text representation | 
| 897  * | 892  * | 
| 898  * @param {String} text         same as in Filter() | 893  * @param {String} text         same as in Filter() | 
| 899  * @param {String} domain       domain part of the text representation (can be e
      mpty) | 894  * @param {String} domain       domain part of the text representation (can be e
      mpty) | 
| 900  * @param {Boolean} isException exception rule indicator | 895  * @param {Boolean} isException exception rule indicator | 
| 901  * @param {String} tagName      tag name part (can be empty) | 896  * @param {String} tagName      tag name part (can be empty) | 
| 902  * @param {String} attrRules    attribute matching rules (can be empty) | 897  * @param {String} attrRules    attribute matching rules (can be empty) | 
| 903  * @param {String} selector     raw CSS selector (can be empty) | 898  * @param {String} selector     raw CSS selector (can be empty) | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 968  * @param {String} selector see ElemHideBase() | 963  * @param {String} selector see ElemHideBase() | 
| 969  * @constructor | 964  * @constructor | 
| 970  * @augments ElemHideBase | 965  * @augments ElemHideBase | 
| 971  */ | 966  */ | 
| 972 function ElemHideFilter(text, domains, selector) | 967 function ElemHideFilter(text, domains, selector) | 
| 973 { | 968 { | 
| 974   ElemHideBase.call(this, text, domains, selector); | 969   ElemHideBase.call(this, text, domains, selector); | 
| 975 } | 970 } | 
| 976 exports.ElemHideFilter = ElemHideFilter; | 971 exports.ElemHideFilter = ElemHideFilter; | 
| 977 | 972 | 
| 978 ElemHideFilter.prototype = | 973 ElemHideFilter.prototype = Object.create(ElemHideBase.prototype, desc({ | 
| 979 { |  | 
| 980   __proto__: ElemHideBase.prototype, |  | 
| 981 |  | 
| 982   type: "elemhide" | 974   type: "elemhide" | 
| 983 }; | 975 })); | 
| 984 | 976 | 
| 985 /** | 977 /** | 
| 986  * Class for element hiding exceptions | 978  * Class for element hiding exceptions | 
| 987  * @param {String} text see Filter() | 979  * @param {String} text see Filter() | 
| 988  * @param {String} domains  see ElemHideBase() | 980  * @param {String} domains  see ElemHideBase() | 
| 989  * @param {String} selector see ElemHideBase() | 981  * @param {String} selector see ElemHideBase() | 
| 990  * @constructor | 982  * @constructor | 
| 991  * @augments ElemHideBase | 983  * @augments ElemHideBase | 
| 992  */ | 984  */ | 
| 993 function ElemHideException(text, domains, selector) | 985 function ElemHideException(text, domains, selector) | 
| 994 { | 986 { | 
| 995   ElemHideBase.call(this, text, domains, selector); | 987   ElemHideBase.call(this, text, domains, selector); | 
| 996 } | 988 } | 
| 997 exports.ElemHideException = ElemHideException; | 989 exports.ElemHideException = ElemHideException; | 
| 998 | 990 | 
| 999 ElemHideException.prototype = | 991 ElemHideException.prototype = Object.create(ElemHideBase.prototype, desc({ | 
| 1000 { |  | 
| 1001   __proto__: ElemHideBase.prototype, |  | 
| 1002 |  | 
| 1003   type: "elemhideexception" | 992   type: "elemhideexception" | 
| 1004 }; | 993 })); | 
| 1005 | 994 | 
| 1006 /** | 995 /** | 
| 1007  * Class for CSS property filters | 996  * Class for CSS property filters | 
| 1008  * @param {String} text           see Filter() | 997  * @param {String} text           see Filter() | 
| 1009  * @param {String} domains        see ElemHideBase() | 998  * @param {String} domains        see ElemHideBase() | 
| 1010  * @param {String} selector       see ElemHideBase() | 999  * @param {String} selector       see ElemHideBase() | 
| 1011  * @param {String} regexpSource   see CSSPropertyFilter.regexpSource | 1000  * @param {String} regexpSource   see CSSPropertyFilter.regexpSource | 
| 1012  * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix | 1001  * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix | 
| 1013  * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix | 1002  * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix | 
| 1014  * @constructor | 1003  * @constructor | 
| 1015  * @augments ElemHideBase | 1004  * @augments ElemHideBase | 
| 1016  */ | 1005  */ | 
| 1017 function CSSPropertyFilter(text, domains, selector, regexpSource, | 1006 function CSSPropertyFilter(text, domains, selector, regexpSource, | 
| 1018   selectorPrefix, selectorSuffix) | 1007   selectorPrefix, selectorSuffix) | 
| 1019 { | 1008 { | 
| 1020   ElemHideBase.call(this, text, domains, selector); | 1009   ElemHideBase.call(this, text, domains, selector); | 
| 1021 | 1010 | 
| 1022   this.regexpSource = regexpSource; | 1011   this.regexpSource = regexpSource; | 
| 1023   this.selectorPrefix = selectorPrefix; | 1012   this.selectorPrefix = selectorPrefix; | 
| 1024   this.selectorSuffix = selectorSuffix; | 1013   this.selectorSuffix = selectorSuffix; | 
| 1025 } | 1014 } | 
| 1026 exports.CSSPropertyFilter = CSSPropertyFilter; | 1015 exports.CSSPropertyFilter = CSSPropertyFilter; | 
| 1027 | 1016 | 
| 1028 CSSPropertyFilter.prototype = | 1017 CSSPropertyFilter.prototype = Object.create(ElemHideBase.prototype, desc({ | 
| 1029 { |  | 
| 1030   __proto__: ElemHideBase.prototype, |  | 
| 1031 |  | 
| 1032   type: "cssproperty", | 1018   type: "cssproperty", | 
| 1033 | 1019 | 
| 1034   /** | 1020   /** | 
| 1035    * Expression from which a regular expression should be generated for matching | 1021    * Expression from which a regular expression should be generated for matching | 
| 1036    * CSS properties - for delayed creation of the regexpString property | 1022    * CSS properties - for delayed creation of the regexpString property | 
| 1037    * @type String | 1023    * @type String | 
| 1038    */ | 1024    */ | 
| 1039   regexpSource: null, | 1025   regexpSource: null, | 
| 1040   /** | 1026   /** | 
| 1041    * Substring of CSS selector before properties for the HTML elements that | 1027    * Substring of CSS selector before properties for the HTML elements that | 
| 1042    * should be hidden | 1028    * should be hidden | 
| 1043    * @type String | 1029    * @type String | 
| 1044    */ | 1030    */ | 
| 1045   selectorPrefix: null, | 1031   selectorPrefix: null, | 
| 1046   /** | 1032   /** | 
| 1047    * Substring of CSS selector after properties for the HTML elements that | 1033    * Substring of CSS selector after properties for the HTML elements that | 
| 1048    * should be hidden | 1034    * should be hidden | 
| 1049    * @type String | 1035    * @type String | 
| 1050    */ | 1036    */ | 
| 1051   selectorSuffix: null, | 1037   selectorSuffix: null, | 
| 1052 | 1038 | 
| 1053   /** | 1039   /** | 
| 1054    * Raw regular expression string to be used when testing CSS properties | 1040    * Raw regular expression string to be used when testing CSS properties | 
| 1055    * against this filter | 1041    * against this filter | 
| 1056    * @type String | 1042    * @type String | 
| 1057    */ | 1043    */ | 
| 1058   get regexpString() | 1044   regexpString: { | 
| 1059   { | 1045     get: function() | 
| 1060     // Despite this property being cached, the getter is called | 1046     { | 
| 1061     // several times on Safari, due to WebKit bug 132872 | 1047       // Despite this property being cached, the getter is called | 
| 1062     let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); | 1048       // several times on Safari, due to WebKit bug 132872 | 
| 1063     if (prop) | 1049       let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); | 
| 1064       return prop.value; | 1050       if (prop) | 
|  | 1051         return prop.value; | 
| 1065 | 1052 | 
| 1066     let regexp = Filter.toRegExp(this.regexpSource); | 1053       let regexp = Filter.toRegExp(this.regexpSource); | 
| 1067     Object.defineProperty(this, "regexpString", {value: regexp}); | 1054       Object.defineProperty(this, "regexpString", {value: regexp}); | 
| 1068     return regexp; | 1055       return regexp; | 
|  | 1056     } | 
| 1069   } | 1057   } | 
| 1070 }; | 1058 })); | 
| OLD | NEW | 
|---|