| 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-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 text = text.replace(/[^\S ]+/g, ""); | 181 text = text.replace(/[^\S ]+/g, ""); |
| 182 | 182 |
| 183 // Don't remove spaces inside comments | 183 // Don't remove spaces inside comments |
| 184 if (/^ *!/.test(text)) | 184 if (/^ *!/.test(text)) |
| 185 return text.trim(); | 185 return text.trim(); |
| 186 | 186 |
| 187 // Special treatment for element hiding filters, right side is allowed to | 187 // Special treatment for element hiding filters, right side is allowed to |
| 188 // contain spaces | 188 // contain spaces |
| 189 if (Filter.elemhideRegExp.test(text)) | 189 if (Filter.elemhideRegExp.test(text)) |
| 190 { | 190 { |
| 191 let [, domain, separator, selector] = /^(.*?)(#[@?]?#?)(.*)$/.exec(text); | 191 let [, domains, separator, selector] = /^(.*?)(#[@?]?#?)(.*)$/.exec(text); |
| 192 return domain.replace(/ +/g, "") + separator + selector.trim(); | 192 return domains.replace(/ +/g, "") + separator + selector.trim(); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // For most regexp filters we strip all spaces, but $csp filter options | 195 // For most regexp filters we strip all spaces, but $csp filter options |
| 196 // are allowed to contain single (non trailing) spaces. | 196 // are allowed to contain single (non trailing) spaces. |
| 197 let strippedText = text.replace(/ +/g, ""); | 197 let strippedText = text.replace(/ +/g, ""); |
| 198 if (!strippedText.includes("$") || !/\bcsp=/i.test(strippedText)) | 198 if (!strippedText.includes("$") || !/\bcsp=/i.test(strippedText)) |
| 199 return strippedText; | 199 return strippedText; |
| 200 | 200 |
| 201 let optionsMatch = Filter.optionsRegExp.exec(strippedText); | 201 let optionsMatch = Filter.optionsRegExp.exec(strippedText); |
| 202 if (!optionsMatch) | 202 if (!optionsMatch) |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 { | 367 { |
| 368 let oldValue = this._lastHit; | 368 let oldValue = this._lastHit; |
| 369 this._lastHit = value; | 369 this._lastHit = value; |
| 370 FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue); | 370 FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue); |
| 371 } | 371 } |
| 372 return this._lastHit; | 372 return this._lastHit; |
| 373 }, | 373 }, |
| 374 | 374 |
| 375 /** | 375 /** |
| 376 * String that the domains property should be generated from | 376 * String that the domains property should be generated from |
| 377 * @type {string} | 377 * @type {?string} |
| 378 */ | 378 */ |
| 379 domainSource: null, | 379 domainSource: null, |
| 380 | 380 |
| 381 /** | 381 /** |
| 382 * Separator character used in domainSource property, must be | 382 * Separator character used in domainSource property, must be |
| 383 * overridden by subclasses | 383 * overridden by subclasses |
| 384 * @type {string} | 384 * @type {string} |
| 385 */ | 385 */ |
| 386 domainSeparator: null, | 386 domainSeparator: null, |
| 387 | 387 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 | 464 |
| 465 this.domainSource = null; | 465 this.domainSource = null; |
| 466 } | 466 } |
| 467 | 467 |
| 468 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); | 468 Object.defineProperty(this, "domains", {value: domains, enumerable: true}); |
| 469 return this.domains; | 469 return this.domains; |
| 470 }, | 470 }, |
| 471 | 471 |
| 472 /** | 472 /** |
| 473 * Array containing public keys of websites that this filter should apply to | 473 * Array containing public keys of websites that this filter should apply to |
| 474 * @type {string[]} | 474 * @type {?string[]} |
| 475 */ | 475 */ |
| 476 sitekeys: null, | 476 sitekeys: null, |
| 477 | 477 |
| 478 /** | 478 /** |
| 479 * Checks whether this filter is active on a domain. | 479 * Checks whether this filter is active on a domain. |
| 480 * @param {string} docDomain domain name of the document that loads the URL | 480 * @param {string} [docDomain] domain name of the document that loads the URL |
| 481 * @param {string} [sitekey] public key provided by the document | 481 * @param {string} [sitekey] public key provided by the document |
| 482 * @return {boolean} true in case of the filter being active | 482 * @return {boolean} true in case of the filter being active |
| 483 */ | 483 */ |
| 484 isActiveOnDomain(docDomain, sitekey) | 484 isActiveOnDomain(docDomain, sitekey) |
| 485 { | 485 { |
| 486 // Sitekeys are case-sensitive so we shouldn't convert them to | 486 // Sitekeys are case-sensitive so we shouldn't convert them to |
| 487 // upper-case to avoid false positives here. Instead we need to | 487 // upper-case to avoid false positives here. Instead we need to |
| 488 // change the way filter options are parsed. | 488 // change the way filter options are parsed. |
| 489 if (this.sitekeys && | 489 if (this.sitekeys && |
| 490 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) | 490 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 contentType: 0x7FFFFFFF, | 679 contentType: 0x7FFFFFFF, |
| 680 /** | 680 /** |
| 681 * Defines whether the filter should distinguish between lower and | 681 * Defines whether the filter should distinguish between lower and |
| 682 * upper case letters | 682 * upper case letters |
| 683 * @type {boolean} | 683 * @type {boolean} |
| 684 */ | 684 */ |
| 685 matchCase: false, | 685 matchCase: false, |
| 686 /** | 686 /** |
| 687 * Defines whether the filter should apply to third-party or | 687 * Defines whether the filter should apply to third-party or |
| 688 * first-party content only. Can be null (apply to all content). | 688 * first-party content only. Can be null (apply to all content). |
| 689 * @type {boolean} | 689 * @type {?boolean} |
| 690 */ | 690 */ |
| 691 thirdParty: null, | 691 thirdParty: null, |
| 692 | 692 |
| 693 /** | 693 /** |
| 694 * String that the sitekey property should be generated from | 694 * String that the sitekey property should be generated from |
| 695 * @type {string} | 695 * @type {?string} |
| 696 */ | 696 */ |
| 697 sitekeySource: null, | 697 sitekeySource: null, |
| 698 | 698 |
| 699 /** | 699 /** |
| 700 * Array containing public keys of websites that this filter should apply to | 700 * @see ActiveFilter.sitekeys |
| 701 * @type {string[]} | |
| 702 */ | 701 */ |
| 703 get sitekeys() | 702 get sitekeys() |
| 704 { | 703 { |
| 705 // Despite this property being cached, the getter is called | 704 // Despite this property being cached, the getter is called |
| 706 // several times on Safari, due to WebKit bug 132872 | 705 // several times on Safari, due to WebKit bug 132872 |
| 707 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | 706 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); |
| 708 if (prop) | 707 if (prop) |
| 709 return prop.value; | 708 return prop.value; |
| 710 | 709 |
| 711 let sitekeys = null; | 710 let sitekeys = null; |
| 712 | 711 |
| 713 if (this.sitekeySource) | 712 if (this.sitekeySource) |
| 714 { | 713 { |
| 715 sitekeys = this.sitekeySource.split("|"); | 714 sitekeys = this.sitekeySource.split("|"); |
| 716 this.sitekeySource = null; | 715 this.sitekeySource = null; |
| 717 } | 716 } |
| 718 | 717 |
| 719 Object.defineProperty( | 718 Object.defineProperty( |
| 720 this, "sitekeys", {value: sitekeys, enumerable: true} | 719 this, "sitekeys", {value: sitekeys, enumerable: true} |
| 721 ); | 720 ); |
| 722 return this.sitekeys; | 721 return this.sitekeys; |
| 723 }, | 722 }, |
| 724 | 723 |
| 725 /** | 724 /** |
| 726 * Tests whether the URL matches this filter | 725 * Tests whether the URL matches this filter |
| 727 * @param {string} location URL to be tested | 726 * @param {string} location URL to be tested |
| 728 * @param {number} typeMask bitmask of content / request types to match | 727 * @param {number} typeMask bitmask of content / request types to match |
| 729 * @param {string} docDomain domain name of the document that loads the URL | 728 * @param {string} [docDomain] domain name of the document that loads the URL |
| 730 * @param {boolean} thirdParty should be true if the URL is a third-party | 729 * @param {boolean} [thirdParty] should be true if the URL is a third-party |
| 731 * request | 730 * request |
| 732 * @param {string} sitekey public key provided by the document | 731 * @param {string} [sitekey] public key provided by the document |
| 733 * @return {boolean} true in case of a match | 732 * @return {boolean} true in case of a match |
| 734 */ | 733 */ |
| 735 matches(location, typeMask, docDomain, thirdParty, sitekey) | 734 matches(location, typeMask, docDomain, thirdParty, sitekey) |
| 736 { | 735 { |
| 737 if (this.contentType & typeMask && | 736 if (this.contentType & typeMask && |
| 738 (this.thirdParty == null || this.thirdParty == thirdParty) && | 737 (this.thirdParty == null || this.thirdParty == thirdParty) && |
| 739 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 738 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) |
| 740 { | 739 { |
| 741 return true; | 740 return true; |
| 742 } | 741 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 RegExpFilter.typeMap.DOCUMENT | | 880 RegExpFilter.typeMap.DOCUMENT | |
| 882 RegExpFilter.typeMap.ELEMHIDE | | 881 RegExpFilter.typeMap.ELEMHIDE | |
| 883 RegExpFilter.typeMap.POPUP | | 882 RegExpFilter.typeMap.POPUP | |
| 884 RegExpFilter.typeMap.GENERICHIDE | | 883 RegExpFilter.typeMap.GENERICHIDE | |
| 885 RegExpFilter.typeMap.GENERICBLOCK); | 884 RegExpFilter.typeMap.GENERICBLOCK); |
| 886 | 885 |
| 887 /** | 886 /** |
| 888 * Class for blocking filters | 887 * Class for blocking filters |
| 889 * @param {string} text see Filter() | 888 * @param {string} text see Filter() |
| 890 * @param {string} regexpSource see RegExpFilter() | 889 * @param {string} regexpSource see RegExpFilter() |
| 891 * @param {number} contentType see RegExpFilter() | 890 * @param {number} [contentType] see RegExpFilter() |
| 892 * @param {boolean} matchCase see RegExpFilter() | 891 * @param {boolean} [matchCase] see RegExpFilter() |
| 893 * @param {string} domains see RegExpFilter() | 892 * @param {string} [domains] see RegExpFilter() |
| 894 * @param {boolean} thirdParty see RegExpFilter() | 893 * @param {boolean} [thirdParty] see RegExpFilter() |
| 895 * @param {string} sitekeys see RegExpFilter() | 894 * @param {string} [sitekeys] see RegExpFilter() |
| 896 * @param {boolean} collapse | 895 * @param {boolean} [collapse] |
| 897 * defines whether the filter should collapse blocked content, can be null | 896 * defines whether the filter should collapse blocked content, can be null |
| 898 * @param {string} [csp] | 897 * @param {string} [csp] |
| 899 * Content Security Policy to inject when the filter matches | 898 * Content Security Policy to inject when the filter matches |
| 900 * @param {string} [rewrite] | 899 * @param {?string} [rewrite] |
| 901 * The rewrite expression | 900 * The (optional) rule specifying how to rewrite the URL. See |
| 901 * BlockingFilter.prototype.rewrite. | |
| 902 * @constructor | 902 * @constructor |
| 903 * @augments RegExpFilter | 903 * @augments RegExpFilter |
| 904 */ | 904 */ |
| 905 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, | 905 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, |
| 906 thirdParty, sitekeys, collapse, csp, rewrite) | 906 thirdParty, sitekeys, collapse, csp, rewrite) |
| 907 { | 907 { |
| 908 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 908 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
| 909 thirdParty, sitekeys); | 909 thirdParty, sitekeys); |
| 910 | 910 |
| 911 this.collapse = collapse; | 911 this.collapse = collapse; |
| 912 this.csp = csp; | 912 this.csp = csp; |
| 913 this.rewrite = rewrite; | 913 this.rewrite = rewrite; |
| 914 } | 914 } |
| 915 exports.BlockingFilter = BlockingFilter; | 915 exports.BlockingFilter = BlockingFilter; |
| 916 | 916 |
| 917 BlockingFilter.prototype = extend(RegExpFilter, { | 917 BlockingFilter.prototype = extend(RegExpFilter, { |
| 918 type: "blocking", | 918 type: "blocking", |
| 919 | 919 |
| 920 /** | 920 /** |
| 921 * Defines whether the filter should collapse blocked content. | 921 * Defines whether the filter should collapse blocked content. |
| 922 * Can be null (use the global preference). | 922 * Can be null (use the global preference). |
| 923 * @type {boolean} | 923 * @type {?boolean} |
| 924 */ | 924 */ |
| 925 collapse: null, | 925 collapse: null, |
| 926 | 926 |
| 927 /** | 927 /** |
| 928 * Content Security Policy to inject for matching requests. | 928 * Content Security Policy to inject for matching requests. |
| 929 * @type {string} | 929 * @type {?string} |
| 930 */ | 930 */ |
| 931 csp: null, | 931 csp: null, |
| 932 | 932 |
| 933 /** | 933 /** |
| 934 * The rewrite expression | 934 * The rule specifying how to rewrite the URL. |
| 935 * @type {string} | 935 * The syntax is similar to the one of String.prototype.replace(). |
| 936 * @type {?string} | |
| 936 */ | 937 */ |
| 937 rewrite: null, | 938 rewrite: null, |
| 938 | 939 |
| 939 /** | 940 /** |
| 940 * Perform the URL rewrite | 941 * Rewrites an URL. |
| 941 * @param {string} urlString the string URL to rewrite | 942 * @param {string} url the URL to rewrite |
| 942 * @returns {string?} the rewritten URL, or null if it doesn't match. | 943 * @return {string} the rewritten URL, or the original in case of failure |
| 943 */ | 944 */ |
| 944 doRewrite(urlString) | 945 rewriteUrl(url) |
| 945 { | 946 { |
| 946 let matches = this.regexp.exec(urlString); | 947 try |
|
Sebastian Noack
2018/05/02 15:10:06
Why do we need to call exec() first? Can't we call
Manish Jethani
2018/05/02 15:31:09
Yeah exec shouldn't be necessary.
hub
2018/05/02 22:14:33
Done.
| |
| 947 if (matches) | 948 { |
| 948 return urlString.replace(this.regexp, this.rewrite); | 949 let rewrittenUrl = new URL(url.replace(this.regexp, this.rewrite), url); |
|
Sebastian Noack
2018/05/02 15:10:05
As mentioned in the discussion on the issue, we sh
hub
2018/05/02 22:14:33
Ok, I'll check the origin
|
kzar
2018/05/17 12:56:06
I forgot to mention before, I thought how you did
hub
2018/05/17 12:58:39
thanks!
|
| 949 | 950 if (rewrittenUrl.origin == new URL(url).origin) |
| 950 return null; | 951 return rewrittenUrl.href; |
| 952 } | |
| 953 catch (e) | |
| 954 { | |
| 955 } | |
| 956 | |
| 957 return url; | |
| 951 } | 958 } |
| 952 }); | 959 }); |
| 953 | 960 |
| 954 /** | 961 /** |
| 955 * Class for whitelist filters | 962 * Class for whitelist filters |
| 956 * @param {string} text see Filter() | 963 * @param {string} text see Filter() |
| 957 * @param {string} regexpSource see RegExpFilter() | 964 * @param {string} regexpSource see RegExpFilter() |
| 958 * @param {number} contentType see RegExpFilter() | 965 * @param {number} [contentType] see RegExpFilter() |
| 959 * @param {boolean} matchCase see RegExpFilter() | 966 * @param {boolean} [matchCase] see RegExpFilter() |
| 960 * @param {string} domains see RegExpFilter() | 967 * @param {string} [domains] see RegExpFilter() |
| 961 * @param {boolean} thirdParty see RegExpFilter() | 968 * @param {boolean} [thirdParty] see RegExpFilter() |
| 962 * @param {string} sitekeys see RegExpFilter() | 969 * @param {string} [sitekeys] see RegExpFilter() |
| 963 * @constructor | 970 * @constructor |
| 964 * @augments RegExpFilter | 971 * @augments RegExpFilter |
| 965 */ | 972 */ |
| 966 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, | 973 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, |
| 967 thirdParty, sitekeys) | 974 thirdParty, sitekeys) |
| 968 { | 975 { |
| 969 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 976 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
| 970 thirdParty, sitekeys); | 977 thirdParty, sitekeys); |
| 971 } | 978 } |
| 972 exports.WhitelistFilter = WhitelistFilter; | 979 exports.WhitelistFilter = WhitelistFilter; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 984 * hidden | 991 * hidden |
| 985 * @constructor | 992 * @constructor |
| 986 * @augments ActiveFilter | 993 * @augments ActiveFilter |
| 987 */ | 994 */ |
| 988 function ElemHideBase(text, domains, selector) | 995 function ElemHideBase(text, domains, selector) |
| 989 { | 996 { |
| 990 ActiveFilter.call(this, text, domains || null); | 997 ActiveFilter.call(this, text, domains || null); |
| 991 | 998 |
| 992 if (domains) | 999 if (domains) |
| 993 { | 1000 { |
| 994 this.selectorDomain = domains.replace(/,~[^,]+/g, "") | 1001 this.selectorDomains = domains.replace(/,~[^,]+/g, "") |
| 995 .replace(/^~[^,]+,?/, "").toLowerCase(); | 1002 .replace(/^~[^,]+,?/, "").toLowerCase(); |
| 996 } | 1003 } |
| 997 | 1004 |
| 998 // Braces are being escaped to prevent CSS rule injection. | 1005 // Braces are being escaped to prevent CSS rule injection. |
| 999 this.selector = selector.replace("{", "\\7B ").replace("}", "\\7D "); | 1006 this.selector = selector.replace("{", "\\7B ").replace("}", "\\7D "); |
| 1000 } | 1007 } |
| 1001 exports.ElemHideBase = ElemHideBase; | 1008 exports.ElemHideBase = ElemHideBase; |
| 1002 | 1009 |
| 1003 ElemHideBase.prototype = extend(ActiveFilter, { | 1010 ElemHideBase.prototype = extend(ActiveFilter, { |
| 1004 /** | 1011 /** |
| 1005 * @see ActiveFilter.domainSeparator | 1012 * @see ActiveFilter.domainSeparator |
| 1006 */ | 1013 */ |
| 1007 domainSeparator: ",", | 1014 domainSeparator: ",", |
| 1008 | 1015 |
| 1009 /** | 1016 /** |
| 1010 * @see ActiveFilter.ignoreTrailingDot | 1017 * @see ActiveFilter.ignoreTrailingDot |
| 1011 */ | 1018 */ |
| 1012 ignoreTrailingDot: false, | 1019 ignoreTrailingDot: false, |
| 1013 | 1020 |
| 1014 /** | 1021 /** |
| 1015 * Host name or domain the filter should be restricted to (can be null for | 1022 * Host names or domains the filter should be restricted to (can be null for |
| 1016 * no restriction) | 1023 * no restriction) |
| 1017 * @type {string} | 1024 * @type {?string} |
| 1018 */ | 1025 */ |
| 1019 selectorDomain: null, | 1026 selectorDomains: null, |
| 1020 /** | 1027 /** |
| 1021 * CSS selector for the HTML elements that should be hidden | 1028 * CSS selector for the HTML elements that should be hidden |
| 1022 * @type {string} | 1029 * @type {string} |
| 1023 */ | 1030 */ |
| 1024 selector: null | 1031 selector: null |
| 1025 }); | 1032 }); |
| 1026 | 1033 |
| 1027 /** | 1034 /** |
| 1028 * Creates an element hiding filter from a pre-parsed text representation | 1035 * Creates an element hiding filter from a pre-parsed text representation |
| 1029 * | 1036 * |
| 1030 * @param {string} text same as in Filter() | 1037 * @param {string} text same as in Filter() |
| 1031 * @param {string?} domain | 1038 * @param {string} [domains] |
| 1032 * domain part of the text representation | 1039 * domains part of the text representation |
| 1033 * @param {string?} type | 1040 * @param {string} [type] |
| 1034 * rule type, either empty or @ (exception) or ? (emulation rule) | 1041 * rule type, either empty or @ (exception) or ? (emulation rule) |
| 1035 * @param {string} selector raw CSS selector | 1042 * @param {string} selector raw CSS selector |
| 1036 * @return {ElemHideFilter|ElemHideException| | 1043 * @return {ElemHideFilter|ElemHideException| |
| 1037 * ElemHideEmulationFilter|InvalidFilter} | 1044 * ElemHideEmulationFilter|InvalidFilter} |
| 1038 */ | 1045 */ |
| 1039 ElemHideBase.fromText = function(text, domain, type, selector) | 1046 ElemHideBase.fromText = function(text, domains, type, selector) |
| 1040 { | 1047 { |
| 1041 // We don't allow ElemHide filters which have any empty domains. | 1048 // We don't allow ElemHide filters which have any empty domains. |
| 1042 // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that | 1049 // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that |
| 1043 // changes this must be changed too. | 1050 // changes this must be changed too. |
| 1044 if (domain && /(^|,)~?(,|$)/.test(domain)) | 1051 if (domains && /(^|,)~?(,|$)/.test(domains)) |
| 1045 return new InvalidFilter(text, "filter_invalid_domain"); | 1052 return new InvalidFilter(text, "filter_invalid_domain"); |
| 1046 | 1053 |
| 1047 if (type == "@") | 1054 if (type == "@") |
| 1048 return new ElemHideException(text, domain, selector); | 1055 return new ElemHideException(text, domains, selector); |
| 1049 | 1056 |
| 1050 if (type == "?") | 1057 if (type == "?") |
| 1051 { | 1058 { |
| 1052 // Element hiding emulation filters are inefficient so we need to make sure | 1059 // Element hiding emulation filters are inefficient so we need to make sure |
| 1053 // that they're only applied if they specify active domains | 1060 // that they're only applied if they specify active domains |
| 1054 if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 1061 if (!/,[^~][^,.]*\.[^,]/.test("," + domains)) |
| 1055 return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); | 1062 return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); |
| 1056 | 1063 |
| 1057 return new ElemHideEmulationFilter(text, domain, selector); | 1064 return new ElemHideEmulationFilter(text, domains, selector); |
| 1058 } | 1065 } |
| 1059 | 1066 |
| 1060 return new ElemHideFilter(text, domain, selector); | 1067 return new ElemHideFilter(text, domains, selector); |
| 1061 }; | 1068 }; |
| 1062 | 1069 |
| 1063 /** | 1070 /** |
| 1064 * Class for element hiding filters | 1071 * Class for element hiding filters |
| 1065 * @param {string} text see Filter() | 1072 * @param {string} text see Filter() |
| 1066 * @param {string} domains see ElemHideBase() | 1073 * @param {string} [domains] see ElemHideBase() |
| 1067 * @param {string} selector see ElemHideBase() | 1074 * @param {string} selector see ElemHideBase() |
| 1068 * @constructor | 1075 * @constructor |
| 1069 * @augments ElemHideBase | 1076 * @augments ElemHideBase |
| 1070 */ | 1077 */ |
| 1071 function ElemHideFilter(text, domains, selector) | 1078 function ElemHideFilter(text, domains, selector) |
| 1072 { | 1079 { |
| 1073 ElemHideBase.call(this, text, domains, selector); | 1080 ElemHideBase.call(this, text, domains, selector); |
| 1074 } | 1081 } |
| 1075 exports.ElemHideFilter = ElemHideFilter; | 1082 exports.ElemHideFilter = ElemHideFilter; |
| 1076 | 1083 |
| 1077 ElemHideFilter.prototype = extend(ElemHideBase, { | 1084 ElemHideFilter.prototype = extend(ElemHideBase, { |
| 1078 type: "elemhide" | 1085 type: "elemhide" |
| 1079 }); | 1086 }); |
| 1080 | 1087 |
| 1081 /** | 1088 /** |
| 1082 * Class for element hiding exceptions | 1089 * Class for element hiding exceptions |
| 1083 * @param {string} text see Filter() | 1090 * @param {string} text see Filter() |
| 1084 * @param {string} domains see ElemHideBase() | 1091 * @param {string} [domains] see ElemHideBase() |
| 1085 * @param {string} selector see ElemHideBase() | 1092 * @param {string} selector see ElemHideBase() |
| 1086 * @constructor | 1093 * @constructor |
| 1087 * @augments ElemHideBase | 1094 * @augments ElemHideBase |
| 1088 */ | 1095 */ |
| 1089 function ElemHideException(text, domains, selector) | 1096 function ElemHideException(text, domains, selector) |
| 1090 { | 1097 { |
| 1091 ElemHideBase.call(this, text, domains, selector); | 1098 ElemHideBase.call(this, text, domains, selector); |
| 1092 } | 1099 } |
| 1093 exports.ElemHideException = ElemHideException; | 1100 exports.ElemHideException = ElemHideException; |
| 1094 | 1101 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1106 */ | 1113 */ |
| 1107 function ElemHideEmulationFilter(text, domains, selector) | 1114 function ElemHideEmulationFilter(text, domains, selector) |
| 1108 { | 1115 { |
| 1109 ElemHideBase.call(this, text, domains, selector); | 1116 ElemHideBase.call(this, text, domains, selector); |
| 1110 } | 1117 } |
| 1111 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1118 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
| 1112 | 1119 |
| 1113 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1120 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
| 1114 type: "elemhideemulation" | 1121 type: "elemhideemulation" |
| 1115 }); | 1122 }); |
| LEFT | RIGHT |