cssLexer.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var chars = require("./chars");
  4. var CssTokenType;
  5. (function (CssTokenType) {
  6. CssTokenType[CssTokenType["EOF"] = 0] = "EOF";
  7. CssTokenType[CssTokenType["String"] = 1] = "String";
  8. CssTokenType[CssTokenType["Comment"] = 2] = "Comment";
  9. CssTokenType[CssTokenType["Identifier"] = 3] = "Identifier";
  10. CssTokenType[CssTokenType["Number"] = 4] = "Number";
  11. CssTokenType[CssTokenType["IdentifierOrNumber"] = 5] = "IdentifierOrNumber";
  12. CssTokenType[CssTokenType["AtKeyword"] = 6] = "AtKeyword";
  13. CssTokenType[CssTokenType["Character"] = 7] = "Character";
  14. CssTokenType[CssTokenType["Whitespace"] = 8] = "Whitespace";
  15. CssTokenType[CssTokenType["Invalid"] = 9] = "Invalid";
  16. })(CssTokenType = exports.CssTokenType || (exports.CssTokenType = {}));
  17. var CssLexerMode;
  18. (function (CssLexerMode) {
  19. CssLexerMode[CssLexerMode["ALL"] = 0] = "ALL";
  20. CssLexerMode[CssLexerMode["ALL_TRACK_WS"] = 1] = "ALL_TRACK_WS";
  21. CssLexerMode[CssLexerMode["SELECTOR"] = 2] = "SELECTOR";
  22. CssLexerMode[CssLexerMode["PSEUDO_SELECTOR"] = 3] = "PSEUDO_SELECTOR";
  23. CssLexerMode[CssLexerMode["PSEUDO_SELECTOR_WITH_ARGUMENTS"] = 4] = "PSEUDO_SELECTOR_WITH_ARGUMENTS";
  24. CssLexerMode[CssLexerMode["ATTRIBUTE_SELECTOR"] = 5] = "ATTRIBUTE_SELECTOR";
  25. CssLexerMode[CssLexerMode["AT_RULE_QUERY"] = 6] = "AT_RULE_QUERY";
  26. CssLexerMode[CssLexerMode["MEDIA_QUERY"] = 7] = "MEDIA_QUERY";
  27. CssLexerMode[CssLexerMode["BLOCK"] = 8] = "BLOCK";
  28. CssLexerMode[CssLexerMode["KEYFRAME_BLOCK"] = 9] = "KEYFRAME_BLOCK";
  29. CssLexerMode[CssLexerMode["STYLE_BLOCK"] = 10] = "STYLE_BLOCK";
  30. CssLexerMode[CssLexerMode["STYLE_VALUE"] = 11] = "STYLE_VALUE";
  31. CssLexerMode[CssLexerMode["STYLE_VALUE_FUNCTION"] = 12] = "STYLE_VALUE_FUNCTION";
  32. CssLexerMode[CssLexerMode["STYLE_CALC_FUNCTION"] = 13] = "STYLE_CALC_FUNCTION";
  33. })(CssLexerMode = exports.CssLexerMode || (exports.CssLexerMode = {}));
  34. var LexedCssResult = (function () {
  35. function LexedCssResult(error, token) {
  36. this.error = error;
  37. this.token = token;
  38. }
  39. return LexedCssResult;
  40. }());
  41. exports.LexedCssResult = LexedCssResult;
  42. function generateErrorMessage(input, message, errorValue, index, row, column) {
  43. return message + " at column " + row + ":" + column + " in expression [" + findProblemCode(input, errorValue, index, column) + ']';
  44. }
  45. exports.generateErrorMessage = generateErrorMessage;
  46. function findProblemCode(input, errorValue, index, column) {
  47. var endOfProblemLine = index;
  48. var current = charCode(input, index);
  49. while (current > 0 && !isNewline(current)) {
  50. current = charCode(input, ++endOfProblemLine);
  51. }
  52. var choppedString = input.substring(0, endOfProblemLine);
  53. var pointerPadding = '';
  54. for (var i = 0; i < column; i++) {
  55. pointerPadding += ' ';
  56. }
  57. var pointerString = '';
  58. for (var i = 0; i < errorValue.length; i++) {
  59. pointerString += '^';
  60. }
  61. return choppedString + '\n' + pointerPadding + pointerString + '\n';
  62. }
  63. exports.findProblemCode = findProblemCode;
  64. var CssToken = (function () {
  65. function CssToken(index, column, line, type, strValue) {
  66. this.index = index;
  67. this.column = column;
  68. this.line = line;
  69. this.type = type;
  70. this.strValue = strValue;
  71. this.numValue = charCode(strValue, 0);
  72. }
  73. return CssToken;
  74. }());
  75. exports.CssToken = CssToken;
  76. var CssLexer = (function () {
  77. function CssLexer() {
  78. }
  79. CssLexer.prototype.scan = function (text, trackComments) {
  80. if (trackComments === void 0) { trackComments = false; }
  81. return new CssScanner(text, trackComments);
  82. };
  83. return CssLexer;
  84. }());
  85. exports.CssLexer = CssLexer;
  86. function cssScannerError(token, message) {
  87. var error = Error('CssParseError: ' + message);
  88. error[ERROR_RAW_MESSAGE] = message;
  89. error[ERROR_TOKEN] = token;
  90. return error;
  91. }
  92. exports.cssScannerError = cssScannerError;
  93. var ERROR_TOKEN = 'ngToken';
  94. var ERROR_RAW_MESSAGE = 'ngRawMessage';
  95. function getRawMessage(error) {
  96. return error[ERROR_RAW_MESSAGE];
  97. }
  98. exports.getRawMessage = getRawMessage;
  99. function getToken(error) {
  100. return error[ERROR_TOKEN];
  101. }
  102. exports.getToken = getToken;
  103. function _trackWhitespace(mode) {
  104. switch (mode) {
  105. case CssLexerMode.SELECTOR:
  106. case CssLexerMode.PSEUDO_SELECTOR:
  107. case CssLexerMode.ALL_TRACK_WS:
  108. case CssLexerMode.STYLE_VALUE:
  109. return true;
  110. default:
  111. return false;
  112. }
  113. }
  114. var CssScanner = (function () {
  115. function CssScanner(input, _trackComments) {
  116. if (_trackComments === void 0) { _trackComments = false; }
  117. this.input = input;
  118. this._trackComments = _trackComments;
  119. this.length = 0;
  120. this.index = -1;
  121. this.column = -1;
  122. this.line = 0;
  123. this._currentMode = CssLexerMode.BLOCK;
  124. this._currentError = null;
  125. this.length = this.input.length;
  126. this.peekPeek = this.peekAt(0);
  127. this.advance();
  128. }
  129. CssScanner.prototype.getMode = function () {
  130. return this._currentMode;
  131. };
  132. CssScanner.prototype.setMode = function (mode) {
  133. if (this._currentMode != mode) {
  134. if (_trackWhitespace(this._currentMode) && !_trackWhitespace(mode)) {
  135. this.consumeWhitespace();
  136. }
  137. this._currentMode = mode;
  138. }
  139. };
  140. CssScanner.prototype.advance = function () {
  141. if (isNewline(this.peek)) {
  142. this.column = 0;
  143. this.line++;
  144. }
  145. else {
  146. this.column++;
  147. }
  148. this.index++;
  149. this.peek = this.peekPeek;
  150. this.peekPeek = this.peekAt(this.index + 1);
  151. };
  152. CssScanner.prototype.peekAt = function (index) {
  153. return index >= this.length ? chars.$EOF : this.input.charCodeAt(index);
  154. };
  155. CssScanner.prototype.consumeEmptyStatements = function () {
  156. this.consumeWhitespace();
  157. while (this.peek == chars.$SEMICOLON) {
  158. this.advance();
  159. this.consumeWhitespace();
  160. }
  161. };
  162. CssScanner.prototype.consumeWhitespace = function () {
  163. while (chars.isWhitespace(this.peek) || isNewline(this.peek)) {
  164. this.advance();
  165. if (!this._trackComments && isCommentStart(this.peek, this.peekPeek)) {
  166. this.advance();
  167. this.advance();
  168. while (!isCommentEnd(this.peek, this.peekPeek)) {
  169. if (this.peek == chars.$EOF) {
  170. this.error('Unterminated comment');
  171. break;
  172. }
  173. this.advance();
  174. }
  175. this.advance();
  176. this.advance();
  177. }
  178. }
  179. };
  180. CssScanner.prototype.consume = function (type, value) {
  181. if (value === void 0) { value = null; }
  182. var mode = this._currentMode;
  183. this.setMode(_trackWhitespace(mode) ? CssLexerMode.ALL_TRACK_WS : CssLexerMode.ALL);
  184. var previousIndex = this.index;
  185. var previousLine = this.line;
  186. var previousColumn = this.column;
  187. var next = undefined;
  188. var output = this.scan();
  189. if (output != null) {
  190. if (output.error != null) {
  191. this.setMode(mode);
  192. return output;
  193. }
  194. next = output.token;
  195. }
  196. if (next == null) {
  197. next = new CssToken(this.index, this.column, this.line, CssTokenType.EOF, 'end of file');
  198. }
  199. var isMatchingType = false;
  200. if (type == CssTokenType.IdentifierOrNumber) {
  201. isMatchingType = next.type == CssTokenType.Number || next.type == CssTokenType.Identifier;
  202. }
  203. else {
  204. isMatchingType = next.type == type;
  205. }
  206. this.setMode(mode);
  207. var error = null;
  208. if (!isMatchingType || (value != null && value != next.strValue)) {
  209. var errorMessage = CssTokenType[next.type] + ' does not match expected ' + CssTokenType[type] + ' value';
  210. if (value != null) {
  211. errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
  212. }
  213. error = cssScannerError(next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex, previousLine, previousColumn));
  214. }
  215. return new LexedCssResult(error, next);
  216. };
  217. CssScanner.prototype.scan = function () {
  218. var trackWS = _trackWhitespace(this._currentMode);
  219. if (this.index == 0 && !trackWS) {
  220. this.consumeWhitespace();
  221. }
  222. var token = this._scan();
  223. if (token == null)
  224. return null;
  225. var error = this._currentError;
  226. this._currentError = null;
  227. if (!trackWS) {
  228. this.consumeWhitespace();
  229. }
  230. return new LexedCssResult(error, token);
  231. };
  232. CssScanner.prototype._scan = function () {
  233. var peek = this.peek;
  234. var peekPeek = this.peekPeek;
  235. if (peek == chars.$EOF)
  236. return null;
  237. if (isCommentStart(peek, peekPeek)) {
  238. var commentToken = this.scanComment();
  239. if (this._trackComments) {
  240. return commentToken;
  241. }
  242. }
  243. if (_trackWhitespace(this._currentMode) && (chars.isWhitespace(peek) || isNewline(peek))) {
  244. return this.scanWhitespace();
  245. }
  246. peek = this.peek;
  247. peekPeek = this.peekPeek;
  248. if (peek == chars.$EOF)
  249. return null;
  250. if (isStringStart(peek, peekPeek)) {
  251. return this.scanString();
  252. }
  253. if (this._currentMode == CssLexerMode.STYLE_VALUE_FUNCTION) {
  254. return this.scanCssValueFunction();
  255. }
  256. var isModifier = peek == chars.$PLUS || peek == chars.$MINUS;
  257. var digitA = isModifier ? false : chars.isDigit(peek);
  258. var digitB = chars.isDigit(peekPeek);
  259. if (digitA || (isModifier && (peekPeek == chars.$PERIOD || digitB)) || (peek == chars.$PERIOD && digitB)) {
  260. return this.scanNumber();
  261. }
  262. if (peek == chars.$AT) {
  263. return this.scanAtExpression();
  264. }
  265. if (isIdentifierStart(peek, peekPeek)) {
  266. return this.scanIdentifier();
  267. }
  268. if (isValidCssCharacter(peek, this._currentMode)) {
  269. return this.scanCharacter();
  270. }
  271. return this.error("Unexpected character [" + String.fromCharCode(peek) + "]");
  272. };
  273. CssScanner.prototype.scanComment = function () {
  274. if (this.assertCondition(isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
  275. return null;
  276. }
  277. var start = this.index;
  278. var startingColumn = this.column;
  279. var startingLine = this.line;
  280. this.advance();
  281. this.advance();
  282. while (!isCommentEnd(this.peek, this.peekPeek)) {
  283. if (this.peek == chars.$EOF) {
  284. this.error('Unterminated comment');
  285. break;
  286. }
  287. this.advance();
  288. }
  289. this.advance();
  290. this.advance();
  291. var str = this.input.substring(start, this.index);
  292. return new CssToken(start, startingColumn, startingLine, CssTokenType.Comment, str);
  293. };
  294. CssScanner.prototype.scanWhitespace = function () {
  295. var start = this.index;
  296. var startingColumn = this.column;
  297. var startingLine = this.line;
  298. while (chars.isWhitespace(this.peek) && this.peek != chars.$EOF) {
  299. this.advance();
  300. }
  301. var str = this.input.substring(start, this.index);
  302. return new CssToken(start, startingColumn, startingLine, CssTokenType.Whitespace, str);
  303. };
  304. CssScanner.prototype.scanString = function () {
  305. if (this.assertCondition(isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
  306. return null;
  307. }
  308. var target = this.peek;
  309. var start = this.index;
  310. var startingColumn = this.column;
  311. var startingLine = this.line;
  312. var previous = target;
  313. this.advance();
  314. while (!isCharMatch(target, previous, this.peek)) {
  315. if (this.peek == chars.$EOF || isNewline(this.peek)) {
  316. this.error('Unterminated quote');
  317. break;
  318. }
  319. previous = this.peek;
  320. this.advance();
  321. }
  322. if (this.assertCondition(this.peek == target, 'Unterminated quote')) {
  323. return null;
  324. }
  325. this.advance();
  326. var str = this.input.substring(start, this.index);
  327. return new CssToken(start, startingColumn, startingLine, CssTokenType.String, str);
  328. };
  329. CssScanner.prototype.scanNumber = function () {
  330. var start = this.index;
  331. var startingColumn = this.column;
  332. if (this.peek == chars.$PLUS || this.peek == chars.$MINUS) {
  333. this.advance();
  334. }
  335. var periodUsed = false;
  336. while (chars.isDigit(this.peek) || this.peek == chars.$PERIOD) {
  337. if (this.peek == chars.$PERIOD) {
  338. if (periodUsed) {
  339. this.error('Unexpected use of a second period value');
  340. }
  341. periodUsed = true;
  342. }
  343. this.advance();
  344. }
  345. var strValue = this.input.substring(start, this.index);
  346. return new CssToken(start, startingColumn, this.line, CssTokenType.Number, strValue);
  347. };
  348. CssScanner.prototype.scanIdentifier = function () {
  349. if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
  350. return null;
  351. }
  352. var start = this.index;
  353. var startingColumn = this.column;
  354. while (isIdentifierPart(this.peek)) {
  355. this.advance();
  356. }
  357. var strValue = this.input.substring(start, this.index);
  358. return new CssToken(start, startingColumn, this.line, CssTokenType.Identifier, strValue);
  359. };
  360. CssScanner.prototype.scanCssValueFunction = function () {
  361. var start = this.index;
  362. var startingColumn = this.column;
  363. var parenBalance = 1;
  364. while (this.peek != chars.$EOF && parenBalance > 0) {
  365. this.advance();
  366. if (this.peek == chars.$LPAREN) {
  367. parenBalance++;
  368. }
  369. else if (this.peek == chars.$RPAREN) {
  370. parenBalance--;
  371. }
  372. }
  373. var strValue = this.input.substring(start, this.index);
  374. return new CssToken(start, startingColumn, this.line, CssTokenType.Identifier, strValue);
  375. };
  376. CssScanner.prototype.scanCharacter = function () {
  377. var start = this.index;
  378. var startingColumn = this.column;
  379. if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode), charStr(this.peek) + ' is not a valid CSS character')) {
  380. return null;
  381. }
  382. var c = this.input.substring(start, start + 1);
  383. this.advance();
  384. return new CssToken(start, startingColumn, this.line, CssTokenType.Character, c);
  385. };
  386. CssScanner.prototype.scanAtExpression = function () {
  387. if (this.assertCondition(this.peek == chars.$AT, 'Expected @ value')) {
  388. return null;
  389. }
  390. var start = this.index;
  391. var startingColumn = this.column;
  392. this.advance();
  393. if (isIdentifierStart(this.peek, this.peekPeek)) {
  394. var ident = this.scanIdentifier();
  395. var strValue = '@' + ident.strValue;
  396. return new CssToken(start, startingColumn, this.line, CssTokenType.AtKeyword, strValue);
  397. }
  398. else {
  399. return this.scanCharacter();
  400. }
  401. };
  402. CssScanner.prototype.assertCondition = function (status, errorMessage) {
  403. if (!status) {
  404. this.error(errorMessage);
  405. return true;
  406. }
  407. return false;
  408. };
  409. CssScanner.prototype.error = function (message, errorTokenValue, doNotAdvance) {
  410. if (errorTokenValue === void 0) { errorTokenValue = null; }
  411. if (doNotAdvance === void 0) { doNotAdvance = false; }
  412. var _a = this, column = _a.column, index = _a.index, line = _a.line;
  413. errorTokenValue = errorTokenValue || String.fromCharCode(this.peek);
  414. var invalidToken = new CssToken(index, column, line, CssTokenType.Invalid, errorTokenValue);
  415. var errorMessage = generateErrorMessage(this.input, message, errorTokenValue, index, line, column);
  416. if (!doNotAdvance) {
  417. this.advance();
  418. }
  419. this._currentError = cssScannerError(invalidToken, errorMessage);
  420. return invalidToken;
  421. };
  422. return CssScanner;
  423. }());
  424. exports.CssScanner = CssScanner;
  425. function isCharMatch(target, previous, code) {
  426. return code == target && previous != chars.$BACKSLASH;
  427. }
  428. function isCommentStart(code, next) {
  429. return code == chars.$SLASH && next == chars.$STAR;
  430. }
  431. function isCommentEnd(code, next) {
  432. return code == chars.$STAR && next == chars.$SLASH;
  433. }
  434. function isStringStart(code, next) {
  435. var target = code;
  436. if (target == chars.$BACKSLASH) {
  437. target = next;
  438. }
  439. return target == chars.$DQ || target == chars.$SQ;
  440. }
  441. function isIdentifierStart(code, next) {
  442. var target = code;
  443. if (target == chars.$MINUS) {
  444. target = next;
  445. }
  446. return chars.isAsciiLetter(target) || target == chars.$BACKSLASH || target == chars.$MINUS || target == chars.$_;
  447. }
  448. function isIdentifierPart(target) {
  449. return chars.isAsciiLetter(target) || target == chars.$BACKSLASH || target == chars.$MINUS || target == chars.$_ || chars.isDigit(target);
  450. }
  451. function isValidPseudoSelectorCharacter(code) {
  452. switch (code) {
  453. case chars.$LPAREN:
  454. case chars.$RPAREN:
  455. return true;
  456. default:
  457. return false;
  458. }
  459. }
  460. function isValidKeyframeBlockCharacter(code) {
  461. return code == chars.$PERCENT;
  462. }
  463. function isValidAttributeSelectorCharacter(code) {
  464. switch (code) {
  465. case chars.$$:
  466. case chars.$PIPE:
  467. case chars.$CARET:
  468. case chars.$TILDA:
  469. case chars.$STAR:
  470. case chars.$EQ:
  471. return true;
  472. default:
  473. return false;
  474. }
  475. }
  476. function isValidSelectorCharacter(code) {
  477. switch (code) {
  478. case chars.$HASH:
  479. case chars.$PERIOD:
  480. case chars.$TILDA:
  481. case chars.$STAR:
  482. case chars.$PLUS:
  483. case chars.$GT:
  484. case chars.$COLON:
  485. case chars.$PIPE:
  486. case chars.$COMMA:
  487. case chars.$LBRACKET:
  488. case chars.$RBRACKET:
  489. return true;
  490. default:
  491. return false;
  492. }
  493. }
  494. function isValidStyleBlockCharacter(code) {
  495. switch (code) {
  496. case chars.$HASH:
  497. case chars.$SEMICOLON:
  498. case chars.$COLON:
  499. case chars.$PERCENT:
  500. case chars.$SLASH:
  501. case chars.$BACKSLASH:
  502. case chars.$BANG:
  503. case chars.$PERIOD:
  504. case chars.$LPAREN:
  505. case chars.$RPAREN:
  506. return true;
  507. default:
  508. return false;
  509. }
  510. }
  511. function isValidMediaQueryRuleCharacter(code) {
  512. switch (code) {
  513. case chars.$LPAREN:
  514. case chars.$RPAREN:
  515. case chars.$COLON:
  516. case chars.$PERCENT:
  517. case chars.$PERIOD:
  518. return true;
  519. default:
  520. return false;
  521. }
  522. }
  523. function isValidAtRuleCharacter(code) {
  524. switch (code) {
  525. case chars.$LPAREN:
  526. case chars.$RPAREN:
  527. case chars.$COLON:
  528. case chars.$PERCENT:
  529. case chars.$PERIOD:
  530. case chars.$SLASH:
  531. case chars.$BACKSLASH:
  532. case chars.$HASH:
  533. case chars.$EQ:
  534. case chars.$QUESTION:
  535. case chars.$AMPERSAND:
  536. case chars.$STAR:
  537. case chars.$COMMA:
  538. case chars.$MINUS:
  539. case chars.$PLUS:
  540. return true;
  541. default:
  542. return false;
  543. }
  544. }
  545. function isValidStyleFunctionCharacter(code) {
  546. switch (code) {
  547. case chars.$PERIOD:
  548. case chars.$MINUS:
  549. case chars.$PLUS:
  550. case chars.$STAR:
  551. case chars.$SLASH:
  552. case chars.$LPAREN:
  553. case chars.$RPAREN:
  554. case chars.$COMMA:
  555. return true;
  556. default:
  557. return false;
  558. }
  559. }
  560. function isValidBlockCharacter(code) {
  561. return code == chars.$AT;
  562. }
  563. function isValidCssCharacter(code, mode) {
  564. switch (mode) {
  565. case CssLexerMode.ALL:
  566. case CssLexerMode.ALL_TRACK_WS:
  567. return true;
  568. case CssLexerMode.SELECTOR:
  569. return isValidSelectorCharacter(code);
  570. case CssLexerMode.PSEUDO_SELECTOR_WITH_ARGUMENTS:
  571. return isValidPseudoSelectorCharacter(code);
  572. case CssLexerMode.ATTRIBUTE_SELECTOR:
  573. return isValidAttributeSelectorCharacter(code);
  574. case CssLexerMode.MEDIA_QUERY:
  575. return isValidMediaQueryRuleCharacter(code);
  576. case CssLexerMode.AT_RULE_QUERY:
  577. return isValidAtRuleCharacter(code);
  578. case CssLexerMode.KEYFRAME_BLOCK:
  579. return isValidKeyframeBlockCharacter(code);
  580. case CssLexerMode.STYLE_BLOCK:
  581. case CssLexerMode.STYLE_VALUE:
  582. return isValidStyleBlockCharacter(code);
  583. case CssLexerMode.STYLE_CALC_FUNCTION:
  584. return isValidStyleFunctionCharacter(code);
  585. case CssLexerMode.BLOCK:
  586. return isValidBlockCharacter(code);
  587. default:
  588. return false;
  589. }
  590. }
  591. function charCode(input, index) {
  592. return index >= input.length ? chars.$EOF : input.charCodeAt(index);
  593. }
  594. function charStr(code) {
  595. return String.fromCharCode(code);
  596. }
  597. function isNewline(code) {
  598. switch (code) {
  599. case chars.$FF:
  600. case chars.$CR:
  601. case chars.$LF:
  602. case chars.$VTAB:
  603. return true;
  604. default:
  605. return false;
  606. }
  607. }
  608. exports.isNewline = isNewline;