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 |