@angular/compiler
Version:
Angular - the compiler library
768 lines • 122 kB
JavaScript
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/compiler/src/css_parser/css_parser", ["require", "exports", "tslib", "@angular/compiler/src/chars", "@angular/compiler/src/parse_util", "@angular/compiler/src/css_parser/css_ast", "@angular/compiler/src/css_parser/css_lexer", "@angular/compiler/src/css_parser/css_lexer", "@angular/compiler/src/css_parser/css_ast"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var chars = require("@angular/compiler/src/chars");
var parse_util_1 = require("@angular/compiler/src/parse_util");
var css_ast_1 = require("@angular/compiler/src/css_parser/css_ast");
var css_lexer_1 = require("@angular/compiler/src/css_parser/css_lexer");
var SPACE_OPERATOR = ' ';
var css_lexer_2 = require("@angular/compiler/src/css_parser/css_lexer");
exports.CssToken = css_lexer_2.CssToken;
var css_ast_2 = require("@angular/compiler/src/css_parser/css_ast");
exports.BlockType = css_ast_2.BlockType;
var SLASH_CHARACTER = '/';
var GT_CHARACTER = '>';
var TRIPLE_GT_OPERATOR_STR = '>>>';
var DEEP_OPERATOR_STR = '/deep/';
var EOF_DELIM_FLAG = 1;
var RBRACE_DELIM_FLAG = 2;
var LBRACE_DELIM_FLAG = 4;
var COMMA_DELIM_FLAG = 8;
var COLON_DELIM_FLAG = 16;
var SEMICOLON_DELIM_FLAG = 32;
var NEWLINE_DELIM_FLAG = 64;
var RPAREN_DELIM_FLAG = 128;
var LPAREN_DELIM_FLAG = 256;
var SPACE_DELIM_FLAG = 512;
function _pseudoSelectorSupportsInnerSelectors(name) {
return ['not', 'host', 'host-context'].indexOf(name) >= 0;
}
function isSelectorOperatorCharacter(code) {
switch (code) {
case chars.$SLASH:
case chars.$TILDA:
case chars.$PLUS:
case chars.$GT:
return true;
default:
return chars.isWhitespace(code);
}
}
function getDelimFromCharacter(code) {
switch (code) {
case chars.$EOF:
return EOF_DELIM_FLAG;
case chars.$COMMA:
return COMMA_DELIM_FLAG;
case chars.$COLON:
return COLON_DELIM_FLAG;
case chars.$SEMICOLON:
return SEMICOLON_DELIM_FLAG;
case chars.$RBRACE:
return RBRACE_DELIM_FLAG;
case chars.$LBRACE:
return LBRACE_DELIM_FLAG;
case chars.$RPAREN:
return RPAREN_DELIM_FLAG;
case chars.$SPACE:
case chars.$TAB:
return SPACE_DELIM_FLAG;
default:
return css_lexer_1.isNewline(code) ? NEWLINE_DELIM_FLAG : 0;
}
}
function characterContainsDelimiter(code, delimiters) {
return (getDelimFromCharacter(code) & delimiters) > 0;
}
var ParsedCssResult = /** @class */ (function () {
function ParsedCssResult(errors, ast) {
this.errors = errors;
this.ast = ast;
}
return ParsedCssResult;
}());
exports.ParsedCssResult = ParsedCssResult;
var CssParser = /** @class */ (function () {
function CssParser() {
this._errors = [];
}
/**
* @param css the CSS code that will be parsed
* @param url the name of the CSS file containing the CSS source code
*/
CssParser.prototype.parse = function (css, url) {
var lexer = new css_lexer_1.CssLexer();
this._file = new parse_util_1.ParseSourceFile(css, url);
this._scanner = lexer.scan(css, false);
var ast = this._parseStyleSheet(EOF_DELIM_FLAG);
var errors = this._errors;
this._errors = [];
var result = new ParsedCssResult(errors, ast);
this._file = null;
this._scanner = null;
return result;
};
/** @internal */
CssParser.prototype._parseStyleSheet = function (delimiters) {
var results = [];
this._scanner.consumeEmptyStatements();
while (this._scanner.peek != chars.$EOF) {
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
results.push(this._parseRule(delimiters));
}
var span = null;
if (results.length > 0) {
var firstRule = results[0];
// we collect the last token like so incase there was an
// EOF token that was emitted sometime during the lexing
span = this._generateSourceSpan(firstRule, this._lastToken);
}
return new css_ast_1.CssStyleSheetAst(span, results);
};
/** @internal */
CssParser.prototype._getSourceContent = function () { return this._scanner != null ? this._scanner.input : ''; };
/** @internal */
CssParser.prototype._extractSourceContent = function (start, end) {
return this._getSourceContent().substring(start, end + 1);
};
/** @internal */
CssParser.prototype._generateSourceSpan = function (start, end) {
if (end === void 0) { end = null; }
var startLoc;
if (start instanceof css_ast_1.CssAst) {
startLoc = start.location.start;
}
else {
var token = start;
if (token == null) {
// the data here is invalid, however, if and when this does
// occur, any other errors associated with this will be collected
token = this._lastToken;
}
startLoc = new parse_util_1.ParseLocation(this._file, token.index, token.line, token.column);
}
if (end == null) {
end = this._lastToken;
}
var endLine = -1;
var endColumn = -1;
var endIndex = -1;
if (end instanceof css_ast_1.CssAst) {
endLine = end.location.end.line;
endColumn = end.location.end.col;
endIndex = end.location.end.offset;
}
else if (end instanceof css_lexer_1.CssToken) {
endLine = end.line;
endColumn = end.column;
endIndex = end.index;
}
var endLoc = new parse_util_1.ParseLocation(this._file, endIndex, endLine, endColumn);
return new parse_util_1.ParseSourceSpan(startLoc, endLoc);
};
/** @internal */
CssParser.prototype._resolveBlockType = function (token) {
switch (token.strValue) {
case '@-o-keyframes':
case '@-moz-keyframes':
case '@-webkit-keyframes':
case '@keyframes':
return css_ast_1.BlockType.Keyframes;
case '@charset':
return css_ast_1.BlockType.Charset;
case '@import':
return css_ast_1.BlockType.Import;
case '@namespace':
return css_ast_1.BlockType.Namespace;
case '@page':
return css_ast_1.BlockType.Page;
case '@document':
return css_ast_1.BlockType.Document;
case '@media':
return css_ast_1.BlockType.MediaQuery;
case '@font-face':
return css_ast_1.BlockType.FontFace;
case '@viewport':
return css_ast_1.BlockType.Viewport;
case '@supports':
return css_ast_1.BlockType.Supports;
default:
return css_ast_1.BlockType.Unsupported;
}
};
/** @internal */
CssParser.prototype._parseRule = function (delimiters) {
if (this._scanner.peek == chars.$AT) {
return this._parseAtRule(delimiters);
}
return this._parseSelectorRule(delimiters);
};
/** @internal */
CssParser.prototype._parseAtRule = function (delimiters) {
var start = this._getScannerIndex();
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
var token = this._scan();
var startToken = token;
this._assertCondition(token.type == css_lexer_1.CssTokenType.AtKeyword, "The CSS Rule " + token.strValue + " is not a valid [@] rule.", token);
var block;
var type = this._resolveBlockType(token);
var span;
var tokens;
var endToken;
var end;
var strValue;
var query;
switch (type) {
case css_ast_1.BlockType.Charset:
case css_ast_1.BlockType.Namespace:
case css_ast_1.BlockType.Import:
var value = this._parseValue(delimiters);
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
this._scanner.consumeEmptyStatements();
span = this._generateSourceSpan(startToken, value);
return new css_ast_1.CssInlineRuleAst(span, type, value);
case css_ast_1.BlockType.Viewport:
case css_ast_1.BlockType.FontFace:
block = this._parseStyleBlock(delimiters);
span = this._generateSourceSpan(startToken, block);
return new css_ast_1.CssBlockRuleAst(span, type, block);
case css_ast_1.BlockType.Keyframes:
tokens = this._collectUntilDelim(delimiters | RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG);
// keyframes only have one identifier name
var name_1 = tokens[0];
block = this._parseKeyframeBlock(delimiters);
span = this._generateSourceSpan(startToken, block);
return new css_ast_1.CssKeyframeRuleAst(span, name_1, block);
case css_ast_1.BlockType.MediaQuery:
this._scanner.setMode(css_lexer_1.CssLexerMode.MEDIA_QUERY);
tokens = this._collectUntilDelim(delimiters | RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG);
endToken = tokens[tokens.length - 1];
// we do not track the whitespace after the mediaQuery predicate ends
// so we have to calculate the end string value on our own
end = endToken.index + endToken.strValue.length - 1;
strValue = this._extractSourceContent(start, end);
span = this._generateSourceSpan(startToken, endToken);
query = new css_ast_1.CssAtRulePredicateAst(span, strValue, tokens);
block = this._parseBlock(delimiters);
strValue = this._extractSourceContent(start, this._getScannerIndex() - 1);
span = this._generateSourceSpan(startToken, block);
return new css_ast_1.CssMediaQueryRuleAst(span, strValue, query, block);
case css_ast_1.BlockType.Document:
case css_ast_1.BlockType.Supports:
case css_ast_1.BlockType.Page:
this._scanner.setMode(css_lexer_1.CssLexerMode.AT_RULE_QUERY);
tokens = this._collectUntilDelim(delimiters | RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG);
endToken = tokens[tokens.length - 1];
// we do not track the whitespace after this block rule predicate ends
// so we have to calculate the end string value on our own
end = endToken.index + endToken.strValue.length - 1;
strValue = this._extractSourceContent(start, end);
span = this._generateSourceSpan(startToken, tokens[tokens.length - 1]);
query = new css_ast_1.CssAtRulePredicateAst(span, strValue, tokens);
block = this._parseBlock(delimiters);
strValue = this._extractSourceContent(start, block.end.offset);
span = this._generateSourceSpan(startToken, block);
return new css_ast_1.CssBlockDefinitionRuleAst(span, strValue, type, query, block);
// if a custom @rule { ... } is used it should still tokenize the insides
default:
var listOfTokens_1 = [];
var tokenName = token.strValue;
this._scanner.setMode(css_lexer_1.CssLexerMode.ALL);
this._error(css_lexer_1.generateErrorMessage(this._getSourceContent(), "The CSS \"at\" rule \"" + tokenName + "\" is not allowed to used here", token.strValue, token.index, token.line, token.column), token);
this._collectUntilDelim(delimiters | LBRACE_DELIM_FLAG | SEMICOLON_DELIM_FLAG)
.forEach(function (token) { listOfTokens_1.push(token); });
if (this._scanner.peek == chars.$LBRACE) {
listOfTokens_1.push(this._consume(css_lexer_1.CssTokenType.Character, '{'));
this._collectUntilDelim(delimiters | RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG)
.forEach(function (token) { listOfTokens_1.push(token); });
listOfTokens_1.push(this._consume(css_lexer_1.CssTokenType.Character, '}'));
}
endToken = listOfTokens_1[listOfTokens_1.length - 1];
span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssUnknownRuleAst(span, tokenName, listOfTokens_1);
}
};
/** @internal */
CssParser.prototype._parseSelectorRule = function (delimiters) {
var start = this._getScannerIndex();
var selectors = this._parseSelectors(delimiters);
var block = this._parseStyleBlock(delimiters);
var ruleAst;
var span;
var startSelector = selectors[0];
if (block != null) {
span = this._generateSourceSpan(startSelector, block);
ruleAst = new css_ast_1.CssSelectorRuleAst(span, selectors, block);
}
else {
var name_2 = this._extractSourceContent(start, this._getScannerIndex() - 1);
var innerTokens_1 = [];
selectors.forEach(function (selector) {
selector.selectorParts.forEach(function (part) {
part.tokens.forEach(function (token) { innerTokens_1.push(token); });
});
});
var endToken = innerTokens_1[innerTokens_1.length - 1];
span = this._generateSourceSpan(startSelector, endToken);
ruleAst = new css_ast_1.CssUnknownTokenListAst(span, name_2, innerTokens_1);
}
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
this._scanner.consumeEmptyStatements();
return ruleAst;
};
/** @internal */
CssParser.prototype._parseSelectors = function (delimiters) {
delimiters |= LBRACE_DELIM_FLAG | SEMICOLON_DELIM_FLAG;
var selectors = [];
var isParsingSelectors = true;
while (isParsingSelectors) {
selectors.push(this._parseSelector(delimiters));
isParsingSelectors = !characterContainsDelimiter(this._scanner.peek, delimiters);
if (isParsingSelectors) {
this._consume(css_lexer_1.CssTokenType.Character, ',');
isParsingSelectors = !characterContainsDelimiter(this._scanner.peek, delimiters);
if (isParsingSelectors) {
this._scanner.consumeWhitespace();
}
}
}
return selectors;
};
/** @internal */
CssParser.prototype._scan = function () {
var output = this._scanner.scan();
var token = output.token;
var error = output.error;
if (error != null) {
this._error(css_lexer_1.getRawMessage(error), token);
}
this._lastToken = token;
return token;
};
/** @internal */
CssParser.prototype._getScannerIndex = function () { return this._scanner.index; };
/** @internal */
CssParser.prototype._consume = function (type, value) {
if (value === void 0) { value = null; }
var output = this._scanner.consume(type, value);
var token = output.token;
var error = output.error;
if (error != null) {
this._error(css_lexer_1.getRawMessage(error), token);
}
this._lastToken = token;
return token;
};
/** @internal */
CssParser.prototype._parseKeyframeBlock = function (delimiters) {
delimiters |= RBRACE_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.KEYFRAME_BLOCK);
var startToken = this._consume(css_lexer_1.CssTokenType.Character, '{');
var definitions = [];
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
definitions.push(this._parseKeyframeDefinition(delimiters));
}
var endToken = this._consume(css_lexer_1.CssTokenType.Character, '}');
var span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssBlockAst(span, definitions);
};
/** @internal */
CssParser.prototype._parseKeyframeDefinition = function (delimiters) {
var start = this._getScannerIndex();
var stepTokens = [];
delimiters |= LBRACE_DELIM_FLAG;
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
stepTokens.push(this._parseKeyframeLabel(delimiters | COMMA_DELIM_FLAG));
if (this._scanner.peek != chars.$LBRACE) {
this._consume(css_lexer_1.CssTokenType.Character, ',');
}
}
var stylesBlock = this._parseStyleBlock(delimiters | RBRACE_DELIM_FLAG);
var span = this._generateSourceSpan(stepTokens[0], stylesBlock);
var ast = new css_ast_1.CssKeyframeDefinitionAst(span, stepTokens, stylesBlock);
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
return ast;
};
/** @internal */
CssParser.prototype._parseKeyframeLabel = function (delimiters) {
this._scanner.setMode(css_lexer_1.CssLexerMode.KEYFRAME_BLOCK);
return css_ast_1.mergeTokens(this._collectUntilDelim(delimiters));
};
/** @internal */
CssParser.prototype._parsePseudoSelector = function (delimiters) {
var start = this._getScannerIndex();
delimiters &= ~COMMA_DELIM_FLAG;
// we keep the original value since we may use it to recurse when :not, :host are used
var startingDelims = delimiters;
var startToken = this._consume(css_lexer_1.CssTokenType.Character, ':');
var tokens = [startToken];
if (this._scanner.peek == chars.$COLON) { // ::something
tokens.push(this._consume(css_lexer_1.CssTokenType.Character, ':'));
}
var innerSelectors = [];
this._scanner.setMode(css_lexer_1.CssLexerMode.PSEUDO_SELECTOR);
// host, host-context, lang, not, nth-child are all identifiers
var pseudoSelectorToken = this._consume(css_lexer_1.CssTokenType.Identifier);
var pseudoSelectorName = pseudoSelectorToken.strValue;
tokens.push(pseudoSelectorToken);
// host(), lang(), nth-child(), etc...
if (this._scanner.peek == chars.$LPAREN) {
this._scanner.setMode(css_lexer_1.CssLexerMode.PSEUDO_SELECTOR_WITH_ARGUMENTS);
var openParenToken = this._consume(css_lexer_1.CssTokenType.Character, '(');
tokens.push(openParenToken);
// :host(innerSelector(s)), :not(selector), etc...
if (_pseudoSelectorSupportsInnerSelectors(pseudoSelectorName)) {
var innerDelims = startingDelims | LPAREN_DELIM_FLAG | RPAREN_DELIM_FLAG;
if (pseudoSelectorName == 'not') {
// the inner selector inside of :not(...) can only be one
// CSS selector (no commas allowed) ... This is according
// to the CSS specification
innerDelims |= COMMA_DELIM_FLAG;
}
// :host(a, b, c) {
this._parseSelectors(innerDelims).forEach(function (selector, index) {
innerSelectors.push(selector);
});
}
else {
// this branch is for things like "en-us, 2k + 1, etc..."
// which all end up in pseudoSelectors like :lang, :nth-child, etc..
var innerValueDelims = delimiters | LBRACE_DELIM_FLAG | COLON_DELIM_FLAG |
RPAREN_DELIM_FLAG | LPAREN_DELIM_FLAG;
while (!characterContainsDelimiter(this._scanner.peek, innerValueDelims)) {
var token = this._scan();
tokens.push(token);
}
}
var closeParenToken = this._consume(css_lexer_1.CssTokenType.Character, ')');
tokens.push(closeParenToken);
}
var end = this._getScannerIndex() - 1;
var strValue = this._extractSourceContent(start, end);
var endToken = tokens[tokens.length - 1];
var span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssPseudoSelectorAst(span, strValue, pseudoSelectorName, tokens, innerSelectors);
};
/** @internal */
CssParser.prototype._parseSimpleSelector = function (delimiters) {
var start = this._getScannerIndex();
delimiters |= COMMA_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.SELECTOR);
var selectorCssTokens = [];
var pseudoSelectors = [];
var previousToken = undefined;
var selectorPartDelimiters = delimiters | SPACE_DELIM_FLAG;
var loopOverSelector = !characterContainsDelimiter(this._scanner.peek, selectorPartDelimiters);
var hasAttributeError = false;
while (loopOverSelector) {
var peek = this._scanner.peek;
switch (peek) {
case chars.$COLON:
var innerPseudo = this._parsePseudoSelector(delimiters);
pseudoSelectors.push(innerPseudo);
this._scanner.setMode(css_lexer_1.CssLexerMode.SELECTOR);
break;
case chars.$LBRACKET:
// we set the mode after the scan because attribute mode does not
// allow attribute [] values. And this also will catch any errors
// if an extra "[" is used inside.
selectorCssTokens.push(this._scan());
this._scanner.setMode(css_lexer_1.CssLexerMode.ATTRIBUTE_SELECTOR);
break;
case chars.$RBRACKET:
if (this._scanner.getMode() != css_lexer_1.CssLexerMode.ATTRIBUTE_SELECTOR) {
hasAttributeError = true;
}
// we set the mode early because attribute mode does not
// allow attribute [] values
this._scanner.setMode(css_lexer_1.CssLexerMode.SELECTOR);
selectorCssTokens.push(this._scan());
break;
default:
if (isSelectorOperatorCharacter(peek)) {
loopOverSelector = false;
continue;
}
var token = this._scan();
previousToken = token;
selectorCssTokens.push(token);
break;
}
loopOverSelector = !characterContainsDelimiter(this._scanner.peek, selectorPartDelimiters);
}
hasAttributeError =
hasAttributeError || this._scanner.getMode() == css_lexer_1.CssLexerMode.ATTRIBUTE_SELECTOR;
if (hasAttributeError) {
this._error("Unbalanced CSS attribute selector at column " + previousToken.line + ":" + previousToken.column, previousToken);
}
var end = this._getScannerIndex() - 1;
// this happens if the selector is not directly followed by
// a comma or curly brace without a space in between
var operator = null;
var operatorScanCount = 0;
var lastOperatorToken = null;
if (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
while (operator == null && !characterContainsDelimiter(this._scanner.peek, delimiters) &&
isSelectorOperatorCharacter(this._scanner.peek)) {
var token = this._scan();
var tokenOperator = token.strValue;
operatorScanCount++;
lastOperatorToken = token;
if (tokenOperator != SPACE_OPERATOR) {
switch (tokenOperator) {
case SLASH_CHARACTER:
// /deep/ operator
var deepToken = this._consume(css_lexer_1.CssTokenType.Identifier);
var deepSlash = this._consume(css_lexer_1.CssTokenType.Character);
var index = lastOperatorToken.index;
var line = lastOperatorToken.line;
var column = lastOperatorToken.column;
if (deepToken != null && deepToken.strValue.toLowerCase() == 'deep' &&
deepSlash.strValue == SLASH_CHARACTER) {
token = new css_lexer_1.CssToken(lastOperatorToken.index, lastOperatorToken.column, lastOperatorToken.line, css_lexer_1.CssTokenType.Identifier, DEEP_OPERATOR_STR);
}
else {
var text = SLASH_CHARACTER + deepToken.strValue + deepSlash.strValue;
this._error(css_lexer_1.generateErrorMessage(this._getSourceContent(), text + " is an invalid CSS operator", text, index, line, column), lastOperatorToken);
token = new css_lexer_1.CssToken(index, column, line, css_lexer_1.CssTokenType.Invalid, text);
}
break;
case GT_CHARACTER:
// >>> operator
if (this._scanner.peek == chars.$GT && this._scanner.peekPeek == chars.$GT) {
this._consume(css_lexer_1.CssTokenType.Character, GT_CHARACTER);
this._consume(css_lexer_1.CssTokenType.Character, GT_CHARACTER);
token = new css_lexer_1.CssToken(lastOperatorToken.index, lastOperatorToken.column, lastOperatorToken.line, css_lexer_1.CssTokenType.Identifier, TRIPLE_GT_OPERATOR_STR);
}
break;
}
operator = token;
}
}
// so long as there is an operator then we can have an
// ending value that is beyond the selector value ...
// otherwise it's just a bunch of trailing whitespace
if (operator != null) {
end = operator.index;
}
}
this._scanner.consumeWhitespace();
var strValue = this._extractSourceContent(start, end);
// if we do come across one or more spaces inside of
// the operators loop then an empty space is still a
// valid operator to use if something else was not found
if (operator == null && operatorScanCount > 0 && this._scanner.peek != chars.$LBRACE) {
operator = lastOperatorToken;
}
// please note that `endToken` is reassigned multiple times below
// so please do not optimize the if statements into if/elseif
var startTokenOrAst = null;
var endTokenOrAst = null;
if (selectorCssTokens.length > 0) {
startTokenOrAst = startTokenOrAst || selectorCssTokens[0];
endTokenOrAst = selectorCssTokens[selectorCssTokens.length - 1];
}
if (pseudoSelectors.length > 0) {
startTokenOrAst = startTokenOrAst || pseudoSelectors[0];
endTokenOrAst = pseudoSelectors[pseudoSelectors.length - 1];
}
if (operator != null) {
startTokenOrAst = startTokenOrAst || operator;
endTokenOrAst = operator;
}
var span = this._generateSourceSpan(startTokenOrAst, endTokenOrAst);
return new css_ast_1.CssSimpleSelectorAst(span, selectorCssTokens, strValue, pseudoSelectors, operator);
};
/** @internal */
CssParser.prototype._parseSelector = function (delimiters) {
delimiters |= COMMA_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.SELECTOR);
var simpleSelectors = [];
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
simpleSelectors.push(this._parseSimpleSelector(delimiters));
this._scanner.consumeWhitespace();
}
var firstSelector = simpleSelectors[0];
var lastSelector = simpleSelectors[simpleSelectors.length - 1];
var span = this._generateSourceSpan(firstSelector, lastSelector);
return new css_ast_1.CssSelectorAst(span, simpleSelectors);
};
/** @internal */
CssParser.prototype._parseValue = function (delimiters) {
delimiters |= RBRACE_DELIM_FLAG | SEMICOLON_DELIM_FLAG | NEWLINE_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_VALUE);
var start = this._getScannerIndex();
var tokens = [];
var wsStr = '';
var previous = undefined;
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
var token = void 0;
if (previous != null && previous.type == css_lexer_1.CssTokenType.Identifier &&
this._scanner.peek == chars.$LPAREN) {
token = this._consume(css_lexer_1.CssTokenType.Character, '(');
tokens.push(token);
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_VALUE_FUNCTION);
token = this._scan();
tokens.push(token);
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_VALUE);
token = this._consume(css_lexer_1.CssTokenType.Character, ')');
tokens.push(token);
}
else {
token = this._scan();
if (token.type == css_lexer_1.CssTokenType.Whitespace) {
wsStr += token.strValue;
}
else {
wsStr = '';
tokens.push(token);
}
}
previous = token;
}
var end = this._getScannerIndex() - 1;
this._scanner.consumeWhitespace();
var code = this._scanner.peek;
if (code == chars.$SEMICOLON) {
this._consume(css_lexer_1.CssTokenType.Character, ';');
}
else if (code != chars.$RBRACE) {
this._error(css_lexer_1.generateErrorMessage(this._getSourceContent(), "The CSS key/value definition did not end with a semicolon", previous.strValue, previous.index, previous.line, previous.column), previous);
}
var strValue = this._extractSourceContent(start, end);
var startToken = tokens[0];
var endToken = tokens[tokens.length - 1];
var span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssStyleValueAst(span, tokens, strValue);
};
/** @internal */
CssParser.prototype._collectUntilDelim = function (delimiters, assertType) {
if (assertType === void 0) { assertType = null; }
var tokens = [];
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
var val = assertType != null ? this._consume(assertType) : this._scan();
tokens.push(val);
}
return tokens;
};
/** @internal */
CssParser.prototype._parseBlock = function (delimiters) {
delimiters |= RBRACE_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
var startToken = this._consume(css_lexer_1.CssTokenType.Character, '{');
this._scanner.consumeEmptyStatements();
var results = [];
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
results.push(this._parseRule(delimiters));
}
var endToken = this._consume(css_lexer_1.CssTokenType.Character, '}');
this._scanner.setMode(css_lexer_1.CssLexerMode.BLOCK);
this._scanner.consumeEmptyStatements();
var span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssBlockAst(span, results);
};
/** @internal */
CssParser.prototype._parseStyleBlock = function (delimiters) {
delimiters |= RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG;
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_BLOCK);
var startToken = this._consume(css_lexer_1.CssTokenType.Character, '{');
if (startToken.numValue != chars.$LBRACE) {
return null;
}
var definitions = [];
this._scanner.consumeEmptyStatements();
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
definitions.push(this._parseDefinition(delimiters));
this._scanner.consumeEmptyStatements();
}
var endToken = this._consume(css_lexer_1.CssTokenType.Character, '}');
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_BLOCK);
this._scanner.consumeEmptyStatements();
var span = this._generateSourceSpan(startToken, endToken);
return new css_ast_1.CssStylesBlockAst(span, definitions);
};
/** @internal */
CssParser.prototype._parseDefinition = function (delimiters) {
this._scanner.setMode(css_lexer_1.CssLexerMode.STYLE_BLOCK);
var prop = this._consume(css_lexer_1.CssTokenType.Identifier);
var parseValue = false;
var value = null;
var endToken = prop;
// the colon value separates the prop from the style.
// there are a few cases as to what could happen if it
// is missing
switch (this._scanner.peek) {
case chars.$SEMICOLON:
case chars.$RBRACE:
case chars.$EOF:
parseValue = false;
break;
default:
var propStr_1 = [prop.strValue];
if (this._scanner.peek != chars.$COLON) {
// this will throw the error
var nextValue = this._consume(css_lexer_1.CssTokenType.Character, ':');
propStr_1.push(nextValue.strValue);
var remainingTokens = this._collectUntilDelim(delimiters | COLON_DELIM_FLAG | SEMICOLON_DELIM_FLAG, css_lexer_1.CssTokenType.Identifier);
if (remainingTokens.length > 0) {
remainingTokens.forEach(function (token) { propStr_1.push(token.strValue); });
}
endToken = prop =
new css_lexer_1.CssToken(prop.index, prop.column, prop.line, prop.type, propStr_1.join(' '));
}
// this means we've reached the end of the definition and/or block
if (this._scanner.peek == chars.$COLON) {
this._consume(css_lexer_1.CssTokenType.Character, ':');
parseValue = true;
}
break;
}
if (parseValue) {
value = this._parseValue(delimiters);
endToken = value;
}
else {
this._error(css_lexer_1.generateErrorMessage(this._getSourceContent(), "The CSS property was not paired with a style value", prop.strValue, prop.index, prop.line, prop.column), prop);
}
var span = this._generateSourceSpan(prop, endToken);
return new css_ast_1.CssDefinitionAst(span, prop, value);
};
/** @internal */
CssParser.prototype._assertCondition = function (status, errorMessage, problemToken) {
if (!status) {
this._error(errorMessage, problemToken);
return true;
}
return false;
};
/** @internal */
CssParser.prototype._error = function (message, problemToken) {
var length = problemToken.strValue.length;
var error = CssParseError.create(this._file, 0, problemToken.line, problemToken.column, length, message);
this._errors.push(error);
};
return CssParser;
}());
exports.CssParser = CssParser;
var CssParseError = /** @class */ (function (_super) {
tslib_1.__extends(CssParseError, _super);
function CssParseError(span, message) {
return _super.call(this, span, message) || this;
}
CssParseError.create = function (file, offset, line, col, length, errMsg) {
var start = new parse_util_1.ParseLocation(file, offset, line, col);
var end = new parse_util_1.ParseLocation(file, offset, line, col + length);
var span = new parse_util_1.ParseSourceSpan(start, end);
return new CssParseError(span, 'CSS Parse Error: ' + errMsg);
};
return CssParseError;
}(parse_util_1.ParseError));
exports.CssParseError = CssParseError;
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3NzX3BhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9jc3NfcGFyc2VyL2Nzc19wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7O0lBRUgsbURBQWtDO0lBQ2xDLCtEQUEwRjtJQUUxRixvRUFBK2E7SUFDL2Esd0VBQXVJO0lBRXZJLElBQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztJQUUzQix3RUFBcUM7SUFBN0IsK0JBQUEsUUFBUSxDQUFBO0lBQ2hCLG9FQUFvQztJQUE1Qiw4QkFBQSxTQUFTLENBQUE7SUFFakIsSUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDO0lBQzVCLElBQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztJQUN6QixJQUFNLHNCQUFzQixHQUFHLEtBQUssQ0FBQztJQUNyQyxJQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQztJQUVuQyxJQUFNLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDekIsSUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7SUFDNUIsSUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7SUFDNUIsSUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFDM0IsSUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDNUIsSUFBTSxvQkFBb0IsR0FBRyxFQUFFLENBQUM7SUFDaEMsSUFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUM7SUFDOUIsSUFBTSxpQkFBaUIsR0FBRyxHQUFHLENBQUM7SUFDOUIsSUFBTSxpQkFBaUIsR0FBRyxHQUFHLENBQUM7SUFDOUIsSUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7SUFFN0IsK0NBQStDLElBQVk7UUFDekQsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1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