| Index: lib/filterClasses.js |
| =================================================================== |
| --- a/lib/filterClasses.js |
| +++ b/lib/filterClasses.js |
| @@ -16,16 +16,17 @@ |
| */ |
| /** |
| * @fileOverview Definition of Filter class and its subclasses. |
| */ |
| let {FilterNotifier} = require("filterNotifier"); |
| let {extend} = require("coreUtils"); |
| +let {elemHideEmulationFeatureMap, filterToRegExp} = require("shared"); |
| /** |
| * Abstract base class for filters |
| * |
| * @param {String} text string representation of the filter |
| * @constructor |
| */ |
| function Filter(text) |
| @@ -90,22 +91,16 @@ |
| * @type RegExp |
| */ |
| Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/; |
| /** |
| * Regular expression that options on a RegExp filter should match |
| * @type RegExp |
| */ |
| Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/; |
| -/** |
| - * Regular expression that CSS property filters should match |
| - * Properties must not contain " or ' |
| - * @type RegExp |
| - */ |
| -Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; |
| /** |
| * Creates a filter of correct type from its text representation - does the basic parsing and |
| * calls the right constructor then. |
| * |
| * @param {String} text as in Filter() |
| * @return {Filter} |
| */ |
| @@ -171,35 +166,19 @@ |
| let [, domain, separator, selector] = /^(.*?)(#\@?#?)(.*)$/.exec(text); |
| return domain.replace(/\s/g, "") + separator + selector.trim(); |
| } |
| else |
| return text.replace(/\s/g, ""); |
| }; |
| /** |
| - * Converts filter text into regular expression string |
| - * @param {String} text as in Filter() |
| - * @return {String} regular expression representation of filter text |
| + * @see filterToRegExp |
| */ |
| -Filter.toRegExp = function(text) |
| -{ |
| - return text |
| - .replace(/\*+/g, "*") // remove multiple wildcards |
| - .replace(/\^\|$/, "^") // remove anchors following separator placeholder |
| - .replace(/\W/g, "\\$&") // escape special symbols |
| - .replace(/\\\*/g, ".*") // replace wildcards by .* |
| - // process separator placeholders (all ANSI characters but alphanumeric characters and _%.-) |
| - .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x7F]|$)") |
| - .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?") // process extended anchor at expression start |
| - .replace(/^\\\|/, "^") // process anchor at expression start |
| - .replace(/\\\|$/, "$") // process anchor at expression end |
| - .replace(/^(\.\*)/, "") // remove leading wildcards |
| - .replace(/(\.\*)$/, ""); // remove trailing wildcards |
| -} |
| +Filter.toRegExp = filterToRegExp; |
| /** |
| * Class for invalid filters |
| * @param {String} text see Filter() |
| * @param {String} reason Reason why this filter is invalid |
| * @constructor |
| * @augments Filter |
| */ |
| @@ -878,17 +857,17 @@ |
| * Creates an element hiding filter from a pre-parsed text representation |
| * |
| * @param {String} text same as in Filter() |
| * @param {String} domain domain part of the text representation (can be empty) |
| * @param {Boolean} isException exception rule indicator |
| * @param {String} tagName tag name part (can be empty) |
| * @param {String} attrRules attribute matching rules (can be empty) |
| * @param {String} selector raw CSS selector (can be empty) |
| - * @return {ElemHideFilter|ElemHideException|CSSPropertyFilter|InvalidFilter} |
| + * @return {ElemHideFilter|ElemHideException|ElemHideEmulationFilter|InvalidFilter} |
| */ |
| ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, selector) |
| { |
| if (!selector) |
| { |
| if (tagName == "*") |
| tagName = ""; |
| @@ -928,27 +907,31 @@ |
| // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that |
| // changes this must be changed too. |
| if (domain && /(^|,)~?(,|$)/.test(domain)) |
| return new InvalidFilter(text, "filter_invalid_domain"); |
| if (isException) |
| return new ElemHideException(text, domain, selector); |
| - let match = Filter.csspropertyRegExp.exec(selector); |
| - if (match) |
| + let emulatedFeatures = 0; |
| + if (selector.indexOf("[-abp-properties") != -1) |
| + emulatedFeatures |= ElemHideEmulationFilter.featureMap.PROPERTY_SELECTOR; |
| + if (selector.indexOf(":has(") != -1) |
|
kzar
2016/11/04 15:45:56
The feature flags are a nice idea but I wonder wha
Felix Dahlke
2016/11/04 16:43:35
Well, if we detect NO feature here, this would jus
kzar
2016/11/07 12:36:26
I guess my question is what's the point of having
Felix Dahlke
2016/11/07 14:41:24
Well, we have to check for emulated features befor
kzar
2016/11/07 15:59:44
Well we don't need to set a boolean flag here eith
Felix Dahlke
2016/11/07 16:51:24
Yeah of course, my bad.
kzar
2016/11/07 17:10:22
That's not quite true, since if we're recording us
Felix Dahlke
2016/11/08 17:45:35
Well, sure, we don't have to run all checks if one
kzar
2016/11/15 16:54:13
Well no I think that if the only reason to add all
Felix Dahlke
2016/11/15 21:11:44
I still think it makes sense to start detecting (y
Wladimir Palant
2016/11/21 11:39:14
I actually have to agree with Dave here. You are d
Felix Dahlke
2016/11/21 14:38:58
Fair enough, I guess if we're not worried about ba
|
| + emulatedFeatures |= ElemHideEmulationFilter.featureMap.HAS_PSEUDO_CLASS; |
| + |
| + if (emulatedFeatures != 0) |
| { |
| - // CSS property filters are inefficient so we need to make sure that |
| - // they're only applied if they specify active domains |
| + // Element hiding emulation filters are inefficient so we need to make sure |
| + // that they're only applied if they specify active domains |
| if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) |
| - return new InvalidFilter(text, "filter_cssproperty_nodomain"); |
| + return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); |
| - return new CSSPropertyFilter(text, domain, selector, match[2], |
| - selector.substr(0, match.index), |
| - selector.substr(match.index + match[0].length)); |
| + return new ElemHideEmulationFilter(text, domain, selector, |
|
kzar
2016/11/04 15:45:56
I wonder if it's really a good idea to move the lo
Felix Dahlke
2016/11/04 16:43:35
Well, one part of the truth is that I don't know h
kzar
2016/11/07 17:19:25
That's a pretty good point actually, I didn't thin
|
| + emulatedFeatures); |
| } |
| return new ElemHideFilter(text, domain, selector); |
| }; |
| /** |
| * Class for element hiding filters |
| * @param {String} text see Filter() |
| @@ -981,69 +964,39 @@ |
| } |
| exports.ElemHideException = ElemHideException; |
| ElemHideException.prototype = extend(ElemHideBase, { |
| type: "elemhideexception" |
| }); |
| /** |
| - * Class for CSS property filters |
| + * Class for element hiding emulation filters |
| * @param {String} text see Filter() |
| * @param {String} domains see ElemHideBase() |
| * @param {String} selector see ElemHideBase() |
| - * @param {String} regexpSource see CSSPropertyFilter.regexpSource |
| - * @param {String} selectorPrefix see CSSPropertyFilter.selectorPrefix |
| - * @param {String} selectorSuffix see CSSPropertyFilter.selectorSuffix |
| + * @param {Integer} features see ElemHideEmulationFilter.features |
| * @constructor |
| * @augments ElemHideBase |
| */ |
| -function CSSPropertyFilter(text, domains, selector, regexpSource, |
| - selectorPrefix, selectorSuffix) |
| +function ElemHideEmulationFilter(text, domains, selector, features) |
| { |
| ElemHideBase.call(this, text, domains, selector); |
| - this.regexpSource = regexpSource; |
| - this.selectorPrefix = selectorPrefix; |
| - this.selectorSuffix = selectorSuffix; |
| + this.features = features; |
| } |
| -exports.CSSPropertyFilter = CSSPropertyFilter; |
| +exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
| -CSSPropertyFilter.prototype = extend(ElemHideBase, { |
| - type: "cssproperty", |
| +ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
| + type: "elemhideemulation", |
| /** |
| - * Expression from which a regular expression should be generated for matching |
| - * CSS properties - for delayed creation of the regexpString property |
| - * @type String |
| + * Features used in this filter, combination of values from |
|
kzar
2016/11/04 15:45:56
Perhaps describe it as bit flags instead of combin
Felix Dahlke
2016/11/04 16:43:35
I thought I'd keep this in line with the doc comme
kzar
2016/11/07 17:19:25
Well bitmap works too. (I guess if you're worried
|
| + * ElemHideEmulationFilter.featureMap |
| + * @type Integer |
| */ |
| - regexpSource: null, |
| - /** |
| - * Substring of CSS selector before properties for the HTML elements that |
| - * should be hidden |
| - * @type String |
| - */ |
| - selectorPrefix: null, |
| - /** |
| - * Substring of CSS selector after properties for the HTML elements that |
| - * should be hidden |
| - * @type String |
| - */ |
| - selectorSuffix: null, |
| + features: 0 |
| +}); |
| - /** |
| - * Raw regular expression string to be used when testing CSS properties |
| - * against this filter |
| - * @type String |
| - */ |
| - get regexpString() |
| - { |
| - // Despite this property being cached, the getter is called |
| - // several times on Safari, due to WebKit bug 132872 |
| - let prop = Object.getOwnPropertyDescriptor(this, "regexpString"); |
| - if (prop) |
| - return prop.value; |
| - |
| - let regexp = Filter.toRegExp(this.regexpSource); |
| - Object.defineProperty(this, "regexpString", {value: regexp}); |
| - return regexp; |
| - } |
| -}); |
| +/** |
| + * @see elemHideEmulationFeatureMap |
| + */ |
| +ElemHideEmulationFilter.featureMap = elemHideEmulationFeatureMap; |