| Left: | ||
| Right: |
| 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 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 * Regular expression that RegExp filters specified as RegExps should match | 89 * Regular expression that RegExp filters specified as RegExps should match |
| 90 * @type RegExp | 90 * @type RegExp |
| 91 */ | 91 */ |
| 92 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[ ^,\s]+)?)*)?$/; | 92 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[ ^,\s]+)?)*)?$/; |
| 93 /** | 93 /** |
| 94 * Regular expression that options on a RegExp filter should match | 94 * Regular expression that options on a RegExp filter should match |
| 95 * @type RegExp | 95 * @type RegExp |
| 96 */ | 96 */ |
| 97 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/ ; | 97 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/ ; |
| 98 /** | 98 /** |
| 99 * Regular expression that CSS property filters should match | 99 * Regular expression that element hiding filters using property selectors |
| 100 * should match | |
| 100 * Properties must not contain " or ' | 101 * Properties must not contain " or ' |
| 101 * @type RegExp | 102 * @type RegExp |
| 102 */ | 103 */ |
| 103 Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; | 104 Filter.propertyselectorRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; |
| 105 /** | |
| 106 * Regular expression that element hiding filters using the :has pseudo-class | |
| 107 * should match | |
| 108 * @type RegExp | |
| 109 */ | |
| 110 Filter.haspseudoclassRegExp = /:has\(/; | |
|
Felix Dahlke
2016/09/23 16:41:59
Didn't want to put too much energy into this regex
Felix Dahlke
2016/10/05 10:08:26
In-person comment from Wladimir: We probably don't
kzar
2016/10/05 11:58:15
Acknowledged.
| |
| 104 | 111 |
| 105 /** | 112 /** |
| 106 * Creates a filter of correct type from its text representation - does the basi c parsing and | 113 * Creates a filter of correct type from its text representation - does the basi c parsing and |
| 107 * calls the right constructor then. | 114 * calls the right constructor then. |
| 108 * | 115 * |
| 109 * @param {String} text as in Filter() | 116 * @param {String} text as in Filter() |
| 110 * @return {Filter} | 117 * @return {Filter} |
| 111 */ | 118 */ |
| 112 Filter.fromText = function(text) | 119 Filter.fromText = function(text) |
| 113 { | 120 { |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 | 883 |
| 877 /** | 884 /** |
| 878 * Creates an element hiding filter from a pre-parsed text representation | 885 * Creates an element hiding filter from a pre-parsed text representation |
| 879 * | 886 * |
| 880 * @param {String} text same as in Filter() | 887 * @param {String} text same as in Filter() |
| 881 * @param {String} domain domain part of the text representation (can be e mpty) | 888 * @param {String} domain domain part of the text representation (can be e mpty) |
| 882 * @param {Boolean} isException exception rule indicator | 889 * @param {Boolean} isException exception rule indicator |
| 883 * @param {String} tagName tag name part (can be empty) | 890 * @param {String} tagName tag name part (can be empty) |
| 884 * @param {String} attrRules attribute matching rules (can be empty) | 891 * @param {String} attrRules attribute matching rules (can be empty) |
| 885 * @param {String} selector raw CSS selector (can be empty) | 892 * @param {String} selector raw CSS selector (can be empty) |
| 886 * @return {ElemHideFilter|ElemHideException|CSSPropertyFilter|InvalidFilter} | 893 * @return {ElemHideFilter|ElemHideException|ElemHideEmulationFilter|InvalidFilt er} |
| 887 */ | 894 */ |
| 888 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, selector) | 895 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, selector) |
| 889 { | 896 { |
| 890 if (!selector) | 897 if (!selector) |
| 891 { | 898 { |
| 892 if (tagName == "*") | 899 if (tagName == "*") |
| 893 tagName = ""; | 900 tagName = ""; |
| 894 | 901 |
| 895 let id = null; | 902 let id = null; |
| 896 let additional = ""; | 903 let additional = ""; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 920 selector = tagName + "." + id + additional + "," + tagName + "#" + id + ad ditional; | 927 selector = tagName + "." + id + additional + "," + tagName + "#" + id + ad ditional; |
| 921 else if (tagName || additional) | 928 else if (tagName || additional) |
| 922 selector = tagName + additional; | 929 selector = tagName + additional; |
| 923 else | 930 else |
| 924 return new InvalidFilter(text, "filter_elemhide_nocriteria"); | 931 return new InvalidFilter(text, "filter_elemhide_nocriteria"); |
| 925 } | 932 } |
| 926 | 933 |
| 927 if (isException) | 934 if (isException) |
| 928 return new ElemHideException(text, domain, selector); | 935 return new ElemHideException(text, domain, selector); |
| 929 | 936 |
| 930 let match = Filter.csspropertyRegExp.exec(selector); | 937 let hasSelectorUsed = Filter.haspseudoclassRegExp.test(selector); |
|
Felix Dahlke
2016/09/23 16:41:59
This code block is all about checking if the eleme
kzar
2016/10/05 11:58:14
Yea I agree, if you don't move this into a separat
Felix Dahlke
2016/11/03 16:14:13
The code is quite a bit shorter now that I reduced
| |
| 931 if (match) | 938 let propertySelectorMatch = Filter.propertyselectorRegExp.exec(selector); |
|
Felix Dahlke
2016/09/23 16:41:59
I'm not really happy that we need to run every fea
kzar
2016/09/25 14:52:06
Could we have a regexp which matches all element h
Felix Dahlke
2016/09/30 10:22:26
Yeah, I think that should be possible. But it woul
| |
| 939 if (hasSelectorUsed || propertySelectorMatch) | |
| 932 { | 940 { |
| 933 // CSS property filters are inefficient so we need to make sure that | 941 // Element hiding emulation filters are inefficient so we need to make sure |
| 934 // they're only applied if they specify active domains | 942 // that they're only applied if they specify active domains |
| 935 if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 943 if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) |
| 936 return new InvalidFilter(text, "filter_cssproperty_nodomain"); | 944 return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); |
|
kzar
2016/09/25 15:51:12
(I guess we'll have to update this string in adblo
Felix Dahlke
2016/09/30 10:22:26
Yup, I was planning to roll out my adblockplus cha
Felix Dahlke
2016/10/05 10:08:27
In-person comment from Wladimir: It's a different
| |
| 937 | 945 |
| 938 return new CSSPropertyFilter(text, domain, selector, match[2], | 946 let regexpSource, selectorPrefix, selectorSuffix; |
| 939 selector.substr(0, match.index), | 947 if (propertySelectorMatch) |
| 940 selector.substr(match.index + match[0].length)); | 948 { |
| 949 regexpSource = propertySelectorMatch[2]; | |
|
Felix Dahlke
2016/09/23 16:41:59
These properties are only necessary for the CSSPro
kzar
2016/09/25 14:52:07
But we still need the selector suffix and prefix f
Felix Dahlke
2016/09/30 10:22:26
Well, a filter can have both :has and property sel
kzar
2016/10/05 11:58:15
OK fair enough, me neither to be honest.
| |
| 950 selectorPrefix = selector.substr(0, propertySelectorMatch.index); | |
| 951 selectorSuffix = selector.substr(propertySelectorMatch.index | |
| 952 + propertySelectorMatch[0].length); | |
| 953 } | |
| 954 | |
| 955 let features = 0; | |
| 956 if (hasSelectorUsed) | |
| 957 features |= ElemHideEmulationFilter.featureMap.HAS_PSEUDO_CLASS; | |
| 958 if (propertySelectorMatch) | |
| 959 features |= ElemHideEmulationFilter.featureMap.PROPERTY_SELECTOR; | |
| 960 | |
| 961 return new ElemHideEmulationFilter(text, domain, selector, features, | |
| 962 regexpSourcex, selectorPrefix, selectorSuffix); | |
| 941 } | 963 } |
| 942 | 964 |
| 943 return new ElemHideFilter(text, domain, selector); | 965 return new ElemHideFilter(text, domain, selector); |
| 944 }; | 966 }; |
| 945 | 967 |
| 946 /** | 968 /** |
| 947 * Class for element hiding filters | 969 * Class for element hiding filters |
| 948 * @param {String} text see Filter() | 970 * @param {String} text see Filter() |
| 949 * @param {String} domains see ElemHideBase() | 971 * @param {String} domains see ElemHideBase() |
| 950 * @param {String} selector see ElemHideBase() | 972 * @param {String} selector see ElemHideBase() |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 973 { | 995 { |
| 974 ElemHideBase.call(this, text, domains, selector); | 996 ElemHideBase.call(this, text, domains, selector); |
| 975 } | 997 } |
| 976 exports.ElemHideException = ElemHideException; | 998 exports.ElemHideException = ElemHideException; |
| 977 | 999 |
| 978 ElemHideException.prototype = extend(ElemHideBase, { | 1000 ElemHideException.prototype = extend(ElemHideBase, { |
| 979 type: "elemhideexception" | 1001 type: "elemhideexception" |
| 980 }); | 1002 }); |
| 981 | 1003 |
| 982 /** | 1004 /** |
| 983 * Class for CSS property filters | 1005 * Class for element hiding emulation filters |
| 984 * @param {String} text see Filter() | 1006 * @param {String} text see Filter() |
| 985 * @param {String} domains see ElemHideBase() | 1007 * @param {String} domains see ElemHideBase() |
| 986 * @param {String} selector see ElemHideBase() | 1008 * @param {String} selector see ElemHideBase() |
| 987 * @param {String} regexpSource see CSSPropertyFilter.regexpSource | 1009 * @param {Integer} features see ElemHideEmulationFilter.features |
| 988 * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix | 1010 * @param {String} regexpSource see ElemHideEmulationFilter.regexpSource |
| 989 * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix | 1011 * @param {String} selectorPrefix see ElemHideEmulationFilter.selectorPrefix |
| 1012 * @param {String} selectorSuffix see ElemHideEmulationFilter.selectorSuffix | |
| 990 * @constructor | 1013 * @constructor |
| 991 * @augments ElemHideBase | 1014 * @augments ElemHideBase |
| 992 */ | 1015 */ |
| 993 function CSSPropertyFilter(text, domains, selector, regexpSource, | 1016 function ElemHideEmulationFilter(text, domains, selector, features, |
| 994 selectorPrefix, selectorSuffix) | 1017 regexpSource, selectorPrefix, selectorSuffix) |
| 995 { | 1018 { |
| 996 ElemHideBase.call(this, text, domains, selector); | 1019 ElemHideBase.call(this, text, domains, selector); |
| 997 | 1020 |
| 1021 this.features = features; | |
| 998 this.regexpSource = regexpSource; | 1022 this.regexpSource = regexpSource; |
| 999 this.selectorPrefix = selectorPrefix; | 1023 this.selectorPrefix = selectorPrefix; |
| 1000 this.selectorSuffix = selectorSuffix; | 1024 this.selectorSuffix = selectorSuffix; |
| 1001 } | 1025 } |
| 1002 exports.CSSPropertyFilter = CSSPropertyFilter; | 1026 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
| 1003 | 1027 |
| 1004 CSSPropertyFilter.prototype = extend(ElemHideBase, { | 1028 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
| 1005 type: "cssproperty", | 1029 type: "elemhideemulation", |
| 1030 | |
| 1031 /** | |
| 1032 * Features used in this filter, combination of values from | |
| 1033 * ElemHideEmulationFilter.featureMap | |
| 1034 * @type Integer | |
| 1035 */ | |
| 1036 features: 0, | |
| 1006 | 1037 |
| 1007 /** | 1038 /** |
| 1008 * Expression from which a regular expression should be generated for matching | 1039 * Expression from which a regular expression should be generated for matching |
| 1009 * CSS properties - for delayed creation of the regexpString property | 1040 * CSS properties - for delayed creation of the regexpString property |
| 1010 * @type String | 1041 * @type String |
| 1011 */ | 1042 */ |
| 1012 regexpSource: null, | 1043 regexpSource: null, |
| 1013 /** | 1044 /** |
| 1014 * Substring of CSS selector before properties for the HTML elements that | 1045 * Substring of CSS selector before properties for the HTML elements that |
| 1015 * should be hidden | 1046 * should be hidden |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1034 // several times on Safari, due to WebKit bug 132872 | 1065 // several times on Safari, due to WebKit bug 132872 |
| 1035 let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); | 1066 let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); |
| 1036 if (prop) | 1067 if (prop) |
| 1037 return prop.value; | 1068 return prop.value; |
| 1038 | 1069 |
| 1039 let regexp = Filter.toRegExp(this.regexpSource); | 1070 let regexp = Filter.toRegExp(this.regexpSource); |
| 1040 Object.defineProperty(this, "regexpString", {value: regexp}); | 1071 Object.defineProperty(this, "regexpString", {value: regexp}); |
| 1041 return regexp; | 1072 return regexp; |
| 1042 } | 1073 } |
| 1043 }); | 1074 }); |
| 1075 | |
| 1076 /** | |
| 1077 * Map of features supported by element hiding emulation filters | |
| 1078 */ | |
| 1079 ElemHideEmulationFilter.featureMap = { | |
| 1080 PROPERTY_SELECTOR: 1, | |
| 1081 HAS_PSEUDO_CLASS: 2 | |
| 1082 }; | |
| OLD | NEW |