processDeclaration method
Implementation
void processDeclaration(CSSStyleDeclaration style) {
// IDENT ':' expr '!important'?
if (TokenKind.isIdentifier(_peekToken.kind)) {
var propertyIdent = camelize(identifier().name);
var resetProperty = false;
var keepGoing = true;
while (keepGoing) {
switch (_peek()) {
case TokenKind.COLON:
_eat(TokenKind.COLON);
keepGoing = false;
break;
case TokenKind.SEMICOLON:
case TokenKind.NEWLINE:
resetProperty = true;
_next();
break;
case TokenKind.IDENTIFIER:
if (resetProperty) {
propertyIdent = identifier().name;
} else {
keepGoing = false;
}
break;
default:
keepGoing = false;
}
}
var expr = processExpr();
if (expr != null) {
// Handle !important (prio)
var importantPriority = _maybeEat(TokenKind.IMPORTANT);
// CSS only allows a single `!important` marker. If we see another
// `!important` (or any other trailing token) before `;`/`}` then the
// whole declaration is invalid and must be ignored, but we should
// recover to continue parsing subsequent declarations.
//
// This matters for custom properties, e.g.:
// --a: var(--b) !important !important;
// which must be dropped per spec.
final trailingToken = _peek();
final hasUnexpectedTrailingToken = trailingToken != TokenKind.SEMICOLON &&
trailingToken != TokenKind.RBRACE &&
trailingToken != TokenKind.END_OF_FILE;
if ((importantPriority && trailingToken == TokenKind.IMPORTANT) || hasUnexpectedTrailingToken) {
_skipToDeclarationEnd();
return;
}
style.setProperty(propertyIdent, expr, isImportant: importantPriority, baseHref: href);
}
} else if (_peekToken.kind == TokenKind.VAR_DEFINITION) {
_next();
} else if (_peekToken.kind == TokenKind.DIRECTIVE_INCLUDE) {
// TODO @include mixinName in the declaration area.
} else if (_peekToken.kind == TokenKind.DIRECTIVE_EXTEND) {
_next();
}
}