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; |