UNPKG

@angular/compiler

Version:

Angular - the compiler library

768 lines • 122 kB
/** * @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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