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-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 * @type RegExp | 81 * @type RegExp |
82 */ | 82 */ |
83 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[ ^,\s]+)?)*)?$/; | 83 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[ ^,\s]+)?)*)?$/; |
84 /** | 84 /** |
85 * Regular expression that options on a RegExp filter should match | 85 * Regular expression that options on a RegExp filter should match |
86 * @type RegExp | 86 * @type RegExp |
87 */ | 87 */ |
88 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/ ; | 88 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/ ; |
89 /** | 89 /** |
90 * Regular expression that CSS property filters should match | 90 * Regular expression that CSS property filters should match |
91 * Properties must not contain " or ' | |
91 * @type RegExp | 92 * @type RegExp |
92 */ | 93 */ |
93 Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; | 94 Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; |
Sebastian Noack
2015/05/05 15:47:02
So we don't allow quotes in the value here. Should
Thomas Greiner
2015/05/06 12:08:32
Done, I added a comment as suggested. We could cha
Thomas Greiner
2015/05/06 15:33:07
Yes, there's currently no negative lookbehind in J
Sebastian Noack
2015/05/06 15:42:29
Yeah, let's stick to not allowing any quotes for n
| |
94 | 95 |
95 /** | 96 /** |
96 * Creates a filter of correct type from its text representation - does the basi c parsing and | 97 * Creates a filter of correct type from its text representation - does the basi c parsing and |
97 * calls the right constructor then. | 98 * calls the right constructor then. |
98 * | 99 * |
99 * @param {String} text as in Filter() | 100 * @param {String} text as in Filter() |
100 * @return {Filter} | 101 * @return {Filter} |
101 */ | 102 */ |
102 Filter.fromText = function(text) | 103 Filter.fromText = function(text) |
103 { | 104 { |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 collapse = true; | 712 collapse = true; |
712 else if (option == "~COLLAPSE") | 713 else if (option == "~COLLAPSE") |
713 collapse = false; | 714 collapse = false; |
714 else if (option == "SITEKEY" && typeof value != "undefined") | 715 else if (option == "SITEKEY" && typeof value != "undefined") |
715 sitekeys = value; | 716 sitekeys = value; |
716 else | 717 else |
717 return new InvalidFilter(origText, "Unknown option " + option.toLowerCas e()); | 718 return new InvalidFilter(origText, "Unknown option " + option.toLowerCas e()); |
718 } | 719 } |
719 } | 720 } |
720 | 721 |
721 if (!blocking && (contentType == null || (contentType & RegExpFilter.typeMap.D OCUMENT)) && | |
722 (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text )) | |
723 { | |
724 // Exception filters shouldn't apply to pages by default unless they start w ith a protocol name | |
725 if (contentType == null) | |
726 contentType = RegExpFilter.prototype.contentType; | |
727 contentType &= ~RegExpFilter.typeMap.DOCUMENT; | |
728 } | |
729 | |
730 try | 722 try |
731 { | 723 { |
732 if (blocking) | 724 if (blocking) |
733 return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse); | 725 return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse); |
734 else | 726 else |
735 return new WhitelistFilter(origText, text, contentType, matchCase, domains , thirdParty, sitekeys); | 727 return new WhitelistFilter(origText, text, contentType, matchCase, domains , thirdParty, sitekeys); |
736 } | 728 } |
737 catch (e) | 729 catch (e) |
738 { | 730 { |
739 return new InvalidFilter(origText, e); | 731 return new InvalidFilter(origText, e); |
(...skipping 18 matching lines...) Expand all Loading... | |
758 DTD: 1, | 750 DTD: 1, |
759 MEDIA: 16384, | 751 MEDIA: 16384, |
760 FONT: 32768, | 752 FONT: 32768, |
761 | 753 |
762 BACKGROUND: 4, // Backwards compat, same as IMAGE | 754 BACKGROUND: 4, // Backwards compat, same as IMAGE |
763 | 755 |
764 POPUP: 0x10000000, | 756 POPUP: 0x10000000, |
765 ELEMHIDE: 0x40000000 | 757 ELEMHIDE: 0x40000000 |
766 }; | 758 }; |
767 | 759 |
768 // ELEMHIDE, POPUP option shouldn't be there by default | 760 // DOCUMENT, ELEMHIDE, POPUP options shouldn't be there by default |
769 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFi lter.typeMap.POPUP); | 761 RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.DOCUMENT | RegExpFi lter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP); |
770 | 762 |
771 /** | 763 /** |
772 * Class for blocking filters | 764 * Class for blocking filters |
773 * @param {String} text see Filter() | 765 * @param {String} text see Filter() |
774 * @param {String} regexpSource see RegExpFilter() | 766 * @param {String} regexpSource see RegExpFilter() |
775 * @param {Number} contentType see RegExpFilter() | 767 * @param {Number} contentType see RegExpFilter() |
776 * @param {Boolean} matchCase see RegExpFilter() | 768 * @param {Boolean} matchCase see RegExpFilter() |
777 * @param {String} domains see RegExpFilter() | 769 * @param {String} domains see RegExpFilter() |
778 * @param {Boolean} thirdParty see RegExpFilter() | 770 * @param {Boolean} thirdParty see RegExpFilter() |
779 * @param {String} sitekeys see RegExpFilter() | 771 * @param {String} sitekeys see RegExpFilter() |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
879 */ | 871 */ |
880 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, selector) | 872 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, selector) |
881 { | 873 { |
882 if (!selector) | 874 if (!selector) |
883 { | 875 { |
884 if (tagName == "*") | 876 if (tagName == "*") |
885 tagName = ""; | 877 tagName = ""; |
886 | 878 |
887 let id = null; | 879 let id = null; |
888 let additional = ""; | 880 let additional = ""; |
889 if (attrRules) { | 881 if (attrRules) |
882 { | |
890 attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g); | 883 attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g); |
891 for (let rule of attrRules) { | 884 for (let rule of attrRules) |
885 { | |
892 rule = rule.substr(1, rule.length - 2); | 886 rule = rule.substr(1, rule.length - 2); |
893 let separatorPos = rule.indexOf("="); | 887 let separatorPos = rule.indexOf("="); |
894 if (separatorPos > 0) { | 888 if (separatorPos > 0) |
889 { | |
895 rule = rule.replace(/=/, '="') + '"'; | 890 rule = rule.replace(/=/, '="') + '"'; |
896 additional += "[" + rule + "]"; | 891 additional += "[" + rule + "]"; |
897 } | 892 } |
898 else { | 893 else |
894 { | |
899 if (id) | 895 if (id) |
900 return new InvalidFilter(text, Utils.getString("filter_elemhide_dupl icate_id")); | 896 return new InvalidFilter(text, Utils.getString("filter_elemhide_dupl icate_id")); |
901 else | 897 |
902 id = rule; | 898 id = rule; |
903 } | 899 } |
904 } | 900 } |
905 } | 901 } |
906 | 902 |
907 if (id) | 903 if (id) |
908 selector = tagName + "." + id + additional + "," + tagName + "#" + id + ad ditional; | 904 selector = tagName + "." + id + additional + "," + tagName + "#" + id + ad ditional; |
909 else if (tagName || additional) | 905 else if (tagName || additional) |
910 selector = tagName + additional; | 906 selector = tagName + additional; |
911 else | 907 else |
912 return new InvalidFilter(text, Utils.getString("filter_elemhide_nocriteria ")); | 908 return new InvalidFilter(text, Utils.getString("filter_elemhide_nocriteria ")); |
913 } | 909 } |
910 | |
914 if (isException) | 911 if (isException) |
915 return new ElemHideException(text, domain, selector); | 912 return new ElemHideException(text, domain, selector); |
916 else | 913 |
917 { | 914 let match = Filter.csspropertyRegExp.exec(selector); |
918 if (Filter.csspropertyRegExp.test(selector)) | 915 if (match) |
919 { | 916 { |
920 // CSS property filters are inefficient so we need to make sure that | 917 // CSS property filters are inefficient so we need to make sure that |
921 // they're only applied if they specify active domains | 918 // they're only applied if they specify active domains |
922 if (/,[^~]/.test("," + domain)) | 919 if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) |
Sebastian Noack
2015/05/05 15:47:02
I wonder whether we should also look for at least
Thomas Greiner
2015/05/06 12:08:32
Good point but note that this still doesn't cover
Sebastian Noack
2015/05/06 13:07:48
Hmm, if we want to do it properly, I suppose we ha
| |
923 return new CSSPropertyFilter(text, domain, selector); | 920 return new InvalidFilter(text, Utils.getString("filter_cssproperty_nodomai n")); |
924 else | 921 |
Sebastian Noack
2015/05/05 15:47:02
Nit: Redundant else statement.
| |
925 return new InvalidFilter(text, Utils.getString("filter_cssproperty_nodom ain")); | 922 return new CSSPropertyFilter(text, domain, selector, match[2], |
926 } | 923 selector.substr(0, match.index), |
927 else | 924 selector.substr(match.index + match[0].length)); |
Sebastian Noack
2015/05/05 15:47:02
Nit: Redundant else statement.
Thomas Greiner
2015/05/06 12:08:32
Done.
| |
928 return new ElemHideFilter(text, domain, selector); | 925 } |
929 } | 926 |
927 return new ElemHideFilter(text, domain, selector); | |
930 }; | 928 }; |
931 | 929 |
932 /** | 930 /** |
933 * Class for element hiding filters | 931 * Class for element hiding filters |
934 * @param {String} text see Filter() | 932 * @param {String} text see Filter() |
935 * @param {String} domains see ElemHideBase() | 933 * @param {String} domains see ElemHideBase() |
936 * @param {String} selector see ElemHideBase() | 934 * @param {String} selector see ElemHideBase() |
937 * @constructor | 935 * @constructor |
938 * @augments ElemHideBase | 936 * @augments ElemHideBase |
939 */ | 937 */ |
(...skipping 22 matching lines...) Expand all Loading... | |
962 } | 960 } |
963 exports.ElemHideException = ElemHideException; | 961 exports.ElemHideException = ElemHideException; |
964 | 962 |
965 ElemHideException.prototype = | 963 ElemHideException.prototype = |
966 { | 964 { |
967 __proto__: ElemHideBase.prototype | 965 __proto__: ElemHideBase.prototype |
968 }; | 966 }; |
969 | 967 |
970 /** | 968 /** |
971 * Class for CSS property filters | 969 * Class for CSS property filters |
972 * @param {String} text see Filter() | 970 * @param {String} text see Filter() |
973 * @param {String} domains see ElemHideBase() | 971 * @param {String} domains see ElemHideBase() |
974 * @param {String} selector see ElemHideBase() | 972 * @param {String} selector see ElemHideBase() |
973 * @param {String} regexpSource see CSSPropertyFilter.regexpSource | |
974 * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix | |
975 * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix | |
975 * @constructor | 976 * @constructor |
976 * @augments ElemHideBase | 977 * @augments ElemHideBase |
977 */ | 978 */ |
978 function CSSPropertyFilter(text, domains, selector) | 979 function CSSPropertyFilter(text, domains, selector, regexpSource, |
980 selectorPrefix, selectorSuffix) | |
979 { | 981 { |
980 ElemHideBase.call(this, text, domains, selector); | 982 ElemHideBase.call(this, text, domains, selector); |
981 | 983 |
982 let properties; | 984 this.regexpSource = regexpSource; |
983 [properties, , this.regexpSource] = selector.match(Filter.csspropertyRegExp); | 985 this.selectorPrefix = selectorPrefix; |
984 [this.selectorPrefix, this.selectorSuffix] = selector.split(properties); | 986 this.selectorSuffix = selectorSuffix; |
985 } | 987 } |
986 exports.CSSPropertyFilter = CSSPropertyFilter; | 988 exports.CSSPropertyFilter = CSSPropertyFilter; |
987 | 989 |
988 CSSPropertyFilter.prototype = | 990 CSSPropertyFilter.prototype = |
989 { | 991 { |
990 __proto__: ElemHideBase.prototype, | 992 __proto__: ElemHideBase.prototype, |
991 | 993 |
992 /** | 994 /** |
993 * Expression from which a regular expression should be generated for matching | 995 * Expression from which a regular expression should be generated for matching |
994 * CSS properties - for delayed creation of the regexp property | 996 * CSS properties - for delayed creation of the regexpString property |
995 * @type String | 997 * @type String |
996 */ | 998 */ |
997 regexpSource: null, | 999 regexpSource: null, |
998 /** | 1000 /** |
999 * Substring of CSS selector before properties for the HTML elements that | 1001 * Substring of CSS selector before properties for the HTML elements that |
1000 * should be hidden | 1002 * should be hidden |
1001 * @type String | 1003 * @type String |
1002 */ | 1004 */ |
1003 selectorPrefix: null, | 1005 selectorPrefix: null, |
1004 /** | 1006 /** |
1005 * Substring of CSS selector after properties for the HTML elements that | 1007 * Substring of CSS selector after properties for the HTML elements that |
1006 * should be hidden | 1008 * should be hidden |
1007 * @type String | 1009 * @type String |
1008 */ | 1010 */ |
1009 selectorSuffix: null, | 1011 selectorSuffix: null, |
1010 | 1012 |
1011 /** | 1013 /** |
1012 * Regular expression to be used when testing CSS properties against | 1014 * Raw regular expression string to be used when testing CSS properties |
1013 * this filter | 1015 * against this filter |
1014 * @type RegExp | 1016 * @type String |
1015 */ | 1017 */ |
1016 get regexp() | 1018 get regexpString() |
Sebastian Noack
2015/05/05 15:47:02
Hmm, this is almost the same code we already have
Thomas Greiner
2015/05/06 12:08:32
You're right, the issue description doesn't explic
Sebastian Noack
2015/05/06 13:07:48
Well, objects get serialized when passed to conten
| |
1017 { | 1019 { |
1018 // Despite this property being cached, the getter is called | 1020 // Despite this property being cached, the getter is called |
1019 // several times on Safari, due to WebKit bug 132872 | 1021 // several times on Safari, due to WebKit bug 132872 |
1020 let prop = Object.getOwnPropertyDescriptor(this, "regexp"); | 1022 let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); |
1021 if (prop) | 1023 if (prop) |
1022 return prop.value; | 1024 return prop.value; |
1023 | 1025 |
1024 let source = Filter.toRegExp(this.regexpSource); | 1026 let regexp = Filter.toRegExp(this.regexpSource); |
1025 let regexp = new RegExp(source, ""); | 1027 Object.defineProperty(this, "regexpString", {value: regexp}); |
1026 Object.defineProperty(this, "regexp", {value: regexp}); | |
1027 return regexp; | 1028 return regexp; |
1028 } | 1029 } |
1029 }; | 1030 }; |
LEFT | RIGHT |