Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/filterClasses.js

Issue 29354827: Issue 4394 - Create a filter class for element hiding emulation filters [WIP] (Closed)
Patch Set: Created Sept. 23, 2016, 4:21 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 };
OLDNEW

Powered by Google App Engine
This is Rietveld