| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 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"; | 18 "use strict"; |
| 19 | 19 |
| 20 /** | 20 /** |
| 21 * @fileOverview Definition of Filter class and its subclasses. | 21 * @fileOverview Definition of Filter class and its subclasses. |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 let {FilterNotifier} = require("filterNotifier"); | 24 const {FilterNotifier} = require("filterNotifier"); |
| 25 let {extend} = require("coreUtils"); | 25 const {extend} = require("coreUtils"); |
| 26 let {filterToRegExp} = require("common"); | 26 const {filterToRegExp} = require("common"); |
| 27 | 27 |
| 28 /** | 28 /** |
| 29 * Abstract base class for filters | 29 * Abstract base class for filters |
| 30 * | 30 * |
| 31 * @param {string} text string representation of the filter | 31 * @param {string} text string representation of the filter |
| 32 * @constructor | 32 * @constructor |
| 33 */ | 33 */ |
| 34 function Filter(text) | 34 function Filter(text) |
| 35 { | 35 { |
| 36 this.text = text; | 36 this.text = text; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 * @type {RegExp} | 93 * @type {RegExp} |
| 94 */ | 94 */ |
| 95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/; | 95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/; |
| 96 /** | 96 /** |
| 97 * Regular expression that options on a RegExp filter should match | 97 * Regular expression that options on a RegExp filter should match |
| 98 * @type {RegExp} | 98 * @type {RegExp} |
| 99 */ | 99 */ |
| 100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/; | 100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/; |
| 101 | 101 |
| 102 /** | 102 /** |
| 103 * Creates a filter of correct type from its text representation - | 103 * Creates a filter of correct type from its text representation - does the |
| 104 * does the basic parsing and calls the right constructor then. | 104 * basic parsing and calls the right constructor then. |
| 105 * | 105 * |
| 106 * @param {string} text as in Filter() | 106 * @param {string} text as in Filter() |
| 107 * @return {Filter} | 107 * @return {Filter} |
| 108 */ | 108 */ |
| 109 Filter.fromText = function(text) | 109 Filter.fromText = function(text) |
| 110 { | 110 { |
| 111 if (text in Filter.knownFilters) | 111 if (text in Filter.knownFilters) |
| 112 return Filter.knownFilters[text]; | 112 return Filter.knownFilters[text]; |
| 113 | 113 |
| 114 let ret; | 114 let ret; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 // Remove line breaks and such | 163 // Remove line breaks and such |
| 164 text = text.replace(/[^\S ]/g, ""); | 164 text = text.replace(/[^\S ]/g, ""); |
| 165 | 165 |
| 166 if (/^\s*!/.test(text)) | 166 if (/^\s*!/.test(text)) |
| 167 { | 167 { |
| 168 // Don't remove spaces inside comments | 168 // Don't remove spaces inside comments |
| 169 return text.trim(); | 169 return text.trim(); |
| 170 } | 170 } |
| 171 else if (Filter.elemhideRegExp.test(text)) | 171 else if (Filter.elemhideRegExp.test(text)) |
| 172 { | 172 { |
| 173 // Special treatment for element hiding filters, right side is | 173 // Special treatment for element hiding filters, right side is allowed to |
| 174 // allowed to contain spaces | 174 // contain spaces |
| 175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text); | 175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text); |
| 176 return domain.replace(/\s/g, "") + separator + selector.trim(); | 176 return domain.replace(/\s/g, "") + separator + selector.trim(); |
| 177 } | 177 } |
| 178 return text.replace(/\s/g, ""); | 178 return text.replace(/\s/g, ""); |
| 179 }; | 179 }; |
| 180 | 180 |
| 181 /** | 181 /** |
| 182 * @see filterToRegExp | 182 * @see filterToRegExp |
| 183 */ | 183 */ |
| 184 Filter.toRegExp = filterToRegExp; | 184 Filter.toRegExp = filterToRegExp; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 202 type: "invalid", | 202 type: "invalid", |
| 203 | 203 |
| 204 /** | 204 /** |
| 205 * Reason why this filter is invalid | 205 * Reason why this filter is invalid |
| 206 * @type {string} | 206 * @type {string} |
| 207 */ | 207 */ |
| 208 reason: null, | 208 reason: null, |
| 209 | 209 |
| 210 /** | 210 /** |
| 211 * See Filter.serialize() | 211 * See Filter.serialize() |
| 212 * @param {string[]} buffer buffer to push the serialization results into | 212 * @inheritdoc |
| 213 */ | 213 */ |
| 214 serialize(buffer) {} | 214 serialize(buffer) {} |
| 215 }); | 215 }); |
| 216 | 216 |
| 217 /** | 217 /** |
| 218 * Class for comments | 218 * Class for comments |
| 219 * @param {string} text see Filter() | 219 * @param {string} text see Filter() |
| 220 * @constructor | 220 * @constructor |
| 221 * @augments Filter | 221 * @augments Filter |
| 222 */ | 222 */ |
| 223 function CommentFilter(text) | 223 function CommentFilter(text) |
| 224 { | 224 { |
| 225 Filter.call(this, text); | 225 Filter.call(this, text); |
| 226 } | 226 } |
| 227 exports.CommentFilter = CommentFilter; | 227 exports.CommentFilter = CommentFilter; |
| 228 | 228 |
| 229 CommentFilter.prototype = extend(Filter, { | 229 CommentFilter.prototype = extend(Filter, { |
| 230 type: "comment", | 230 type: "comment", |
| 231 | 231 |
| 232 /** | 232 /** |
| 233 * See Filter.serialize() | 233 * See Filter.serialize() |
| 234 * @param {string[]} buffer buffer to push the serialization results into | 234 * @inheritdoc |
| 235 */ | 235 */ |
| 236 serialize(buffer) {} | 236 serialize(buffer) {} |
| 237 }); | 237 }); |
| 238 | 238 |
| 239 /** | 239 /** |
| 240 * Abstract base class for filters that can get hits | 240 * Abstract base class for filters that can get hits |
| 241 * @param {string} text see Filter() | 241 * @param {string} text |
| 242 * @param {string} [domains] Domains that the filter is restricted to | 242 * see Filter() |
| 243 * separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" | 243 * @param {string} [domains] |
| 244 * Domains that the filter is restricted to separated by domainSeparator | |
| 245 * e.g. "foo.com|bar.com|~baz.com" | |
| 244 * @constructor | 246 * @constructor |
| 245 * @augments Filter | 247 * @augments Filter |
| 246 */ | 248 */ |
| 247 function ActiveFilter(text, domains) | 249 function ActiveFilter(text, domains) |
| 248 { | 250 { |
| 249 Filter.call(this, text); | 251 Filter.call(this, text); |
| 250 | 252 |
| 251 this.domainSource = domains; | 253 this.domainSource = domains; |
| 252 } | 254 } |
| 253 exports.ActiveFilter = ActiveFilter; | 255 exports.ActiveFilter = ActiveFilter; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 271 { | 273 { |
| 272 let oldValue = this._disabled; | 274 let oldValue = this._disabled; |
| 273 this._disabled = value; | 275 this._disabled = value; |
| 274 FilterNotifier.triggerListeners("filter.disabled", this, value, oldValue); | 276 FilterNotifier.triggerListeners("filter.disabled", this, value, oldValue); |
| 275 } | 277 } |
| 276 return this._disabled; | 278 return this._disabled; |
| 277 }, | 279 }, |
| 278 | 280 |
| 279 /** | 281 /** |
| 280 * Number of hits on the filter since the last reset | 282 * Number of hits on the filter since the last reset |
| 281 * @type {Number} | 283 * @type {number} |
| 282 */ | 284 */ |
| 283 get hitCount() | 285 get hitCount() |
| 284 { | 286 { |
| 285 return this._hitCount; | 287 return this._hitCount; |
| 286 }, | 288 }, |
| 287 set hitCount(value) | 289 set hitCount(value) |
| 288 { | 290 { |
| 289 if (value != this._hitCount) | 291 if (value != this._hitCount) |
| 290 { | 292 { |
| 291 let oldValue = this._hitCount; | 293 let oldValue = this._hitCount; |
| 292 this._hitCount = value; | 294 this._hitCount = value; |
| 293 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); | 295 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); |
| 294 } | 296 } |
| 295 return this._hitCount; | 297 return this._hitCount; |
| 296 }, | 298 }, |
| 297 | 299 |
| 298 /** | 300 /** |
| 299 * Last time the filter had a hit (in milliseconds since the | 301 * Last time the filter had a hit (in milliseconds since the beginning of the |
| 300 * beginning of the epoch) | 302 * epoch) |
| 301 * @type {Number} | 303 * @type {number} |
| 302 */ | 304 */ |
| 303 get lastHit() | 305 get lastHit() |
| 304 { | 306 { |
| 305 return this._lastHit; | 307 return this._lastHit; |
| 306 }, | 308 }, |
| 307 set lastHit(value) | 309 set lastHit(value) |
| 308 { | 310 { |
| 309 if (value != this._lastHit) | 311 if (value != this._lastHit) |
| 310 { | 312 { |
| 311 let oldValue = this._lastHit; | 313 let oldValue = this._lastHit; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 * @param {string} [sitekey] public key provided by the document | 428 * @param {string} [sitekey] public key provided by the document |
| 427 * @return {boolean} true in case of the filter being active | 429 * @return {boolean} true in case of the filter being active |
| 428 */ | 430 */ |
| 429 isActiveOnDomain(docDomain, sitekey) | 431 isActiveOnDomain(docDomain, sitekey) |
| 430 { | 432 { |
| 431 // Sitekeys are case-sensitive so we shouldn't convert them to | 433 // Sitekeys are case-sensitive so we shouldn't convert them to |
| 432 // upper-case to avoid false positives here. Instead we need to | 434 // upper-case to avoid false positives here. Instead we need to |
| 433 // change the way filter options are parsed. | 435 // change the way filter options are parsed. |
| 434 if (this.sitekeys && | 436 if (this.sitekeys && |
| 435 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) | 437 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) |
| 438 { | |
| 436 return false; | 439 return false; |
| 440 } | |
| 437 | 441 |
| 438 // If no domains are set the rule matches everywhere | 442 // If no domains are set the rule matches everywhere |
| 439 if (!this.domains) | 443 if (!this.domains) |
| 440 return true; | 444 return true; |
| 441 | 445 |
| 442 // If the document has no host name, match only if the filter | 446 // If the document has no host name, match only if the filter |
| 443 // isn't restricted to specific domains | 447 // isn't restricted to specific domains |
| 444 if (!docDomain) | 448 if (!docDomain) |
| 445 return this.domains[""]; | 449 return this.domains[""]; |
| 446 | 450 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 470 { | 474 { |
| 471 if (!docDomain || !this.domains || this.domains[""]) | 475 if (!docDomain || !this.domains || this.domains[""]) |
| 472 return false; | 476 return false; |
| 473 | 477 |
| 474 if (this.ignoreTrailingDot) | 478 if (this.ignoreTrailingDot) |
| 475 docDomain = docDomain.replace(/\.+$/, ""); | 479 docDomain = docDomain.replace(/\.+$/, ""); |
| 476 docDomain = docDomain.toUpperCase(); | 480 docDomain = docDomain.toUpperCase(); |
| 477 | 481 |
| 478 for (let domain in this.domains) | 482 for (let domain in this.domains) |
| 479 { | 483 { |
| 480 if (this.domains[domain] && domain != docDomain && | 484 if (this.domains[domain] && domain != docDomain) |
| 481 (domain.length <= docDomain.length || | 485 { |
| 482 domain.indexOf("." + docDomain) != | 486 if (domain.length <= docDomain.length) |
| 483 domain.length - docDomain.length - 1)) | 487 return false; |
|
Sebastian Noack
2017/02/21 09:19:31
Perhaps this rather complex condition is either to
kzar
2017/02/21 10:37:01
Looks much clearer to me, Done.
| |
| 484 return false; | 488 |
| 489 if (!domain.endsWith("." + docDomain)) | |
| 490 return false; | |
| 491 } | |
| 485 } | 492 } |
| 486 | 493 |
| 487 return true; | 494 return true; |
| 488 }, | 495 }, |
| 489 | 496 |
| 490 /** | 497 /** |
| 491 * Checks whether this filter is generic or specific | 498 * Checks whether this filter is generic or specific |
| 492 * @return {boolean} | 499 * @return {boolean} |
| 493 */ | 500 */ |
| 494 isGeneric() | 501 isGeneric() |
| 495 { | 502 { |
| 496 return !(this.sitekeys && this.sitekeys.length) && | 503 return !(this.sitekeys && this.sitekeys.length) && |
| 497 (!this.domains || this.domains[""]); | 504 (!this.domains || this.domains[""]); |
| 498 }, | 505 }, |
| 499 | 506 |
| 500 /** | 507 /** |
| 501 * See Filter.serialize() | 508 * See Filter.serialize() |
| 502 * @param {string[]} buffer buffer to push the serialization results into | 509 * @inheritdoc |
| 503 */ | 510 */ |
| 504 serialize(buffer) | 511 serialize(buffer) |
| 505 { | 512 { |
| 506 if (this._disabled || this._hitCount || this._lastHit) | 513 if (this._disabled || this._hitCount || this._lastHit) |
| 507 { | 514 { |
| 508 Filter.prototype.serialize.call(this, buffer); | 515 Filter.prototype.serialize.call(this, buffer); |
| 509 if (this._disabled) | 516 if (this._disabled) |
| 510 buffer.push("disabled=true"); | 517 buffer.push("disabled=true"); |
| 511 if (this._hitCount) | 518 if (this._hitCount) |
| 512 buffer.push("hitCount=" + this._hitCount); | 519 buffer.push("hitCount=" + this._hitCount); |
| 513 if (this._lastHit) | 520 if (this._lastHit) |
| 514 buffer.push("lastHit=" + this._lastHit); | 521 buffer.push("lastHit=" + this._lastHit); |
| 515 } | 522 } |
| 516 } | 523 } |
| 517 }); | 524 }); |
| 518 | 525 |
| 519 /** | 526 /** |
| 520 * Abstract base class for RegExp-based filters | 527 * Abstract base class for RegExp-based filters |
| 521 * @param {string} text see Filter() | 528 * @param {string} text see Filter() |
| 522 * @param {string} regexpSource filter part that the regular expression should | 529 * @param {string} regexpSource |
| 523 * be build from | 530 * filter part that the regular expression should be build from |
| 524 * @param {Number} [contentType] Content types the filter applies to, | 531 * @param {number} [contentType] |
| 525 * combination of values from RegExpFilter.typeMap | 532 * Content types the filter applies to, combination of values from |
| 526 * @param {boolean} [matchCase] Defines whether the filter should distinguish | 533 * RegExpFilter.typeMap |
| 527 * between lower and upper case letters | 534 * @param {boolean} [matchCase] |
| 528 * @param {string} [domains] Domains that the filter is restricted to, | 535 * Defines whether the filter should distinguish between lower and upper case |
| 529 * e.g. "foo.com|bar.com|~baz.com" | 536 * letters |
| 530 * @param {boolean} [thirdParty] Defines whether the filter should apply to | 537 * @param {string} [domains] |
| 531 * third-party or first-party content only | 538 * Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" |
| 532 * @param {string} [sitekeys] Public keys of websites that this filter should | 539 * @param {boolean} [thirdParty] |
| 533 * apply to | 540 * Defines whether the filter should apply to third-party or first-party |
| 541 * content only | |
| 542 * @param {string} [sitekeys] | |
| 543 * Public keys of websites that this filter should apply to | |
| 534 * @constructor | 544 * @constructor |
| 535 * @augments ActiveFilter | 545 * @augments ActiveFilter |
| 536 */ | 546 */ |
| 537 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, | 547 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, |
| 538 thirdParty, sitekeys) | 548 thirdParty, sitekeys) |
| 539 { | 549 { |
| 540 ActiveFilter.call(this, text, domains, sitekeys); | 550 ActiveFilter.call(this, text, domains, sitekeys); |
| 541 | 551 |
| 542 if (contentType != null) | 552 if (contentType != null) |
| 543 this.contentType = contentType; | 553 this.contentType = contentType; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 return prop.value; | 613 return prop.value; |
| 604 | 614 |
| 605 let source = Filter.toRegExp(this.regexpSource); | 615 let source = Filter.toRegExp(this.regexpSource); |
| 606 let regexp = new RegExp(source, this.matchCase ? "" : "i"); | 616 let regexp = new RegExp(source, this.matchCase ? "" : "i"); |
| 607 Object.defineProperty(this, "regexp", {value: regexp}); | 617 Object.defineProperty(this, "regexp", {value: regexp}); |
| 608 return regexp; | 618 return regexp; |
| 609 }, | 619 }, |
| 610 /** | 620 /** |
| 611 * Content types the filter applies to, combination of values from | 621 * Content types the filter applies to, combination of values from |
| 612 * RegExpFilter.typeMap | 622 * RegExpFilter.typeMap |
| 613 * @type {Number} | 623 * @type {number} |
| 614 */ | 624 */ |
| 615 contentType: 0x7FFFFFFF, | 625 contentType: 0x7FFFFFFF, |
| 616 /** | 626 /** |
| 617 * Defines whether the filter should distinguish between lower and | 627 * Defines whether the filter should distinguish between lower and |
| 618 * upper case letters | 628 * upper case letters |
| 619 * @type {boolean} | 629 * @type {boolean} |
| 620 */ | 630 */ |
| 621 matchCase: false, | 631 matchCase: false, |
| 622 /** | 632 /** |
| 623 * Defines whether the filter should apply to third-party or | 633 * Defines whether the filter should apply to third-party or |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 * @param {boolean} thirdParty should be true if the URL is a third-party | 676 * @param {boolean} thirdParty should be true if the URL is a third-party |
| 667 * request | 677 * request |
| 668 * @param {string} sitekey public key provided by the document | 678 * @param {string} sitekey public key provided by the document |
| 669 * @return {boolean} true in case of a match | 679 * @return {boolean} true in case of a match |
| 670 */ | 680 */ |
| 671 matches(location, typeMask, docDomain, thirdParty, sitekey) | 681 matches(location, typeMask, docDomain, thirdParty, sitekey) |
| 672 { | 682 { |
| 673 if (this.contentType & typeMask && | 683 if (this.contentType & typeMask && |
| 674 (this.thirdParty == null || this.thirdParty == thirdParty) && | 684 (this.thirdParty == null || this.thirdParty == thirdParty) && |
| 675 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 685 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) |
| 686 { | |
| 676 return true; | 687 return true; |
| 688 } | |
| 677 return false; | 689 return false; |
| 678 } | 690 } |
| 679 }); | 691 }); |
| 680 | 692 |
| 681 // Required to optimize Matcher, see also RegExpFilter.prototype.length | 693 // Required to optimize Matcher, see also RegExpFilter.prototype.length |
| 682 Object.defineProperty(RegExpFilter.prototype, "0", { | 694 Object.defineProperty(RegExpFilter.prototype, "0", { |
| 683 get() { return this; } | 695 get() { return this; } |
| 684 }); | 696 }); |
| 685 | 697 |
| 686 /** | 698 /** |
| 687 * Creates a RegExp filter from its text representation | 699 * Creates a RegExp filter from its text representation |
| 688 * @param {string} text same as in Filter() | 700 * @param {string} text same as in Filter() |
| 689 * @return {RegExpFilter} | 701 * @return {Filter} |
| 690 */ | 702 */ |
| 691 RegExpFilter.fromText = function(text) | 703 RegExpFilter.fromText = function(text) |
| 692 { | 704 { |
| 693 let blocking = true; | 705 let blocking = true; |
| 694 let origText = text; | 706 let origText = text; |
| 695 if (text.indexOf("@@") == 0) | 707 if (text.indexOf("@@") == 0) |
| 696 { | 708 { |
| 697 blocking = false; | 709 blocking = false; |
| 698 text = text.substr(2); | 710 text = text.substr(2); |
| 699 } | 711 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 802 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.DOCUMENT | | 814 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.DOCUMENT | |
| 803 RegExpFilter.typeMap.ELEMHIDE | | 815 RegExpFilter.typeMap.ELEMHIDE | |
| 804 RegExpFilter.typeMap.POPUP | | 816 RegExpFilter.typeMap.POPUP | |
| 805 RegExpFilter.typeMap.GENERICHIDE | | 817 RegExpFilter.typeMap.GENERICHIDE | |
| 806 RegExpFilter.typeMap.GENERICBLOCK); | 818 RegExpFilter.typeMap.GENERICBLOCK); |
| 807 | 819 |
| 808 /** | 820 /** |
| 809 * Class for blocking filters | 821 * Class for blocking filters |
| 810 * @param {string} text see Filter() | 822 * @param {string} text see Filter() |
| 811 * @param {string} regexpSource see RegExpFilter() | 823 * @param {string} regexpSource see RegExpFilter() |
| 812 * @param {Number} contentType see RegExpFilter() | 824 * @param {number} contentType see RegExpFilter() |
| 813 * @param {boolean} matchCase see RegExpFilter() | 825 * @param {boolean} matchCase see RegExpFilter() |
| 814 * @param {string} domains see RegExpFilter() | 826 * @param {string} domains see RegExpFilter() |
| 815 * @param {boolean} thirdParty see RegExpFilter() | 827 * @param {boolean} thirdParty see RegExpFilter() |
| 816 * @param {string} sitekeys see RegExpFilter() | 828 * @param {string} sitekeys see RegExpFilter() |
| 817 * @param {boolean} collapse defines whether the filter should collapse blocked | 829 * @param {boolean} collapse |
| 818 * content, can be null | 830 * defines whether the filter should collapse blocked content, can be null |
| 819 * @constructor | 831 * @constructor |
| 820 * @augments RegExpFilter | 832 * @augments RegExpFilter |
| 821 */ | 833 */ |
| 822 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, | 834 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, |
| 823 thirdParty, sitekeys, collapse) | 835 thirdParty, sitekeys, collapse) |
| 824 { | 836 { |
| 825 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 837 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
| 826 thirdParty, sitekeys); | 838 thirdParty, sitekeys); |
| 827 | 839 |
| 828 this.collapse = collapse; | 840 this.collapse = collapse; |
| 829 } | 841 } |
| 830 exports.BlockingFilter = BlockingFilter; | 842 exports.BlockingFilter = BlockingFilter; |
| 831 | 843 |
| 832 BlockingFilter.prototype = extend(RegExpFilter, { | 844 BlockingFilter.prototype = extend(RegExpFilter, { |
| 833 type: "blocking", | 845 type: "blocking", |
| 834 | 846 |
| 835 /** | 847 /** |
| 836 * Defines whether the filter should collapse blocked content. | 848 * Defines whether the filter should collapse blocked content. |
| 837 * Can be null (use the global preference). | 849 * Can be null (use the global preference). |
| 838 * @type {boolean} | 850 * @type {boolean} |
| 839 */ | 851 */ |
| 840 collapse: null | 852 collapse: null |
| 841 }); | 853 }); |
| 842 | 854 |
| 843 /** | 855 /** |
| 844 * Class for whitelist filters | 856 * Class for whitelist filters |
| 845 * @param {string} text see Filter() | 857 * @param {string} text see Filter() |
| 846 * @param {string} regexpSource see RegExpFilter() | 858 * @param {string} regexpSource see RegExpFilter() |
| 847 * @param {Number} contentType see RegExpFilter() | 859 * @param {number} contentType see RegExpFilter() |
| 848 * @param {boolean} matchCase see RegExpFilter() | 860 * @param {boolean} matchCase see RegExpFilter() |
| 849 * @param {string} domains see RegExpFilter() | 861 * @param {string} domains see RegExpFilter() |
| 850 * @param {boolean} thirdParty see RegExpFilter() | 862 * @param {boolean} thirdParty see RegExpFilter() |
| 851 * @param {string} sitekeys see RegExpFilter() | 863 * @param {string} sitekeys see RegExpFilter() |
| 852 * @constructor | 864 * @constructor |
| 853 * @augments RegExpFilter | 865 * @augments RegExpFilter |
| 854 */ | 866 */ |
| 855 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, | 867 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, |
| 856 thirdParty, sitekeys) | 868 thirdParty, sitekeys) |
| 857 { | 869 { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 873 * hidden | 885 * hidden |
| 874 * @constructor | 886 * @constructor |
| 875 * @augments ActiveFilter | 887 * @augments ActiveFilter |
| 876 */ | 888 */ |
| 877 function ElemHideBase(text, domains, selector) | 889 function ElemHideBase(text, domains, selector) |
| 878 { | 890 { |
| 879 ActiveFilter.call(this, text, domains || null); | 891 ActiveFilter.call(this, text, domains || null); |
| 880 | 892 |
| 881 if (domains) | 893 if (domains) |
| 882 { | 894 { |
| 883 this.selectorDomain = domains.replace(/,~[^,]+/g, ""). | 895 this.selectorDomain = domains.replace(/,~[^,]+/g, "") |
| 884 replace(/^~[^,]+,?/, "").toLowerCase(); | 896 .replace(/^~[^,]+,?/, "").toLowerCase(); |
|
Sebastian Noack
2017/02/21 09:19:30
I think it's more readable when indented like this
kzar
2017/02/21 10:37:01
Done.
| |
| 885 } | 897 } |
| 886 | 898 |
| 887 // Braces are being escaped to prevent CSS rule injection. | 899 // Braces are being escaped to prevent CSS rule injection. |
| 888 this.selector = selector.replace("{", "\\x7B ").replace("}", "\\x7D "); | 900 this.selector = selector.replace("{", "\\x7B ").replace("}", "\\x7D "); |
| 889 } | 901 } |
| 890 exports.ElemHideBase = ElemHideBase; | 902 exports.ElemHideBase = ElemHideBase; |
| 891 | 903 |
| 892 ElemHideBase.prototype = extend(ActiveFilter, { | 904 ElemHideBase.prototype = extend(ActiveFilter, { |
| 893 /** | 905 /** |
| 894 * @see ActiveFilter.domainSeparator | 906 * @see ActiveFilter.domainSeparator |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 910 * CSS selector for the HTML elements that should be hidden | 922 * CSS selector for the HTML elements that should be hidden |
| 911 * @type {string} | 923 * @type {string} |
| 912 */ | 924 */ |
| 913 selector: null | 925 selector: null |
| 914 }); | 926 }); |
| 915 | 927 |
| 916 /** | 928 /** |
| 917 * Creates an element hiding filter from a pre-parsed text representation | 929 * Creates an element hiding filter from a pre-parsed text representation |
| 918 * | 930 * |
| 919 * @param {string} text same as in Filter() | 931 * @param {string} text same as in Filter() |
| 920 * @param {string} domain domain part of the text representation | 932 * @param {string} domain |
| 921 * (can be empty) | 933 * domain part of the text representation (can be empty) |
| 922 * @param {boolean} isException exception rule indicator | 934 * @param {boolean} isException exception rule indicator |
| 923 * @param {string} tagName tag name part (can be empty) | 935 * @param {string} tagName tag name part (can be empty) |
| 924 * @param {string} attrRules attribute matching rules (can be empty) | 936 * @param {string} attrRules attribute matching rules (can be empty) |
| 925 * @param {string} selector raw CSS selector (can be empty) | 937 * @param {string} selector raw CSS selector (can be empty) |
| 926 * @return {ElemHideFilter|ElemHideException| | 938 * @return {ElemHideFilter|ElemHideException| |
| 927 * ElemHideEmulationFilter|InvalidFilter} | 939 * ElemHideEmulationFilter|InvalidFilter} |
| 928 */ | 940 */ |
| 929 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, | 941 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, |
| 930 selector) | 942 selector) |
| 931 { | 943 { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1034 */ | 1046 */ |
| 1035 function ElemHideEmulationFilter(text, domains, selector) | 1047 function ElemHideEmulationFilter(text, domains, selector) |
| 1036 { | 1048 { |
| 1037 ElemHideBase.call(this, text, domains, selector); | 1049 ElemHideBase.call(this, text, domains, selector); |
| 1038 } | 1050 } |
| 1039 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1051 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
| 1040 | 1052 |
| 1041 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1053 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
| 1042 type: "elemhideemulation" | 1054 type: "elemhideemulation" |
| 1043 }); | 1055 }); |
| LEFT | RIGHT |