tokenizer.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. "use strict";
  2. // https://www.w3.org/TR/css-syntax-3
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. var css_line_break_1 = require("css-line-break");
  5. var TokenType;
  6. (function (TokenType) {
  7. TokenType[TokenType["STRING_TOKEN"] = 0] = "STRING_TOKEN";
  8. TokenType[TokenType["BAD_STRING_TOKEN"] = 1] = "BAD_STRING_TOKEN";
  9. TokenType[TokenType["LEFT_PARENTHESIS_TOKEN"] = 2] = "LEFT_PARENTHESIS_TOKEN";
  10. TokenType[TokenType["RIGHT_PARENTHESIS_TOKEN"] = 3] = "RIGHT_PARENTHESIS_TOKEN";
  11. TokenType[TokenType["COMMA_TOKEN"] = 4] = "COMMA_TOKEN";
  12. TokenType[TokenType["HASH_TOKEN"] = 5] = "HASH_TOKEN";
  13. TokenType[TokenType["DELIM_TOKEN"] = 6] = "DELIM_TOKEN";
  14. TokenType[TokenType["AT_KEYWORD_TOKEN"] = 7] = "AT_KEYWORD_TOKEN";
  15. TokenType[TokenType["PREFIX_MATCH_TOKEN"] = 8] = "PREFIX_MATCH_TOKEN";
  16. TokenType[TokenType["DASH_MATCH_TOKEN"] = 9] = "DASH_MATCH_TOKEN";
  17. TokenType[TokenType["INCLUDE_MATCH_TOKEN"] = 10] = "INCLUDE_MATCH_TOKEN";
  18. TokenType[TokenType["LEFT_CURLY_BRACKET_TOKEN"] = 11] = "LEFT_CURLY_BRACKET_TOKEN";
  19. TokenType[TokenType["RIGHT_CURLY_BRACKET_TOKEN"] = 12] = "RIGHT_CURLY_BRACKET_TOKEN";
  20. TokenType[TokenType["SUFFIX_MATCH_TOKEN"] = 13] = "SUFFIX_MATCH_TOKEN";
  21. TokenType[TokenType["SUBSTRING_MATCH_TOKEN"] = 14] = "SUBSTRING_MATCH_TOKEN";
  22. TokenType[TokenType["DIMENSION_TOKEN"] = 15] = "DIMENSION_TOKEN";
  23. TokenType[TokenType["PERCENTAGE_TOKEN"] = 16] = "PERCENTAGE_TOKEN";
  24. TokenType[TokenType["NUMBER_TOKEN"] = 17] = "NUMBER_TOKEN";
  25. TokenType[TokenType["FUNCTION"] = 18] = "FUNCTION";
  26. TokenType[TokenType["FUNCTION_TOKEN"] = 19] = "FUNCTION_TOKEN";
  27. TokenType[TokenType["IDENT_TOKEN"] = 20] = "IDENT_TOKEN";
  28. TokenType[TokenType["COLUMN_TOKEN"] = 21] = "COLUMN_TOKEN";
  29. TokenType[TokenType["URL_TOKEN"] = 22] = "URL_TOKEN";
  30. TokenType[TokenType["BAD_URL_TOKEN"] = 23] = "BAD_URL_TOKEN";
  31. TokenType[TokenType["CDC_TOKEN"] = 24] = "CDC_TOKEN";
  32. TokenType[TokenType["CDO_TOKEN"] = 25] = "CDO_TOKEN";
  33. TokenType[TokenType["COLON_TOKEN"] = 26] = "COLON_TOKEN";
  34. TokenType[TokenType["SEMICOLON_TOKEN"] = 27] = "SEMICOLON_TOKEN";
  35. TokenType[TokenType["LEFT_SQUARE_BRACKET_TOKEN"] = 28] = "LEFT_SQUARE_BRACKET_TOKEN";
  36. TokenType[TokenType["RIGHT_SQUARE_BRACKET_TOKEN"] = 29] = "RIGHT_SQUARE_BRACKET_TOKEN";
  37. TokenType[TokenType["UNICODE_RANGE_TOKEN"] = 30] = "UNICODE_RANGE_TOKEN";
  38. TokenType[TokenType["WHITESPACE_TOKEN"] = 31] = "WHITESPACE_TOKEN";
  39. TokenType[TokenType["EOF_TOKEN"] = 32] = "EOF_TOKEN";
  40. })(TokenType = exports.TokenType || (exports.TokenType = {}));
  41. exports.FLAG_UNRESTRICTED = 1 << 0;
  42. exports.FLAG_ID = 1 << 1;
  43. exports.FLAG_INTEGER = 1 << 2;
  44. exports.FLAG_NUMBER = 1 << 3;
  45. var LINE_FEED = 0x000a;
  46. var SOLIDUS = 0x002f;
  47. var REVERSE_SOLIDUS = 0x005c;
  48. var CHARACTER_TABULATION = 0x0009;
  49. var SPACE = 0x0020;
  50. var QUOTATION_MARK = 0x0022;
  51. var EQUALS_SIGN = 0x003d;
  52. var NUMBER_SIGN = 0x0023;
  53. var DOLLAR_SIGN = 0x0024;
  54. var PERCENTAGE_SIGN = 0x0025;
  55. var APOSTROPHE = 0x0027;
  56. var LEFT_PARENTHESIS = 0x0028;
  57. var RIGHT_PARENTHESIS = 0x0029;
  58. var LOW_LINE = 0x005f;
  59. var HYPHEN_MINUS = 0x002d;
  60. var EXCLAMATION_MARK = 0x0021;
  61. var LESS_THAN_SIGN = 0x003c;
  62. var GREATER_THAN_SIGN = 0x003e;
  63. var COMMERCIAL_AT = 0x0040;
  64. var LEFT_SQUARE_BRACKET = 0x005b;
  65. var RIGHT_SQUARE_BRACKET = 0x005d;
  66. var CIRCUMFLEX_ACCENT = 0x003d;
  67. var LEFT_CURLY_BRACKET = 0x007b;
  68. var QUESTION_MARK = 0x003f;
  69. var RIGHT_CURLY_BRACKET = 0x007d;
  70. var VERTICAL_LINE = 0x007c;
  71. var TILDE = 0x007e;
  72. var CONTROL = 0x0080;
  73. var REPLACEMENT_CHARACTER = 0xfffd;
  74. var ASTERISK = 0x002a;
  75. var PLUS_SIGN = 0x002b;
  76. var COMMA = 0x002c;
  77. var COLON = 0x003a;
  78. var SEMICOLON = 0x003b;
  79. var FULL_STOP = 0x002e;
  80. var NULL = 0x0000;
  81. var BACKSPACE = 0x0008;
  82. var LINE_TABULATION = 0x000b;
  83. var SHIFT_OUT = 0x000e;
  84. var INFORMATION_SEPARATOR_ONE = 0x001f;
  85. var DELETE = 0x007f;
  86. var EOF = -1;
  87. var ZERO = 0x0030;
  88. var a = 0x0061;
  89. var e = 0x0065;
  90. var f = 0x0066;
  91. var u = 0x0075;
  92. var z = 0x007a;
  93. var A = 0x0041;
  94. var E = 0x0045;
  95. var F = 0x0046;
  96. var U = 0x0055;
  97. var Z = 0x005a;
  98. var isDigit = function (codePoint) { return codePoint >= ZERO && codePoint <= 0x0039; };
  99. var isSurrogateCodePoint = function (codePoint) { return codePoint >= 0xd800 && codePoint <= 0xdfff; };
  100. var isHex = function (codePoint) {
  101. return isDigit(codePoint) || (codePoint >= A && codePoint <= F) || (codePoint >= a && codePoint <= f);
  102. };
  103. var isLowerCaseLetter = function (codePoint) { return codePoint >= a && codePoint <= z; };
  104. var isUpperCaseLetter = function (codePoint) { return codePoint >= A && codePoint <= Z; };
  105. var isLetter = function (codePoint) { return isLowerCaseLetter(codePoint) || isUpperCaseLetter(codePoint); };
  106. var isNonASCIICodePoint = function (codePoint) { return codePoint >= CONTROL; };
  107. var isWhiteSpace = function (codePoint) {
  108. return codePoint === LINE_FEED || codePoint === CHARACTER_TABULATION || codePoint === SPACE;
  109. };
  110. var isNameStartCodePoint = function (codePoint) {
  111. return isLetter(codePoint) || isNonASCIICodePoint(codePoint) || codePoint === LOW_LINE;
  112. };
  113. var isNameCodePoint = function (codePoint) {
  114. return isNameStartCodePoint(codePoint) || isDigit(codePoint) || codePoint === HYPHEN_MINUS;
  115. };
  116. var isNonPrintableCodePoint = function (codePoint) {
  117. return ((codePoint >= NULL && codePoint <= BACKSPACE) ||
  118. codePoint === LINE_TABULATION ||
  119. (codePoint >= SHIFT_OUT && codePoint <= INFORMATION_SEPARATOR_ONE) ||
  120. codePoint === DELETE);
  121. };
  122. var isValidEscape = function (c1, c2) {
  123. if (c1 !== REVERSE_SOLIDUS) {
  124. return false;
  125. }
  126. return c2 !== LINE_FEED;
  127. };
  128. var isIdentifierStart = function (c1, c2, c3) {
  129. if (c1 === HYPHEN_MINUS) {
  130. return isNameStartCodePoint(c2) || isValidEscape(c2, c3);
  131. }
  132. else if (isNameStartCodePoint(c1)) {
  133. return true;
  134. }
  135. else if (c1 === REVERSE_SOLIDUS && isValidEscape(c1, c2)) {
  136. return true;
  137. }
  138. return false;
  139. };
  140. var isNumberStart = function (c1, c2, c3) {
  141. if (c1 === PLUS_SIGN || c1 === HYPHEN_MINUS) {
  142. if (isDigit(c2)) {
  143. return true;
  144. }
  145. return c2 === FULL_STOP && isDigit(c3);
  146. }
  147. if (c1 === FULL_STOP) {
  148. return isDigit(c2);
  149. }
  150. return isDigit(c1);
  151. };
  152. var stringToNumber = function (codePoints) {
  153. var c = 0;
  154. var sign = 1;
  155. if (codePoints[c] === PLUS_SIGN || codePoints[c] === HYPHEN_MINUS) {
  156. if (codePoints[c] === HYPHEN_MINUS) {
  157. sign = -1;
  158. }
  159. c++;
  160. }
  161. var integers = [];
  162. while (isDigit(codePoints[c])) {
  163. integers.push(codePoints[c++]);
  164. }
  165. var int = integers.length ? parseInt(css_line_break_1.fromCodePoint.apply(void 0, integers), 10) : 0;
  166. if (codePoints[c] === FULL_STOP) {
  167. c++;
  168. }
  169. var fraction = [];
  170. while (isDigit(codePoints[c])) {
  171. fraction.push(codePoints[c++]);
  172. }
  173. var fracd = fraction.length;
  174. var frac = fracd ? parseInt(css_line_break_1.fromCodePoint.apply(void 0, fraction), 10) : 0;
  175. if (codePoints[c] === E || codePoints[c] === e) {
  176. c++;
  177. }
  178. var expsign = 1;
  179. if (codePoints[c] === PLUS_SIGN || codePoints[c] === HYPHEN_MINUS) {
  180. if (codePoints[c] === HYPHEN_MINUS) {
  181. expsign = -1;
  182. }
  183. c++;
  184. }
  185. var exponent = [];
  186. while (isDigit(codePoints[c])) {
  187. exponent.push(codePoints[c++]);
  188. }
  189. var exp = exponent.length ? parseInt(css_line_break_1.fromCodePoint.apply(void 0, exponent), 10) : 0;
  190. return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);
  191. };
  192. var LEFT_PARENTHESIS_TOKEN = {
  193. type: TokenType.LEFT_PARENTHESIS_TOKEN
  194. };
  195. var RIGHT_PARENTHESIS_TOKEN = {
  196. type: TokenType.RIGHT_PARENTHESIS_TOKEN
  197. };
  198. var COMMA_TOKEN = { type: TokenType.COMMA_TOKEN };
  199. var SUFFIX_MATCH_TOKEN = { type: TokenType.SUFFIX_MATCH_TOKEN };
  200. var PREFIX_MATCH_TOKEN = { type: TokenType.PREFIX_MATCH_TOKEN };
  201. var COLUMN_TOKEN = { type: TokenType.COLUMN_TOKEN };
  202. var DASH_MATCH_TOKEN = { type: TokenType.DASH_MATCH_TOKEN };
  203. var INCLUDE_MATCH_TOKEN = { type: TokenType.INCLUDE_MATCH_TOKEN };
  204. var LEFT_CURLY_BRACKET_TOKEN = {
  205. type: TokenType.LEFT_CURLY_BRACKET_TOKEN
  206. };
  207. var RIGHT_CURLY_BRACKET_TOKEN = {
  208. type: TokenType.RIGHT_CURLY_BRACKET_TOKEN
  209. };
  210. var SUBSTRING_MATCH_TOKEN = { type: TokenType.SUBSTRING_MATCH_TOKEN };
  211. var BAD_URL_TOKEN = { type: TokenType.BAD_URL_TOKEN };
  212. var BAD_STRING_TOKEN = { type: TokenType.BAD_STRING_TOKEN };
  213. var CDO_TOKEN = { type: TokenType.CDO_TOKEN };
  214. var CDC_TOKEN = { type: TokenType.CDC_TOKEN };
  215. var COLON_TOKEN = { type: TokenType.COLON_TOKEN };
  216. var SEMICOLON_TOKEN = { type: TokenType.SEMICOLON_TOKEN };
  217. var LEFT_SQUARE_BRACKET_TOKEN = {
  218. type: TokenType.LEFT_SQUARE_BRACKET_TOKEN
  219. };
  220. var RIGHT_SQUARE_BRACKET_TOKEN = {
  221. type: TokenType.RIGHT_SQUARE_BRACKET_TOKEN
  222. };
  223. var WHITESPACE_TOKEN = { type: TokenType.WHITESPACE_TOKEN };
  224. exports.EOF_TOKEN = { type: TokenType.EOF_TOKEN };
  225. var Tokenizer = /** @class */ (function () {
  226. function Tokenizer() {
  227. this._value = [];
  228. }
  229. Tokenizer.prototype.write = function (chunk) {
  230. this._value = this._value.concat(css_line_break_1.toCodePoints(chunk));
  231. };
  232. Tokenizer.prototype.read = function () {
  233. var tokens = [];
  234. var token = this.consumeToken();
  235. while (token !== exports.EOF_TOKEN) {
  236. tokens.push(token);
  237. token = this.consumeToken();
  238. }
  239. return tokens;
  240. };
  241. Tokenizer.prototype.consumeToken = function () {
  242. var codePoint = this.consumeCodePoint();
  243. switch (codePoint) {
  244. case QUOTATION_MARK:
  245. return this.consumeStringToken(QUOTATION_MARK);
  246. case NUMBER_SIGN:
  247. var c1 = this.peekCodePoint(0);
  248. var c2 = this.peekCodePoint(1);
  249. var c3 = this.peekCodePoint(2);
  250. if (isNameCodePoint(c1) || isValidEscape(c2, c3)) {
  251. var flags = isIdentifierStart(c1, c2, c3) ? exports.FLAG_ID : exports.FLAG_UNRESTRICTED;
  252. var value = this.consumeName();
  253. return { type: TokenType.HASH_TOKEN, value: value, flags: flags };
  254. }
  255. break;
  256. case DOLLAR_SIGN:
  257. if (this.peekCodePoint(0) === EQUALS_SIGN) {
  258. this.consumeCodePoint();
  259. return SUFFIX_MATCH_TOKEN;
  260. }
  261. break;
  262. case APOSTROPHE:
  263. return this.consumeStringToken(APOSTROPHE);
  264. case LEFT_PARENTHESIS:
  265. return LEFT_PARENTHESIS_TOKEN;
  266. case RIGHT_PARENTHESIS:
  267. return RIGHT_PARENTHESIS_TOKEN;
  268. case ASTERISK:
  269. if (this.peekCodePoint(0) === EQUALS_SIGN) {
  270. this.consumeCodePoint();
  271. return SUBSTRING_MATCH_TOKEN;
  272. }
  273. break;
  274. case PLUS_SIGN:
  275. if (isNumberStart(codePoint, this.peekCodePoint(0), this.peekCodePoint(1))) {
  276. this.reconsumeCodePoint(codePoint);
  277. return this.consumeNumericToken();
  278. }
  279. break;
  280. case COMMA:
  281. return COMMA_TOKEN;
  282. case HYPHEN_MINUS:
  283. var e1 = codePoint;
  284. var e2 = this.peekCodePoint(0);
  285. var e3 = this.peekCodePoint(1);
  286. if (isNumberStart(e1, e2, e3)) {
  287. this.reconsumeCodePoint(codePoint);
  288. return this.consumeNumericToken();
  289. }
  290. if (isIdentifierStart(e1, e2, e3)) {
  291. this.reconsumeCodePoint(codePoint);
  292. return this.consumeIdentLikeToken();
  293. }
  294. if (e2 === HYPHEN_MINUS && e3 === GREATER_THAN_SIGN) {
  295. this.consumeCodePoint();
  296. this.consumeCodePoint();
  297. return CDC_TOKEN;
  298. }
  299. break;
  300. case FULL_STOP:
  301. if (isNumberStart(codePoint, this.peekCodePoint(0), this.peekCodePoint(1))) {
  302. this.reconsumeCodePoint(codePoint);
  303. return this.consumeNumericToken();
  304. }
  305. break;
  306. case SOLIDUS:
  307. if (this.peekCodePoint(0) === ASTERISK) {
  308. this.consumeCodePoint();
  309. while (true) {
  310. var c = this.consumeCodePoint();
  311. if (c === ASTERISK) {
  312. c = this.consumeCodePoint();
  313. if (c === SOLIDUS) {
  314. return this.consumeToken();
  315. }
  316. }
  317. if (c === EOF) {
  318. return this.consumeToken();
  319. }
  320. }
  321. }
  322. break;
  323. case COLON:
  324. return COLON_TOKEN;
  325. case SEMICOLON:
  326. return SEMICOLON_TOKEN;
  327. case LESS_THAN_SIGN:
  328. if (this.peekCodePoint(0) === EXCLAMATION_MARK &&
  329. this.peekCodePoint(1) === HYPHEN_MINUS &&
  330. this.peekCodePoint(2) === HYPHEN_MINUS) {
  331. this.consumeCodePoint();
  332. this.consumeCodePoint();
  333. return CDO_TOKEN;
  334. }
  335. break;
  336. case COMMERCIAL_AT:
  337. var a1 = this.peekCodePoint(0);
  338. var a2 = this.peekCodePoint(1);
  339. var a3 = this.peekCodePoint(2);
  340. if (isIdentifierStart(a1, a2, a3)) {
  341. var value = this.consumeName();
  342. return { type: TokenType.AT_KEYWORD_TOKEN, value: value };
  343. }
  344. break;
  345. case LEFT_SQUARE_BRACKET:
  346. return LEFT_SQUARE_BRACKET_TOKEN;
  347. case REVERSE_SOLIDUS:
  348. if (isValidEscape(codePoint, this.peekCodePoint(0))) {
  349. this.reconsumeCodePoint(codePoint);
  350. return this.consumeIdentLikeToken();
  351. }
  352. break;
  353. case RIGHT_SQUARE_BRACKET:
  354. return RIGHT_SQUARE_BRACKET_TOKEN;
  355. case CIRCUMFLEX_ACCENT:
  356. if (this.peekCodePoint(0) === EQUALS_SIGN) {
  357. this.consumeCodePoint();
  358. return PREFIX_MATCH_TOKEN;
  359. }
  360. break;
  361. case LEFT_CURLY_BRACKET:
  362. return LEFT_CURLY_BRACKET_TOKEN;
  363. case RIGHT_CURLY_BRACKET:
  364. return RIGHT_CURLY_BRACKET_TOKEN;
  365. case u:
  366. case U:
  367. var u1 = this.peekCodePoint(0);
  368. var u2 = this.peekCodePoint(1);
  369. if (u1 === PLUS_SIGN && (isHex(u2) || u2 === QUESTION_MARK)) {
  370. this.consumeCodePoint();
  371. this.consumeUnicodeRangeToken();
  372. }
  373. this.reconsumeCodePoint(codePoint);
  374. return this.consumeIdentLikeToken();
  375. case VERTICAL_LINE:
  376. if (this.peekCodePoint(0) === EQUALS_SIGN) {
  377. this.consumeCodePoint();
  378. return DASH_MATCH_TOKEN;
  379. }
  380. if (this.peekCodePoint(0) === VERTICAL_LINE) {
  381. this.consumeCodePoint();
  382. return COLUMN_TOKEN;
  383. }
  384. break;
  385. case TILDE:
  386. if (this.peekCodePoint(0) === EQUALS_SIGN) {
  387. this.consumeCodePoint();
  388. return INCLUDE_MATCH_TOKEN;
  389. }
  390. break;
  391. case EOF:
  392. return exports.EOF_TOKEN;
  393. }
  394. if (isWhiteSpace(codePoint)) {
  395. this.consumeWhiteSpace();
  396. return WHITESPACE_TOKEN;
  397. }
  398. if (isDigit(codePoint)) {
  399. this.reconsumeCodePoint(codePoint);
  400. return this.consumeNumericToken();
  401. }
  402. if (isNameStartCodePoint(codePoint)) {
  403. this.reconsumeCodePoint(codePoint);
  404. return this.consumeIdentLikeToken();
  405. }
  406. return { type: TokenType.DELIM_TOKEN, value: css_line_break_1.fromCodePoint(codePoint) };
  407. };
  408. Tokenizer.prototype.consumeCodePoint = function () {
  409. var value = this._value.shift();
  410. return typeof value === 'undefined' ? -1 : value;
  411. };
  412. Tokenizer.prototype.reconsumeCodePoint = function (codePoint) {
  413. this._value.unshift(codePoint);
  414. };
  415. Tokenizer.prototype.peekCodePoint = function (delta) {
  416. if (delta >= this._value.length) {
  417. return -1;
  418. }
  419. return this._value[delta];
  420. };
  421. Tokenizer.prototype.consumeUnicodeRangeToken = function () {
  422. var digits = [];
  423. var codePoint = this.consumeCodePoint();
  424. while (isHex(codePoint) && digits.length < 6) {
  425. digits.push(codePoint);
  426. codePoint = this.consumeCodePoint();
  427. }
  428. var questionMarks = false;
  429. while (codePoint === QUESTION_MARK && digits.length < 6) {
  430. digits.push(codePoint);
  431. codePoint = this.consumeCodePoint();
  432. questionMarks = true;
  433. }
  434. if (questionMarks) {
  435. var start_1 = parseInt(css_line_break_1.fromCodePoint.apply(void 0, digits.map(function (digit) { return (digit === QUESTION_MARK ? ZERO : digit); })), 16);
  436. var end = parseInt(css_line_break_1.fromCodePoint.apply(void 0, digits.map(function (digit) { return (digit === QUESTION_MARK ? F : digit); })), 16);
  437. return { type: TokenType.UNICODE_RANGE_TOKEN, start: start_1, end: end };
  438. }
  439. var start = parseInt(css_line_break_1.fromCodePoint.apply(void 0, digits), 16);
  440. if (this.peekCodePoint(0) === HYPHEN_MINUS && isHex(this.peekCodePoint(1))) {
  441. this.consumeCodePoint();
  442. codePoint = this.consumeCodePoint();
  443. var endDigits = [];
  444. while (isHex(codePoint) && endDigits.length < 6) {
  445. endDigits.push(codePoint);
  446. codePoint = this.consumeCodePoint();
  447. }
  448. var end = parseInt(css_line_break_1.fromCodePoint.apply(void 0, endDigits), 16);
  449. return { type: TokenType.UNICODE_RANGE_TOKEN, start: start, end: end };
  450. }
  451. else {
  452. return { type: TokenType.UNICODE_RANGE_TOKEN, start: start, end: start };
  453. }
  454. };
  455. Tokenizer.prototype.consumeIdentLikeToken = function () {
  456. var value = this.consumeName();
  457. if (value.toLowerCase() === 'url' && this.peekCodePoint(0) === LEFT_PARENTHESIS) {
  458. this.consumeCodePoint();
  459. return this.consumeUrlToken();
  460. }
  461. else if (this.peekCodePoint(0) === LEFT_PARENTHESIS) {
  462. this.consumeCodePoint();
  463. return { type: TokenType.FUNCTION_TOKEN, value: value };
  464. }
  465. return { type: TokenType.IDENT_TOKEN, value: value };
  466. };
  467. Tokenizer.prototype.consumeUrlToken = function () {
  468. var value = [];
  469. this.consumeWhiteSpace();
  470. if (this.peekCodePoint(0) === EOF) {
  471. return { type: TokenType.URL_TOKEN, value: '' };
  472. }
  473. var next = this.peekCodePoint(0);
  474. if (next === APOSTROPHE || next === QUOTATION_MARK) {
  475. var stringToken = this.consumeStringToken(this.consumeCodePoint());
  476. if (stringToken.type === TokenType.STRING_TOKEN) {
  477. this.consumeWhiteSpace();
  478. if (this.peekCodePoint(0) === EOF || this.peekCodePoint(0) === RIGHT_PARENTHESIS) {
  479. this.consumeCodePoint();
  480. return { type: TokenType.URL_TOKEN, value: stringToken.value };
  481. }
  482. }
  483. this.consumeBadUrlRemnants();
  484. return BAD_URL_TOKEN;
  485. }
  486. while (true) {
  487. var codePoint = this.consumeCodePoint();
  488. if (codePoint === EOF || codePoint === RIGHT_PARENTHESIS) {
  489. return { type: TokenType.URL_TOKEN, value: css_line_break_1.fromCodePoint.apply(void 0, value) };
  490. }
  491. else if (isWhiteSpace(codePoint)) {
  492. this.consumeWhiteSpace();
  493. if (this.peekCodePoint(0) === EOF || this.peekCodePoint(0) === RIGHT_PARENTHESIS) {
  494. this.consumeCodePoint();
  495. return { type: TokenType.URL_TOKEN, value: css_line_break_1.fromCodePoint.apply(void 0, value) };
  496. }
  497. this.consumeBadUrlRemnants();
  498. return BAD_URL_TOKEN;
  499. }
  500. else if (codePoint === QUOTATION_MARK ||
  501. codePoint === APOSTROPHE ||
  502. codePoint === LEFT_PARENTHESIS ||
  503. isNonPrintableCodePoint(codePoint)) {
  504. this.consumeBadUrlRemnants();
  505. return BAD_URL_TOKEN;
  506. }
  507. else if (codePoint === REVERSE_SOLIDUS) {
  508. if (isValidEscape(codePoint, this.peekCodePoint(0))) {
  509. value.push(this.consumeEscapedCodePoint());
  510. }
  511. else {
  512. this.consumeBadUrlRemnants();
  513. return BAD_URL_TOKEN;
  514. }
  515. }
  516. else {
  517. value.push(codePoint);
  518. }
  519. }
  520. };
  521. Tokenizer.prototype.consumeWhiteSpace = function () {
  522. while (isWhiteSpace(this.peekCodePoint(0))) {
  523. this.consumeCodePoint();
  524. }
  525. };
  526. Tokenizer.prototype.consumeBadUrlRemnants = function () {
  527. while (true) {
  528. var codePoint = this.consumeCodePoint();
  529. if (codePoint === RIGHT_PARENTHESIS || codePoint === EOF) {
  530. return;
  531. }
  532. if (isValidEscape(codePoint, this.peekCodePoint(0))) {
  533. this.consumeEscapedCodePoint();
  534. }
  535. }
  536. };
  537. Tokenizer.prototype.consumeStringSlice = function (count) {
  538. var SLICE_STACK_SIZE = 60000;
  539. var value = '';
  540. while (count > 0) {
  541. var amount = Math.min(SLICE_STACK_SIZE, count);
  542. value += css_line_break_1.fromCodePoint.apply(void 0, this._value.splice(0, amount));
  543. count -= amount;
  544. }
  545. this._value.shift();
  546. return value;
  547. };
  548. Tokenizer.prototype.consumeStringToken = function (endingCodePoint) {
  549. var value = '';
  550. var i = 0;
  551. do {
  552. var codePoint = this._value[i];
  553. if (codePoint === EOF || codePoint === undefined || codePoint === endingCodePoint) {
  554. value += this.consumeStringSlice(i);
  555. return { type: TokenType.STRING_TOKEN, value: value };
  556. }
  557. if (codePoint === LINE_FEED) {
  558. this._value.splice(0, i);
  559. return BAD_STRING_TOKEN;
  560. }
  561. if (codePoint === REVERSE_SOLIDUS) {
  562. var next = this._value[i + 1];
  563. if (next !== EOF && next !== undefined) {
  564. if (next === LINE_FEED) {
  565. value += this.consumeStringSlice(i);
  566. i = -1;
  567. this._value.shift();
  568. }
  569. else if (isValidEscape(codePoint, next)) {
  570. value += this.consumeStringSlice(i);
  571. value += css_line_break_1.fromCodePoint(this.consumeEscapedCodePoint());
  572. i = -1;
  573. }
  574. }
  575. }
  576. i++;
  577. } while (true);
  578. };
  579. Tokenizer.prototype.consumeNumber = function () {
  580. var repr = [];
  581. var type = exports.FLAG_INTEGER;
  582. var c1 = this.peekCodePoint(0);
  583. if (c1 === PLUS_SIGN || c1 === HYPHEN_MINUS) {
  584. repr.push(this.consumeCodePoint());
  585. }
  586. while (isDigit(this.peekCodePoint(0))) {
  587. repr.push(this.consumeCodePoint());
  588. }
  589. c1 = this.peekCodePoint(0);
  590. var c2 = this.peekCodePoint(1);
  591. if (c1 === FULL_STOP && isDigit(c2)) {
  592. repr.push(this.consumeCodePoint(), this.consumeCodePoint());
  593. type = exports.FLAG_NUMBER;
  594. while (isDigit(this.peekCodePoint(0))) {
  595. repr.push(this.consumeCodePoint());
  596. }
  597. }
  598. c1 = this.peekCodePoint(0);
  599. c2 = this.peekCodePoint(1);
  600. var c3 = this.peekCodePoint(2);
  601. if ((c1 === E || c1 === e) && (((c2 === PLUS_SIGN || c2 === HYPHEN_MINUS) && isDigit(c3)) || isDigit(c2))) {
  602. repr.push(this.consumeCodePoint(), this.consumeCodePoint());
  603. type = exports.FLAG_NUMBER;
  604. while (isDigit(this.peekCodePoint(0))) {
  605. repr.push(this.consumeCodePoint());
  606. }
  607. }
  608. return [stringToNumber(repr), type];
  609. };
  610. Tokenizer.prototype.consumeNumericToken = function () {
  611. var _a = this.consumeNumber(), number = _a[0], flags = _a[1];
  612. var c1 = this.peekCodePoint(0);
  613. var c2 = this.peekCodePoint(1);
  614. var c3 = this.peekCodePoint(2);
  615. if (isIdentifierStart(c1, c2, c3)) {
  616. var unit = this.consumeName();
  617. return { type: TokenType.DIMENSION_TOKEN, number: number, flags: flags, unit: unit };
  618. }
  619. if (c1 === PERCENTAGE_SIGN) {
  620. this.consumeCodePoint();
  621. return { type: TokenType.PERCENTAGE_TOKEN, number: number, flags: flags };
  622. }
  623. return { type: TokenType.NUMBER_TOKEN, number: number, flags: flags };
  624. };
  625. Tokenizer.prototype.consumeEscapedCodePoint = function () {
  626. var codePoint = this.consumeCodePoint();
  627. if (isHex(codePoint)) {
  628. var hex = css_line_break_1.fromCodePoint(codePoint);
  629. while (isHex(this.peekCodePoint(0)) && hex.length < 6) {
  630. hex += css_line_break_1.fromCodePoint(this.consumeCodePoint());
  631. }
  632. if (isWhiteSpace(this.peekCodePoint(0))) {
  633. this.consumeCodePoint();
  634. }
  635. var hexCodePoint = parseInt(hex, 16);
  636. if (hexCodePoint === 0 || isSurrogateCodePoint(hexCodePoint) || hexCodePoint > 0x10ffff) {
  637. return REPLACEMENT_CHARACTER;
  638. }
  639. return hexCodePoint;
  640. }
  641. if (codePoint === EOF) {
  642. return REPLACEMENT_CHARACTER;
  643. }
  644. return codePoint;
  645. };
  646. Tokenizer.prototype.consumeName = function () {
  647. var result = '';
  648. while (true) {
  649. var codePoint = this.consumeCodePoint();
  650. if (isNameCodePoint(codePoint)) {
  651. result += css_line_break_1.fromCodePoint(codePoint);
  652. }
  653. else if (isValidEscape(codePoint, this.peekCodePoint(0))) {
  654. result += css_line_break_1.fromCodePoint(this.consumeEscapedCodePoint());
  655. }
  656. else {
  657. this.reconsumeCodePoint(codePoint);
  658. return result;
  659. }
  660. }
  661. };
  662. return Tokenizer;
  663. }());
  664. exports.Tokenizer = Tokenizer;
  665. //# sourceMappingURL=tokenizer.js.map