| 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 {extend} = require("coreUtils"); | 23 let {extend} = require("coreUtils"); | 
|  | 24 let {filterToRegExp} = require("common"); | 
| 24 | 25 | 
| 25 /** | 26 /** | 
| 26  * Abstract base class for filters | 27  * Abstract base class for filters | 
| 27  * | 28  * | 
| 28  * @param {String} text   string representation of the filter | 29  * @param {String} text   string representation of the filter | 
| 29  * @constructor | 30  * @constructor | 
| 30  */ | 31  */ | 
| 31 function Filter(text) | 32 function Filter(text) | 
| 32 { | 33 { | 
| 33   this.text = text; | 34   this.text = text; | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 88 /** | 89 /** | 
| 89  * Regular expression that RegExp filters specified as RegExps should match | 90  * Regular expression that RegExp filters specified as RegExps should match | 
| 90  * @type RegExp | 91  * @type RegExp | 
| 91  */ | 92  */ | 
| 92 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[
      ^,\s]+)?)*)?$/; | 93 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[
      ^,\s]+)?)*)?$/; | 
| 93 /** | 94 /** | 
| 94  * Regular expression that options on a RegExp filter should match | 95  * Regular expression that options on a RegExp filter should match | 
| 95  * @type RegExp | 96  * @type RegExp | 
| 96  */ | 97  */ | 
| 97 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/
      ; | 98 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/
      ; | 
| 98 /** |  | 
| 99  * Regular expression that CSS property filters should match |  | 
| 100  * Properties must not contain " or ' |  | 
| 101  * @type RegExp |  | 
| 102  */ |  | 
| 103 Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; |  | 
| 104 | 99 | 
| 105 /** | 100 /** | 
| 106  * Creates a filter of correct type from its text representation - does the basi
      c parsing and | 101  * Creates a filter of correct type from its text representation - does the basi
      c parsing and | 
| 107  * calls the right constructor then. | 102  * calls the right constructor then. | 
| 108  * | 103  * | 
| 109  * @param {String} text   as in Filter() | 104  * @param {String} text   as in Filter() | 
| 110  * @return {Filter} | 105  * @return {Filter} | 
| 111  */ | 106  */ | 
| 112 Filter.fromText = function(text) | 107 Filter.fromText = function(text) | 
| 113 { | 108 { | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 169   { | 164   { | 
| 170     // Special treatment for element hiding filters, right side is allowed to co
      ntain spaces | 165     // Special treatment for element hiding filters, right side is allowed to co
      ntain spaces | 
| 171     let [, domain, separator, selector] = /^(.*?)(#\@?#?)(.*)$/.exec(text); | 166     let [, domain, separator, selector] = /^(.*?)(#\@?#?)(.*)$/.exec(text); | 
| 172     return domain.replace(/\s/g, "") + separator + selector.trim(); | 167     return domain.replace(/\s/g, "") + separator + selector.trim(); | 
| 173   } | 168   } | 
| 174   else | 169   else | 
| 175     return text.replace(/\s/g, ""); | 170     return text.replace(/\s/g, ""); | 
| 176 }; | 171 }; | 
| 177 | 172 | 
| 178 /** | 173 /** | 
| 179  * Converts filter text into regular expression string | 174  * @see filterToRegExp | 
| 180  * @param {String} text as in Filter() |  | 
| 181  * @return {String} regular expression representation of filter text |  | 
| 182  */ | 175  */ | 
| 183 Filter.toRegExp = function(text) | 176 Filter.toRegExp = filterToRegExp; | 
| 184 { |  | 
| 185   return text |  | 
| 186     .replace(/\*+/g, "*")        // remove multiple wildcards |  | 
| 187     .replace(/\^\|$/, "^")       // remove anchors following separator placehold
      er |  | 
| 188     .replace(/\W/g, "\\$&")      // escape special symbols |  | 
| 189     .replace(/\\\*/g, ".*")      // replace wildcards by .* |  | 
| 190     // process separator placeholders (all ANSI characters but alphanumeric char
      acters and _%.-) |  | 
| 191     .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x6
      0\\x7B-\\x7F]|$)") |  | 
| 192     .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?") // process ex
      tended anchor at expression start |  | 
| 193     .replace(/^\\\|/, "^")       // process anchor at expression start |  | 
| 194     .replace(/\\\|$/, "$")       // process anchor at expression end |  | 
| 195     .replace(/^(\.\*)/, "")      // remove leading wildcards |  | 
| 196     .replace(/(\.\*)$/, "");     // remove trailing wildcards |  | 
| 197 } |  | 
| 198 | 177 | 
| 199 /** | 178 /** | 
| 200  * Class for invalid filters | 179  * Class for invalid filters | 
| 201  * @param {String} text see Filter() | 180  * @param {String} text see Filter() | 
| 202  * @param {String} reason Reason why this filter is invalid | 181  * @param {String} reason Reason why this filter is invalid | 
| 203  * @constructor | 182  * @constructor | 
| 204  * @augments Filter | 183  * @augments Filter | 
| 205  */ | 184  */ | 
| 206 function InvalidFilter(text, reason) | 185 function InvalidFilter(text, reason) | 
| 207 { | 186 { | 
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 876 | 855 | 
| 877 /** | 856 /** | 
| 878  * Creates an element hiding filter from a pre-parsed text representation | 857  * Creates an element hiding filter from a pre-parsed text representation | 
| 879  * | 858  * | 
| 880  * @param {String} text         same as in Filter() | 859  * @param {String} text         same as in Filter() | 
| 881  * @param {String} domain       domain part of the text representation (can be e
      mpty) | 860  * @param {String} domain       domain part of the text representation (can be e
      mpty) | 
| 882  * @param {Boolean} isException exception rule indicator | 861  * @param {Boolean} isException exception rule indicator | 
| 883  * @param {String} tagName      tag name part (can be empty) | 862  * @param {String} tagName      tag name part (can be empty) | 
| 884  * @param {String} attrRules    attribute matching rules (can be empty) | 863  * @param {String} attrRules    attribute matching rules (can be empty) | 
| 885  * @param {String} selector     raw CSS selector (can be empty) | 864  * @param {String} selector     raw CSS selector (can be empty) | 
| 886  * @return {ElemHideFilter|ElemHideException|CSSPropertyFilter|InvalidFilter} | 865  * @return {ElemHideFilter|ElemHideException|ElemHideEmulationFilter|InvalidFilt
      er} | 
| 887  */ | 866  */ | 
| 888 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, 
      selector) | 867 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, 
      selector) | 
| 889 { | 868 { | 
| 890   if (!selector) | 869   if (!selector) | 
| 891   { | 870   { | 
| 892     if (tagName == "*") | 871     if (tagName == "*") | 
| 893       tagName = ""; | 872       tagName = ""; | 
| 894 | 873 | 
| 895     let id = null; | 874     let id = null; | 
| 896     let additional = ""; | 875     let additional = ""; | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 926 | 905 | 
| 927   // We don't allow ElemHide filters which have any empty domains. | 906   // We don't allow ElemHide filters which have any empty domains. | 
| 928   // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that | 907   // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that | 
| 929   // changes this must be changed too. | 908   // changes this must be changed too. | 
| 930   if (domain && /(^|,)~?(,|$)/.test(domain)) | 909   if (domain && /(^|,)~?(,|$)/.test(domain)) | 
| 931     return new InvalidFilter(text, "filter_invalid_domain"); | 910     return new InvalidFilter(text, "filter_invalid_domain"); | 
| 932 | 911 | 
| 933   if (isException) | 912   if (isException) | 
| 934     return new ElemHideException(text, domain, selector); | 913     return new ElemHideException(text, domain, selector); | 
| 935 | 914 | 
| 936   let match = Filter.csspropertyRegExp.exec(selector); | 915   if (selector.indexOf("[-abp-properties") != -1) | 
| 937   if (match) |  | 
| 938   { | 916   { | 
| 939     // CSS property filters are inefficient so we need to make sure that | 917     // Element hiding emulation filters are inefficient so we need to make sure | 
| 940     // they're only applied if they specify active domains | 918     // that they're only applied if they specify active domains | 
| 941     if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 919     if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 
| 942       return new InvalidFilter(text, "filter_cssproperty_nodomain"); | 920       return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); | 
| 943 | 921 | 
| 944     return new CSSPropertyFilter(text, domain, selector, match[2], | 922     return new ElemHideEmulationFilter(text, domain, selector); | 
| 945       selector.substr(0, match.index), |  | 
| 946       selector.substr(match.index + match[0].length)); |  | 
| 947   } | 923   } | 
| 948 | 924 | 
| 949   return new ElemHideFilter(text, domain, selector); | 925   return new ElemHideFilter(text, domain, selector); | 
| 950 }; | 926 }; | 
| 951 | 927 | 
| 952 /** | 928 /** | 
| 953  * Class for element hiding filters | 929  * Class for element hiding filters | 
| 954  * @param {String} text see Filter() | 930  * @param {String} text see Filter() | 
| 955  * @param {String} domains  see ElemHideBase() | 931  * @param {String} domains  see ElemHideBase() | 
| 956  * @param {String} selector see ElemHideBase() | 932  * @param {String} selector see ElemHideBase() | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 979 { | 955 { | 
| 980   ElemHideBase.call(this, text, domains, selector); | 956   ElemHideBase.call(this, text, domains, selector); | 
| 981 } | 957 } | 
| 982 exports.ElemHideException = ElemHideException; | 958 exports.ElemHideException = ElemHideException; | 
| 983 | 959 | 
| 984 ElemHideException.prototype = extend(ElemHideBase, { | 960 ElemHideException.prototype = extend(ElemHideBase, { | 
| 985   type: "elemhideexception" | 961   type: "elemhideexception" | 
| 986 }); | 962 }); | 
| 987 | 963 | 
| 988 /** | 964 /** | 
| 989  * Class for CSS property filters | 965  * Class for element hiding emulation filters | 
| 990  * @param {String} text           see Filter() | 966  * @param {String} text           see Filter() | 
| 991  * @param {String} domains        see ElemHideBase() | 967  * @param {String} domains        see ElemHideBase() | 
| 992  * @param {String} selector       see ElemHideBase() | 968  * @param {String} selector       see ElemHideBase() | 
| 993  * @param {String} regexpSource   see CSSPropertyFilter.regexpSource |  | 
| 994  * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix |  | 
| 995  * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix |  | 
| 996  * @constructor | 969  * @constructor | 
| 997  * @augments ElemHideBase | 970  * @augments ElemHideBase | 
| 998  */ | 971  */ | 
| 999 function CSSPropertyFilter(text, domains, selector, regexpSource, | 972 function ElemHideEmulationFilter(text, domains, selector) | 
| 1000   selectorPrefix, selectorSuffix) |  | 
| 1001 { | 973 { | 
| 1002   ElemHideBase.call(this, text, domains, selector); | 974   ElemHideBase.call(this, text, domains, selector); | 
|  | 975 } | 
|  | 976 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 
| 1003 | 977 | 
| 1004   this.regexpSource = regexpSource; | 978 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 
| 1005   this.selectorPrefix = selectorPrefix; | 979   type: "elemhideemulation" | 
| 1006   this.selectorSuffix = selectorSuffix; |  | 
| 1007 } |  | 
| 1008 exports.CSSPropertyFilter = CSSPropertyFilter; |  | 
| 1009 |  | 
| 1010 CSSPropertyFilter.prototype = extend(ElemHideBase, { |  | 
| 1011   type: "cssproperty", |  | 
| 1012 |  | 
| 1013   /** |  | 
| 1014    * Expression from which a regular expression should be generated for matching |  | 
| 1015    * CSS properties - for delayed creation of the regexpString property |  | 
| 1016    * @type String |  | 
| 1017    */ |  | 
| 1018   regexpSource: null, |  | 
| 1019   /** |  | 
| 1020    * Substring of CSS selector before properties for the HTML elements that |  | 
| 1021    * should be hidden |  | 
| 1022    * @type String |  | 
| 1023    */ |  | 
| 1024   selectorPrefix: null, |  | 
| 1025   /** |  | 
| 1026    * Substring of CSS selector after properties for the HTML elements that |  | 
| 1027    * should be hidden |  | 
| 1028    * @type String |  | 
| 1029    */ |  | 
| 1030   selectorSuffix: null, |  | 
| 1031 |  | 
| 1032   /** |  | 
| 1033    * Raw regular expression string to be used when testing CSS properties |  | 
| 1034    * against this filter |  | 
| 1035    * @type String |  | 
| 1036    */ |  | 
| 1037   get regexpString() |  | 
| 1038   { |  | 
| 1039     // Despite this property being cached, the getter is called |  | 
| 1040     // several times on Safari, due to WebKit bug 132872 |  | 
| 1041     let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); |  | 
| 1042     if (prop) |  | 
| 1043       return prop.value; |  | 
| 1044 |  | 
| 1045     let regexp; |  | 
| 1046     if (this.regexpSource.length >= 2 && this.regexpSource[0] == "/" && |  | 
| 1047         this.regexpSource[this.regexpSource.length - 1] == "/") |  | 
| 1048       regexp = this.regexpSource.slice(1, -1); |  | 
| 1049     else |  | 
| 1050       regexp = Filter.toRegExp(this.regexpSource); |  | 
| 1051     Object.defineProperty(this, "regexpString", {value: regexp}); |  | 
| 1052     return regexp; |  | 
| 1053   } |  | 
| 1054 }); | 980 }); | 
| OLD | NEW | 
|---|