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

Unified Diff: lib/filterClasses.js

Issue 29361668: Issue 4394 - Create a filter class for element hiding emulation filters (Closed) Base URL: https://bitbucket.org/fhd/adblockpluscore
Patch Set: Address Wladimir's comments Created Nov. 21, 2016, 2:34 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 {filterToRegExp} = require("common");
/**
* 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,25 @@
// 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)
+ if (selector.indexOf("[-abp-properties") != -1 ||
+ selector.indexOf(":has(") != -1)
kzar 2016/11/21 16:24:55 You're still checking for ":has".
Felix Dahlke 2016/11/21 17:26:12 Done.
{
- // 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);
}
return new ElemHideFilter(text, domain, selector);
};
/**
* Class for element hiding filters
* @param {String} text see Filter()
@@ -981,74 +958,24 @@
}
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
* @constructor
* @augments ElemHideBase
*/
-function CSSPropertyFilter(text, domains, selector, regexpSource,
- selectorPrefix, selectorSuffix)
+function ElemHideEmulationFilter(text, domains, selector)
{
ElemHideBase.call(this, text, domains, selector);
-
- this.regexpSource = regexpSource;
- this.selectorPrefix = selectorPrefix;
- this.selectorSuffix = selectorSuffix;
}
-exports.CSSPropertyFilter = CSSPropertyFilter;
-
-CSSPropertyFilter.prototype = extend(ElemHideBase, {
- type: "cssproperty",
+exports.ElemHideEmulationFilter = ElemHideEmulationFilter;
- /**
- * Expression from which a regular expression should be generated for matching
- * CSS properties - for delayed creation of the regexpString property
- * @type String
- */
- 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,
-
- /**
- * 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;
- if (this.regexpSource.length >= 2 && this.regexpSource[0] == "/" &&
- this.regexpSource[this.regexpSource.length - 1] == "/")
- regexp = this.regexpSource.slice(1, -1);
- else
- regexp = Filter.toRegExp(this.regexpSource);
- Object.defineProperty(this, "regexpString", {value: regexp});
- return regexp;
- }
+ElemHideEmulationFilter.prototype = extend(ElemHideBase, {
+ type: "elemhideemulation"
});

Powered by Google App Engine
This is Rietveld