This commit is contained in:
Raymond Hill 2017-12-30 16:02:34 -05:00
parent 9f89c67f3f
commit e84e79f96e
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -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; } // Unbalanced parenthesis?
selector = selector.slice(matches.index + nextOperator.length); 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 || depth !== 0 ) { return; } if ( tasks.length === 0 ) {
return { selector: firstOperand, tasks: tasks }; prefix = raw;
tasks = undefined;
}
if ( prefix !== '' && isValidCSSSelector(prefix) === false ) {
return;
}
return { selector: prefix, tasks: tasks };
}; };
var entryPoint = function(raw) { var entryPoint = function(raw) {