mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-11 09:31:01 +01:00
code review fix as per https://github.com/gorhill/uBlock/issues/2793#issuecomment-333269387
This commit is contained in:
parent
b3e4caa59f
commit
ca299a394f
1 changed files with 77 additions and 22 deletions
|
@ -723,9 +723,17 @@ FilterContainer.prototype.compileSelector = (function() {
|
||||||
reStyleBad = /url\([^)]+\)/,
|
reStyleBad = /url\([^)]+\)/,
|
||||||
reScriptSelector = /^script:(contains|inject)\((.+)\)$/,
|
reScriptSelector = /^script:(contains|inject)\((.+)\)$/,
|
||||||
reExtendedSyntax = /\[-(?:abp|ext)-[a-z-]+=(['"])(?:.+?)(?:\1)\]/,
|
reExtendedSyntax = /\[-(?:abp|ext)-[a-z-]+=(['"])(?:.+?)(?:\1)\]/,
|
||||||
reExtendedSyntaxHas = /\[-ext-has=(['"])(.+?)\1\]/,
|
reExtendedSyntaxParser = /\[-(?:abp|ext)-([a-z-]+)=(['"])(.+?)\2\]/,
|
||||||
div = document.createElement('div');
|
div = document.createElement('div');
|
||||||
|
|
||||||
|
var normalizedExtendedSyntaxOperators = new Map([
|
||||||
|
[ 'contains', ':has-text' ],
|
||||||
|
[ 'has', ':if' ],
|
||||||
|
[ 'matches-css', ':matches-css' ],
|
||||||
|
[ 'matches-css-after', ':matches-css-after' ],
|
||||||
|
[ 'matches-css-before', ':matches-css-before' ],
|
||||||
|
]);
|
||||||
|
|
||||||
var isValidStyleProperty = function(cssText) {
|
var isValidStyleProperty = function(cssText) {
|
||||||
if ( reStyleBad.test(cssText) ) { return false; }
|
if ( reStyleBad.test(cssText) ) { return false; }
|
||||||
div.style.cssText = cssText;
|
div.style.cssText = cssText;
|
||||||
|
@ -735,32 +743,32 @@ FilterContainer.prototype.compileSelector = (function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var entryPoint = function(raw) {
|
var entryPoint = function(raw) {
|
||||||
if ( isValidCSSSelector(raw) && reExtendedSyntax.test(raw) === false ) {
|
var extendedSyntax = reExtendedSyntax.test(raw);
|
||||||
|
if ( isValidCSSSelector(raw) && extendedSyntax === false ) {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We rarely reach this point -- majority of selectors are plain
|
// We rarely reach this point -- majority of selectors are plain
|
||||||
// CSS selectors.
|
// CSS selectors.
|
||||||
|
|
||||||
// Unsupported ABP's advanced selector syntax.
|
var matches, operator;
|
||||||
if ( raw.indexOf('[-abp-properties=') !== -1 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var matches;
|
// Supported Adguard/ABP advanced selector syntax: will translate into
|
||||||
|
|
||||||
// Supported Adguard's advanced selector syntax: will translate into
|
|
||||||
// uBO's syntax before further processing.
|
// uBO's syntax before further processing.
|
||||||
//
|
// Mind unsupported advanced selector syntax, such as ABP's
|
||||||
// [-ext-has=...]
|
// `-abp-properties`.
|
||||||
// Converted to `:if(...)`, because Adguard accepts procedural
|
// Note: extended selector syntax has been deprecated in ABP, in favor
|
||||||
// selectors within its `:has(...)` selector.
|
// of the procedural one (i.e. `:operator(...)`). See
|
||||||
if ( (matches = reExtendedSyntaxHas.exec(raw)) !== null ) {
|
// https://issues.adblockplus.org/ticket/5287
|
||||||
return this.compileSelector(
|
if ( extendedSyntax ) {
|
||||||
raw.slice(0, matches.index) +
|
while ( (matches = reExtendedSyntaxParser.exec(raw)) !== null ) {
|
||||||
':if('+ matches[2].replace(/:contains\(/g, ':has-text(') + ')' +
|
operator = normalizedExtendedSyntaxOperators.get(matches[1]);
|
||||||
raw.slice(matches.index + matches[0].length)
|
if ( operator === undefined ) { return; }
|
||||||
);
|
raw = raw.slice(0, matches.index) +
|
||||||
|
operator + '(' + matches[3] + ')' +
|
||||||
|
raw.slice(matches.index + matches[0].length);
|
||||||
|
}
|
||||||
|
return this.compileSelector(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
var selector = raw,
|
var selector = raw,
|
||||||
|
@ -838,7 +846,8 @@ FilterContainer.prototype.compileProceduralSelector = (function() {
|
||||||
reFirstParentheses = /^\(*/,
|
reFirstParentheses = /^\(*/,
|
||||||
reLastParentheses = /\)*$/,
|
reLastParentheses = /\)*$/,
|
||||||
reEscapeRegex = /[.*+?^${}()|[\]\\]/g,
|
reEscapeRegex = /[.*+?^${}()|[\]\\]/g,
|
||||||
reNeedScope = /^\s*[+>~]/;
|
reNeedScope = /^\s*[+>~]/,
|
||||||
|
reAllForwardSlashes = /\//g;
|
||||||
|
|
||||||
var lastProceduralSelector = '',
|
var lastProceduralSelector = '',
|
||||||
lastProceduralSelectorCompiled;
|
lastProceduralSelectorCompiled;
|
||||||
|
@ -916,6 +925,53 @@ FilterContainer.prototype.compileProceduralSelector = (function() {
|
||||||
[ ':xpath', compileXpathExpression ]
|
[ ':xpath', compileXpathExpression ]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/2793#issuecomment-333269387
|
||||||
|
// - Normalize (somewhat) the stringified version of procedural cosmetic
|
||||||
|
// filters -- this increase the likelihood of detecting duplicates given
|
||||||
|
// that uBO is able to understand syntax specific to other blockers.
|
||||||
|
// The normalized string version is what is reported in the logger, by
|
||||||
|
// design.
|
||||||
|
var decompile = function(compiled) {
|
||||||
|
var raw = [ compiled.selector ],
|
||||||
|
tasks = compiled.tasks;
|
||||||
|
if ( Array.isArray(tasks) ) {
|
||||||
|
for ( var i = 0, n = tasks.length, task; i < n; i++ ) {
|
||||||
|
task = tasks[i];
|
||||||
|
switch ( task[0] ) {
|
||||||
|
case ':has':
|
||||||
|
case ':xpath':
|
||||||
|
raw.push(task[0], '(', task[1], ')');
|
||||||
|
break;
|
||||||
|
case ':has-text':
|
||||||
|
raw.push(
|
||||||
|
task[0],
|
||||||
|
'(/',
|
||||||
|
task[1].replace(reAllForwardSlashes, '\\/'),
|
||||||
|
'/)'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ':matches-css':
|
||||||
|
case ':matches-css-after':
|
||||||
|
case ':matches-css-before':
|
||||||
|
raw.push(
|
||||||
|
task[0],
|
||||||
|
'(',
|
||||||
|
task[1].name,
|
||||||
|
': /',
|
||||||
|
task[1].value.replace(reAllForwardSlashes, '\\/'),
|
||||||
|
'/)'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ':if':
|
||||||
|
case ':if-not':
|
||||||
|
raw.push(task[0], '(', decompile(task[1]), ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return raw.join('');
|
||||||
|
};
|
||||||
|
|
||||||
var compile = function(raw) {
|
var compile = function(raw) {
|
||||||
var matches = reOperatorParser.exec(raw);
|
var matches = reOperatorParser.exec(raw);
|
||||||
if ( matches === null ) {
|
if ( matches === null ) {
|
||||||
|
@ -970,7 +1026,7 @@ FilterContainer.prototype.compileProceduralSelector = (function() {
|
||||||
lastProceduralSelector = raw;
|
lastProceduralSelector = raw;
|
||||||
var compiled = compile(raw);
|
var compiled = compile(raw);
|
||||||
if ( compiled !== undefined ) {
|
if ( compiled !== undefined ) {
|
||||||
compiled.raw = raw;
|
compiled.raw = decompile(compiled);
|
||||||
compiled = JSON.stringify(compiled);
|
compiled = JSON.stringify(compiled);
|
||||||
}
|
}
|
||||||
lastProceduralSelectorCompiled = compiled;
|
lastProceduralSelectorCompiled = compiled;
|
||||||
|
@ -1027,7 +1083,6 @@ FilterContainer.prototype.compile = function(s, writer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( parsed.invalid ) {
|
if ( parsed.invalid ) {
|
||||||
//console.error("uBlock Origin> discarding invalid cosmetic filter '%s'", s);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue