mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-11 09:31:01 +01:00
fix #3367
This commit is contained in:
parent
9f89c67f3f
commit
e84e79f96e
1 changed files with 58 additions and 57 deletions
|
@ -121,8 +121,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var compileProceduralSelector = (function() {
|
var compileProceduralSelector = (function() {
|
||||||
var reOperatorParser = new RegExp([
|
var reProceduralOperator = new RegExp([
|
||||||
'(:(?:',
|
'^(?:',
|
||||||
[
|
[
|
||||||
'-abp-contains',
|
'-abp-contains',
|
||||||
'-abp-has',
|
'-abp-has',
|
||||||
|
@ -136,12 +136,10 @@
|
||||||
'matches-css-before',
|
'matches-css-before',
|
||||||
'xpath'
|
'xpath'
|
||||||
].join('|'),
|
].join('|'),
|
||||||
'))\\(.+\\)$'
|
')\\('
|
||||||
].join(''));
|
].join(''));
|
||||||
|
|
||||||
var reFirstParentheses = /^\(*/,
|
var reEscapeRegex = /[.*+?^${}()|[\]\\]/g,
|
||||||
reLastParentheses = /\)*$/,
|
|
||||||
reEscapeRegex = /[.*+?^${}()|[\]\\]/g,
|
|
||||||
reNeedScope = /^\s*[+>~]/;
|
reNeedScope = /^\s*[+>~]/;
|
||||||
|
|
||||||
var lastProceduralSelector = '',
|
var lastProceduralSelector = '',
|
||||||
|
@ -269,62 +267,65 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var compile = function(raw) {
|
var compile = function(raw) {
|
||||||
var matches = reOperatorParser.exec(raw);
|
if ( raw === '' ) { return; }
|
||||||
if ( matches === null ) {
|
var prefix = '',
|
||||||
if ( isValidCSSSelector(raw) ) { return { selector: raw }; }
|
tasks = [];
|
||||||
return;
|
|
||||||
}
|
|
||||||
var tasks = [],
|
|
||||||
firstOperand = raw.slice(0, matches.index),
|
|
||||||
currentOperator = matches[1],
|
|
||||||
selector = raw.slice(matches.index + currentOperator.length),
|
|
||||||
currentArgument = '', nextOperand, nextOperator,
|
|
||||||
depth = 0, opening, closing;
|
|
||||||
if (
|
|
||||||
firstOperand !== '' &&
|
|
||||||
isValidCSSSelector(firstOperand) === false
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
matches = reOperatorParser.exec(selector);
|
var i = 0,
|
||||||
if ( matches !== null ) {
|
n = raw.length,
|
||||||
nextOperand = selector.slice(0, matches.index);
|
c, match;
|
||||||
nextOperator = matches[1];
|
// Advance to next operator.
|
||||||
} else {
|
while ( i < n ) {
|
||||||
nextOperand = selector;
|
c = raw.charCodeAt(i++);
|
||||||
nextOperator = '';
|
if ( c === 0x3A /* ':' */ ) {
|
||||||
}
|
match = reProceduralOperator.exec(raw.slice(i));
|
||||||
opening = reFirstParentheses.exec(nextOperand)[0].length;
|
if ( match !== null ) { break; }
|
||||||
closing = reLastParentheses.exec(nextOperand)[0].length;
|
|
||||||
if ( opening > closing ) {
|
|
||||||
if ( depth === 0 ) { currentArgument = ''; }
|
|
||||||
depth += 1;
|
|
||||||
} else if ( closing > opening && depth > 0 ) {
|
|
||||||
depth -= 1;
|
|
||||||
if ( depth === 0 ) {
|
|
||||||
nextOperand = currentArgument + nextOperand;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( depth !== 0 ) {
|
if ( i === n ) { break; }
|
||||||
currentArgument += nextOperand + nextOperator;
|
var opNameBeg = i - 1;
|
||||||
} else {
|
var opNameEnd = i + match[0].length - 1;
|
||||||
currentOperator =
|
i += match[0].length;
|
||||||
normalizedOperators.get(currentOperator) ||
|
// Find end of argument: first balanced closing parenthesis.
|
||||||
currentOperator;
|
// Note: unbalanced parenthesis can be used in a regex literal
|
||||||
currentArgument =
|
// when they are escaped using `\`.
|
||||||
compileArgument.get(currentOperator)(
|
var pcnt = 1;
|
||||||
nextOperand.slice(1, -1)
|
while ( i < n ) {
|
||||||
);
|
c = raw.charCodeAt(i++);
|
||||||
if ( currentArgument === undefined ) { return; }
|
if ( c === 0x5C /* '\\' */ ) {
|
||||||
tasks.push([ currentOperator, currentArgument ]);
|
if ( i < n ) { i += 1; }
|
||||||
currentOperator = nextOperator;
|
} else if ( c === 0x28 /* '(' */ ) {
|
||||||
|
pcnt +=1 ;
|
||||||
|
} else if ( c === 0x29 /* ')' */ ) {
|
||||||
|
pcnt -= 1;
|
||||||
|
if ( pcnt === 0 ) { break; }
|
||||||
}
|
}
|
||||||
if ( nextOperator === '' ) { break; }
|
|
||||||
selector = selector.slice(matches.index + nextOperator.length);
|
|
||||||
}
|
}
|
||||||
if ( tasks.length === 0 || depth !== 0 ) { return; }
|
// Unbalanced parenthesis?
|
||||||
return { selector: firstOperand, tasks: tasks };
|
if ( pcnt !== 0 ) { return; }
|
||||||
|
// Extract and remember operator details.
|
||||||
|
var operator = raw.slice(opNameBeg, opNameEnd);
|
||||||
|
operator = normalizedOperators.get(operator) || operator;
|
||||||
|
var args = raw.slice(opNameEnd + 1, i - 1);
|
||||||
|
args = compileArgument.get(operator)(args);
|
||||||
|
if ( args === undefined ) { return; }
|
||||||
|
if ( tasks.length === 0 ) {
|
||||||
|
prefix = raw.slice(0, opNameBeg);
|
||||||
|
} else if ( opNameBeg !== 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tasks.push([ operator, args ]);
|
||||||
|
if ( i === n ) { break; }
|
||||||
|
raw = raw.slice(i);
|
||||||
|
}
|
||||||
|
if ( tasks.length === 0 ) {
|
||||||
|
prefix = raw;
|
||||||
|
tasks = undefined;
|
||||||
|
}
|
||||||
|
if ( prefix !== '' && isValidCSSSelector(prefix) === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return { selector: prefix, tasks: tasks };
|
||||||
};
|
};
|
||||||
|
|
||||||
var entryPoint = function(raw) {
|
var entryPoint = function(raw) {
|
||||||
|
|
Loading…
Reference in a new issue