processPseudoSelector method
Implementation
SimpleSelector? processPseudoSelector(FileSpan start) {
// :pseudo-class ::pseudo-element
// TODO(terry): '::' should be token.
_eat(TokenKind.COLON);
var pseudoElement = _maybeEat(TokenKind.COLON);
// TODO(terry): If no identifier specified consider optimizing out the
// : or :: and making this a normal selector. For now,
// create an empty pseudoName.
// TODO(jiangzhou): Forced to evade
Identifier pseudoName;
if (_peekIdentifier()) {
pseudoName = identifier();
if (pseudoName.isFunction()) {
return null;
}
} else {
return null;
}
var name = pseudoName.name.toLowerCase();
// Functional pseudo?
if (_peekToken.kind == TokenKind.LPAREN) {
if (!pseudoElement && name == 'not') {
_eat(TokenKind.LPAREN);
// Negation : ':NOT(' S* negation_arg S* ')'
var negArg = simpleSelector();
_eat(TokenKind.RPAREN);
return NegationSelector(negArg);
} else if (!pseudoElement &&
(name == 'host' || name == 'host-context' || name == 'global-context' || name == '-acx-global-context')) {
_eat(TokenKind.LPAREN);
var selector = processCompoundSelector();
if (selector == null) {
_errorExpected('a selector argument');
return null;
}
_eat(TokenKind.RPAREN);
return PseudoClassFunctionSelector(pseudoName, selector);
} else {
// Special parsing for expressions in pseudo functions. Minus is used
// as operator not identifier.
// TODO(jmesserly): we need to flip this before we eat the "(" as the
// next token will be fetched when we do that. I think we should try to
// refactor so we don't need this boolean; it seems fragile.
tokenizer.inSelectorExpression = true;
_eat(TokenKind.LPAREN);
// Handle function expression.
var expr = processSelectorExpression();
tokenizer.inSelectorExpression = false;
// Used during selector look-a-head if not a SelectorExpression is
// bad.
_eat(TokenKind.RPAREN);
return (pseudoElement)
? PseudoElementFunctionSelector(pseudoName, expr)
: PseudoClassFunctionSelector(pseudoName, expr);
}
}
// Treat CSS2.1 pseudo-elements defined with pseudo class syntax as pseudo-
// elements for backwards compatibility.
return pseudoElement || _legacyPseudoElements.contains(name)
? PseudoElementSelector(pseudoName, isLegacy: !pseudoElement)
: PseudoClassSelector(pseudoName);
}