You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12144 lines
408 KiB

4 years ago
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global = global || self, global.csstree = factory());
  5. }(this, function () { 'use strict';
  6. //
  7. // list
  8. // ┌──────┐
  9. // ┌──────────────┼─head │
  10. // │ │ tail─┼──────────────┐
  11. // │ └──────┘ │
  12. // ▼ ▼
  13. // item item item item
  14. // ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
  15. // null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
  16. // │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
  17. // ├──────┤ ├──────┤ ├──────┤ ├──────┤
  18. // │ data │ │ data │ │ data │ │ data │
  19. // └──────┘ └──────┘ └──────┘ └──────┘
  20. //
  21. function createItem(data) {
  22. return {
  23. prev: null,
  24. next: null,
  25. data: data
  26. };
  27. }
  28. function allocateCursor(node, prev, next) {
  29. var cursor;
  30. if (cursors !== null) {
  31. cursor = cursors;
  32. cursors = cursors.cursor;
  33. cursor.prev = prev;
  34. cursor.next = next;
  35. cursor.cursor = node.cursor;
  36. } else {
  37. cursor = {
  38. prev: prev,
  39. next: next,
  40. cursor: node.cursor
  41. };
  42. }
  43. node.cursor = cursor;
  44. return cursor;
  45. }
  46. function releaseCursor(node) {
  47. var cursor = node.cursor;
  48. node.cursor = cursor.cursor;
  49. cursor.prev = null;
  50. cursor.next = null;
  51. cursor.cursor = cursors;
  52. cursors = cursor;
  53. }
  54. var cursors = null;
  55. var List = function() {
  56. this.cursor = null;
  57. this.head = null;
  58. this.tail = null;
  59. };
  60. List.createItem = createItem;
  61. List.prototype.createItem = createItem;
  62. List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
  63. var cursor = this.cursor;
  64. while (cursor !== null) {
  65. if (cursor.prev === prevOld) {
  66. cursor.prev = prevNew;
  67. }
  68. if (cursor.next === nextOld) {
  69. cursor.next = nextNew;
  70. }
  71. cursor = cursor.cursor;
  72. }
  73. };
  74. List.prototype.getSize = function() {
  75. var size = 0;
  76. var cursor = this.head;
  77. while (cursor) {
  78. size++;
  79. cursor = cursor.next;
  80. }
  81. return size;
  82. };
  83. List.prototype.fromArray = function(array) {
  84. var cursor = null;
  85. this.head = null;
  86. for (var i = 0; i < array.length; i++) {
  87. var item = createItem(array[i]);
  88. if (cursor !== null) {
  89. cursor.next = item;
  90. } else {
  91. this.head = item;
  92. }
  93. item.prev = cursor;
  94. cursor = item;
  95. }
  96. this.tail = cursor;
  97. return this;
  98. };
  99. List.prototype.toArray = function() {
  100. var cursor = this.head;
  101. var result = [];
  102. while (cursor) {
  103. result.push(cursor.data);
  104. cursor = cursor.next;
  105. }
  106. return result;
  107. };
  108. List.prototype.toJSON = List.prototype.toArray;
  109. List.prototype.isEmpty = function() {
  110. return this.head === null;
  111. };
  112. List.prototype.first = function() {
  113. return this.head && this.head.data;
  114. };
  115. List.prototype.last = function() {
  116. return this.tail && this.tail.data;
  117. };
  118. List.prototype.each = function(fn, context) {
  119. var item;
  120. if (context === undefined) {
  121. context = this;
  122. }
  123. // push cursor
  124. var cursor = allocateCursor(this, null, this.head);
  125. while (cursor.next !== null) {
  126. item = cursor.next;
  127. cursor.next = item.next;
  128. fn.call(context, item.data, item, this);
  129. }
  130. // pop cursor
  131. releaseCursor(this);
  132. };
  133. List.prototype.forEach = List.prototype.each;
  134. List.prototype.eachRight = function(fn, context) {
  135. var item;
  136. if (context === undefined) {
  137. context = this;
  138. }
  139. // push cursor
  140. var cursor = allocateCursor(this, this.tail, null);
  141. while (cursor.prev !== null) {
  142. item = cursor.prev;
  143. cursor.prev = item.prev;
  144. fn.call(context, item.data, item, this);
  145. }
  146. // pop cursor
  147. releaseCursor(this);
  148. };
  149. List.prototype.forEachRight = List.prototype.eachRight;
  150. List.prototype.nextUntil = function(start, fn, context) {
  151. if (start === null) {
  152. return;
  153. }
  154. var item;
  155. if (context === undefined) {
  156. context = this;
  157. }
  158. // push cursor
  159. var cursor = allocateCursor(this, null, start);
  160. while (cursor.next !== null) {
  161. item = cursor.next;
  162. cursor.next = item.next;
  163. if (fn.call(context, item.data, item, this)) {
  164. break;
  165. }
  166. }
  167. // pop cursor
  168. releaseCursor(this);
  169. };
  170. List.prototype.prevUntil = function(start, fn, context) {
  171. if (start === null) {
  172. return;
  173. }
  174. var item;
  175. if (context === undefined) {
  176. context = this;
  177. }
  178. // push cursor
  179. var cursor = allocateCursor(this, start, null);
  180. while (cursor.prev !== null) {
  181. item = cursor.prev;
  182. cursor.prev = item.prev;
  183. if (fn.call(context, item.data, item, this)) {
  184. break;
  185. }
  186. }
  187. // pop cursor
  188. releaseCursor(this);
  189. };
  190. List.prototype.some = function(fn, context) {
  191. var cursor = this.head;
  192. if (context === undefined) {
  193. context = this;
  194. }
  195. while (cursor !== null) {
  196. if (fn.call(context, cursor.data, cursor, this)) {
  197. return true;
  198. }
  199. cursor = cursor.next;
  200. }
  201. return false;
  202. };
  203. List.prototype.map = function(fn, context) {
  204. var result = new List();
  205. var cursor = this.head;
  206. if (context === undefined) {
  207. context = this;
  208. }
  209. while (cursor !== null) {
  210. result.appendData(fn.call(context, cursor.data, cursor, this));
  211. cursor = cursor.next;
  212. }
  213. return result;
  214. };
  215. List.prototype.filter = function(fn, context) {
  216. var result = new List();
  217. var cursor = this.head;
  218. if (context === undefined) {
  219. context = this;
  220. }
  221. while (cursor !== null) {
  222. if (fn.call(context, cursor.data, cursor, this)) {
  223. result.appendData(cursor.data);
  224. }
  225. cursor = cursor.next;
  226. }
  227. return result;
  228. };
  229. List.prototype.clear = function() {
  230. this.head = null;
  231. this.tail = null;
  232. };
  233. List.prototype.copy = function() {
  234. var result = new List();
  235. var cursor = this.head;
  236. while (cursor !== null) {
  237. result.insert(createItem(cursor.data));
  238. cursor = cursor.next;
  239. }
  240. return result;
  241. };
  242. List.prototype.prepend = function(item) {
  243. // head
  244. // ^
  245. // item
  246. this.updateCursors(null, item, this.head, item);
  247. // insert to the beginning of the list
  248. if (this.head !== null) {
  249. // new item <- first item
  250. this.head.prev = item;
  251. // new item -> first item
  252. item.next = this.head;
  253. } else {
  254. // if list has no head, then it also has no tail
  255. // in this case tail points to the new item
  256. this.tail = item;
  257. }
  258. // head always points to new item
  259. this.head = item;
  260. return this;
  261. };
  262. List.prototype.prependData = function(data) {
  263. return this.prepend(createItem(data));
  264. };
  265. List.prototype.append = function(item) {
  266. return this.insert(item);
  267. };
  268. List.prototype.appendData = function(data) {
  269. return this.insert(createItem(data));
  270. };
  271. List.prototype.insert = function(item, before) {
  272. if (before !== undefined && before !== null) {
  273. // prev before
  274. // ^
  275. // item
  276. this.updateCursors(before.prev, item, before, item);
  277. if (before.prev === null) {
  278. // insert to the beginning of list
  279. if (this.head !== before) {
  280. throw new Error('before doesn\'t belong to list');
  281. }
  282. // since head points to before therefore list doesn't empty
  283. // no need to check tail
  284. this.head = item;
  285. before.prev = item;
  286. item.next = before;
  287. this.updateCursors(null, item);
  288. } else {
  289. // insert between two items
  290. before.prev.next = item;
  291. item.prev = before.prev;
  292. before.prev = item;
  293. item.next = before;
  294. }
  295. } else {
  296. // tail
  297. // ^
  298. // item
  299. this.updateCursors(this.tail, item, null, item);
  300. // insert to the ending of the list
  301. if (this.tail !== null) {
  302. // last item -> new item
  303. this.tail.next = item;
  304. // last item <- new item
  305. item.prev = this.tail;
  306. } else {
  307. // if list has no tail, then it also has no head
  308. // in this case head points to new item
  309. this.head = item;
  310. }
  311. // tail always points to new item
  312. this.tail = item;
  313. }
  314. return this;
  315. };
  316. List.prototype.insertData = function(data, before) {
  317. return this.insert(createItem(data), before);
  318. };
  319. List.prototype.remove = function(item) {
  320. // item
  321. // ^
  322. // prev next
  323. this.updateCursors(item, item.prev, item, item.next);
  324. if (item.prev !== null) {
  325. item.prev.next = item.next;
  326. } else {
  327. if (this.head !== item) {
  328. throw new Error('item doesn\'t belong to list');
  329. }
  330. this.head = item.next;
  331. }
  332. if (item.next !== null) {
  333. item.next.prev = item.prev;
  334. } else {
  335. if (this.tail !== item) {
  336. throw new Error('item doesn\'t belong to list');
  337. }
  338. this.tail = item.prev;
  339. }
  340. item.prev = null;
  341. item.next = null;
  342. return item;
  343. };
  344. List.prototype.push = function(data) {
  345. this.insert(createItem(data));
  346. };
  347. List.prototype.pop = function() {
  348. if (this.tail !== null) {
  349. return this.remove(this.tail);
  350. }
  351. };
  352. List.prototype.unshift = function(data) {
  353. this.prepend(createItem(data));
  354. };
  355. List.prototype.shift = function() {
  356. if (this.head !== null) {
  357. return this.remove(this.head);
  358. }
  359. };
  360. List.prototype.prependList = function(list) {
  361. return this.insertList(list, this.head);
  362. };
  363. List.prototype.appendList = function(list) {
  364. return this.insertList(list);
  365. };
  366. List.prototype.insertList = function(list, before) {
  367. // ignore empty lists
  368. if (list.head === null) {
  369. return this;
  370. }
  371. if (before !== undefined && before !== null) {
  372. this.updateCursors(before.prev, list.tail, before, list.head);
  373. // insert in the middle of dist list
  374. if (before.prev !== null) {
  375. // before.prev <-> list.head
  376. before.prev.next = list.head;
  377. list.head.prev = before.prev;
  378. } else {
  379. this.head = list.head;
  380. }
  381. before.prev = list.tail;
  382. list.tail.next = before;
  383. } else {
  384. this.updateCursors(this.tail, list.tail, null, list.head);
  385. // insert to end of the list
  386. if (this.tail !== null) {
  387. // if destination list has a tail, then it also has a head,
  388. // but head doesn't change
  389. // dest tail -> source head
  390. this.tail.next = list.head;
  391. // dest tail <- source head
  392. list.head.prev = this.tail;
  393. } else {
  394. // if list has no a tail, then it also has no a head
  395. // in this case points head to new item
  396. this.head = list.head;
  397. }
  398. // tail always start point to new item
  399. this.tail = list.tail;
  400. }
  401. list.head = null;
  402. list.tail = null;
  403. return this;
  404. };
  405. List.prototype.replace = function(oldItem, newItemOrList) {
  406. if ('head' in newItemOrList) {
  407. this.insertList(newItemOrList, oldItem);
  408. } else {
  409. this.insert(newItemOrList, oldItem);
  410. }
  411. this.remove(oldItem);
  412. };
  413. var List_1 = List;
  414. var createCustomError = function createCustomError(name, message) {
  415. // use Object.create(), because some VMs prevent setting line/column otherwise
  416. // (iOS Safari 10 even throws an exception)
  417. var error = Object.create(SyntaxError.prototype);
  418. var errorStack = new Error();
  419. error.name = name;
  420. error.message = message;
  421. Object.defineProperty(error, 'stack', {
  422. get: function() {
  423. return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
  424. }
  425. });
  426. return error;
  427. };
  428. var MAX_LINE_LENGTH = 100;
  429. var OFFSET_CORRECTION = 60;
  430. var TAB_REPLACEMENT = ' ';
  431. function sourceFragment(error, extraLines) {
  432. function processLines(start, end) {
  433. return lines.slice(start, end).map(function(line, idx) {
  434. var num = String(start + idx + 1);
  435. while (num.length < maxNumLength) {
  436. num = ' ' + num;
  437. }
  438. return num + ' |' + line;
  439. }).join('\n');
  440. }
  441. var lines = error.source.split(/\r\n?|\n|\f/);
  442. var line = error.line;
  443. var column = error.column;
  444. var startLine = Math.max(1, line - extraLines) - 1;
  445. var endLine = Math.min(line + extraLines, lines.length + 1);
  446. var maxNumLength = Math.max(4, String(endLine).length) + 1;
  447. var cutLeft = 0;
  448. // column correction according to replaced tab before column
  449. column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
  450. if (column > MAX_LINE_LENGTH) {
  451. cutLeft = column - OFFSET_CORRECTION + 3;
  452. column = OFFSET_CORRECTION - 2;
  453. }
  454. for (var i = startLine; i <= endLine; i++) {
  455. if (i >= 0 && i < lines.length) {
  456. lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
  457. lines[i] =
  458. (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
  459. lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
  460. (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
  461. }
  462. }
  463. return [
  464. processLines(startLine, line),
  465. new Array(column + maxNumLength + 2).join('-') + '^',
  466. processLines(line, endLine)
  467. ].filter(Boolean).join('\n');
  468. }
  469. var SyntaxError$1 = function(message, source, offset, line, column) {
  470. var error = createCustomError('SyntaxError', message);
  471. error.source = source;
  472. error.offset = offset;
  473. error.line = line;
  474. error.column = column;
  475. error.sourceFragment = function(extraLines) {
  476. return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
  477. };
  478. Object.defineProperty(error, 'formattedMessage', {
  479. get: function() {
  480. return (
  481. 'Parse error: ' + error.message + '\n' +
  482. sourceFragment(error, 2)
  483. );
  484. }
  485. });
  486. // for backward capability
  487. error.parseError = {
  488. offset: offset,
  489. line: line,
  490. column: column
  491. };
  492. return error;
  493. };
  494. var _SyntaxError = SyntaxError$1;
  495. // CSS Syntax Module Level 3
  496. // https://www.w3.org/TR/css-syntax-3/
  497. var TYPE = {
  498. EOF: 0, // <EOF-token>
  499. Ident: 1, // <ident-token>
  500. Function: 2, // <function-token>
  501. AtKeyword: 3, // <at-keyword-token>
  502. Hash: 4, // <hash-token>
  503. String: 5, // <string-token>
  504. BadString: 6, // <bad-string-token>
  505. Url: 7, // <url-token>
  506. BadUrl: 8, // <bad-url-token>
  507. Delim: 9, // <delim-token>
  508. Number: 10, // <number-token>
  509. Percentage: 11, // <percentage-token>
  510. Dimension: 12, // <dimension-token>
  511. WhiteSpace: 13, // <whitespace-token>
  512. CDO: 14, // <CDO-token>
  513. CDC: 15, // <CDC-token>
  514. Colon: 16, // <colon-token> :
  515. Semicolon: 17, // <semicolon-token> ;
  516. Comma: 18, // <comma-token> ,
  517. LeftSquareBracket: 19, // <[-token>
  518. RightSquareBracket: 20, // <]-token>
  519. LeftParenthesis: 21, // <(-token>
  520. RightParenthesis: 22, // <)-token>
  521. LeftCurlyBracket: 23, // <{-token>
  522. RightCurlyBracket: 24, // <}-token>
  523. Comment: 25
  524. };
  525. var NAME = Object.keys(TYPE).reduce(function(result, key) {
  526. result[TYPE[key]] = key;
  527. return result;
  528. }, {});
  529. var _const = {
  530. TYPE: TYPE,
  531. NAME: NAME
  532. };
  533. var EOF = 0;
  534. // https://drafts.csswg.org/css-syntax-3/
  535. // § 4.2. Definitions
  536. // digit
  537. // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
  538. function isDigit(code) {
  539. return code >= 0x0030 && code <= 0x0039;
  540. }
  541. // hex digit
  542. // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
  543. // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
  544. function isHexDigit(code) {
  545. return (
  546. isDigit(code) || // 0 .. 9
  547. (code >= 0x0041 && code <= 0x0046) || // A .. F
  548. (code >= 0x0061 && code <= 0x0066) // a .. f
  549. );
  550. }
  551. // uppercase letter
  552. // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
  553. function isUppercaseLetter(code) {
  554. return code >= 0x0041 && code <= 0x005A;
  555. }
  556. // lowercase letter
  557. // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
  558. function isLowercaseLetter(code) {
  559. return code >= 0x0061 && code <= 0x007A;
  560. }
  561. // letter
  562. // An uppercase letter or a lowercase letter.
  563. function isLetter(code) {
  564. return isUppercaseLetter(code) || isLowercaseLetter(code);
  565. }
  566. // non-ASCII code point
  567. // A code point with a value equal to or greater than U+0080 <control>.
  568. function isNonAscii(code) {
  569. return code >= 0x0080;
  570. }
  571. // name-start code point
  572. // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
  573. function isNameStart(code) {
  574. return isLetter(code) || isNonAscii(code) || code === 0x005F;
  575. }
  576. // name code point
  577. // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
  578. function isName(code) {
  579. return isNameStart(code) || isDigit(code) || code === 0x002D;
  580. }
  581. // non-printable code point
  582. // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
  583. // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
  584. function isNonPrintable(code) {
  585. return (
  586. (code >= 0x0000 && code <= 0x0008) ||
  587. (code === 0x000B) ||
  588. (code >= 0x000E && code <= 0x001F) ||
  589. (code === 0x007F)
  590. );
  591. }
  592. // newline
  593. // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
  594. // as they are converted to U+000A LINE FEED during preprocessing.
  595. // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
  596. function isNewline(code) {
  597. return code === 0x000A || code === 0x000D || code === 0x000C;
  598. }
  599. // whitespace
  600. // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
  601. function isWhiteSpace(code) {
  602. return isNewline(code) || code === 0x0020 || code === 0x0009;
  603. }
  604. // § 4.3.8. Check if two code points are a valid escape
  605. function isValidEscape(first, second) {
  606. // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
  607. if (first !== 0x005C) {
  608. return false;
  609. }
  610. // Otherwise, if the second code point is a newline or EOF, return false.
  611. if (isNewline(second) || second === EOF) {
  612. return false;
  613. }
  614. // Otherwise, return true.
  615. return true;
  616. }
  617. // § 4.3.9. Check if three code points would start an identifier
  618. function isIdentifierStart(first, second, third) {
  619. // Look at the first code point:
  620. // U+002D HYPHEN-MINUS
  621. if (first === 0x002D) {
  622. // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
  623. // or the second and third code points are a valid escape, return true. Otherwise, return false.
  624. return (
  625. isNameStart(second) ||
  626. second === 0x002D ||
  627. isValidEscape(second, third)
  628. );
  629. }
  630. // name-start code point
  631. if (isNameStart(first)) {
  632. // Return true.
  633. return true;
  634. }
  635. // U+005C REVERSE SOLIDUS (\)
  636. if (first === 0x005C) {
  637. // If the first and second code points are a valid escape, return true. Otherwise, return false.
  638. return isValidEscape(first, second);
  639. }
  640. // anything else
  641. // Return false.
  642. return false;
  643. }
  644. // § 4.3.10. Check if three code points would start a number
  645. function isNumberStart(first, second, third) {
  646. // Look at the first code point:
  647. // U+002B PLUS SIGN (+)
  648. // U+002D HYPHEN-MINUS (-)
  649. if (first === 0x002B || first === 0x002D) {
  650. // If the second code point is a digit, return true.
  651. if (isDigit(second)) {
  652. return 2;
  653. }
  654. // Otherwise, if the second code point is a U+002E FULL STOP (.)
  655. // and the third code point is a digit, return true.
  656. // Otherwise, return false.
  657. return second === 0x002E && isDigit(third) ? 3 : 0;
  658. }
  659. // U+002E FULL STOP (.)
  660. if (first === 0x002E) {
  661. // If the second code point is a digit, return true. Otherwise, return false.
  662. return isDigit(second) ? 2 : 0;
  663. }
  664. // digit
  665. if (isDigit(first)) {
  666. // Return true.
  667. return 1;
  668. }
  669. // anything else
  670. // Return false.
  671. return 0;
  672. }
  673. //
  674. // Misc
  675. //
  676. // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
  677. function isBOM(code) {
  678. // UTF-16BE
  679. if (code === 0xFEFF) {
  680. return 1;
  681. }
  682. // UTF-16LE
  683. if (code === 0xFFFE) {
  684. return 1;
  685. }
  686. return 0;
  687. }
  688. // Fast code category
  689. //
  690. // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
  691. // > non-ASCII code point
  692. // > A code point with a value equal to or greater than U+0080 <control>
  693. // > name-start code point
  694. // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
  695. // > name code point
  696. // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
  697. // That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
  698. var CATEGORY = new Array(0x80);
  699. charCodeCategory.Eof = 0x80;
  700. charCodeCategory.WhiteSpace = 0x82;
  701. charCodeCategory.Digit = 0x83;
  702. charCodeCategory.NameStart = 0x84;
  703. charCodeCategory.NonPrintable = 0x85;
  704. for (var i = 0; i < CATEGORY.length; i++) {
  705. switch (true) {
  706. case isWhiteSpace(i):
  707. CATEGORY[i] = charCodeCategory.WhiteSpace;
  708. break;
  709. case isDigit(i):
  710. CATEGORY[i] = charCodeCategory.Digit;
  711. break;
  712. case isNameStart(i):
  713. CATEGORY[i] = charCodeCategory.NameStart;
  714. break;
  715. case isNonPrintable(i):
  716. CATEGORY[i] = charCodeCategory.NonPrintable;
  717. break;
  718. default:
  719. CATEGORY[i] = i || charCodeCategory.Eof;
  720. }
  721. }
  722. function charCodeCategory(code) {
  723. return code < 0x80 ? CATEGORY[code] : charCodeCategory.NameStart;
  724. }
  725. var charCodeDefinitions = {
  726. isDigit: isDigit,
  727. isHexDigit: isHexDigit,
  728. isUppercaseLetter: isUppercaseLetter,
  729. isLowercaseLetter: isLowercaseLetter,
  730. isLetter: isLetter,
  731. isNonAscii: isNonAscii,
  732. isNameStart: isNameStart,
  733. isName: isName,
  734. isNonPrintable: isNonPrintable,
  735. isNewline: isNewline,
  736. isWhiteSpace: isWhiteSpace,
  737. isValidEscape: isValidEscape,
  738. isIdentifierStart: isIdentifierStart,
  739. isNumberStart: isNumberStart,
  740. isBOM: isBOM,
  741. charCodeCategory: charCodeCategory
  742. };
  743. var isDigit$1 = charCodeDefinitions.isDigit;
  744. var isHexDigit$1 = charCodeDefinitions.isHexDigit;
  745. var isUppercaseLetter$1 = charCodeDefinitions.isUppercaseLetter;
  746. var isName$1 = charCodeDefinitions.isName;
  747. var isWhiteSpace$1 = charCodeDefinitions.isWhiteSpace;
  748. var isValidEscape$1 = charCodeDefinitions.isValidEscape;
  749. function getCharCode(source, offset) {
  750. return offset < source.length ? source.charCodeAt(offset) : 0;
  751. }
  752. function getNewlineLength(source, offset, code) {
  753. if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
  754. return 2;
  755. }
  756. return 1;
  757. }
  758. function cmpChar(testStr, offset, referenceCode) {
  759. var code = testStr.charCodeAt(offset);
  760. // code.toLowerCase() for A..Z
  761. if (isUppercaseLetter$1(code)) {
  762. code = code | 32;
  763. }
  764. return code === referenceCode;
  765. }
  766. function cmpStr(testStr, start, end, referenceStr) {
  767. if (end - start !== referenceStr.length) {
  768. return false;
  769. }
  770. if (start < 0 || end > testStr.length) {
  771. return false;
  772. }
  773. for (var i = start; i < end; i++) {
  774. var testCode = testStr.charCodeAt(i);
  775. var referenceCode = referenceStr.charCodeAt(i - start);
  776. // testCode.toLowerCase() for A..Z
  777. if (isUppercaseLetter$1(testCode)) {
  778. testCode = testCode | 32;
  779. }
  780. if (testCode !== referenceCode) {
  781. return false;
  782. }
  783. }
  784. return true;
  785. }
  786. function findWhiteSpaceStart(source, offset) {
  787. for (; offset >= 0; offset--) {
  788. if (!isWhiteSpace$1(source.charCodeAt(offset))) {
  789. break;
  790. }
  791. }
  792. return offset + 1;
  793. }
  794. function findWhiteSpaceEnd(source, offset) {
  795. for (; offset < source.length; offset++) {
  796. if (!isWhiteSpace$1(source.charCodeAt(offset))) {
  797. break;
  798. }
  799. }
  800. return offset;
  801. }
  802. function findDecimalNumberEnd(source, offset) {
  803. for (; offset < source.length; offset++) {
  804. if (!isDigit$1(source.charCodeAt(offset))) {
  805. break;
  806. }
  807. }
  808. return offset;
  809. }
  810. // § 4.3.7. Consume an escaped code point
  811. function consumeEscaped(source, offset) {
  812. // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
  813. // that the next input code point has already been verified to be part of a valid escape.
  814. offset += 2;
  815. // hex digit
  816. if (isHexDigit$1(getCharCode(source, offset - 1))) {
  817. // Consume as many hex digits as possible, but no more than 5.
  818. // Note that this means 1-6 hex digits have been consumed in total.
  819. for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
  820. if (!isHexDigit$1(getCharCode(source, offset))) {
  821. break;
  822. }
  823. }
  824. // If the next input code point is whitespace, consume it as well.
  825. var code = getCharCode(source, offset);
  826. if (isWhiteSpace$1(code)) {
  827. offset += getNewlineLength(source, offset, code);
  828. }
  829. }
  830. return offset;
  831. }
  832. // §4.3.11. Consume a name
  833. // Note: This algorithm does not do the verification of the first few code points that are necessary
  834. // to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
  835. // ensure that the stream starts with an identifier before calling this algorithm.
  836. function consumeName(source, offset) {
  837. // Let result initially be an empty string.
  838. // Repeatedly consume the next input code point from the stream:
  839. for (; offset < source.length; offset++) {
  840. var code = source.charCodeAt(offset);
  841. // name code point
  842. if (isName$1(code)) {
  843. // Append the code point to result.
  844. continue;
  845. }
  846. // the stream starts with a valid escape
  847. if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
  848. // Consume an escaped code point. Append the returned code point to result.
  849. offset = consumeEscaped(source, offset) - 1;
  850. continue;
  851. }
  852. // anything else
  853. // Reconsume the current input code point. Return result.
  854. break;
  855. }
  856. return offset;
  857. }
  858. // §4.3.12. Consume a number
  859. function consumeNumber(source, offset) {
  860. var code = source.charCodeAt(offset);
  861. // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
  862. // consume it and append it to repr.
  863. if (code === 0x002B || code === 0x002D) {
  864. code = source.charCodeAt(offset += 1);
  865. }
  866. // 3. While the next input code point is a digit, consume it and append it to repr.
  867. if (isDigit$1(code)) {
  868. offset = findDecimalNumberEnd(source, offset + 1);
  869. code = source.charCodeAt(offset);
  870. }
  871. // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
  872. if (code === 0x002E && isDigit$1(source.charCodeAt(offset + 1))) {
  873. // 4.1 Consume them.
  874. // 4.2 Append them to repr.
  875. code = source.charCodeAt(offset += 2);
  876. // 4.3 Set type to "number".
  877. // TODO
  878. // 4.4 While the next input code point is a digit, consume it and append it to repr.
  879. offset = findDecimalNumberEnd(source, offset);
  880. }
  881. // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
  882. // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
  883. if (cmpChar(source, offset, 101 /* e */)) {
  884. var sign = 0;
  885. code = source.charCodeAt(offset + 1);
  886. // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
  887. if (code === 0x002D || code === 0x002B) {
  888. sign = 1;
  889. code = source.charCodeAt(offset + 2);
  890. }
  891. // ... followed by a digit
  892. if (isDigit$1(code)) {
  893. // 5.1 Consume them.
  894. // 5.2 Append them to repr.
  895. // 5.3 Set type to "number".
  896. // TODO
  897. // 5.4 While the next input code point is a digit, consume it and append it to repr.
  898. offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
  899. }
  900. }
  901. return offset;
  902. }
  903. // § 4.3.14. Consume the remnants of a bad url
  904. // ... its sole use is to consume enough of the input stream to reach a recovery point
  905. // where normal tokenizing can resume.
  906. function consumeBadUrlRemnants(source, offset) {
  907. // Repeatedly consume the next input code point from the stream:
  908. for (; offset < source.length; offset++) {
  909. var code = source.charCodeAt(offset);
  910. // U+0029 RIGHT PARENTHESIS ())
  911. // EOF
  912. if (code === 0x0029) {
  913. // Return.
  914. offset++;
  915. break;
  916. }
  917. if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
  918. // Consume an escaped code point.
  919. // Note: This allows an escaped right parenthesis ("\)") to be encountered
  920. // without ending the <bad-url-token>. This is otherwise identical to
  921. // the "anything else" clause.
  922. offset = consumeEscaped(source, offset);
  923. }
  924. }
  925. return offset;
  926. }
  927. var utils = {
  928. consumeEscaped: consumeEscaped,
  929. consumeName: consumeName,
  930. consumeNumber: consumeNumber,
  931. consumeBadUrlRemnants: consumeBadUrlRemnants,
  932. cmpChar: cmpChar,
  933. cmpStr: cmpStr,
  934. getNewlineLength: getNewlineLength,
  935. findWhiteSpaceStart: findWhiteSpaceStart,
  936. findWhiteSpaceEnd: findWhiteSpaceEnd
  937. };
  938. var TYPE$1 = _const.TYPE;
  939. var NAME$1 = _const.NAME;
  940. var cmpStr$1 = utils.cmpStr;
  941. var EOF$1 = TYPE$1.EOF;
  942. var WHITESPACE = TYPE$1.WhiteSpace;
  943. var COMMENT = TYPE$1.Comment;
  944. var OFFSET_MASK = 0x00FFFFFF;
  945. var TYPE_SHIFT = 24;
  946. var TokenStream = function() {
  947. this.offsetAndType = null;
  948. this.balance = null;
  949. this.reset();
  950. };
  951. TokenStream.prototype = {
  952. reset: function() {
  953. this.eof = false;
  954. this.tokenIndex = -1;
  955. this.tokenType = 0;
  956. this.tokenStart = this.firstCharOffset;
  957. this.tokenEnd = this.firstCharOffset;
  958. },
  959. lookupType: function(offset) {
  960. offset += this.tokenIndex;
  961. if (offset < this.tokenCount) {
  962. return this.offsetAndType[offset] >> TYPE_SHIFT;
  963. }
  964. return EOF$1;
  965. },
  966. lookupOffset: function(offset) {
  967. offset += this.tokenIndex;
  968. if (offset < this.tokenCount) {
  969. return this.offsetAndType[offset - 1] & OFFSET_MASK;
  970. }
  971. return this.source.length;
  972. },
  973. lookupValue: function(offset, referenceStr) {
  974. offset += this.tokenIndex;
  975. if (offset < this.tokenCount) {
  976. return cmpStr$1(
  977. this.source,
  978. this.offsetAndType[offset - 1] & OFFSET_MASK,
  979. this.offsetAndType[offset] & OFFSET_MASK,
  980. referenceStr
  981. );
  982. }
  983. return false;
  984. },
  985. getTokenStart: function(tokenIndex) {
  986. if (tokenIndex === this.tokenIndex) {
  987. return this.tokenStart;
  988. }
  989. if (tokenIndex > 0) {
  990. return tokenIndex < this.tokenCount
  991. ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
  992. : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
  993. }
  994. return this.firstCharOffset;
  995. },
  996. // TODO: -> skipUntilBalanced
  997. getRawLength: function(startToken, mode) {
  998. var cursor = startToken;
  999. var balanceEnd;
  1000. var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK;
  1001. var type;
  1002. loop:
  1003. for (; cursor < this.tokenCount; cursor++) {
  1004. balanceEnd = this.balance[cursor];
  1005. // stop scanning on balance edge that points to offset before start token
  1006. if (balanceEnd < startToken) {
  1007. break loop;
  1008. }
  1009. type = this.offsetAndType[cursor] >> TYPE_SHIFT;
  1010. // check token is stop type
  1011. switch (mode(type, this.source, offset)) {
  1012. case 1:
  1013. break loop;
  1014. case 2:
  1015. cursor++;
  1016. break loop;
  1017. default:
  1018. offset = this.offsetAndType[cursor] & OFFSET_MASK;
  1019. // fast forward to the end of balanced block
  1020. if (this.balance[balanceEnd] === cursor) {
  1021. cursor = balanceEnd;
  1022. }
  1023. }
  1024. }
  1025. return cursor - this.tokenIndex;
  1026. },
  1027. isBalanceEdge: function(pos) {
  1028. return this.balance[this.tokenIndex] < pos;
  1029. },
  1030. isDelim: function(code, offset) {
  1031. if (offset) {
  1032. return (
  1033. this.lookupType(offset) === TYPE$1.Delim &&
  1034. this.source.charCodeAt(this.lookupOffset(offset)) === code
  1035. );
  1036. }
  1037. return (
  1038. this.tokenType === TYPE$1.Delim &&
  1039. this.source.charCodeAt(this.tokenStart) === code
  1040. );
  1041. },
  1042. getTokenValue: function() {
  1043. return this.source.substring(this.tokenStart, this.tokenEnd);
  1044. },
  1045. getTokenLength: function() {
  1046. return this.tokenEnd - this.tokenStart;
  1047. },
  1048. substrToCursor: function(start) {
  1049. return this.source.substring(start, this.tokenStart);
  1050. },
  1051. skipWS: function() {
  1052. for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
  1053. if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE) {
  1054. break;
  1055. }
  1056. }
  1057. if (skipTokenCount > 0) {
  1058. this.skip(skipTokenCount);
  1059. }
  1060. },
  1061. skipSC: function() {
  1062. while (this.tokenType === WHITESPACE || this.tokenType === COMMENT) {
  1063. this.next();
  1064. }
  1065. },
  1066. skip: function(tokenCount) {
  1067. var next = this.tokenIndex + tokenCount;
  1068. if (next < this.tokenCount) {
  1069. this.tokenIndex = next;
  1070. this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
  1071. next = this.offsetAndType[next];
  1072. this.tokenType = next >> TYPE_SHIFT;
  1073. this.tokenEnd = next & OFFSET_MASK;
  1074. } else {
  1075. this.tokenIndex = this.tokenCount;
  1076. this.next();
  1077. }
  1078. },
  1079. next: function() {
  1080. var next = this.tokenIndex + 1;
  1081. if (next < this.tokenCount) {
  1082. this.tokenIndex = next;
  1083. this.tokenStart = this.tokenEnd;
  1084. next = this.offsetAndType[next];
  1085. this.tokenType = next >> TYPE_SHIFT;
  1086. this.tokenEnd = next & OFFSET_MASK;
  1087. } else {
  1088. this.tokenIndex = this.tokenCount;
  1089. this.eof = true;
  1090. this.tokenType = EOF$1;
  1091. this.tokenStart = this.tokenEnd = this.source.length;
  1092. }
  1093. },
  1094. dump: function() {
  1095. var offset = this.firstCharOffset;
  1096. return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
  1097. var start = offset;
  1098. var end = item & OFFSET_MASK;
  1099. offset = end;
  1100. return {
  1101. idx: idx,
  1102. type: NAME$1[item >> TYPE_SHIFT],
  1103. chunk: this.source.substring(start, end),
  1104. balance: this.balance[idx]
  1105. };
  1106. }, this);
  1107. }
  1108. };
  1109. var TokenStream_1 = TokenStream;
  1110. function noop(value) {
  1111. return value;
  1112. }
  1113. function generateMultiplier(multiplier) {
  1114. if (multiplier.min === 0 && multiplier.max === 0) {
  1115. return '*';
  1116. }
  1117. if (multiplier.min === 0 && multiplier.max === 1) {
  1118. return '?';
  1119. }
  1120. if (multiplier.min === 1 && multiplier.max === 0) {
  1121. return multiplier.comma ? '#' : '+';
  1122. }
  1123. if (multiplier.min === 1 && multiplier.max === 1) {
  1124. return '';
  1125. }
  1126. return (
  1127. (multiplier.comma ? '#' : '') +
  1128. (multiplier.min === multiplier.max
  1129. ? '{' + multiplier.min + '}'
  1130. : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
  1131. )
  1132. );
  1133. }
  1134. function generateTypeOpts(node) {
  1135. switch (node.type) {
  1136. case 'Range':
  1137. return (
  1138. ' [' +
  1139. (node.min === null ? '-∞' : node.min) +
  1140. ',' +
  1141. (node.max === null ? '∞' : node.max) +
  1142. ']'
  1143. );
  1144. default:
  1145. throw new Error('Unknown node type `' + node.type + '`');
  1146. }
  1147. }
  1148. function generateSequence(node, decorate, forceBraces, compact) {
  1149. var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
  1150. var result = node.terms.map(function(term) {
  1151. return generate(term, decorate, forceBraces, compact);
  1152. }).join(combinator);
  1153. if (node.explicit || forceBraces) {
  1154. result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
  1155. }
  1156. return result;
  1157. }
  1158. function generate(node, decorate, forceBraces, compact) {
  1159. var result;
  1160. switch (node.type) {
  1161. case 'Group':
  1162. result =
  1163. generateSequence(node, decorate, forceBraces, compact) +
  1164. (node.disallowEmpty ? '!' : '');
  1165. break;
  1166. case 'Multiplier':
  1167. // return since node is a composition
  1168. return (
  1169. generate(node.term, decorate, forceBraces, compact) +
  1170. decorate(generateMultiplier(node), node)
  1171. );
  1172. case 'Type':
  1173. result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
  1174. break;
  1175. case 'Property':
  1176. result = '<\'' + node.name + '\'>';
  1177. break;
  1178. case 'Keyword':
  1179. result = node.name;
  1180. break;
  1181. case 'AtKeyword':
  1182. result = '@' + node.name;
  1183. break;
  1184. case 'Function':
  1185. result = node.name + '(';
  1186. break;
  1187. case 'String':
  1188. case 'Token':
  1189. result = node.value;
  1190. break;
  1191. case 'Comma':
  1192. result = ',';
  1193. break;
  1194. default:
  1195. throw new Error('Unknown node type `' + node.type + '`');
  1196. }
  1197. return decorate(result, node);
  1198. }
  1199. var generate_1 = function(node, options) {
  1200. var decorate = noop;
  1201. var forceBraces = false;
  1202. var compact = false;
  1203. if (typeof options === 'function') {
  1204. decorate = options;
  1205. } else if (options) {
  1206. forceBraces = Boolean(options.forceBraces);
  1207. compact = Boolean(options.compact);
  1208. if (typeof options.decorate === 'function') {
  1209. decorate = options.decorate;
  1210. }
  1211. }
  1212. return generate(node, decorate, forceBraces, compact);
  1213. };
  1214. function fromMatchResult(matchResult) {
  1215. var tokens = matchResult.tokens;
  1216. var longestMatch = matchResult.longestMatch;
  1217. var node = longestMatch < tokens.length ? tokens[longestMatch].node : null;
  1218. var mismatchOffset = -1;
  1219. var entries = 0;
  1220. var css = '';
  1221. for (var i = 0; i < tokens.length; i++) {
  1222. if (i === longestMatch) {
  1223. mismatchOffset = css.length;
  1224. }
  1225. if (node !== null && tokens[i].node === node) {
  1226. if (i <= longestMatch) {
  1227. entries++;
  1228. } else {
  1229. entries = 0;
  1230. }
  1231. }
  1232. css += tokens[i].value;
  1233. }
  1234. return {
  1235. node: node,
  1236. css: css,
  1237. mismatchOffset: mismatchOffset === -1 ? css.length : mismatchOffset,
  1238. last: node === null || entries > 1
  1239. };
  1240. }
  1241. function getLocation(node, point) {
  1242. var loc = node && node.loc && node.loc[point];
  1243. if (loc) {
  1244. return {
  1245. offset: loc.offset,
  1246. line: loc.line,
  1247. column: loc.column
  1248. };
  1249. }
  1250. return null;
  1251. }
  1252. var SyntaxReferenceError = function(type, referenceName) {
  1253. var error = createCustomError(
  1254. 'SyntaxReferenceError',
  1255. type + (referenceName ? ' `' + referenceName + '`' : '')
  1256. );
  1257. error.reference = referenceName;
  1258. return error;
  1259. };
  1260. var MatchError = function(message, syntax, node, matchResult) {
  1261. var error = createCustomError('SyntaxMatchError', message);
  1262. var details = fromMatchResult(matchResult);
  1263. var mismatchOffset = details.mismatchOffset || 0;
  1264. var badNode = details.node || node;
  1265. var end = getLocation(badNode, 'end');
  1266. var start = details.last ? end : getLocation(badNode, 'start');
  1267. var css = details.css;
  1268. error.rawMessage = message;
  1269. error.syntax = syntax ? generate_1(syntax) : '<generic>';
  1270. error.css = css;
  1271. error.mismatchOffset = mismatchOffset;
  1272. error.loc = {
  1273. source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
  1274. start: start,
  1275. end: end
  1276. };
  1277. error.line = start ? start.line : undefined;
  1278. error.column = start ? start.column : undefined;
  1279. error.offset = start ? start.offset : undefined;
  1280. error.message = message + '\n' +
  1281. ' syntax: ' + error.syntax + '\n' +
  1282. ' value: ' + (error.css || '<empty string>') + '\n' +
  1283. ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
  1284. return error;
  1285. };
  1286. var error = {
  1287. SyntaxReferenceError: SyntaxReferenceError,
  1288. MatchError: MatchError
  1289. };
  1290. var hasOwnProperty = Object.prototype.hasOwnProperty;
  1291. var keywords = Object.create(null);
  1292. var properties = Object.create(null);
  1293. var HYPHENMINUS = 45; // '-'.charCodeAt()
  1294. function isCustomProperty(str, offset) {
  1295. offset = offset || 0;
  1296. return str.length - offset >= 2 &&
  1297. str.charCodeAt(offset) === HYPHENMINUS &&
  1298. str.charCodeAt(offset + 1) === HYPHENMINUS;
  1299. }
  1300. function getVendorPrefix(str, offset) {
  1301. offset = offset || 0;
  1302. // verdor prefix should be at least 3 chars length
  1303. if (str.length - offset >= 3) {
  1304. // vendor prefix starts with hyper minus following non-hyper minus
  1305. if (str.charCodeAt(offset) === HYPHENMINUS &&
  1306. str.charCodeAt(offset + 1) !== HYPHENMINUS) {
  1307. // vendor prefix should contain a hyper minus at the ending
  1308. var secondDashIndex = str.indexOf('-', offset + 2);
  1309. if (secondDashIndex !== -1) {
  1310. return str.substring(offset, secondDashIndex + 1);
  1311. }
  1312. }
  1313. }
  1314. return '';
  1315. }
  1316. function getKeywordDescriptor(keyword) {
  1317. if (hasOwnProperty.call(keywords, keyword)) {
  1318. return keywords[keyword];
  1319. }
  1320. var name = keyword.toLowerCase();
  1321. if (hasOwnProperty.call(keywords, name)) {
  1322. return keywords[keyword] = keywords[name];
  1323. }
  1324. var custom = isCustomProperty(name, 0);
  1325. var vendor = !custom ? getVendorPrefix(name, 0) : '';
  1326. return keywords[keyword] = Object.freeze({
  1327. basename: name.substr(vendor.length),
  1328. name: name,
  1329. vendor: vendor,
  1330. prefix: vendor,
  1331. custom: custom
  1332. });
  1333. }
  1334. function getPropertyDescriptor(property) {
  1335. if (hasOwnProperty.call(properties, property)) {
  1336. return properties[property];
  1337. }
  1338. var name = property;
  1339. var hack = property[0];
  1340. if (hack === '/') {
  1341. hack = property[1] === '/' ? '//' : '/';
  1342. } else if (hack !== '_' &&
  1343. hack !== '*' &&
  1344. hack !== '$' &&
  1345. hack !== '#' &&
  1346. hack !== '+' &&
  1347. hack !== '&') {
  1348. hack = '';
  1349. }
  1350. var custom = isCustomProperty(name, hack.length);
  1351. // re-use result when possible (the same as for lower case)
  1352. if (!custom) {
  1353. name = name.toLowerCase();
  1354. if (hasOwnProperty.call(properties, name)) {
  1355. return properties[property] = properties[name];
  1356. }
  1357. }
  1358. var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
  1359. var prefix = name.substr(0, hack.length + vendor.length);
  1360. return properties[property] = Object.freeze({
  1361. basename: name.substr(prefix.length),
  1362. name: name.substr(hack.length),
  1363. hack: hack,
  1364. vendor: vendor,
  1365. prefix: prefix,
  1366. custom: custom
  1367. });
  1368. }
  1369. var names = {
  1370. keyword: getKeywordDescriptor,
  1371. property: getPropertyDescriptor,
  1372. isCustomProperty: isCustomProperty,
  1373. vendorPrefix: getVendorPrefix
  1374. };
  1375. var MIN_SIZE = 16 * 1024;
  1376. var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
  1377. var adoptBuffer = function adoptBuffer(buffer, size) {
  1378. if (buffer === null || buffer.length < size) {
  1379. return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
  1380. }
  1381. return buffer;
  1382. };
  1383. var TYPE$2 = _const.TYPE;
  1384. var isNewline$1 = charCodeDefinitions.isNewline;
  1385. var isName$2 = charCodeDefinitions.isName;
  1386. var isValidEscape$2 = charCodeDefinitions.isValidEscape;
  1387. var isNumberStart$1 = charCodeDefinitions.isNumberStart;
  1388. var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
  1389. var charCodeCategory$1 = charCodeDefinitions.charCodeCategory;
  1390. var isBOM$1 = charCodeDefinitions.isBOM;
  1391. var cmpStr$2 = utils.cmpStr;
  1392. var getNewlineLength$1 = utils.getNewlineLength;
  1393. var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
  1394. var consumeEscaped$1 = utils.consumeEscaped;
  1395. var consumeName$1 = utils.consumeName;
  1396. var consumeNumber$1 = utils.consumeNumber;
  1397. var consumeBadUrlRemnants$1 = utils.consumeBadUrlRemnants;
  1398. var OFFSET_MASK$1 = 0x00FFFFFF;
  1399. var TYPE_SHIFT$1 = 24;
  1400. function tokenize(source, stream) {
  1401. function getCharCode(offset) {
  1402. return offset < sourceLength ? source.charCodeAt(offset) : 0;
  1403. }
  1404. // § 4.3.3. Consume a numeric token
  1405. function consumeNumericToken() {
  1406. // Consume a number and let number be the result.
  1407. offset = consumeNumber$1(source, offset);
  1408. // If the next 3 input code points would start an identifier, then:
  1409. if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
  1410. // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
  1411. // Consume a name. Set the <dimension-token>’s unit to the returned value.
  1412. // Return the <dimension-token>.
  1413. type = TYPE$2.Dimension;
  1414. offset = consumeName$1(source, offset);
  1415. return;
  1416. }
  1417. // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
  1418. if (getCharCode(offset) === 0x0025) {
  1419. // Create a <percentage-token> with the same value as number, and return it.
  1420. type = TYPE$2.Percentage;
  1421. offset++;
  1422. return;
  1423. }
  1424. // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
  1425. type = TYPE$2.Number;
  1426. }
  1427. // § 4.3.4. Consume an ident-like token
  1428. function consumeIdentLikeToken() {
  1429. const nameStartOffset = offset;
  1430. // Consume a name, and let string be the result.
  1431. offset = consumeName$1(source, offset);
  1432. // If string’s value is an ASCII case-insensitive match for "url",
  1433. // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
  1434. if (cmpStr$2(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
  1435. // While the next two input code points are whitespace, consume the next input code point.
  1436. offset = findWhiteSpaceEnd$1(source, offset + 1);
  1437. // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
  1438. // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
  1439. // then create a <function-token> with its value set to string and return it.
  1440. if (getCharCode(offset) === 0x0022 ||
  1441. getCharCode(offset) === 0x0027) {
  1442. type = TYPE$2.Function;
  1443. offset = nameStartOffset + 4;
  1444. return;
  1445. }
  1446. // Otherwise, consume a url token, and return it.
  1447. consumeUrlToken();
  1448. return;
  1449. }
  1450. // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
  1451. // Create a <function-token> with its value set to string and return it.
  1452. if (getCharCode(offset) === 0x0028) {
  1453. type = TYPE$2.Function;
  1454. offset++;
  1455. return;
  1456. }
  1457. // Otherwise, create an <ident-token> with its value set to string and return it.
  1458. type = TYPE$2.Ident;
  1459. }
  1460. // § 4.3.5. Consume a string token
  1461. function consumeStringToken(endingCodePoint) {
  1462. // This algorithm may be called with an ending code point, which denotes the code point
  1463. // that ends the string. If an ending code point is not specified,
  1464. // the current input code point is used.
  1465. if (!endingCodePoint) {
  1466. endingCodePoint = getCharCode(offset++);
  1467. }
  1468. // Initially create a <string-token> with its value set to the empty string.
  1469. type = TYPE$2.String;
  1470. // Repeatedly consume the next input code point from the stream:
  1471. for (; offset < source.length; offset++) {
  1472. var code = source.charCodeAt(offset);
  1473. switch (charCodeCategory$1(code)) {
  1474. // ending code point
  1475. case endingCodePoint:
  1476. // Return the <string-token>.
  1477. offset++;
  1478. return;
  1479. // EOF
  1480. case charCodeCategory$1.Eof:
  1481. // This is a parse error. Return the <string-token>.
  1482. return;
  1483. // newline
  1484. case charCodeCategory$1.WhiteSpace:
  1485. if (isNewline$1(code)) {
  1486. // This is a parse error. Reconsume the current input code point,
  1487. // create a <bad-string-token>, and return it.
  1488. offset += getNewlineLength$1(source, offset, code);
  1489. type = TYPE$2.BadString;
  1490. return;
  1491. }
  1492. break;
  1493. // U+005C REVERSE SOLIDUS (\)
  1494. case 0x005C:
  1495. // If the next input code point is EOF, do nothing.
  1496. if (offset === source.length - 1) {
  1497. break;
  1498. }
  1499. var nextCode = getCharCode(offset + 1);
  1500. // Otherwise, if the next input code point is a newline, consume it.
  1501. if (isNewline$1(nextCode)) {
  1502. offset += getNewlineLength$1(source, offset + 1, nextCode);
  1503. } else if (isValidEscape$2(code, nextCode)) {
  1504. // Otherwise, (the stream starts with a valid escape) consume
  1505. // an escaped code point and append the returned code point to
  1506. // the <string-token>’s value.
  1507. offset = consumeEscaped$1(source, offset) - 1;
  1508. }
  1509. break;
  1510. // anything else
  1511. // Append the current input code point to the <string-token>’s value.
  1512. }
  1513. }
  1514. }
  1515. // § 4.3.6. Consume a url token
  1516. // Note: This algorithm assumes that the initial "url(" has already been consumed.
  1517. // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
  1518. // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
  1519. // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
  1520. function consumeUrlToken() {
  1521. // Initially create a <url-token> with its value set to the empty string.
  1522. type = TYPE$2.Url;
  1523. // Consume as much whitespace as possible.
  1524. offset = findWhiteSpaceEnd$1(source, offset);
  1525. // Repeatedly consume the next input code point from the stream:
  1526. for (; offset < source.length; offset++) {
  1527. var code = source.charCodeAt(offset);
  1528. switch (charCodeCategory$1(code)) {
  1529. // U+0029 RIGHT PARENTHESIS ())
  1530. case 0x0029:
  1531. // Return the <url-token>.
  1532. offset++;
  1533. return;
  1534. // EOF
  1535. case charCodeCategory$1.Eof:
  1536. // This is a parse error. Return the <url-token>.
  1537. return;
  1538. // whitespace
  1539. case charCodeCategory$1.WhiteSpace:
  1540. // Consume as much whitespace as possible.
  1541. offset = findWhiteSpaceEnd$1(source, offset);
  1542. // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
  1543. // consume it and return the <url-token>
  1544. // (if EOF was encountered, this is a parse error);
  1545. if (getCharCode(offset) === 0x0029 || offset >= source.length) {
  1546. if (offset < source.length) {
  1547. offset++;
  1548. }
  1549. return;
  1550. }
  1551. // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
  1552. // and return it.
  1553. offset = consumeBadUrlRemnants$1(source, offset);
  1554. type = TYPE$2.BadUrl;
  1555. return;
  1556. // U+0022 QUOTATION MARK (")
  1557. // U+0027 APOSTROPHE (')
  1558. // U+0028 LEFT PARENTHESIS (()
  1559. // non-printable code point
  1560. case 0x0022:
  1561. case 0x0027:
  1562. case 0x0028:
  1563. case charCodeCategory$1.NonPrintable:
  1564. // This is a parse error. Consume the remnants of a bad url,
  1565. // create a <bad-url-token>, and return it.
  1566. offset = consumeBadUrlRemnants$1(source, offset);
  1567. type = TYPE$2.BadUrl;
  1568. return;
  1569. // U+005C REVERSE SOLIDUS (\)
  1570. case 0x005C:
  1571. // If the stream starts with a valid escape, consume an escaped code point and
  1572. // append the returned code point to the <url-token>’s value.
  1573. if (isValidEscape$2(code, getCharCode(offset + 1))) {
  1574. offset = consumeEscaped$1(source, offset) - 1;
  1575. break;
  1576. }
  1577. // Otherwise, this is a parse error. Consume the remnants of a bad url,
  1578. // create a <bad-url-token>, and return it.
  1579. offset = consumeBadUrlRemnants$1(source, offset);
  1580. type = TYPE$2.BadUrl;
  1581. return;
  1582. // anything else
  1583. // Append the current input code point to the <url-token>’s value.
  1584. }
  1585. }
  1586. }
  1587. if (!stream) {
  1588. stream = new TokenStream_1();
  1589. }
  1590. // ensure source is a string
  1591. source = String(source || '');
  1592. var sourceLength = source.length;
  1593. var offsetAndType = adoptBuffer(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
  1594. var balance = adoptBuffer(stream.balance, sourceLength + 1);
  1595. var tokenCount = 0;
  1596. var start = isBOM$1(getCharCode(0));
  1597. var offset = start;
  1598. var balanceCloseType = 0;
  1599. var balanceStart = 0;
  1600. var balancePrev = 0;
  1601. // https://drafts.csswg.org/css-syntax-3/#consume-token
  1602. // § 4.3.1. Consume a token
  1603. while (offset < sourceLength) {
  1604. var code = source.charCodeAt(offset);
  1605. var type = 0;
  1606. balance[tokenCount] = sourceLength;
  1607. switch (charCodeCategory$1(code)) {
  1608. // whitespace
  1609. case charCodeCategory$1.WhiteSpace:
  1610. // Consume as much whitespace as possible. Return a <whitespace-token>.
  1611. type = TYPE$2.WhiteSpace;
  1612. offset = findWhiteSpaceEnd$1(source, offset + 1);
  1613. break;
  1614. // U+0022 QUOTATION MARK (")
  1615. case 0x0022:
  1616. // Consume a string token and return it.
  1617. consumeStringToken();
  1618. break;
  1619. // U+0023 NUMBER SIGN (#)
  1620. case 0x0023:
  1621. // If the next input code point is a name code point or the next two input code points are a valid escape, then:
  1622. if (isName$2(getCharCode(offset + 1)) || isValidEscape$2(getCharCode(offset + 1), getCharCode(offset + 2))) {
  1623. // Create a <hash-token>.
  1624. type = TYPE$2.Hash;
  1625. // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
  1626. // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
  1627. // // TODO: set id flag
  1628. // }
  1629. // Consume a name, and set the <hash-token>’s value to the returned string.
  1630. offset = consumeName$1(source, offset + 1);
  1631. // Return the <hash-token>.
  1632. } else {
  1633. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1634. type = TYPE$2.Delim;
  1635. offset++;
  1636. }
  1637. break;
  1638. // U+0027 APOSTROPHE (')
  1639. case 0x0027:
  1640. // Consume a string token and return it.
  1641. consumeStringToken();
  1642. break;
  1643. // U+0028 LEFT PARENTHESIS (()
  1644. case 0x0028:
  1645. // Return a <(-token>.
  1646. type = TYPE$2.LeftParenthesis;
  1647. offset++;
  1648. break;
  1649. // U+0029 RIGHT PARENTHESIS ())
  1650. case 0x0029:
  1651. // Return a <)-token>.
  1652. type = TYPE$2.RightParenthesis;
  1653. offset++;
  1654. break;
  1655. // U+002B PLUS SIGN (+)
  1656. case 0x002B:
  1657. // If the input stream starts with a number, ...
  1658. if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
  1659. // ... reconsume the current input code point, consume a numeric token, and return it.
  1660. consumeNumericToken();
  1661. } else {
  1662. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1663. type = TYPE$2.Delim;
  1664. offset++;
  1665. }
  1666. break;
  1667. // U+002C COMMA (,)
  1668. case 0x002C:
  1669. // Return a <comma-token>.
  1670. type = TYPE$2.Comma;
  1671. offset++;
  1672. break;
  1673. // U+002D HYPHEN-MINUS (-)
  1674. case 0x002D:
  1675. // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
  1676. if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
  1677. consumeNumericToken();
  1678. } else {
  1679. // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
  1680. if (getCharCode(offset + 1) === 0x002D &&
  1681. getCharCode(offset + 2) === 0x003E) {
  1682. type = TYPE$2.CDC;
  1683. offset = offset + 3;
  1684. } else {
  1685. // Otherwise, if the input stream starts with an identifier, ...
  1686. if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
  1687. // ... reconsume the current input code point, consume an ident-like token, and return it.
  1688. consumeIdentLikeToken();
  1689. } else {
  1690. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1691. type = TYPE$2.Delim;
  1692. offset++;
  1693. }
  1694. }
  1695. }
  1696. break;
  1697. // U+002E FULL STOP (.)
  1698. case 0x002E:
  1699. // If the input stream starts with a number, ...
  1700. if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
  1701. // ... reconsume the current input code point, consume a numeric token, and return it.
  1702. consumeNumericToken();
  1703. } else {
  1704. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1705. type = TYPE$2.Delim;
  1706. offset++;
  1707. }
  1708. break;
  1709. // U+002F SOLIDUS (/)
  1710. case 0x002F:
  1711. // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
  1712. if (getCharCode(offset + 1) === 0x002A) {
  1713. // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
  1714. // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
  1715. type = TYPE$2.Comment;
  1716. offset = source.indexOf('*/', offset + 2) + 2;
  1717. if (offset === 1) {
  1718. offset = source.length;
  1719. }
  1720. } else {
  1721. type = TYPE$2.Delim;
  1722. offset++;
  1723. }
  1724. break;
  1725. // U+003A COLON (:)
  1726. case 0x003A:
  1727. // Return a <colon-token>.
  1728. type = TYPE$2.Colon;
  1729. offset++;
  1730. break;
  1731. // U+003B SEMICOLON (;)
  1732. case 0x003B:
  1733. // Return a <semicolon-token>.
  1734. type = TYPE$2.Semicolon;
  1735. offset++;
  1736. break;
  1737. // U+003C LESS-THAN SIGN (<)
  1738. case 0x003C:
  1739. // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
  1740. if (getCharCode(offset + 1) === 0x0021 &&
  1741. getCharCode(offset + 2) === 0x002D &&
  1742. getCharCode(offset + 3) === 0x002D) {
  1743. // ... consume them and return a <CDO-token>.
  1744. type = TYPE$2.CDO;
  1745. offset = offset + 4;
  1746. } else {
  1747. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1748. type = TYPE$2.Delim;
  1749. offset++;
  1750. }
  1751. break;
  1752. // U+0040 COMMERCIAL AT (@)
  1753. case 0x0040:
  1754. // If the next 3 input code points would start an identifier, ...
  1755. if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
  1756. // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
  1757. type = TYPE$2.AtKeyword;
  1758. offset = consumeName$1(source, offset + 1);
  1759. } else {
  1760. // Otherwise, return a <delim-token> with its value set to the current input code point.
  1761. type = TYPE$2.Delim;
  1762. offset++;
  1763. }
  1764. break;
  1765. // U+005B LEFT SQUARE BRACKET ([)
  1766. case 0x005B:
  1767. // Return a <[-token>.
  1768. type = TYPE$2.LeftSquareBracket;
  1769. offset++;
  1770. break;
  1771. // U+005C REVERSE SOLIDUS (\)
  1772. case 0x005C:
  1773. // If the input stream starts with a valid escape, ...
  1774. if (isValidEscape$2(code, getCharCode(offset + 1))) {
  1775. // ... reconsume the current input code point, consume an ident-like token, and return it.
  1776. consumeIdentLikeToken();
  1777. } else {
  1778. // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
  1779. type = TYPE$2.Delim;
  1780. offset++;
  1781. }
  1782. break;
  1783. // U+005D RIGHT SQUARE BRACKET (])
  1784. case 0x005D:
  1785. // Return a <]-token>.
  1786. type = TYPE$2.RightSquareBracket;
  1787. offset++;
  1788. break;
  1789. // U+007B LEFT CURLY BRACKET ({)
  1790. case 0x007B:
  1791. // Return a <{-token>.
  1792. type = TYPE$2.LeftCurlyBracket;
  1793. offset++;
  1794. break;
  1795. // U+007D RIGHT CURLY BRACKET (})
  1796. case 0x007D:
  1797. // Return a <}-token>.
  1798. type = TYPE$2.RightCurlyBracket;
  1799. offset++;
  1800. break;
  1801. // digit
  1802. case charCodeCategory$1.Digit:
  1803. // Reconsume the current input code point, consume a numeric token, and return it.
  1804. consumeNumericToken();
  1805. break;
  1806. // name-start code point
  1807. case charCodeCategory$1.NameStart:
  1808. // Reconsume the current input code point, consume an ident-like token, and return it.
  1809. consumeIdentLikeToken();
  1810. break;
  1811. // EOF
  1812. case charCodeCategory$1.Eof:
  1813. // Return an <EOF-token>.
  1814. break;
  1815. // anything else
  1816. default:
  1817. // Return a <delim-token> with its value set to the current input code point.
  1818. type = TYPE$2.Delim;
  1819. offset++;
  1820. }
  1821. switch (type) {
  1822. case balanceCloseType:
  1823. balancePrev = balanceStart & OFFSET_MASK$1;
  1824. balanceStart = balance[balancePrev];
  1825. balanceCloseType = balanceStart >> TYPE_SHIFT$1;
  1826. balance[tokenCount] = balancePrev;
  1827. balance[balancePrev++] = tokenCount;
  1828. for (; balancePrev < tokenCount; balancePrev++) {
  1829. if (balance[balancePrev] === sourceLength) {
  1830. balance[balancePrev] = tokenCount;
  1831. }
  1832. }
  1833. break;
  1834. case TYPE$2.LeftParenthesis:
  1835. case TYPE$2.Function:
  1836. balance[tokenCount] = balanceStart;
  1837. balanceCloseType = TYPE$2.RightParenthesis;
  1838. balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
  1839. break;
  1840. case TYPE$2.LeftSquareBracket:
  1841. balance[tokenCount] = balanceStart;
  1842. balanceCloseType = TYPE$2.RightSquareBracket;
  1843. balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
  1844. break;
  1845. case TYPE$2.LeftCurlyBracket:
  1846. balance[tokenCount] = balanceStart;
  1847. balanceCloseType = TYPE$2.RightCurlyBracket;
  1848. balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
  1849. break;
  1850. }
  1851. offsetAndType[tokenCount++] = (type << TYPE_SHIFT$1) | offset;
  1852. }
  1853. // finalize buffers
  1854. offsetAndType[tokenCount] = (TYPE$2.EOF << TYPE_SHIFT$1) | offset; // <EOF-token>
  1855. balance[tokenCount] = sourceLength;
  1856. balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
  1857. while (balanceStart !== 0) {
  1858. balancePrev = balanceStart & OFFSET_MASK$1;
  1859. balanceStart = balance[balancePrev];
  1860. balance[balancePrev] = sourceLength;
  1861. }
  1862. // update stream
  1863. stream.source = source;
  1864. stream.firstCharOffset = start;
  1865. stream.offsetAndType = offsetAndType;
  1866. stream.tokenCount = tokenCount;
  1867. stream.balance = balance;
  1868. stream.reset();
  1869. stream.next();
  1870. return stream;
  1871. }
  1872. // extend tokenizer with constants
  1873. Object.keys(_const).forEach(function(key) {
  1874. tokenize[key] = _const[key];
  1875. });
  1876. // extend tokenizer with static methods from utils
  1877. Object.keys(charCodeDefinitions).forEach(function(key) {
  1878. tokenize[key] = charCodeDefinitions[key];
  1879. });
  1880. Object.keys(utils).forEach(function(key) {
  1881. tokenize[key] = utils[key];
  1882. });
  1883. var tokenizer = tokenize;
  1884. var isDigit$2 = tokenizer.isDigit;
  1885. var cmpChar$1 = tokenizer.cmpChar;
  1886. var TYPE$3 = tokenizer.TYPE;
  1887. var DELIM = TYPE$3.Delim;
  1888. var WHITESPACE$1 = TYPE$3.WhiteSpace;
  1889. var COMMENT$1 = TYPE$3.Comment;
  1890. var IDENT = TYPE$3.Ident;
  1891. var NUMBER = TYPE$3.Number;
  1892. var DIMENSION = TYPE$3.Dimension;
  1893. var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
  1894. var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
  1895. var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
  1896. var DISALLOW_SIGN = true;
  1897. var ALLOW_SIGN = false;
  1898. function isDelim(token, code) {
  1899. return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
  1900. }
  1901. function skipSC(token, offset, getNextToken) {
  1902. while (token !== null && (token.type === WHITESPACE$1 || token.type === COMMENT$1)) {
  1903. token = getNextToken(++offset);
  1904. }
  1905. return offset;
  1906. }
  1907. function checkInteger(token, valueOffset, disallowSign, offset) {
  1908. if (!token) {
  1909. return 0;
  1910. }
  1911. var code = token.value.charCodeAt(valueOffset);
  1912. if (code === PLUSSIGN || code === HYPHENMINUS$1) {
  1913. if (disallowSign) {
  1914. // Number sign is not allowed
  1915. return 0;
  1916. }
  1917. valueOffset++;
  1918. }
  1919. for (; valueOffset < token.value.length; valueOffset++) {
  1920. if (!isDigit$2(token.value.charCodeAt(valueOffset))) {
  1921. // Integer is expected
  1922. return 0;
  1923. }
  1924. }
  1925. return offset + 1;
  1926. }
  1927. // ... <signed-integer>
  1928. // ... ['+' | '-'] <signless-integer>
  1929. function consumeB(token, offset_, getNextToken) {
  1930. var sign = false;
  1931. var offset = skipSC(token, offset_, getNextToken);
  1932. token = getNextToken(offset);
  1933. if (token === null) {
  1934. return offset_;
  1935. }
  1936. if (token.type !== NUMBER) {
  1937. if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS$1)) {
  1938. sign = true;
  1939. offset = skipSC(getNextToken(++offset), offset, getNextToken);
  1940. token = getNextToken(offset);
  1941. if (token === null && token.type !== NUMBER) {
  1942. return 0;
  1943. }
  1944. } else {
  1945. return offset_;
  1946. }
  1947. }
  1948. if (!sign) {
  1949. var code = token.value.charCodeAt(0);
  1950. if (code !== PLUSSIGN && code !== HYPHENMINUS$1) {
  1951. // Number sign is expected
  1952. return 0;
  1953. }
  1954. }
  1955. return checkInteger(token, sign ? 0 : 1, sign, offset);
  1956. }
  1957. // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
  1958. var genericAnPlusB = function anPlusB(token, getNextToken) {
  1959. /* eslint-disable brace-style*/
  1960. var offset = 0;
  1961. if (!token) {
  1962. return 0;
  1963. }
  1964. // <integer>
  1965. if (token.type === NUMBER) {
  1966. return checkInteger(token, 0, ALLOW_SIGN, offset); // b
  1967. }
  1968. // -n
  1969. // -n <signed-integer>
  1970. // -n ['+' | '-'] <signless-integer>
  1971. // -n- <signless-integer>
  1972. // <dashndashdigit-ident>
  1973. else if (token.type === IDENT && token.value.charCodeAt(0) === HYPHENMINUS$1) {
  1974. // expect 1st char is N
  1975. if (!cmpChar$1(token.value, 1, N)) {
  1976. return 0;
  1977. }
  1978. switch (token.value.length) {
  1979. // -n
  1980. // -n <signed-integer>
  1981. // -n ['+' | '-'] <signless-integer>
  1982. case 2:
  1983. return consumeB(getNextToken(++offset), offset, getNextToken);
  1984. // -n- <signless-integer>
  1985. case 3:
  1986. if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
  1987. return 0;
  1988. }
  1989. offset = skipSC(getNextToken(++offset), offset, getNextToken);
  1990. token = getNextToken(offset);
  1991. return checkInteger(token, 0, DISALLOW_SIGN, offset);
  1992. // <dashndashdigit-ident>
  1993. default:
  1994. if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
  1995. return 0;
  1996. }
  1997. return checkInteger(token, 3, DISALLOW_SIGN, offset);
  1998. }
  1999. }
  2000. // '+'? n
  2001. // '+'? n <signed-integer>
  2002. // '+'? n ['+' | '-'] <signless-integer>
  2003. // '+'? n- <signless-integer>
  2004. // '+'? <ndashdigit-ident>
  2005. else if (token.type === IDENT || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === IDENT)) {
  2006. // just ignore a plus
  2007. if (token.type !== IDENT) {
  2008. token = getNextToken(++offset);
  2009. }
  2010. if (token === null || !cmpChar$1(token.value, 0, N)) {
  2011. return 0;
  2012. }
  2013. switch (token.value.length) {
  2014. // '+'? n
  2015. // '+'? n <signed-integer>
  2016. // '+'? n ['+' | '-'] <signless-integer>
  2017. case 1:
  2018. return consumeB(getNextToken(++offset), offset, getNextToken);
  2019. // '+'? n- <signless-integer>
  2020. case 2:
  2021. if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
  2022. return 0;
  2023. }
  2024. offset = skipSC(getNextToken(++offset), offset, getNextToken);
  2025. token = getNextToken(offset);
  2026. return checkInteger(token, 0, DISALLOW_SIGN, offset);
  2027. // '+'? <ndashdigit-ident>
  2028. default:
  2029. if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
  2030. return 0;
  2031. }
  2032. return checkInteger(token, 2, DISALLOW_SIGN, offset);
  2033. }
  2034. }
  2035. // <ndashdigit-dimension>
  2036. // <ndash-dimension> <signless-integer>
  2037. // <n-dimension>
  2038. // <n-dimension> <signed-integer>
  2039. // <n-dimension> ['+' | '-'] <signless-integer>
  2040. else if (token.type === DIMENSION) {
  2041. var code = token.value.charCodeAt(0);
  2042. var sign = code === PLUSSIGN || code === HYPHENMINUS$1 ? 1 : 0;
  2043. for (var i = sign; i < token.value.length; i++) {
  2044. if (!isDigit$2(token.value.charCodeAt(i))) {
  2045. break;
  2046. }
  2047. }
  2048. if (i === sign) {
  2049. // Integer is expected
  2050. return 0;
  2051. }
  2052. if (!cmpChar$1(token.value, i, N)) {
  2053. return 0;
  2054. }
  2055. // <n-dimension>
  2056. // <n-dimension> <signed-integer>
  2057. // <n-dimension> ['+' | '-'] <signless-integer>
  2058. if (i + 1 === token.value.length) {
  2059. return consumeB(getNextToken(++offset), offset, getNextToken);
  2060. } else {
  2061. if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$1) {
  2062. return 0;
  2063. }
  2064. // <ndash-dimension> <signless-integer>
  2065. if (i + 2 === token.value.length) {
  2066. offset = skipSC(getNextToken(++offset), offset, getNextToken);
  2067. token = getNextToken(offset);
  2068. return checkInteger(token, 0, DISALLOW_SIGN, offset);
  2069. }
  2070. // <ndashdigit-dimension>
  2071. else {
  2072. return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
  2073. }
  2074. }
  2075. }
  2076. return 0;
  2077. };
  2078. var isHexDigit$2 = tokenizer.isHexDigit;
  2079. var cmpChar$2 = tokenizer.cmpChar;
  2080. var TYPE$4 = tokenizer.TYPE;
  2081. var IDENT$1 = TYPE$4.Ident;
  2082. var DELIM$1 = TYPE$4.Delim;
  2083. var NUMBER$1 = TYPE$4.Number;
  2084. var DIMENSION$1 = TYPE$4.Dimension;
  2085. var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
  2086. var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
  2087. var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
  2088. var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
  2089. function isDelim$1(token, code) {
  2090. return token !== null && token.type === DELIM$1 && token.value.charCodeAt(0) === code;
  2091. }
  2092. function startsWith(token, code) {
  2093. return token.value.charCodeAt(0) === code;
  2094. }
  2095. function hexSequence(token, offset, allowDash) {
  2096. for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
  2097. var code = token.value.charCodeAt(pos);
  2098. if (code === HYPHENMINUS$2 && allowDash && hexlen !== 0) {
  2099. if (hexSequence(token, offset + hexlen + 1, false) > 0) {
  2100. return 6; // dissallow following question marks
  2101. }
  2102. return 0; // dash at the ending of a hex sequence is not allowed
  2103. }
  2104. if (!isHexDigit$2(code)) {
  2105. return 0; // not a hex digit
  2106. }
  2107. if (++hexlen > 6) {
  2108. return 0; // too many hex digits
  2109. } }
  2110. return hexlen;
  2111. }
  2112. function withQuestionMarkSequence(consumed, length, getNextToken) {
  2113. if (!consumed) {
  2114. return 0; // nothing consumed
  2115. }
  2116. while (isDelim$1(getNextToken(length), QUESTIONMARK)) {
  2117. if (++consumed > 6) {
  2118. return 0; // too many question marks
  2119. }
  2120. length++;
  2121. }
  2122. return length;
  2123. }
  2124. // https://drafts.csswg.org/css-syntax/#urange
  2125. // Informally, the <urange> production has three forms:
  2126. // U+0001
  2127. // Defines a range consisting of a single code point, in this case the code point "1".
  2128. // U+0001-00ff
  2129. // Defines a range of codepoints between the first and the second value, in this case
  2130. // the range between "1" and "ff" (255 in decimal) inclusive.
  2131. // U+00??
  2132. // Defines a range of codepoints where the "?" characters range over all hex digits,
  2133. // in this case defining the same as the value U+0000-00ff.
  2134. // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
  2135. //
  2136. // <urange> =
  2137. // u '+' <ident-token> '?'* |
  2138. // u <dimension-token> '?'* |
  2139. // u <number-token> '?'* |
  2140. // u <number-token> <dimension-token> |
  2141. // u <number-token> <number-token> |
  2142. // u '+' '?'+
  2143. var genericUrange = function urange(token, getNextToken) {
  2144. var length = 0;
  2145. // should start with `u` or `U`
  2146. if (token === null || token.type !== IDENT$1 || !cmpChar$2(token.value, 0, U)) {
  2147. return 0;
  2148. }
  2149. token = getNextToken(++length);
  2150. if (token === null) {
  2151. return 0;
  2152. }
  2153. // u '+' <ident-token> '?'*
  2154. // u '+' '?'+
  2155. if (isDelim$1(token, PLUSSIGN$1)) {
  2156. token = getNextToken(++length);
  2157. if (token === null) {
  2158. return 0;
  2159. }
  2160. if (token.type === IDENT$1) {
  2161. // u '+' <ident-token> '?'*
  2162. return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
  2163. }
  2164. if (isDelim$1(token, QUESTIONMARK)) {
  2165. // u '+' '?'+
  2166. return withQuestionMarkSequence(1, ++length, getNextToken);
  2167. }
  2168. // Hex digit or question mark is expected
  2169. return 0;
  2170. }
  2171. // u <number-token> '?'*
  2172. // u <number-token> <dimension-token>
  2173. // u <number-token> <number-token>
  2174. if (token.type === NUMBER$1) {
  2175. if (!startsWith(token, PLUSSIGN$1)) {
  2176. return 0;
  2177. }
  2178. var consumedHexLength = hexSequence(token, 1, true);
  2179. if (consumedHexLength === 0) {
  2180. return 0;
  2181. }
  2182. token = getNextToken(++length);
  2183. if (token === null) {
  2184. // u <number-token> <eof>
  2185. return length;
  2186. }
  2187. if (token.type === DIMENSION$1 || token.type === NUMBER$1) {
  2188. // u <number-token> <dimension-token>
  2189. // u <number-token> <number-token>
  2190. if (!startsWith(token, HYPHENMINUS$2) || !hexSequence(token, 1, false)) {
  2191. return 0;
  2192. }
  2193. return length + 1;
  2194. }
  2195. // u <number-token> '?'*
  2196. return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
  2197. }
  2198. // u <dimension-token> '?'*
  2199. if (token.type === DIMENSION$1) {
  2200. if (!startsWith(token, PLUSSIGN$1)) {
  2201. return 0;
  2202. }
  2203. return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
  2204. }
  2205. return 0;
  2206. };
  2207. var isIdentifierStart$2 = tokenizer.isIdentifierStart;
  2208. var isHexDigit$3 = tokenizer.isHexDigit;
  2209. var isDigit$3 = tokenizer.isDigit;
  2210. var cmpStr$3 = tokenizer.cmpStr;
  2211. var consumeNumber$2 = tokenizer.consumeNumber;
  2212. var TYPE$5 = tokenizer.TYPE;
  2213. var cssWideKeywords = ['unset', 'initial', 'inherit'];
  2214. var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
  2215. // https://www.w3.org/TR/css-values-3/#lengths
  2216. var LENGTH = {
  2217. // absolute length units
  2218. 'px': true,
  2219. 'mm': true,
  2220. 'cm': true,
  2221. 'in': true,
  2222. 'pt': true,
  2223. 'pc': true,
  2224. 'q': true,
  2225. // relative length units
  2226. 'em': true,
  2227. 'ex': true,
  2228. 'ch': true,
  2229. 'rem': true,
  2230. // viewport-percentage lengths
  2231. 'vh': true,
  2232. 'vw': true,
  2233. 'vmin': true,
  2234. 'vmax': true,
  2235. 'vm': true
  2236. };
  2237. var ANGLE = {
  2238. 'deg': true,
  2239. 'grad': true,
  2240. 'rad': true,
  2241. 'turn': true
  2242. };
  2243. var TIME = {
  2244. 's': true,
  2245. 'ms': true
  2246. };
  2247. var FREQUENCY = {
  2248. 'hz': true,
  2249. 'khz': true
  2250. };
  2251. // https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
  2252. var RESOLUTION = {
  2253. 'dpi': true,
  2254. 'dpcm': true,
  2255. 'dppx': true,
  2256. 'x': true // https://github.com/w3c/csswg-drafts/issues/461
  2257. };
  2258. // https://drafts.csswg.org/css-grid/#fr-unit
  2259. var FLEX = {
  2260. 'fr': true
  2261. };
  2262. // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
  2263. var DECIBEL = {
  2264. 'db': true
  2265. };
  2266. // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
  2267. var SEMITONES = {
  2268. 'st': true
  2269. };
  2270. // safe char code getter
  2271. function charCode(str, index) {
  2272. return index < str.length ? str.charCodeAt(index) : 0;
  2273. }
  2274. function eqStr(actual, expected) {
  2275. return cmpStr$3(actual, 0, actual.length, expected);
  2276. }
  2277. function eqStrAny(actual, expected) {
  2278. for (var i = 0; i < expected.length; i++) {
  2279. if (eqStr(actual, expected[i])) {
  2280. return true;
  2281. }
  2282. }
  2283. return false;
  2284. }
  2285. // IE postfix hack, i.e. 123\0 or 123px\9
  2286. function isPostfixIeHack(str, offset) {
  2287. if (offset !== str.length - 2) {
  2288. return false;
  2289. }
  2290. return (
  2291. str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
  2292. isDigit$3(str.charCodeAt(offset + 1))
  2293. );
  2294. }
  2295. function outOfRange(opts, value, numEnd) {
  2296. if (opts && opts.type === 'Range') {
  2297. var num = Number(
  2298. numEnd !== undefined && numEnd !== value.length
  2299. ? value.substr(0, numEnd)
  2300. : value
  2301. );
  2302. if (isNaN(num)) {
  2303. return true;
  2304. }
  2305. if (opts.min !== null && num < opts.min) {
  2306. return true;
  2307. }
  2308. if (opts.max !== null && num > opts.max) {
  2309. return true;
  2310. }
  2311. }
  2312. return false;
  2313. }
  2314. function consumeFunction(token, getNextToken) {
  2315. var startIdx = token.index;
  2316. var length = 0;
  2317. // balanced token consuming
  2318. do {
  2319. length++;
  2320. if (token.balance <= startIdx) {
  2321. break;
  2322. }
  2323. } while (token = getNextToken(length));
  2324. return length;
  2325. }
  2326. // TODO: implement
  2327. // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
  2328. // https://drafts.csswg.org/css-values/#calc-notation
  2329. function calc(next) {
  2330. return function(token, getNextToken, opts) {
  2331. if (token === null) {
  2332. return 0;
  2333. }
  2334. if (token.type === TYPE$5.Function && eqStrAny(token.value, calcFunctionNames)) {
  2335. return consumeFunction(token, getNextToken);
  2336. }
  2337. return next(token, getNextToken, opts);
  2338. };
  2339. }
  2340. function tokenType(expectedTokenType) {
  2341. return function(token) {
  2342. if (token === null || token.type !== expectedTokenType) {
  2343. return 0;
  2344. }
  2345. return 1;
  2346. };
  2347. }
  2348. function func(name) {
  2349. name = name + '(';
  2350. return function(token, getNextToken) {
  2351. if (token !== null && eqStr(token.value, name)) {
  2352. return consumeFunction(token, getNextToken);
  2353. }
  2354. return 0;
  2355. };
  2356. }
  2357. // =========================
  2358. // Complex types
  2359. //
  2360. // https://drafts.csswg.org/css-values-4/#custom-idents
  2361. // 4.2. Author-defined Identifiers: the <custom-ident> type
  2362. // Some properties accept arbitrary author-defined identifiers as a component value.
  2363. // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
  2364. // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
  2365. //
  2366. // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
  2367. function customIdent(token) {
  2368. if (token === null || token.type !== TYPE$5.Ident) {
  2369. return 0;
  2370. }
  2371. var name = token.value.toLowerCase();
  2372. // The CSS-wide keywords are not valid <custom-ident>s
  2373. if (eqStrAny(name, cssWideKeywords)) {
  2374. return 0;
  2375. }
  2376. // The default keyword is reserved and is also not a valid <custom-ident>
  2377. if (eqStr(name, 'default')) {
  2378. return 0;
  2379. }
  2380. // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
  2381. // Specifications using <custom-ident> must specify clearly what other keywords
  2382. // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
  2383. // in that property’s value definition are excluded. Excluded keywords are excluded
  2384. // in all ASCII case permutations.
  2385. return 1;
  2386. }
  2387. // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
  2388. // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
  2389. // The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
  2390. // that starts with two dashes, except -- itself, which is reserved for future use by CSS.
  2391. // NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
  2392. function customPropertyName(token) {
  2393. // ... defined as any valid identifier
  2394. if (token === null || token.type !== TYPE$5.Ident) {
  2395. return 0;
  2396. }
  2397. // ... that starts with two dashes (U+002D HYPHEN-MINUS)
  2398. if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
  2399. return 0;
  2400. }
  2401. return 1;
  2402. }
  2403. // https://drafts.csswg.org/css-color-4/#hex-notation
  2404. // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
  2405. // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
  2406. // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
  2407. function hexColor(token) {
  2408. if (token === null || token.type !== TYPE$5.Hash) {
  2409. return 0;
  2410. }
  2411. var length = token.value.length;
  2412. // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
  2413. if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
  2414. return 0;
  2415. }
  2416. for (var i = 1; i < length; i++) {
  2417. if (!isHexDigit$3(token.value.charCodeAt(i))) {
  2418. return 0;
  2419. }
  2420. }
  2421. return 1;
  2422. }
  2423. function idSelector(token) {
  2424. if (token === null || token.type !== TYPE$5.Hash) {
  2425. return 0;
  2426. }
  2427. if (!isIdentifierStart$2(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
  2428. return 0;
  2429. }
  2430. return 1;
  2431. }
  2432. // https://drafts.csswg.org/css-syntax/#any-value
  2433. // It represents the entirety of what a valid declaration can have as its value.
  2434. function declarationValue(token, getNextToken) {
  2435. if (!token) {
  2436. return 0;
  2437. }
  2438. var length = 0;
  2439. var level = 0;
  2440. var startIdx = token.index;
  2441. // The <declaration-value> production matches any sequence of one or more tokens,
  2442. // so long as the sequence ...
  2443. scan:
  2444. do {
  2445. switch (token.type) {
  2446. // ... does not contain <bad-string-token>, <bad-url-token>,
  2447. case TYPE$5.BadString:
  2448. case TYPE$5.BadUrl:
  2449. break scan;
  2450. // ... unmatched <)-token>, <]-token>, or <}-token>,
  2451. case TYPE$5.RightCurlyBracket:
  2452. case TYPE$5.RightParenthesis:
  2453. case TYPE$5.RightSquareBracket:
  2454. if (token.balance > token.index || token.balance < startIdx) {
  2455. break scan;
  2456. }
  2457. level--;
  2458. break;
  2459. // ... or top-level <semicolon-token> tokens
  2460. case TYPE$5.Semicolon:
  2461. if (level === 0) {
  2462. break scan;
  2463. }
  2464. break;
  2465. // ... or <delim-token> tokens with a value of "!"
  2466. case TYPE$5.Delim:
  2467. if (token.value === '!' && level === 0) {
  2468. break scan;
  2469. }
  2470. break;
  2471. case TYPE$5.Function:
  2472. case TYPE$5.LeftParenthesis:
  2473. case TYPE$5.LeftSquareBracket:
  2474. case TYPE$5.LeftCurlyBracket:
  2475. level++;
  2476. break;
  2477. }
  2478. length++;
  2479. // until balance closing
  2480. if (token.balance <= startIdx) {
  2481. break;
  2482. }
  2483. } while (token = getNextToken(length));
  2484. return length;
  2485. }
  2486. // https://drafts.csswg.org/css-syntax/#any-value
  2487. // The <any-value> production is identical to <declaration-value>, but also
  2488. // allows top-level <semicolon-token> tokens and <delim-token> tokens
  2489. // with a value of "!". It represents the entirety of what valid CSS can be in any context.
  2490. function anyValue(token, getNextToken) {
  2491. if (!token) {
  2492. return 0;
  2493. }
  2494. var startIdx = token.index;
  2495. var length = 0;
  2496. // The <any-value> production matches any sequence of one or more tokens,
  2497. // so long as the sequence ...
  2498. scan:
  2499. do {
  2500. switch (token.type) {
  2501. // ... does not contain <bad-string-token>, <bad-url-token>,
  2502. case TYPE$5.BadString:
  2503. case TYPE$5.BadUrl:
  2504. break scan;
  2505. // ... unmatched <)-token>, <]-token>, or <}-token>,
  2506. case TYPE$5.RightCurlyBracket:
  2507. case TYPE$5.RightParenthesis:
  2508. case TYPE$5.RightSquareBracket:
  2509. if (token.balance > token.index || token.balance < startIdx) {
  2510. break scan;
  2511. }
  2512. break;
  2513. }
  2514. length++;
  2515. // until balance closing
  2516. if (token.balance <= startIdx) {
  2517. break;
  2518. }
  2519. } while (token = getNextToken(length));
  2520. return length;
  2521. }
  2522. // =========================
  2523. // Dimensions
  2524. //
  2525. function dimension(type) {
  2526. return function(token, getNextToken, opts) {
  2527. if (token === null || token.type !== TYPE$5.Dimension) {
  2528. return 0;
  2529. }
  2530. var numberEnd = consumeNumber$2(token.value, 0);
  2531. // check unit
  2532. if (type !== null) {
  2533. // check for IE postfix hack, i.e. 123px\0 or 123px\9
  2534. var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
  2535. var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
  2536. ? token.value.substr(numberEnd)
  2537. : token.value.substring(numberEnd, reverseSolidusOffset);
  2538. if (type.hasOwnProperty(unit.toLowerCase()) === false) {
  2539. return 0;
  2540. }
  2541. }
  2542. // check range if specified
  2543. if (outOfRange(opts, token.value, numberEnd)) {
  2544. return 0;
  2545. }
  2546. return 1;
  2547. };
  2548. }
  2549. // =========================
  2550. // Percentage
  2551. //
  2552. // §5.5. Percentages: the <percentage> type
  2553. // https://drafts.csswg.org/css-values-4/#percentages
  2554. function percentage(token, getNextToken, opts) {
  2555. // ... corresponds to the <percentage-token> production
  2556. if (token === null || token.type !== TYPE$5.Percentage) {
  2557. return 0;
  2558. }
  2559. // check range if specified
  2560. if (outOfRange(opts, token.value, token.value.length - 1)) {
  2561. return 0;
  2562. }
  2563. return 1;
  2564. }
  2565. // =========================
  2566. // Numeric
  2567. //
  2568. // https://drafts.csswg.org/css-values-4/#numbers
  2569. // The value <zero> represents a literal number with the value 0. Expressions that merely
  2570. // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
  2571. // only literal <number-token>s do.
  2572. function zero(next) {
  2573. if (typeof next !== 'function') {
  2574. next = function() {
  2575. return 0;
  2576. };
  2577. }
  2578. return function(token, getNextToken, opts) {
  2579. if (token !== null && token.type === TYPE$5.Number) {
  2580. if (Number(token.value) === 0) {
  2581. return 1;
  2582. }
  2583. }
  2584. return next(token, getNextToken, opts);
  2585. };
  2586. }
  2587. // § 5.3. Real Numbers: the <number> type
  2588. // https://drafts.csswg.org/css-values-4/#numbers
  2589. // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
  2590. // ... It corresponds to the <number-token> production
  2591. function number(token, getNextToken, opts) {
  2592. if (token === null) {
  2593. return 0;
  2594. }
  2595. var numberEnd = consumeNumber$2(token.value, 0);
  2596. var isNumber = numberEnd === token.value.length;
  2597. if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
  2598. return 0;
  2599. }
  2600. // check range if specified
  2601. if (outOfRange(opts, token.value, numberEnd)) {
  2602. return 0;
  2603. }
  2604. return 1;
  2605. }
  2606. // §5.2. Integers: the <integer> type
  2607. // https://drafts.csswg.org/css-values-4/#integers
  2608. function integer(token, getNextToken, opts) {
  2609. // ... corresponds to a subset of the <number-token> production
  2610. if (token === null || token.type !== TYPE$5.Number) {
  2611. return 0;
  2612. }
  2613. // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
  2614. var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
  2615. token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
  2616. // When written literally, an integer is one or more decimal digits 0 through 9 ...
  2617. for (; i < token.value.length; i++) {
  2618. if (!isDigit$3(token.value.charCodeAt(i))) {
  2619. return 0;
  2620. }
  2621. }
  2622. // check range if specified
  2623. if (outOfRange(opts, token.value, i)) {
  2624. return 0;
  2625. }
  2626. return 1;
  2627. }
  2628. var generic = {
  2629. // token types
  2630. 'ident-token': tokenType(TYPE$5.Ident),
  2631. 'function-token': tokenType(TYPE$5.Function),
  2632. 'at-keyword-token': tokenType(TYPE$5.AtKeyword),
  2633. 'hash-token': tokenType(TYPE$5.Hash),
  2634. 'string-token': tokenType(TYPE$5.String),
  2635. 'bad-string-token': tokenType(TYPE$5.BadString),
  2636. 'url-token': tokenType(TYPE$5.Url),
  2637. 'bad-url-token': tokenType(TYPE$5.BadUrl),
  2638. 'delim-token': tokenType(TYPE$5.Delim),
  2639. 'number-token': tokenType(TYPE$5.Number),
  2640. 'percentage-token': tokenType(TYPE$5.Percentage),
  2641. 'dimension-token': tokenType(TYPE$5.Dimension),
  2642. 'whitespace-token': tokenType(TYPE$5.WhiteSpace),
  2643. 'CDO-token': tokenType(TYPE$5.CDO),
  2644. 'CDC-token': tokenType(TYPE$5.CDC),
  2645. 'colon-token': tokenType(TYPE$5.Colon),
  2646. 'semicolon-token': tokenType(TYPE$5.Semicolon),
  2647. 'comma-token': tokenType(TYPE$5.Comma),
  2648. '[-token': tokenType(TYPE$5.LeftSquareBracket),
  2649. ']-token': tokenType(TYPE$5.RightSquareBracket),
  2650. '(-token': tokenType(TYPE$5.LeftParenthesis),
  2651. ')-token': tokenType(TYPE$5.RightParenthesis),
  2652. '{-token': tokenType(TYPE$5.LeftCurlyBracket),
  2653. '}-token': tokenType(TYPE$5.RightCurlyBracket),
  2654. // token type aliases
  2655. 'string': tokenType(TYPE$5.String),
  2656. 'ident': tokenType(TYPE$5.Ident),
  2657. // complex types
  2658. 'custom-ident': customIdent,
  2659. 'custom-property-name': customPropertyName,
  2660. 'hex-color': hexColor,
  2661. 'id-selector': idSelector, // element( <id-selector> )
  2662. 'an-plus-b': genericAnPlusB,
  2663. 'urange': genericUrange,
  2664. 'declaration-value': declarationValue,
  2665. 'any-value': anyValue,
  2666. // dimensions
  2667. 'dimension': calc(dimension(null)),
  2668. 'angle': calc(dimension(ANGLE)),
  2669. 'decibel': calc(dimension(DECIBEL)),
  2670. 'frequency': calc(dimension(FREQUENCY)),
  2671. 'flex': calc(dimension(FLEX)),
  2672. 'length': calc(zero(dimension(LENGTH))),
  2673. 'resolution': calc(dimension(RESOLUTION)),
  2674. 'semitones': calc(dimension(SEMITONES)),
  2675. 'time': calc(dimension(TIME)),
  2676. // percentage
  2677. 'percentage': calc(percentage),
  2678. // numeric
  2679. 'zero': zero(),
  2680. 'number': calc(number),
  2681. 'integer': calc(integer),
  2682. // old IE stuff
  2683. '-ms-legacy-expression': func('expression')
  2684. };
  2685. var _SyntaxError$1 = function SyntaxError(message, input, offset) {
  2686. var error = createCustomError('SyntaxError', message);
  2687. error.input = input;
  2688. error.offset = offset;
  2689. error.rawMessage = message;
  2690. error.message = error.rawMessage + '\n' +
  2691. ' ' + error.input + '\n' +
  2692. '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
  2693. return error;
  2694. };
  2695. var TAB = 9;
  2696. var N$1 = 10;
  2697. var F = 12;
  2698. var R = 13;
  2699. var SPACE = 32;
  2700. var Tokenizer = function(str) {
  2701. this.str = str;
  2702. this.pos = 0;
  2703. };
  2704. Tokenizer.prototype = {
  2705. charCodeAt: function(pos) {
  2706. return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
  2707. },
  2708. charCode: function() {
  2709. return this.charCodeAt(this.pos);
  2710. },
  2711. nextCharCode: function() {
  2712. return this.charCodeAt(this.pos + 1);
  2713. },
  2714. nextNonWsCode: function(pos) {
  2715. return this.charCodeAt(this.findWsEnd(pos));
  2716. },
  2717. findWsEnd: function(pos) {
  2718. for (; pos < this.str.length; pos++) {
  2719. var code = this.str.charCodeAt(pos);
  2720. if (code !== R && code !== N$1 && code !== F && code !== SPACE && code !== TAB) {
  2721. break;
  2722. }
  2723. }
  2724. return pos;
  2725. },
  2726. substringToPos: function(end) {
  2727. return this.str.substring(this.pos, this.pos = end);
  2728. },
  2729. eat: function(code) {
  2730. if (this.charCode() !== code) {
  2731. this.error('Expect `' + String.fromCharCode(code) + '`');
  2732. }
  2733. this.pos++;
  2734. },
  2735. peek: function() {
  2736. return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
  2737. },
  2738. error: function(message) {
  2739. throw new _SyntaxError$1(message, this.str, this.pos);
  2740. }
  2741. };
  2742. var tokenizer$1 = Tokenizer;
  2743. var TAB$1 = 9;
  2744. var N$2 = 10;
  2745. var F$1 = 12;
  2746. var R$1 = 13;
  2747. var SPACE$1 = 32;
  2748. var EXCLAMATIONMARK = 33; // !
  2749. var NUMBERSIGN = 35; // #
  2750. var AMPERSAND = 38; // &
  2751. var APOSTROPHE = 39; // '
  2752. var LEFTPARENTHESIS = 40; // (
  2753. var RIGHTPARENTHESIS = 41; // )
  2754. var ASTERISK = 42; // *
  2755. var PLUSSIGN$2 = 43; // +
  2756. var COMMA = 44; // ,
  2757. var HYPERMINUS = 45; // -
  2758. var LESSTHANSIGN = 60; // <
  2759. var GREATERTHANSIGN = 62; // >
  2760. var QUESTIONMARK$1 = 63; // ?
  2761. var COMMERCIALAT = 64; // @
  2762. var LEFTSQUAREBRACKET = 91; // [
  2763. var RIGHTSQUAREBRACKET = 93; // ]
  2764. var LEFTCURLYBRACKET = 123; // {
  2765. var VERTICALLINE = 124; // |
  2766. var RIGHTCURLYBRACKET = 125; // }
  2767. var INFINITY = 8734; // ∞
  2768. var NAME_CHAR = createCharMap(function(ch) {
  2769. return /[a-zA-Z0-9\-]/.test(ch);
  2770. });
  2771. var COMBINATOR_PRECEDENCE = {
  2772. ' ': 1,
  2773. '&&': 2,
  2774. '||': 3,
  2775. '|': 4
  2776. };
  2777. function createCharMap(fn) {
  2778. var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
  2779. for (var i = 0; i < 128; i++) {
  2780. array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
  2781. }
  2782. return array;
  2783. }
  2784. function scanSpaces(tokenizer) {
  2785. return tokenizer.substringToPos(
  2786. tokenizer.findWsEnd(tokenizer.pos)
  2787. );
  2788. }
  2789. function scanWord(tokenizer) {
  2790. var end = tokenizer.pos;
  2791. for (; end < tokenizer.str.length; end++) {
  2792. var code = tokenizer.str.charCodeAt(end);
  2793. if (code >= 128 || NAME_CHAR[code] === 0) {
  2794. break;
  2795. }
  2796. }
  2797. if (tokenizer.pos === end) {
  2798. tokenizer.error('Expect a keyword');
  2799. }
  2800. return tokenizer.substringToPos(end);
  2801. }
  2802. function scanNumber(tokenizer) {
  2803. var end = tokenizer.pos;
  2804. for (; end < tokenizer.str.length; end++) {
  2805. var code = tokenizer.str.charCodeAt(end);
  2806. if (code < 48 || code > 57) {
  2807. break;
  2808. }
  2809. }
  2810. if (tokenizer.pos === end) {
  2811. tokenizer.error('Expect a number');
  2812. }
  2813. return tokenizer.substringToPos(end);
  2814. }
  2815. function scanString(tokenizer) {
  2816. var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
  2817. if (end === -1) {
  2818. tokenizer.pos = tokenizer.str.length;
  2819. tokenizer.error('Expect an apostrophe');
  2820. }
  2821. return tokenizer.substringToPos(end + 1);
  2822. }
  2823. function readMultiplierRange(tokenizer) {
  2824. var min = null;
  2825. var max = null;
  2826. tokenizer.eat(LEFTCURLYBRACKET);
  2827. min = scanNumber(tokenizer);
  2828. if (tokenizer.charCode() === COMMA) {
  2829. tokenizer.pos++;
  2830. if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
  2831. max = scanNumber(tokenizer);
  2832. }
  2833. } else {
  2834. max = min;
  2835. }
  2836. tokenizer.eat(RIGHTCURLYBRACKET);
  2837. return {
  2838. min: Number(min),
  2839. max: max ? Number(max) : 0
  2840. };
  2841. }
  2842. function readMultiplier(tokenizer) {
  2843. var range = null;
  2844. var comma = false;
  2845. switch (tokenizer.charCode()) {
  2846. case ASTERISK:
  2847. tokenizer.pos++;
  2848. range = {
  2849. min: 0,
  2850. max: 0
  2851. };
  2852. break;
  2853. case PLUSSIGN$2:
  2854. tokenizer.pos++;
  2855. range = {
  2856. min: 1,
  2857. max: 0
  2858. };
  2859. break;
  2860. case QUESTIONMARK$1:
  2861. tokenizer.pos++;
  2862. range = {
  2863. min: 0,
  2864. max: 1
  2865. };
  2866. break;
  2867. case NUMBERSIGN:
  2868. tokenizer.pos++;
  2869. comma = true;
  2870. if (tokenizer.charCode() === LEFTCURLYBRACKET) {
  2871. range = readMultiplierRange(tokenizer);
  2872. } else {
  2873. range = {
  2874. min: 1,
  2875. max: 0
  2876. };
  2877. }
  2878. break;
  2879. case LEFTCURLYBRACKET:
  2880. range = readMultiplierRange(tokenizer);
  2881. break;
  2882. default:
  2883. return null;
  2884. }
  2885. return {
  2886. type: 'Multiplier',
  2887. comma: comma,
  2888. min: range.min,
  2889. max: range.max,
  2890. term: null
  2891. };
  2892. }
  2893. function maybeMultiplied(tokenizer, node) {
  2894. var multiplier = readMultiplier(tokenizer);
  2895. if (multiplier !== null) {
  2896. multiplier.term = node;
  2897. return multiplier;
  2898. }
  2899. return node;
  2900. }
  2901. function maybeToken(tokenizer) {
  2902. var ch = tokenizer.peek();
  2903. if (ch === '') {
  2904. return null;
  2905. }
  2906. return {
  2907. type: 'Token',
  2908. value: ch
  2909. };
  2910. }
  2911. function readProperty(tokenizer) {
  2912. var name;
  2913. tokenizer.eat(LESSTHANSIGN);
  2914. tokenizer.eat(APOSTROPHE);
  2915. name = scanWord(tokenizer);
  2916. tokenizer.eat(APOSTROPHE);
  2917. tokenizer.eat(GREATERTHANSIGN);
  2918. return maybeMultiplied(tokenizer, {
  2919. type: 'Property',
  2920. name: name
  2921. });
  2922. }
  2923. // https://drafts.csswg.org/css-values-3/#numeric-ranges
  2924. // 4.1. Range Restrictions and Range Definition Notation
  2925. //
  2926. // Range restrictions can be annotated in the numeric type notation using CSS bracketed
  2927. // range notation—[min,max]—within the angle brackets, after the identifying keyword,
  2928. // indicating a closed range between (and including) min and max.
  2929. // For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
  2930. function readTypeRange(tokenizer) {
  2931. // use null for Infinity to make AST format JSON serializable/deserializable
  2932. var min = null; // -Infinity
  2933. var max = null; // Infinity
  2934. var sign = 1;
  2935. tokenizer.eat(LEFTSQUAREBRACKET);
  2936. if (tokenizer.charCode() === HYPERMINUS) {
  2937. tokenizer.peek();
  2938. sign = -1;
  2939. }
  2940. if (sign == -1 && tokenizer.charCode() === INFINITY) {
  2941. tokenizer.peek();
  2942. } else {
  2943. min = sign * Number(scanNumber(tokenizer));
  2944. }
  2945. scanSpaces(tokenizer);
  2946. tokenizer.eat(COMMA);
  2947. scanSpaces(tokenizer);
  2948. if (tokenizer.charCode() === INFINITY) {
  2949. tokenizer.peek();
  2950. } else {
  2951. sign = 1;
  2952. if (tokenizer.charCode() === HYPERMINUS) {
  2953. tokenizer.peek();
  2954. sign = -1;
  2955. }
  2956. max = sign * Number(scanNumber(tokenizer));
  2957. }
  2958. tokenizer.eat(RIGHTSQUAREBRACKET);
  2959. // If no range is indicated, either by using the bracketed range notation
  2960. // or in the property description, then [−∞,∞] is assumed.
  2961. if (min === null && max === null) {
  2962. return null;
  2963. }
  2964. return {
  2965. type: 'Range',
  2966. min: min,
  2967. max: max
  2968. };
  2969. }
  2970. function readType(tokenizer) {
  2971. var name;
  2972. var opts = null;
  2973. tokenizer.eat(LESSTHANSIGN);
  2974. name = scanWord(tokenizer);
  2975. if (tokenizer.charCode() === LEFTPARENTHESIS &&
  2976. tokenizer.nextCharCode() === RIGHTPARENTHESIS) {
  2977. tokenizer.pos += 2;
  2978. name += '()';
  2979. }
  2980. if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET) {
  2981. scanSpaces(tokenizer);
  2982. opts = readTypeRange(tokenizer);
  2983. }
  2984. tokenizer.eat(GREATERTHANSIGN);
  2985. return maybeMultiplied(tokenizer, {
  2986. type: 'Type',
  2987. name: name,
  2988. opts: opts
  2989. });
  2990. }
  2991. function readKeywordOrFunction(tokenizer) {
  2992. var name;
  2993. name = scanWord(tokenizer);
  2994. if (tokenizer.charCode() === LEFTPARENTHESIS) {
  2995. tokenizer.pos++;
  2996. return {
  2997. type: 'Function',
  2998. name: name
  2999. };
  3000. }
  3001. return maybeMultiplied(tokenizer, {
  3002. type: 'Keyword',
  3003. name: name
  3004. });
  3005. }
  3006. function regroupTerms(terms, combinators) {
  3007. function createGroup(terms, combinator) {
  3008. return {
  3009. type: 'Group',
  3010. terms: terms,
  3011. combinator: combinator,
  3012. disallowEmpty: false,
  3013. explicit: false
  3014. };
  3015. }
  3016. combinators = Object.keys(combinators).sort(function(a, b) {
  3017. return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
  3018. });
  3019. while (combinators.length > 0) {
  3020. var combinator = combinators.shift();
  3021. for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
  3022. var term = terms[i];
  3023. if (term.type === 'Combinator') {
  3024. if (term.value === combinator) {
  3025. if (subgroupStart === -1) {
  3026. subgroupStart = i - 1;
  3027. }
  3028. terms.splice(i, 1);
  3029. i--;
  3030. } else {
  3031. if (subgroupStart !== -1 && i - subgroupStart > 1) {
  3032. terms.splice(
  3033. subgroupStart,
  3034. i - subgroupStart,
  3035. createGroup(terms.slice(subgroupStart, i), combinator)
  3036. );
  3037. i = subgroupStart + 1;
  3038. }
  3039. subgroupStart = -1;
  3040. }
  3041. }
  3042. }
  3043. if (subgroupStart !== -1 && combinators.length) {
  3044. terms.splice(
  3045. subgroupStart,
  3046. i - subgroupStart,
  3047. createGroup(terms.slice(subgroupStart, i), combinator)
  3048. );
  3049. }
  3050. }
  3051. return combinator;
  3052. }
  3053. function readImplicitGroup(tokenizer) {
  3054. var terms = [];
  3055. var combinators = {};
  3056. var token;
  3057. var prevToken = null;
  3058. var prevTokenPos = tokenizer.pos;
  3059. while (token = peek(tokenizer)) {
  3060. if (token.type !== 'Spaces') {
  3061. if (token.type === 'Combinator') {
  3062. // check for combinator in group beginning and double combinator sequence
  3063. if (prevToken === null || prevToken.type === 'Combinator') {
  3064. tokenizer.pos = prevTokenPos;
  3065. tokenizer.error('Unexpected combinator');
  3066. }
  3067. combinators[token.value] = true;
  3068. } else if (prevToken !== null && prevToken.type !== 'Combinator') {
  3069. combinators[' '] = true; // a b
  3070. terms.push({
  3071. type: 'Combinator',
  3072. value: ' '
  3073. });
  3074. }
  3075. terms.push(token);
  3076. prevToken = token;
  3077. prevTokenPos = tokenizer.pos;
  3078. }
  3079. }
  3080. // check for combinator in group ending
  3081. if (prevToken !== null && prevToken.type === 'Combinator') {
  3082. tokenizer.pos -= prevTokenPos;
  3083. tokenizer.error('Unexpected combinator');
  3084. }
  3085. return {
  3086. type: 'Group',
  3087. terms: terms,
  3088. combinator: regroupTerms(terms, combinators) || ' ',
  3089. disallowEmpty: false,
  3090. explicit: false
  3091. };
  3092. }
  3093. function readGroup(tokenizer) {
  3094. var result;
  3095. tokenizer.eat(LEFTSQUAREBRACKET);
  3096. result = readImplicitGroup(tokenizer);
  3097. tokenizer.eat(RIGHTSQUAREBRACKET);
  3098. result.explicit = true;
  3099. if (tokenizer.charCode() === EXCLAMATIONMARK) {
  3100. tokenizer.pos++;
  3101. result.disallowEmpty = true;
  3102. }
  3103. return result;
  3104. }
  3105. function peek(tokenizer) {
  3106. var code = tokenizer.charCode();
  3107. if (code < 128 && NAME_CHAR[code] === 1) {
  3108. return readKeywordOrFunction(tokenizer);
  3109. }
  3110. switch (code) {
  3111. case RIGHTSQUAREBRACKET:
  3112. // don't eat, stop scan a group
  3113. break;
  3114. case LEFTSQUAREBRACKET:
  3115. return maybeMultiplied(tokenizer, readGroup(tokenizer));
  3116. case LESSTHANSIGN:
  3117. return tokenizer.nextCharCode() === APOSTROPHE
  3118. ? readProperty(tokenizer)
  3119. : readType(tokenizer);
  3120. case VERTICALLINE:
  3121. return {
  3122. type: 'Combinator',
  3123. value: tokenizer.substringToPos(
  3124. tokenizer.nextCharCode() === VERTICALLINE
  3125. ? tokenizer.pos + 2
  3126. : tokenizer.pos + 1
  3127. )
  3128. };
  3129. case AMPERSAND:
  3130. tokenizer.pos++;
  3131. tokenizer.eat(AMPERSAND);
  3132. return {
  3133. type: 'Combinator',
  3134. value: '&&'
  3135. };
  3136. case COMMA:
  3137. tokenizer.pos++;
  3138. return {
  3139. type: 'Comma'
  3140. };
  3141. case APOSTROPHE:
  3142. return maybeMultiplied(tokenizer, {
  3143. type: 'String',
  3144. value: scanString(tokenizer)
  3145. });
  3146. case SPACE$1:
  3147. case TAB$1:
  3148. case N$2:
  3149. case R$1:
  3150. case F$1:
  3151. return {
  3152. type: 'Spaces',
  3153. value: scanSpaces(tokenizer)
  3154. };
  3155. case COMMERCIALAT:
  3156. code = tokenizer.nextCharCode();
  3157. if (code < 128 && NAME_CHAR[code] === 1) {
  3158. tokenizer.pos++;
  3159. return {
  3160. type: 'AtKeyword',
  3161. name: scanWord(tokenizer)
  3162. };
  3163. }
  3164. return maybeToken(tokenizer);
  3165. case ASTERISK:
  3166. case PLUSSIGN$2:
  3167. case QUESTIONMARK$1:
  3168. case NUMBERSIGN:
  3169. case EXCLAMATIONMARK:
  3170. // prohibited tokens (used as a multiplier start)
  3171. break;
  3172. case LEFTCURLYBRACKET:
  3173. // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
  3174. // check next char isn't a number, because it's likely a disjoined multiplier
  3175. code = tokenizer.nextCharCode();
  3176. if (code < 48 || code > 57) {
  3177. return maybeToken(tokenizer);
  3178. }
  3179. break;
  3180. default:
  3181. return maybeToken(tokenizer);
  3182. }
  3183. }
  3184. function parse(source) {
  3185. var tokenizer = new tokenizer$1(source);
  3186. var result = readImplicitGroup(tokenizer);
  3187. if (tokenizer.pos !== source.length) {
  3188. tokenizer.error('Unexpected input');
  3189. }
  3190. // reduce redundant groups with single group term
  3191. if (result.terms.length === 1 && result.terms[0].type === 'Group') {
  3192. result = result.terms[0];
  3193. }
  3194. return result;
  3195. }
  3196. // warm up parse to elimitate code branches that never execute
  3197. // fix soft deoptimizations (insufficient type feedback)
  3198. parse('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
  3199. var parse_1 = parse;
  3200. var noop$1 = function() {};
  3201. function ensureFunction(value) {
  3202. return typeof value === 'function' ? value : noop$1;
  3203. }
  3204. var walk = function(node, options, context) {
  3205. function walk(node) {
  3206. enter.call(context, node);
  3207. switch (node.type) {
  3208. case 'Group':
  3209. node.terms.forEach(walk);
  3210. break;
  3211. case 'Multiplier':
  3212. walk(node.term);
  3213. break;
  3214. case 'Type':
  3215. case 'Property':
  3216. case 'Keyword':
  3217. case 'AtKeyword':
  3218. case 'Function':
  3219. case 'String':
  3220. case 'Token':
  3221. case 'Comma':
  3222. break;
  3223. default:
  3224. throw new Error('Unknown type: ' + node.type);
  3225. }
  3226. leave.call(context, node);
  3227. }
  3228. var enter = noop$1;
  3229. var leave = noop$1;
  3230. if (typeof options === 'function') {
  3231. enter = options;
  3232. } else if (options) {
  3233. enter = ensureFunction(options.enter);
  3234. leave = ensureFunction(options.leave);
  3235. }
  3236. if (enter === noop$1 && leave === noop$1) {
  3237. throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
  3238. }
  3239. walk(node);
  3240. };
  3241. var tokenStream = new TokenStream_1();
  3242. var astToTokens = {
  3243. decorator: function(handlers) {
  3244. var curNode = null;
  3245. var prev = { len: 0, node: null };
  3246. var nodes = [prev];
  3247. var buffer = '';
  3248. return {
  3249. children: handlers.children,
  3250. node: function(node) {
  3251. var tmp = curNode;
  3252. curNode = node;
  3253. handlers.node.call(this, node);
  3254. curNode = tmp;
  3255. },
  3256. chunk: function(chunk) {
  3257. buffer += chunk;
  3258. if (prev.node !== curNode) {
  3259. nodes.push({
  3260. len: chunk.length,
  3261. node: curNode
  3262. });
  3263. } else {
  3264. prev.len += chunk.length;
  3265. }
  3266. },
  3267. result: function() {
  3268. return prepareTokens(buffer, nodes);
  3269. }
  3270. };
  3271. }
  3272. };
  3273. function prepareTokens(str, nodes) {
  3274. var tokens = [];
  3275. var nodesOffset = 0;
  3276. var nodesIndex = 0;
  3277. var currentNode = nodes ? nodes[nodesIndex].node : null;
  3278. tokenizer(str, tokenStream);
  3279. while (!tokenStream.eof) {
  3280. if (nodes) {
  3281. while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
  3282. nodesOffset += nodes[nodesIndex++].len;
  3283. currentNode = nodes[nodesIndex].node;
  3284. }
  3285. }
  3286. tokens.push({
  3287. type: tokenStream.tokenType,
  3288. value: tokenStream.getTokenValue(),
  3289. index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
  3290. balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
  3291. node: currentNode
  3292. });
  3293. tokenStream.next();
  3294. // console.log({ ...tokens[tokens.length - 1], node: undefined });
  3295. }
  3296. return tokens;
  3297. }
  3298. var prepareTokens_1 = function(value, syntax) {
  3299. if (typeof value === 'string') {
  3300. return prepareTokens(value, null);
  3301. }
  3302. return syntax.generate(value, astToTokens);
  3303. };
  3304. var MATCH = { type: 'Match' };
  3305. var MISMATCH = { type: 'Mismatch' };
  3306. var DISALLOW_EMPTY = { type: 'DisallowEmpty' };
  3307. var LEFTPARENTHESIS$1 = 40; // (
  3308. var RIGHTPARENTHESIS$1 = 41; // )
  3309. function createCondition(match, thenBranch, elseBranch) {
  3310. // reduce node count
  3311. if (thenBranch === MATCH && elseBranch === MISMATCH) {
  3312. return match;
  3313. }
  3314. if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
  3315. return match;
  3316. }
  3317. if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
  3318. thenBranch = match.then;
  3319. match = match.match;
  3320. }
  3321. return {
  3322. type: 'If',
  3323. match: match,
  3324. then: thenBranch,
  3325. else: elseBranch
  3326. };
  3327. }
  3328. function isFunctionType(name) {
  3329. return (
  3330. name.length > 2 &&
  3331. name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$1 &&
  3332. name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$1
  3333. );
  3334. }
  3335. function isEnumCapatible(term) {
  3336. return (
  3337. term.type === 'Keyword' ||
  3338. term.type === 'AtKeyword' ||
  3339. term.type === 'Function' ||
  3340. term.type === 'Type' && isFunctionType(term.name)
  3341. );
  3342. }
  3343. function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
  3344. switch (combinator) {
  3345. case ' ':
  3346. // Juxtaposing components means that all of them must occur, in the given order.
  3347. //
  3348. // a b c
  3349. // =
  3350. // match a
  3351. // then match b
  3352. // then match c
  3353. // then MATCH
  3354. // else MISMATCH
  3355. // else MISMATCH
  3356. // else MISMATCH
  3357. var result = MATCH;
  3358. for (var i = terms.length - 1; i >= 0; i--) {
  3359. var term = terms[i];
  3360. result = createCondition(
  3361. term,
  3362. result,
  3363. MISMATCH
  3364. );
  3365. }
  3366. return result;
  3367. case '|':
  3368. // A bar (|) separates two or more alternatives: exactly one of them must occur.
  3369. //
  3370. // a | b | c
  3371. // =
  3372. // match a
  3373. // then MATCH
  3374. // else match b
  3375. // then MATCH
  3376. // else match c
  3377. // then MATCH
  3378. // else MISMATCH
  3379. var result = MISMATCH;
  3380. var map = null;
  3381. for (var i = terms.length - 1; i >= 0; i--) {
  3382. var term = terms[i];
  3383. // reduce sequence of keywords into a Enum
  3384. if (isEnumCapatible(term)) {
  3385. if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
  3386. map = Object.create(null);
  3387. result = createCondition(
  3388. {
  3389. type: 'Enum',
  3390. map: map
  3391. },
  3392. MATCH,
  3393. result
  3394. );
  3395. }
  3396. if (map !== null) {
  3397. var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
  3398. if (key in map === false) {
  3399. map[key] = term;
  3400. continue;
  3401. }
  3402. }
  3403. }
  3404. map = null;
  3405. // create a new conditonal node
  3406. result = createCondition(
  3407. term,
  3408. MATCH,
  3409. result
  3410. );
  3411. }
  3412. return result;
  3413. case '&&':
  3414. // A double ampersand (&&) separates two or more components,
  3415. // all of which must occur, in any order.
  3416. // Use MatchOnce for groups with a large number of terms,
  3417. // since &&-groups produces at least N!-node trees
  3418. if (terms.length > 5) {
  3419. return {
  3420. type: 'MatchOnce',
  3421. terms: terms,
  3422. all: true
  3423. };
  3424. }
  3425. // Use a combination tree for groups with small number of terms
  3426. //
  3427. // a && b && c
  3428. // =
  3429. // match a
  3430. // then [b && c]
  3431. // else match b
  3432. // then [a && c]
  3433. // else match c
  3434. // then [a && b]
  3435. // else MISMATCH
  3436. //
  3437. // a && b
  3438. // =
  3439. // match a
  3440. // then match b
  3441. // then MATCH
  3442. // else MISMATCH
  3443. // else match b
  3444. // then match a
  3445. // then MATCH
  3446. // else MISMATCH
  3447. // else MISMATCH
  3448. var result = MISMATCH;
  3449. for (var i = terms.length - 1; i >= 0; i--) {
  3450. var term = terms[i];
  3451. var thenClause;
  3452. if (terms.length > 1) {
  3453. thenClause = buildGroupMatchGraph(
  3454. combinator,
  3455. terms.filter(function(newGroupTerm) {
  3456. return newGroupTerm !== term;
  3457. }),
  3458. false
  3459. );
  3460. } else {
  3461. thenClause = MATCH;
  3462. }
  3463. result = createCondition(
  3464. term,
  3465. thenClause,
  3466. result
  3467. );
  3468. }
  3469. return result;
  3470. case '||':
  3471. // A double bar (||) separates two or more options:
  3472. // one or more of them must occur, in any order.
  3473. // Use MatchOnce for groups with a large number of terms,
  3474. // since ||-groups produces at least N!-node trees
  3475. if (terms.length > 5) {
  3476. return {
  3477. type: 'MatchOnce',
  3478. terms: terms,
  3479. all: false
  3480. };
  3481. }
  3482. // Use a combination tree for groups with small number of terms
  3483. //
  3484. // a || b || c
  3485. // =
  3486. // match a
  3487. // then [b || c]
  3488. // else match b
  3489. // then [a || c]
  3490. // else match c
  3491. // then [a || b]
  3492. // else MISMATCH
  3493. //
  3494. // a || b
  3495. // =
  3496. // match a
  3497. // then match b
  3498. // then MATCH
  3499. // else MATCH
  3500. // else match b
  3501. // then match a
  3502. // then MATCH
  3503. // else MATCH
  3504. // else MISMATCH
  3505. var result = atLeastOneTermMatched ? MATCH : MISMATCH;
  3506. for (var i = terms.length - 1; i >= 0; i--) {
  3507. var term = terms[i];
  3508. var thenClause;
  3509. if (terms.length > 1) {
  3510. thenClause = buildGroupMatchGraph(
  3511. combinator,
  3512. terms.filter(function(newGroupTerm) {
  3513. return newGroupTerm !== term;
  3514. }),
  3515. true
  3516. );
  3517. } else {
  3518. thenClause = MATCH;
  3519. }
  3520. result = createCondition(
  3521. term,
  3522. thenClause,
  3523. result
  3524. );
  3525. }
  3526. return result;
  3527. }
  3528. }
  3529. function buildMultiplierMatchGraph(node) {
  3530. var result = MATCH;
  3531. var matchTerm = buildMatchGraph(node.term);
  3532. if (node.max === 0) {
  3533. // disable repeating of empty match to prevent infinite loop
  3534. matchTerm = createCondition(
  3535. matchTerm,
  3536. DISALLOW_EMPTY,
  3537. MISMATCH
  3538. );
  3539. // an occurrence count is not limited, make a cycle;
  3540. // to collect more terms on each following matching mismatch
  3541. result = createCondition(
  3542. matchTerm,
  3543. null, // will be a loop
  3544. MISMATCH
  3545. );
  3546. result.then = createCondition(
  3547. MATCH,
  3548. MATCH,
  3549. result // make a loop
  3550. );
  3551. if (node.comma) {
  3552. result.then.else = createCondition(
  3553. { type: 'Comma', syntax: node },
  3554. result,
  3555. MISMATCH
  3556. );
  3557. }
  3558. } else {
  3559. // create a match node chain for [min .. max] interval with optional matches
  3560. for (var i = node.min || 1; i <= node.max; i++) {
  3561. if (node.comma && result !== MATCH) {
  3562. result = createCondition(
  3563. { type: 'Comma', syntax: node },
  3564. result,
  3565. MISMATCH
  3566. );
  3567. }
  3568. result = createCondition(
  3569. matchTerm,
  3570. createCondition(
  3571. MATCH,
  3572. MATCH,
  3573. result
  3574. ),
  3575. MISMATCH
  3576. );
  3577. }
  3578. }
  3579. if (node.min === 0) {
  3580. // allow zero match
  3581. result = createCondition(
  3582. MATCH,
  3583. MATCH,
  3584. result
  3585. );
  3586. } else {
  3587. // create a match node chain to collect [0 ... min - 1] required matches
  3588. for (var i = 0; i < node.min - 1; i++) {
  3589. if (node.comma && result !== MATCH) {
  3590. result = createCondition(
  3591. { type: 'Comma', syntax: node },
  3592. result,
  3593. MISMATCH
  3594. );
  3595. }
  3596. result = createCondition(
  3597. matchTerm,
  3598. result,
  3599. MISMATCH
  3600. );
  3601. }
  3602. }
  3603. return result;
  3604. }
  3605. function buildMatchGraph(node) {
  3606. if (typeof node === 'function') {
  3607. return {
  3608. type: 'Generic',
  3609. fn: node
  3610. };
  3611. }
  3612. switch (node.type) {
  3613. case 'Group':
  3614. var result = buildGroupMatchGraph(
  3615. node.combinator,
  3616. node.terms.map(buildMatchGraph),
  3617. false
  3618. );
  3619. if (node.disallowEmpty) {
  3620. result = createCondition(
  3621. result,
  3622. DISALLOW_EMPTY,
  3623. MISMATCH
  3624. );
  3625. }
  3626. return result;
  3627. case 'Multiplier':
  3628. return buildMultiplierMatchGraph(node);
  3629. case 'Type':
  3630. case 'Property':
  3631. return {
  3632. type: node.type,
  3633. name: node.name,
  3634. syntax: node
  3635. };
  3636. case 'Keyword':
  3637. return {
  3638. type: node.type,
  3639. name: node.name.toLowerCase(),
  3640. syntax: node
  3641. };
  3642. case 'AtKeyword':
  3643. return {
  3644. type: node.type,
  3645. name: '@' + node.name.toLowerCase(),
  3646. syntax: node
  3647. };
  3648. case 'Function':
  3649. return {
  3650. type: node.type,
  3651. name: node.name.toLowerCase() + '(',
  3652. syntax: node
  3653. };
  3654. case 'String':
  3655. // convert a one char length String to a Token
  3656. if (node.value.length === 3) {
  3657. return {
  3658. type: 'Token',
  3659. value: node.value.charAt(1),
  3660. syntax: node
  3661. };
  3662. }
  3663. // otherwise use it as is
  3664. return {
  3665. type: node.type,
  3666. value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
  3667. syntax: node
  3668. };
  3669. case 'Token':
  3670. return {
  3671. type: node.type,
  3672. value: node.value,
  3673. syntax: node
  3674. };
  3675. case 'Comma':
  3676. return {
  3677. type: node.type,
  3678. syntax: node
  3679. };
  3680. default:
  3681. throw new Error('Unknown node type:', node.type);
  3682. }
  3683. }
  3684. var matchGraph = {
  3685. MATCH: MATCH,
  3686. MISMATCH: MISMATCH,
  3687. DISALLOW_EMPTY: DISALLOW_EMPTY,
  3688. buildMatchGraph: function(syntaxTree, ref) {
  3689. if (typeof syntaxTree === 'string') {
  3690. syntaxTree = parse_1(syntaxTree);
  3691. }
  3692. return {
  3693. type: 'MatchGraph',
  3694. match: buildMatchGraph(syntaxTree),
  3695. syntax: ref || null,
  3696. source: syntaxTree
  3697. };
  3698. }
  3699. };
  3700. var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
  3701. var MATCH$1 = matchGraph.MATCH;
  3702. var MISMATCH$1 = matchGraph.MISMATCH;
  3703. var DISALLOW_EMPTY$1 = matchGraph.DISALLOW_EMPTY;
  3704. var TYPE$6 = _const.TYPE;
  3705. var STUB = 0;
  3706. var TOKEN = 1;
  3707. var OPEN_SYNTAX = 2;
  3708. var CLOSE_SYNTAX = 3;
  3709. var EXIT_REASON_MATCH = 'Match';
  3710. var EXIT_REASON_MISMATCH = 'Mismatch';
  3711. var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
  3712. var ITERATION_LIMIT = 15000;
  3713. var totalIterationCount = 0;
  3714. function reverseList(list) {
  3715. var prev = null;
  3716. var next = null;
  3717. var item = list;
  3718. while (item !== null) {
  3719. next = item.prev;
  3720. item.prev = prev;
  3721. prev = item;
  3722. item = next;
  3723. }
  3724. return prev;
  3725. }
  3726. function areStringsEqualCaseInsensitive(testStr, referenceStr) {
  3727. if (testStr.length !== referenceStr.length) {
  3728. return false;
  3729. }
  3730. for (var i = 0; i < testStr.length; i++) {
  3731. var testCode = testStr.charCodeAt(i);
  3732. var referenceCode = referenceStr.charCodeAt(i);
  3733. // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
  3734. if (testCode >= 0x0041 && testCode <= 0x005A) {
  3735. testCode = testCode | 32;
  3736. }
  3737. if (testCode !== referenceCode) {
  3738. return false;
  3739. }
  3740. }
  3741. return true;
  3742. }
  3743. function isCommaContextStart(token) {
  3744. if (token === null) {
  3745. return true;
  3746. }
  3747. return (
  3748. token.type === TYPE$6.Comma ||
  3749. token.type === TYPE$6.Function ||
  3750. token.type === TYPE$6.LeftParenthesis ||
  3751. token.type === TYPE$6.LeftSquareBracket ||
  3752. token.type === TYPE$6.LeftCurlyBracket ||
  3753. token.type === TYPE$6.Delim
  3754. );
  3755. }
  3756. function isCommaContextEnd(token) {
  3757. if (token === null) {
  3758. return true;
  3759. }
  3760. return (
  3761. token.type === TYPE$6.RightParenthesis ||
  3762. token.type === TYPE$6.RightSquareBracket ||
  3763. token.type === TYPE$6.RightCurlyBracket ||
  3764. token.type === TYPE$6.Delim
  3765. );
  3766. }
  3767. function internalMatch(tokens, state, syntaxes) {
  3768. function moveToNextToken() {
  3769. do {
  3770. tokenIndex++;
  3771. token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
  3772. } while (token !== null && (token.type === TYPE$6.WhiteSpace || token.type === TYPE$6.Comment));
  3773. }
  3774. function getNextToken(offset) {
  3775. var nextIndex = tokenIndex + offset;
  3776. return nextIndex < tokens.length ? tokens[nextIndex] : null;
  3777. }
  3778. function stateSnapshotFromSyntax(nextState, prev) {
  3779. return {
  3780. nextState: nextState,
  3781. matchStack: matchStack,
  3782. syntaxStack: syntaxStack,
  3783. thenStack: thenStack,
  3784. tokenIndex: tokenIndex,
  3785. prev: prev
  3786. };
  3787. }
  3788. function pushThenStack(nextState) {
  3789. thenStack = {
  3790. nextState: nextState,
  3791. matchStack: matchStack,
  3792. syntaxStack: syntaxStack,
  3793. prev: thenStack
  3794. };
  3795. }
  3796. function pushElseStack(nextState) {
  3797. elseStack = stateSnapshotFromSyntax(nextState, elseStack);
  3798. }
  3799. function addTokenToMatch() {
  3800. matchStack = {
  3801. type: TOKEN,
  3802. syntax: state.syntax,
  3803. token: token,
  3804. prev: matchStack
  3805. };
  3806. moveToNextToken();
  3807. syntaxStash = null;
  3808. if (tokenIndex > longestMatch) {
  3809. longestMatch = tokenIndex;
  3810. }
  3811. }
  3812. function openSyntax() {
  3813. syntaxStack = {
  3814. syntax: state.syntax,
  3815. opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
  3816. prev: syntaxStack
  3817. };
  3818. matchStack = {
  3819. type: OPEN_SYNTAX,
  3820. syntax: state.syntax,
  3821. token: matchStack.token,
  3822. prev: matchStack
  3823. };
  3824. }
  3825. function closeSyntax() {
  3826. if (matchStack.type === OPEN_SYNTAX) {
  3827. matchStack = matchStack.prev;
  3828. } else {
  3829. matchStack = {
  3830. type: CLOSE_SYNTAX,
  3831. syntax: syntaxStack.syntax,
  3832. token: matchStack.token,
  3833. prev: matchStack
  3834. };
  3835. }
  3836. syntaxStack = syntaxStack.prev;
  3837. }
  3838. var syntaxStack = null;
  3839. var thenStack = null;
  3840. var elseStack = null;
  3841. // null – stashing allowed, nothing stashed
  3842. // false – stashing disabled, nothing stashed
  3843. // anithing else – fail stashable syntaxes, some syntax stashed
  3844. var syntaxStash = null;
  3845. var iterationCount = 0; // count iterations and prevent infinite loop
  3846. var exitReason = null;
  3847. var token = null;
  3848. var tokenIndex = -1;
  3849. var longestMatch = 0;
  3850. var matchStack = {
  3851. type: STUB,
  3852. syntax: null,
  3853. token: null,
  3854. prev: null
  3855. };
  3856. moveToNextToken();
  3857. while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
  3858. // function mapList(list, fn) {
  3859. // var result = [];
  3860. // while (list) {
  3861. // result.unshift(fn(list));
  3862. // list = list.prev;
  3863. // }
  3864. // return result;
  3865. // }
  3866. // console.log('--\n',
  3867. // '#' + iterationCount,
  3868. // require('util').inspect({
  3869. // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null),
  3870. // token: token && token.value,
  3871. // tokenIndex,
  3872. // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
  3873. // }, { depth: null })
  3874. // );
  3875. switch (state.type) {
  3876. case 'Match':
  3877. if (thenStack === null) {
  3878. // turn to MISMATCH when some tokens left unmatched
  3879. if (token !== null) {
  3880. // doesn't mismatch if just one token left and it's an IE hack
  3881. if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
  3882. state = MISMATCH$1;
  3883. break;
  3884. }
  3885. }
  3886. // break the main loop, return a result - MATCH
  3887. exitReason = EXIT_REASON_MATCH;
  3888. break;
  3889. }
  3890. // go to next syntax (`then` branch)
  3891. state = thenStack.nextState;
  3892. // check match is not empty
  3893. if (state === DISALLOW_EMPTY$1) {
  3894. if (thenStack.matchStack === matchStack) {
  3895. state = MISMATCH$1;
  3896. break;
  3897. } else {
  3898. state = MATCH$1;
  3899. }
  3900. }
  3901. // close syntax if needed
  3902. while (thenStack.syntaxStack !== syntaxStack) {
  3903. closeSyntax();
  3904. }
  3905. // pop stack
  3906. thenStack = thenStack.prev;
  3907. break;
  3908. case 'Mismatch':
  3909. // when some syntax is stashed
  3910. if (syntaxStash !== null && syntaxStash !== false) {
  3911. // there is no else branches or a branch reduce match stack
  3912. if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
  3913. // restore state from the stash
  3914. elseStack = syntaxStash;
  3915. syntaxStash = false; // disable stashing
  3916. }
  3917. } else if (elseStack === null) {
  3918. // no else branches -> break the main loop
  3919. // return a result - MISMATCH
  3920. exitReason = EXIT_REASON_MISMATCH;
  3921. break;
  3922. }
  3923. // go to next syntax (`else` branch)
  3924. state = elseStack.nextState;
  3925. // restore all the rest stack states
  3926. thenStack = elseStack.thenStack;
  3927. syntaxStack = elseStack.syntaxStack;
  3928. matchStack = elseStack.matchStack;
  3929. tokenIndex = elseStack.tokenIndex;
  3930. token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
  3931. // pop stack
  3932. elseStack = elseStack.prev;
  3933. break;
  3934. case 'MatchGraph':
  3935. state = state.match;
  3936. break;
  3937. case 'If':
  3938. // IMPORTANT: else stack push must go first,
  3939. // since it stores the state of thenStack before changes
  3940. if (state.else !== MISMATCH$1) {
  3941. pushElseStack(state.else);
  3942. }
  3943. if (state.then !== MATCH$1) {
  3944. pushThenStack(state.then);
  3945. }
  3946. state = state.match;
  3947. break;
  3948. case 'MatchOnce':
  3949. state = {
  3950. type: 'MatchOnceBuffer',
  3951. syntax: state,
  3952. index: 0,
  3953. mask: 0
  3954. };
  3955. break;
  3956. case 'MatchOnceBuffer':
  3957. var terms = state.syntax.terms;
  3958. if (state.index === terms.length) {
  3959. // no matches at all or it's required all terms to be matched
  3960. if (state.mask === 0 || state.syntax.all) {
  3961. state = MISMATCH$1;
  3962. break;
  3963. }
  3964. // a partial match is ok
  3965. state = MATCH$1;
  3966. break;
  3967. }
  3968. // all terms are matched
  3969. if (state.mask === (1 << terms.length) - 1) {
  3970. state = MATCH$1;
  3971. break;
  3972. }
  3973. for (; state.index < terms.length; state.index++) {
  3974. var matchFlag = 1 << state.index;
  3975. if ((state.mask & matchFlag) === 0) {
  3976. // IMPORTANT: else stack push must go first,
  3977. // since it stores the state of thenStack before changes
  3978. pushElseStack(state);
  3979. pushThenStack({
  3980. type: 'AddMatchOnce',
  3981. syntax: state.syntax,
  3982. mask: state.mask | matchFlag
  3983. });
  3984. // match
  3985. state = terms[state.index++];
  3986. break;
  3987. }
  3988. }
  3989. break;
  3990. case 'AddMatchOnce':
  3991. state = {
  3992. type: 'MatchOnceBuffer',
  3993. syntax: state.syntax,
  3994. index: 0,
  3995. mask: state.mask
  3996. };
  3997. break;
  3998. case 'Enum':
  3999. if (token !== null) {
  4000. var name = token.value.toLowerCase();
  4001. // drop \0 and \9 hack from keyword name
  4002. if (name.indexOf('\\') !== -1) {
  4003. name = name.replace(/\\[09].*$/, '');
  4004. }
  4005. if (hasOwnProperty$1.call(state.map, name)) {
  4006. state = state.map[name];
  4007. break;
  4008. }
  4009. }
  4010. state = MISMATCH$1;
  4011. break;
  4012. case 'Generic':
  4013. var opts = syntaxStack !== null ? syntaxStack.opts : null;
  4014. var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
  4015. if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
  4016. while (tokenIndex < lastTokenIndex) {
  4017. addTokenToMatch();
  4018. }
  4019. state = MATCH$1;
  4020. } else {
  4021. state = MISMATCH$1;
  4022. }
  4023. break;
  4024. case 'Type':
  4025. case 'Property':
  4026. var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
  4027. var dictSyntax = hasOwnProperty$1.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
  4028. if (!dictSyntax || !dictSyntax.match) {
  4029. throw new Error(
  4030. 'Bad syntax reference: ' +
  4031. (state.type === 'Type'
  4032. ? '<' + state.name + '>'
  4033. : '<\'' + state.name + '\'>')
  4034. );
  4035. }
  4036. // stash a syntax for types with low priority
  4037. if (syntaxStash !== false && token !== null && state.type === 'Type') {
  4038. var lowPriorityMatching =
  4039. // https://drafts.csswg.org/css-values-4/#custom-idents
  4040. // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
  4041. // can only claim the keyword if no other unfulfilled production can claim it.
  4042. (state.name === 'custom-ident' && token.type === TYPE$6.Ident) ||
  4043. // https://drafts.csswg.org/css-values-4/#lengths
  4044. // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
  4045. // it must parse as a <number>
  4046. (state.name === 'length' && token.value === '0');
  4047. if (lowPriorityMatching) {
  4048. if (syntaxStash === null) {
  4049. syntaxStash = stateSnapshotFromSyntax(state, elseStack);
  4050. }
  4051. state = MISMATCH$1;
  4052. break;
  4053. }
  4054. }
  4055. openSyntax();
  4056. state = dictSyntax.match;
  4057. break;
  4058. case 'Keyword':
  4059. var name = state.name;
  4060. if (token !== null) {
  4061. var keywordName = token.value;
  4062. // drop \0 and \9 hack from keyword name
  4063. if (keywordName.indexOf('\\') !== -1) {
  4064. keywordName = keywordName.replace(/\\[09].*$/, '');
  4065. }
  4066. if (areStringsEqualCaseInsensitive(keywordName, name)) {
  4067. addTokenToMatch();
  4068. state = MATCH$1;
  4069. break;
  4070. }
  4071. }
  4072. state = MISMATCH$1;
  4073. break;
  4074. case 'AtKeyword':
  4075. case 'Function':
  4076. if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
  4077. addTokenToMatch();
  4078. state = MATCH$1;
  4079. break;
  4080. }
  4081. state = MISMATCH$1;
  4082. break;
  4083. case 'Token':
  4084. if (token !== null && token.value === state.value) {
  4085. addTokenToMatch();
  4086. state = MATCH$1;
  4087. break;
  4088. }
  4089. state = MISMATCH$1;
  4090. break;
  4091. case 'Comma':
  4092. if (token !== null && token.type === TYPE$6.Comma) {
  4093. if (isCommaContextStart(matchStack.token)) {
  4094. state = MISMATCH$1;
  4095. } else {
  4096. addTokenToMatch();
  4097. state = isCommaContextEnd(token) ? MISMATCH$1 : MATCH$1;
  4098. }
  4099. } else {
  4100. state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH$1 : MISMATCH$1;
  4101. }
  4102. break;
  4103. case 'String':
  4104. var string = '';
  4105. for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
  4106. string += tokens[lastTokenIndex].value;
  4107. }
  4108. if (areStringsEqualCaseInsensitive(string, state.value)) {
  4109. while (tokenIndex < lastTokenIndex) {
  4110. addTokenToMatch();
  4111. }
  4112. state = MATCH$1;
  4113. } else {
  4114. state = MISMATCH$1;
  4115. }
  4116. break;
  4117. default:
  4118. throw new Error('Unknown node type: ' + state.type);
  4119. }
  4120. }
  4121. totalIterationCount += iterationCount;
  4122. switch (exitReason) {
  4123. case null:
  4124. console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
  4125. exitReason = EXIT_REASON_ITERATION_LIMIT;
  4126. matchStack = null;
  4127. break;
  4128. case EXIT_REASON_MATCH:
  4129. while (syntaxStack !== null) {
  4130. closeSyntax();
  4131. }
  4132. break;
  4133. default:
  4134. matchStack = null;
  4135. }
  4136. return {
  4137. tokens: tokens,
  4138. reason: exitReason,
  4139. iterations: iterationCount,
  4140. match: matchStack,
  4141. longestMatch: longestMatch
  4142. };
  4143. }
  4144. function matchAsList(tokens, matchGraph, syntaxes) {
  4145. var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
  4146. if (matchResult.match !== null) {
  4147. var item = reverseList(matchResult.match).prev;
  4148. matchResult.match = [];
  4149. while (item !== null) {
  4150. switch (item.type) {
  4151. case STUB:
  4152. break;
  4153. case OPEN_SYNTAX:
  4154. case CLOSE_SYNTAX:
  4155. matchResult.match.push({
  4156. type: item.type,
  4157. syntax: item.syntax
  4158. });
  4159. break;
  4160. default:
  4161. matchResult.match.push({
  4162. token: item.token.value,
  4163. node: item.token.node
  4164. });
  4165. break;
  4166. }
  4167. item = item.prev;
  4168. }
  4169. }
  4170. return matchResult;
  4171. }
  4172. function matchAsTree(tokens, matchGraph, syntaxes) {
  4173. var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
  4174. if (matchResult.match === null) {
  4175. return matchResult;
  4176. }
  4177. var item = matchResult.match;
  4178. var host = matchResult.match = {
  4179. syntax: matchGraph.syntax || null,
  4180. match: []
  4181. };
  4182. var hostStack = [host];
  4183. // revert a list and start with 2nd item since 1st is a stub item
  4184. item = reverseList(item).prev;
  4185. // build a tree
  4186. while (item !== null) {
  4187. switch (item.type) {
  4188. case OPEN_SYNTAX:
  4189. host.match.push(host = {
  4190. syntax: item.syntax,
  4191. match: []
  4192. });
  4193. hostStack.push(host);
  4194. break;
  4195. case CLOSE_SYNTAX:
  4196. hostStack.pop();
  4197. host = hostStack[hostStack.length - 1];
  4198. break;
  4199. default:
  4200. host.match.push({
  4201. syntax: item.syntax || null,
  4202. token: item.token.value,
  4203. node: item.token.node
  4204. });
  4205. }
  4206. item = item.prev;
  4207. }
  4208. return matchResult;
  4209. }
  4210. var match = {
  4211. matchAsList: matchAsList,
  4212. matchAsTree: matchAsTree,
  4213. getTotalIterationCount: function() {
  4214. return totalIterationCount;
  4215. }
  4216. };
  4217. function getTrace(node) {
  4218. function shouldPutToTrace(syntax) {
  4219. if (syntax === null) {
  4220. return false;
  4221. }
  4222. return (
  4223. syntax.type === 'Type' ||
  4224. syntax.type === 'Property' ||
  4225. syntax.type === 'Keyword'
  4226. );
  4227. }
  4228. function hasMatch(matchNode) {
  4229. if (Array.isArray(matchNode.match)) {
  4230. // use for-loop for better perfomance
  4231. for (var i = 0; i < matchNode.match.length; i++) {
  4232. if (hasMatch(matchNode.match[i])) {
  4233. if (shouldPutToTrace(matchNode.syntax)) {
  4234. result.unshift(matchNode.syntax);
  4235. }
  4236. return true;
  4237. }
  4238. }
  4239. } else if (matchNode.node === node) {
  4240. result = shouldPutToTrace(matchNode.syntax)
  4241. ? [matchNode.syntax]
  4242. : [];
  4243. return true;
  4244. }
  4245. return false;
  4246. }
  4247. var result = null;
  4248. if (this.matched !== null) {
  4249. hasMatch(this.matched);
  4250. }
  4251. return result;
  4252. }
  4253. function testNode(match, node, fn) {
  4254. var trace = getTrace.call(match, node);
  4255. if (trace === null) {
  4256. return false;
  4257. }
  4258. return trace.some(fn);
  4259. }
  4260. function isType(node, type) {
  4261. return testNode(this, node, function(matchNode) {
  4262. return matchNode.type === 'Type' && matchNode.name === type;
  4263. });
  4264. }
  4265. function isProperty(node, property) {
  4266. return testNode(this, node, function(matchNode) {
  4267. return matchNode.type === 'Property' && matchNode.name === property;
  4268. });
  4269. }
  4270. function isKeyword(node) {
  4271. return testNode(this, node, function(matchNode) {
  4272. return matchNode.type === 'Keyword';
  4273. });
  4274. }
  4275. var trace = {
  4276. getTrace: getTrace,
  4277. isType: isType,
  4278. isProperty: isProperty,
  4279. isKeyword: isKeyword
  4280. };
  4281. function getFirstMatchNode(matchNode) {
  4282. if ('node' in matchNode) {
  4283. return matchNode.node;
  4284. }
  4285. return getFirstMatchNode(matchNode.match[0]);
  4286. }
  4287. function getLastMatchNode(matchNode) {
  4288. if ('node' in matchNode) {
  4289. return matchNode.node;
  4290. }
  4291. return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
  4292. }
  4293. function matchFragments(lexer, ast, match, type, name) {
  4294. function findFragments(matchNode) {
  4295. if (matchNode.syntax !== null &&
  4296. matchNode.syntax.type === type &&
  4297. matchNode.syntax.name === name) {
  4298. var start = getFirstMatchNode(matchNode);
  4299. var end = getLastMatchNode(matchNode);
  4300. lexer.syntax.walk(ast, function(node, item, list) {
  4301. if (node === start) {
  4302. var nodes = new List_1();
  4303. do {
  4304. nodes.appendData(item.data);
  4305. if (item.data === end) {
  4306. break;
  4307. }
  4308. item = item.next;
  4309. } while (item !== null);
  4310. fragments.push({
  4311. parent: list,
  4312. nodes: nodes
  4313. });
  4314. }
  4315. });
  4316. }
  4317. if (Array.isArray(matchNode.match)) {
  4318. matchNode.match.forEach(findFragments);
  4319. }
  4320. }
  4321. var fragments = [];
  4322. if (match.matched !== null) {
  4323. findFragments(match.matched);
  4324. }
  4325. return fragments;
  4326. }
  4327. var search = {
  4328. matchFragments: matchFragments
  4329. };
  4330. var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
  4331. function isValidNumber(value) {
  4332. // Number.isInteger(value) && value >= 0
  4333. return (
  4334. typeof value === 'number' &&
  4335. isFinite(value) &&
  4336. Math.floor(value) === value &&
  4337. value >= 0
  4338. );
  4339. }
  4340. function isValidLocation(loc) {
  4341. return (
  4342. Boolean(loc) &&
  4343. isValidNumber(loc.offset) &&
  4344. isValidNumber(loc.line) &&
  4345. isValidNumber(loc.column)
  4346. );
  4347. }
  4348. function createNodeStructureChecker(type, fields) {
  4349. return function checkNode(node, warn) {
  4350. if (!node || node.constructor !== Object) {
  4351. return warn(node, 'Type of node should be an Object');
  4352. }
  4353. for (var key in node) {
  4354. var valid = true;
  4355. if (hasOwnProperty$2.call(node, key) === false) {
  4356. continue;
  4357. }
  4358. if (key === 'type') {
  4359. if (node.type !== type) {
  4360. warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
  4361. }
  4362. } else if (key === 'loc') {
  4363. if (node.loc === null) {
  4364. continue;
  4365. } else if (node.loc && node.loc.constructor === Object) {
  4366. if (typeof node.loc.source !== 'string') {
  4367. key += '.source';
  4368. } else if (!isValidLocation(node.loc.start)) {
  4369. key += '.start';
  4370. } else if (!isValidLocation(node.loc.end)) {
  4371. key += '.end';
  4372. } else {
  4373. continue;
  4374. }
  4375. }
  4376. valid = false;
  4377. } else if (fields.hasOwnProperty(key)) {
  4378. for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
  4379. var fieldType = fields[key][i];
  4380. switch (fieldType) {
  4381. case String:
  4382. valid = typeof node[key] === 'string';
  4383. break;
  4384. case Boolean:
  4385. valid = typeof node[key] === 'boolean';
  4386. break;
  4387. case null:
  4388. valid = node[key] === null;
  4389. break;
  4390. default:
  4391. if (typeof fieldType === 'string') {
  4392. valid = node[key] && node[key].type === fieldType;
  4393. } else if (Array.isArray(fieldType)) {
  4394. valid = node[key] instanceof List_1;
  4395. }
  4396. }
  4397. }
  4398. } else {
  4399. warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
  4400. }
  4401. if (!valid) {
  4402. warn(node, 'Bad value for `' + type + '.' + key + '`');
  4403. }
  4404. }
  4405. for (var key in fields) {
  4406. if (hasOwnProperty$2.call(fields, key) &&
  4407. hasOwnProperty$2.call(node, key) === false) {
  4408. warn(node, 'Field `' + type + '.' + key + '` is missed');
  4409. }
  4410. }
  4411. };
  4412. }
  4413. function processStructure(name, nodeType) {
  4414. var structure = nodeType.structure;
  4415. var fields = {
  4416. type: String,
  4417. loc: true
  4418. };
  4419. var docs = {
  4420. type: '"' + name + '"'
  4421. };
  4422. for (var key in structure) {
  4423. if (hasOwnProperty$2.call(structure, key) === false) {
  4424. continue;
  4425. }
  4426. var docsTypes = [];
  4427. var fieldTypes = fields[key] = Array.isArray(structure[key])
  4428. ? structure[key].slice()
  4429. : [structure[key]];
  4430. for (var i = 0; i < fieldTypes.length; i++) {
  4431. var fieldType = fieldTypes[i];
  4432. if (fieldType === String || fieldType === Boolean) {
  4433. docsTypes.push(fieldType.name);
  4434. } else if (fieldType === null) {
  4435. docsTypes.push('null');
  4436. } else if (typeof fieldType === 'string') {
  4437. docsTypes.push('<' + fieldType + '>');
  4438. } else if (Array.isArray(fieldType)) {
  4439. docsTypes.push('List'); // TODO: use type enum
  4440. } else {
  4441. throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
  4442. }
  4443. }
  4444. docs[key] = docsTypes.join(' | ');
  4445. }
  4446. return {
  4447. docs: docs,
  4448. check: createNodeStructureChecker(name, fields)
  4449. };
  4450. }
  4451. var structure = {
  4452. getStructureFromConfig: function(config) {
  4453. var structure = {};
  4454. if (config.node) {
  4455. for (var name in config.node) {
  4456. if (hasOwnProperty$2.call(config.node, name)) {
  4457. var nodeType = config.node[name];
  4458. if (nodeType.structure) {
  4459. structure[name] = processStructure(name, nodeType);
  4460. } else {
  4461. throw new Error('Missed `structure` field in `' + name + '` node type definition');
  4462. }
  4463. }
  4464. }
  4465. }
  4466. return structure;
  4467. }
  4468. };
  4469. var SyntaxReferenceError$1 = error.SyntaxReferenceError;
  4470. var MatchError$1 = error.MatchError;
  4471. var buildMatchGraph$1 = matchGraph.buildMatchGraph;
  4472. var matchAsTree$1 = match.matchAsTree;
  4473. var getStructureFromConfig = structure.getStructureFromConfig;
  4474. var cssWideKeywords$1 = buildMatchGraph$1('inherit | initial | unset');
  4475. var cssWideKeywordsWithExpression = buildMatchGraph$1('inherit | initial | unset | <-ms-legacy-expression>');
  4476. function dumpMapSyntax(map, compact, syntaxAsAst) {
  4477. var result = {};
  4478. for (var name in map) {
  4479. if (map[name].syntax) {
  4480. result[name] = syntaxAsAst
  4481. ? map[name].syntax
  4482. : generate_1(map[name].syntax, { compact: compact });
  4483. }
  4484. }
  4485. return result;
  4486. }
  4487. function valueHasVar(tokens) {
  4488. for (var i = 0; i < tokens.length; i++) {
  4489. if (tokens[i].value.toLowerCase() === 'var(') {
  4490. return true;
  4491. }
  4492. }
  4493. return false;
  4494. }
  4495. function buildMatchResult(match, error, iterations) {
  4496. return {
  4497. matched: match,
  4498. iterations: iterations,
  4499. error: error,
  4500. getTrace: trace.getTrace,
  4501. isType: trace.isType,
  4502. isProperty: trace.isProperty,
  4503. isKeyword: trace.isKeyword
  4504. };
  4505. }
  4506. function matchSyntax(lexer, syntax, value, useCommon) {
  4507. var tokens = prepareTokens_1(value, lexer.syntax);
  4508. var result;
  4509. if (valueHasVar(tokens)) {
  4510. return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
  4511. }
  4512. if (useCommon) {
  4513. result = matchAsTree$1(tokens, lexer.valueCommonSyntax, lexer);
  4514. }
  4515. if (!useCommon || !result.match) {
  4516. result = matchAsTree$1(tokens, syntax.match, lexer);
  4517. if (!result.match) {
  4518. return buildMatchResult(
  4519. null,
  4520. new MatchError$1(result.reason, syntax.syntax, value, result),
  4521. result.iterations
  4522. );
  4523. }
  4524. }
  4525. return buildMatchResult(result.match, null, result.iterations);
  4526. }
  4527. var Lexer = function(config, syntax, structure) {
  4528. this.valueCommonSyntax = cssWideKeywords$1;
  4529. this.syntax = syntax;
  4530. this.generic = false;
  4531. this.properties = {};
  4532. this.types = {};
  4533. this.structure = structure || getStructureFromConfig(config);
  4534. if (config) {
  4535. if (config.types) {
  4536. for (var name in config.types) {
  4537. this.addType_(name, config.types[name]);
  4538. }
  4539. }
  4540. if (config.generic) {
  4541. this.generic = true;
  4542. for (var name in generic) {
  4543. this.addType_(name, generic[name]);
  4544. }
  4545. }
  4546. if (config.properties) {
  4547. for (var name in config.properties) {
  4548. this.addProperty_(name, config.properties[name]);
  4549. }
  4550. }
  4551. }
  4552. };
  4553. Lexer.prototype = {
  4554. structure: {},
  4555. checkStructure: function(ast) {
  4556. function collectWarning(node, message) {
  4557. warns.push({
  4558. node: node,
  4559. message: message
  4560. });
  4561. }
  4562. var structure = this.structure;
  4563. var warns = [];
  4564. this.syntax.walk(ast, function(node) {
  4565. if (structure.hasOwnProperty(node.type)) {
  4566. structure[node.type].check(node, collectWarning);
  4567. } else {
  4568. collectWarning(node, 'Unknown node type `' + node.type + '`');
  4569. }
  4570. });
  4571. return warns.length ? warns : false;
  4572. },
  4573. createDescriptor: function(syntax, type, name) {
  4574. var ref = {
  4575. type: type,
  4576. name: name
  4577. };
  4578. var descriptor = {
  4579. type: type,
  4580. name: name,
  4581. syntax: null,
  4582. match: null
  4583. };
  4584. if (typeof syntax === 'function') {
  4585. descriptor.match = buildMatchGraph$1(syntax, ref);
  4586. } else {
  4587. if (typeof syntax === 'string') {
  4588. // lazy parsing on first access
  4589. Object.defineProperty(descriptor, 'syntax', {
  4590. get: function() {
  4591. Object.defineProperty(descriptor, 'syntax', {
  4592. value: parse_1(syntax)
  4593. });
  4594. return descriptor.syntax;
  4595. }
  4596. });
  4597. } else {
  4598. descriptor.syntax = syntax;
  4599. }
  4600. // lazy graph build on first access
  4601. Object.defineProperty(descriptor, 'match', {
  4602. get: function() {
  4603. Object.defineProperty(descriptor, 'match', {
  4604. value: buildMatchGraph$1(descriptor.syntax, ref)
  4605. });
  4606. return descriptor.match;
  4607. }
  4608. });
  4609. }
  4610. return descriptor;
  4611. },
  4612. addProperty_: function(name, syntax) {
  4613. this.properties[name] = this.createDescriptor(syntax, 'Property', name);
  4614. },
  4615. addType_: function(name, syntax) {
  4616. this.types[name] = this.createDescriptor(syntax, 'Type', name);
  4617. if (syntax === generic['-ms-legacy-expression']) {
  4618. this.valueCommonSyntax = cssWideKeywordsWithExpression;
  4619. }
  4620. },
  4621. matchDeclaration: function(node) {
  4622. if (node.type !== 'Declaration') {
  4623. return buildMatchResult(null, new Error('Not a Declaration node'));
  4624. }
  4625. return this.matchProperty(node.property, node.value);
  4626. },
  4627. matchProperty: function(propertyName, value) {
  4628. var property = names.property(propertyName);
  4629. // don't match syntax for a custom property
  4630. if (property.custom) {
  4631. return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
  4632. }
  4633. var propertySyntax = property.vendor
  4634. ? this.getProperty(property.name) || this.getProperty(property.basename)
  4635. : this.getProperty(property.name);
  4636. if (!propertySyntax) {
  4637. return buildMatchResult(null, new SyntaxReferenceError$1('Unknown property', propertyName));
  4638. }
  4639. return matchSyntax(this, propertySyntax, value, true);
  4640. },
  4641. matchType: function(typeName, value) {
  4642. var typeSyntax = this.getType(typeName);
  4643. if (!typeSyntax) {
  4644. return buildMatchResult(null, new SyntaxReferenceError$1('Unknown type', typeName));
  4645. }
  4646. return matchSyntax(this, typeSyntax, value, false);
  4647. },
  4648. match: function(syntax, value) {
  4649. if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
  4650. return buildMatchResult(null, new SyntaxReferenceError$1('Bad syntax'));
  4651. }
  4652. if (typeof syntax === 'string' || !syntax.match) {
  4653. syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
  4654. }
  4655. return matchSyntax(this, syntax, value, false);
  4656. },
  4657. findValueFragments: function(propertyName, value, type, name) {
  4658. return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
  4659. },
  4660. findDeclarationValueFragments: function(declaration, type, name) {
  4661. return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
  4662. },
  4663. findAllFragments: function(ast, type, name) {
  4664. var result = [];
  4665. this.syntax.walk(ast, {
  4666. visit: 'Declaration',
  4667. enter: function(declaration) {
  4668. result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
  4669. }.bind(this)
  4670. });
  4671. return result;
  4672. },
  4673. getProperty: function(name) {
  4674. return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
  4675. },
  4676. getType: function(name) {
  4677. return this.types.hasOwnProperty(name) ? this.types[name] : null;
  4678. },
  4679. validate: function() {
  4680. function validate(syntax, name, broken, descriptor) {
  4681. if (broken.hasOwnProperty(name)) {
  4682. return broken[name];
  4683. }
  4684. broken[name] = false;
  4685. if (descriptor.syntax !== null) {
  4686. walk(descriptor.syntax, function(node) {
  4687. if (node.type !== 'Type' && node.type !== 'Property') {
  4688. return;
  4689. }
  4690. var map = node.type === 'Type' ? syntax.types : syntax.properties;
  4691. var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
  4692. if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
  4693. broken[name] = true;
  4694. }
  4695. }, this);
  4696. }
  4697. }
  4698. var brokenTypes = {};
  4699. var brokenProperties = {};
  4700. for (var key in this.types) {
  4701. validate(this, key, brokenTypes, this.types[key]);
  4702. }
  4703. for (var key in this.properties) {
  4704. validate(this, key, brokenProperties, this.properties[key]);
  4705. }
  4706. brokenTypes = Object.keys(brokenTypes).filter(function(name) {
  4707. return brokenTypes[name];
  4708. });
  4709. brokenProperties = Object.keys(brokenProperties).filter(function(name) {
  4710. return brokenProperties[name];
  4711. });
  4712. if (brokenTypes.length || brokenProperties.length) {
  4713. return {
  4714. types: brokenTypes,
  4715. properties: brokenProperties
  4716. };
  4717. }
  4718. return null;
  4719. },
  4720. dump: function(syntaxAsAst, pretty) {
  4721. return {
  4722. generic: this.generic,
  4723. types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
  4724. properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst)
  4725. };
  4726. },
  4727. toString: function() {
  4728. return JSON.stringify(this.dump());
  4729. }
  4730. };
  4731. var Lexer_1 = Lexer;
  4732. var definitionSyntax = {
  4733. SyntaxError: _SyntaxError$1,
  4734. parse: parse_1,
  4735. generate: generate_1,
  4736. walk: walk
  4737. };
  4738. var isBOM$2 = tokenizer.isBOM;
  4739. var N$3 = 10;
  4740. var F$2 = 12;
  4741. var R$2 = 13;
  4742. function computeLinesAndColumns(host, source) {
  4743. var sourceLength = source.length;
  4744. var lines = adoptBuffer(host.lines, sourceLength); // +1
  4745. var line = host.startLine;
  4746. var columns = adoptBuffer(host.columns, sourceLength);
  4747. var column = host.startColumn;
  4748. var startOffset = source.length > 0 ? isBOM$2(source.charCodeAt(0)) : 0;
  4749. for (var i = startOffset; i < sourceLength; i++) { // -1
  4750. var code = source.charCodeAt(i);
  4751. lines[i] = line;
  4752. columns[i] = column++;
  4753. if (code === N$3 || code === R$2 || code === F$2) {
  4754. if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$3) {
  4755. i++;
  4756. lines[i] = line;
  4757. columns[i] = column;
  4758. }
  4759. line++;
  4760. column = 1;
  4761. }
  4762. }
  4763. lines[i] = line;
  4764. columns[i] = column;
  4765. host.lines = lines;
  4766. host.columns = columns;
  4767. }
  4768. var OffsetToLocation = function() {
  4769. this.lines = null;
  4770. this.columns = null;
  4771. this.linesAndColumnsComputed = false;
  4772. };
  4773. OffsetToLocation.prototype = {
  4774. setSource: function(source, startOffset, startLine, startColumn) {
  4775. this.source = source;
  4776. this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
  4777. this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
  4778. this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
  4779. this.linesAndColumnsComputed = false;
  4780. },
  4781. ensureLinesAndColumnsComputed: function() {
  4782. if (!this.linesAndColumnsComputed) {
  4783. computeLinesAndColumns(this, this.source);
  4784. this.linesAndColumnsComputed = true;
  4785. }
  4786. },
  4787. getLocation: function(offset, filename) {
  4788. this.ensureLinesAndColumnsComputed();
  4789. return {
  4790. source: filename,
  4791. offset: this.startOffset + offset,
  4792. line: this.lines[offset],
  4793. column: this.columns[offset]
  4794. };
  4795. },
  4796. getLocationRange: function(start, end, filename) {
  4797. this.ensureLinesAndColumnsComputed();
  4798. return {
  4799. source: filename,
  4800. start: {
  4801. offset: this.startOffset + start,
  4802. line: this.lines[start],
  4803. column: this.columns[start]
  4804. },
  4805. end: {
  4806. offset: this.startOffset + end,
  4807. line: this.lines[end],
  4808. column: this.columns[end]
  4809. }
  4810. };
  4811. }
  4812. };
  4813. var OffsetToLocation_1 = OffsetToLocation;
  4814. var TYPE$7 = tokenizer.TYPE;
  4815. var WHITESPACE$2 = TYPE$7.WhiteSpace;
  4816. var COMMENT$2 = TYPE$7.Comment;
  4817. var sequence = function readSequence(recognizer) {
  4818. var children = this.createList();
  4819. var child = null;
  4820. var context = {
  4821. recognizer: recognizer,
  4822. space: null,
  4823. ignoreWS: false,
  4824. ignoreWSAfter: false
  4825. };
  4826. this.scanner.skipSC();
  4827. while (!this.scanner.eof) {
  4828. switch (this.scanner.tokenType) {
  4829. case COMMENT$2:
  4830. this.scanner.next();
  4831. continue;
  4832. case WHITESPACE$2:
  4833. if (context.ignoreWS) {
  4834. this.scanner.next();
  4835. } else {
  4836. context.space = this.WhiteSpace();
  4837. }
  4838. continue;
  4839. }
  4840. child = recognizer.getNode.call(this, context);
  4841. if (child === undefined) {
  4842. break;
  4843. }
  4844. if (context.space !== null) {
  4845. children.push(context.space);
  4846. context.space = null;
  4847. }
  4848. children.push(child);
  4849. if (context.ignoreWSAfter) {
  4850. context.ignoreWSAfter = false;
  4851. context.ignoreWS = true;
  4852. } else {
  4853. context.ignoreWS = false;
  4854. }
  4855. }
  4856. return children;
  4857. };
  4858. var findWhiteSpaceStart$1 = utils.findWhiteSpaceStart;
  4859. var noop$2 = function() {};
  4860. var TYPE$8 = _const.TYPE;
  4861. var NAME$2 = _const.NAME;
  4862. var WHITESPACE$3 = TYPE$8.WhiteSpace;
  4863. var IDENT$2 = TYPE$8.Ident;
  4864. var FUNCTION = TYPE$8.Function;
  4865. var URL = TYPE$8.Url;
  4866. var HASH = TYPE$8.Hash;
  4867. var PERCENTAGE = TYPE$8.Percentage;
  4868. var NUMBER$2 = TYPE$8.Number;
  4869. var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
  4870. var NULL = 0;
  4871. function createParseContext(name) {
  4872. return function() {
  4873. return this[name]();
  4874. };
  4875. }
  4876. function processConfig(config) {
  4877. var parserConfig = {
  4878. context: {},
  4879. scope: {},
  4880. atrule: {},
  4881. pseudo: {}
  4882. };
  4883. if (config.parseContext) {
  4884. for (var name in config.parseContext) {
  4885. switch (typeof config.parseContext[name]) {
  4886. case 'function':
  4887. parserConfig.context[name] = config.parseContext[name];
  4888. break;
  4889. case 'string':
  4890. parserConfig.context[name] = createParseContext(config.parseContext[name]);
  4891. break;
  4892. }
  4893. }
  4894. }
  4895. if (config.scope) {
  4896. for (var name in config.scope) {
  4897. parserConfig.scope[name] = config.scope[name];
  4898. }
  4899. }
  4900. if (config.atrule) {
  4901. for (var name in config.atrule) {
  4902. var atrule = config.atrule[name];
  4903. if (atrule.parse) {
  4904. parserConfig.atrule[name] = atrule.parse;
  4905. }
  4906. }
  4907. }
  4908. if (config.pseudo) {
  4909. for (var name in config.pseudo) {
  4910. var pseudo = config.pseudo[name];
  4911. if (pseudo.parse) {
  4912. parserConfig.pseudo[name] = pseudo.parse;
  4913. }
  4914. }
  4915. }
  4916. if (config.node) {
  4917. for (var name in config.node) {
  4918. parserConfig[name] = config.node[name].parse;
  4919. }
  4920. }
  4921. return parserConfig;
  4922. }
  4923. var create = function createParser(config) {
  4924. var parser = {
  4925. scanner: new TokenStream_1(),
  4926. locationMap: new OffsetToLocation_1(),
  4927. filename: '<unknown>',
  4928. needPositions: false,
  4929. onParseError: noop$2,
  4930. onParseErrorThrow: false,
  4931. parseAtrulePrelude: true,
  4932. parseRulePrelude: true,
  4933. parseValue: true,
  4934. parseCustomProperty: false,
  4935. readSequence: sequence,
  4936. createList: function() {
  4937. return new List_1();
  4938. },
  4939. createSingleNodeList: function(node) {
  4940. return new List_1().appendData(node);
  4941. },
  4942. getFirstListNode: function(list) {
  4943. return list && list.first();
  4944. },
  4945. getLastListNode: function(list) {
  4946. return list.last();
  4947. },
  4948. parseWithFallback: function(consumer, fallback) {
  4949. var startToken = this.scanner.tokenIndex;
  4950. try {
  4951. return consumer.call(this);
  4952. } catch (e) {
  4953. if (this.onParseErrorThrow) {
  4954. throw e;
  4955. }
  4956. var fallbackNode = fallback.call(this, startToken);
  4957. this.onParseErrorThrow = true;
  4958. this.onParseError(e, fallbackNode);
  4959. this.onParseErrorThrow = false;
  4960. return fallbackNode;
  4961. }
  4962. },
  4963. lookupNonWSType: function(offset) {
  4964. do {
  4965. var type = this.scanner.lookupType(offset++);
  4966. if (type !== WHITESPACE$3) {
  4967. return type;
  4968. }
  4969. } while (type !== NULL);
  4970. return NULL;
  4971. },
  4972. eat: function(tokenType) {
  4973. if (this.scanner.tokenType !== tokenType) {
  4974. var offset = this.scanner.tokenStart;
  4975. var message = NAME$2[tokenType] + ' is expected';
  4976. // tweak message and offset
  4977. switch (tokenType) {
  4978. case IDENT$2:
  4979. // when identifier is expected but there is a function or url
  4980. if (this.scanner.tokenType === FUNCTION || this.scanner.tokenType === URL) {
  4981. offset = this.scanner.tokenEnd - 1;
  4982. message = 'Identifier is expected but function found';
  4983. } else {
  4984. message = 'Identifier is expected';
  4985. }
  4986. break;
  4987. case HASH:
  4988. if (this.scanner.isDelim(NUMBERSIGN$1)) {
  4989. this.scanner.next();
  4990. offset++;
  4991. message = 'Name is expected';
  4992. }
  4993. break;
  4994. case PERCENTAGE:
  4995. if (this.scanner.tokenType === NUMBER$2) {
  4996. offset = this.scanner.tokenEnd;
  4997. message = 'Percent sign is expected';
  4998. }
  4999. break;
  5000. default:
  5001. // when test type is part of another token show error for current position + 1
  5002. // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
  5003. if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
  5004. offset = offset + 1;
  5005. }
  5006. }
  5007. this.error(message, offset);
  5008. }
  5009. this.scanner.next();
  5010. },
  5011. consume: function(tokenType) {
  5012. var value = this.scanner.getTokenValue();
  5013. this.eat(tokenType);
  5014. return value;
  5015. },
  5016. consumeFunctionName: function() {
  5017. var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
  5018. this.eat(FUNCTION);
  5019. return name;
  5020. },
  5021. getLocation: function(start, end) {
  5022. if (this.needPositions) {
  5023. return this.locationMap.getLocationRange(
  5024. start,
  5025. end,
  5026. this.filename
  5027. );
  5028. }
  5029. return null;
  5030. },
  5031. getLocationFromList: function(list) {
  5032. if (this.needPositions) {
  5033. var head = this.getFirstListNode(list);
  5034. var tail = this.getLastListNode(list);
  5035. return this.locationMap.getLocationRange(
  5036. head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
  5037. tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
  5038. this.filename
  5039. );
  5040. }
  5041. return null;
  5042. },
  5043. error: function(message, offset) {
  5044. var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
  5045. ? this.locationMap.getLocation(offset)
  5046. : this.scanner.eof
  5047. ? this.locationMap.getLocation(findWhiteSpaceStart$1(this.scanner.source, this.scanner.source.length - 1))
  5048. : this.locationMap.getLocation(this.scanner.tokenStart);
  5049. throw new _SyntaxError(
  5050. message || 'Unexpected input',
  5051. this.scanner.source,
  5052. location.offset,
  5053. location.line,
  5054. location.column
  5055. );
  5056. }
  5057. };
  5058. config = processConfig(config || {});
  5059. for (var key in config) {
  5060. parser[key] = config[key];
  5061. }
  5062. return function(source, options) {
  5063. options = options || {};
  5064. var context = options.context || 'default';
  5065. var ast;
  5066. tokenizer(source, parser.scanner);
  5067. parser.locationMap.setSource(
  5068. source,
  5069. options.offset,
  5070. options.line,
  5071. options.column
  5072. );
  5073. parser.filename = options.filename || '<unknown>';
  5074. parser.needPositions = Boolean(options.positions);
  5075. parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$2;
  5076. parser.onParseErrorThrow = false;
  5077. parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
  5078. parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
  5079. parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
  5080. parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
  5081. if (!parser.context.hasOwnProperty(context)) {
  5082. throw new Error('Unknown context `' + context + '`');
  5083. }
  5084. ast = parser.context[context].call(parser, options);
  5085. if (!parser.scanner.eof) {
  5086. parser.error();
  5087. }
  5088. return ast;
  5089. };
  5090. };
  5091. /* -*- Mode: js; js-indent-level: 2; -*- */
  5092. /*
  5093. * Copyright 2011 Mozilla Foundation and contributors
  5094. * Licensed under the New BSD license. See LICENSE or:
  5095. * http://opensource.org/licenses/BSD-3-Clause
  5096. */
  5097. var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
  5098. /**
  5099. * Encode an integer in the range of 0 to 63 to a single base 64 digit.
  5100. */
  5101. var encode = function (number) {
  5102. if (0 <= number && number < intToCharMap.length) {
  5103. return intToCharMap[number];
  5104. }
  5105. throw new TypeError("Must be between 0 and 63: " + number);
  5106. };
  5107. /**
  5108. * Decode a single base 64 character code digit to an integer. Returns -1 on
  5109. * failure.
  5110. */
  5111. var decode = function (charCode) {
  5112. var bigA = 65; // 'A'
  5113. var bigZ = 90; // 'Z'
  5114. var littleA = 97; // 'a'
  5115. var littleZ = 122; // 'z'
  5116. var zero = 48; // '0'
  5117. var nine = 57; // '9'
  5118. var plus = 43; // '+'
  5119. var slash = 47; // '/'
  5120. var littleOffset = 26;
  5121. var numberOffset = 52;
  5122. // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  5123. if (bigA <= charCode && charCode <= bigZ) {
  5124. return (charCode - bigA);
  5125. }
  5126. // 26 - 51: abcdefghijklmnopqrstuvwxyz
  5127. if (littleA <= charCode && charCode <= littleZ) {
  5128. return (charCode - littleA + littleOffset);
  5129. }
  5130. // 52 - 61: 0123456789
  5131. if (zero <= charCode && charCode <= nine) {
  5132. return (charCode - zero + numberOffset);
  5133. }
  5134. // 62: +
  5135. if (charCode == plus) {
  5136. return 62;
  5137. }
  5138. // 63: /
  5139. if (charCode == slash) {
  5140. return 63;
  5141. }
  5142. // Invalid base64 digit.
  5143. return -1;
  5144. };
  5145. var base64 = {
  5146. encode: encode,
  5147. decode: decode
  5148. };
  5149. /* -*- Mode: js; js-indent-level: 2; -*- */
  5150. /*
  5151. * Copyright 2011 Mozilla Foundation and contributors
  5152. * Licensed under the New BSD license. See LICENSE or:
  5153. * http://opensource.org/licenses/BSD-3-Clause
  5154. *
  5155. * Based on the Base 64 VLQ implementation in Closure Compiler:
  5156. * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
  5157. *
  5158. * Copyright 2011 The Closure Compiler Authors. All rights reserved.
  5159. * Redistribution and use in source and binary forms, with or without
  5160. * modification, are permitted provided that the following conditions are
  5161. * met:
  5162. *
  5163. * * Redistributions of source code must retain the above copyright
  5164. * notice, this list of conditions and the following disclaimer.
  5165. * * Redistributions in binary form must reproduce the above
  5166. * copyright notice, this list of conditions and the following
  5167. * disclaimer in the documentation and/or other materials provided
  5168. * with the distribution.
  5169. * * Neither the name of Google Inc. nor the names of its
  5170. * contributors may be used to endorse or promote products derived
  5171. * from this software without specific prior written permission.
  5172. *
  5173. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  5174. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5175. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  5176. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  5177. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  5178. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  5179. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  5180. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  5181. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5182. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  5183. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5184. */
  5185. // A single base 64 digit can contain 6 bits of data. For the base 64 variable
  5186. // length quantities we use in the source map spec, the first bit is the sign,
  5187. // the next four bits are the actual value, and the 6th bit is the
  5188. // continuation bit. The continuation bit tells us whether there are more
  5189. // digits in this value following this digit.
  5190. //
  5191. // Continuation
  5192. // | Sign
  5193. // | |
  5194. // V V
  5195. // 101011
  5196. var VLQ_BASE_SHIFT = 5;
  5197. // binary: 100000
  5198. var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
  5199. // binary: 011111
  5200. var VLQ_BASE_MASK = VLQ_BASE - 1;
  5201. // binary: 100000
  5202. var VLQ_CONTINUATION_BIT = VLQ_BASE;
  5203. /**
  5204. * Converts from a two-complement value to a value where the sign bit is
  5205. * placed in the least significant bit. For example, as decimals:
  5206. * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
  5207. * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
  5208. */
  5209. function toVLQSigned(aValue) {
  5210. return aValue < 0
  5211. ? ((-aValue) << 1) + 1
  5212. : (aValue << 1) + 0;
  5213. }
  5214. /**
  5215. * Converts to a two-complement value from a value where the sign bit is
  5216. * placed in the least significant bit. For example, as decimals:
  5217. * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
  5218. * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
  5219. */
  5220. function fromVLQSigned(aValue) {
  5221. var isNegative = (aValue & 1) === 1;
  5222. var shifted = aValue >> 1;
  5223. return isNegative
  5224. ? -shifted
  5225. : shifted;
  5226. }
  5227. /**
  5228. * Returns the base 64 VLQ encoded value.
  5229. */
  5230. var encode$1 = function base64VLQ_encode(aValue) {
  5231. var encoded = "";
  5232. var digit;
  5233. var vlq = toVLQSigned(aValue);
  5234. do {
  5235. digit = vlq & VLQ_BASE_MASK;
  5236. vlq >>>= VLQ_BASE_SHIFT;
  5237. if (vlq > 0) {
  5238. // There are still more digits in this value, so we must make sure the
  5239. // continuation bit is marked.
  5240. digit |= VLQ_CONTINUATION_BIT;
  5241. }
  5242. encoded += base64.encode(digit);
  5243. } while (vlq > 0);
  5244. return encoded;
  5245. };
  5246. /**
  5247. * Decodes the next base 64 VLQ value from the given string and returns the
  5248. * value and the rest of the string via the out parameter.
  5249. */
  5250. var decode$1 = function base64VLQ_decode(aStr, aIndex, aOutParam) {
  5251. var strLen = aStr.length;
  5252. var result = 0;
  5253. var shift = 0;
  5254. var continuation, digit;
  5255. do {
  5256. if (aIndex >= strLen) {
  5257. throw new Error("Expected more digits in base 64 VLQ value.");
  5258. }
  5259. digit = base64.decode(aStr.charCodeAt(aIndex++));
  5260. if (digit === -1) {
  5261. throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
  5262. }
  5263. continuation = !!(digit & VLQ_CONTINUATION_BIT);
  5264. digit &= VLQ_BASE_MASK;
  5265. result = result + (digit << shift);
  5266. shift += VLQ_BASE_SHIFT;
  5267. } while (continuation);
  5268. aOutParam.value = fromVLQSigned(result);
  5269. aOutParam.rest = aIndex;
  5270. };
  5271. var base64Vlq = {
  5272. encode: encode$1,
  5273. decode: decode$1
  5274. };
  5275. function createCommonjsModule(fn, module) {
  5276. return module = { exports: {} }, fn(module, module.exports), module.exports;
  5277. }
  5278. function getCjsExportFromNamespace (n) {
  5279. return n && n['default'] || n;
  5280. }
  5281. var util = createCommonjsModule(function (module, exports) {
  5282. /* -*- Mode: js; js-indent-level: 2; -*- */
  5283. /*
  5284. * Copyright 2011 Mozilla Foundation and contributors
  5285. * Licensed under the New BSD license. See LICENSE or:
  5286. * http://opensource.org/licenses/BSD-3-Clause
  5287. */
  5288. /**
  5289. * This is a helper function for getting values from parameter/options
  5290. * objects.
  5291. *
  5292. * @param args The object we are extracting values from
  5293. * @param name The name of the property we are getting.
  5294. * @param defaultValue An optional value to return if the property is missing
  5295. * from the object. If this is not specified and the property is missing, an
  5296. * error will be thrown.
  5297. */
  5298. function getArg(aArgs, aName, aDefaultValue) {
  5299. if (aName in aArgs) {
  5300. return aArgs[aName];
  5301. } else if (arguments.length === 3) {
  5302. return aDefaultValue;
  5303. } else {
  5304. throw new Error('"' + aName + '" is a required argument.');
  5305. }
  5306. }
  5307. exports.getArg = getArg;
  5308. var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
  5309. var dataUrlRegexp = /^data:.+\,.+$/;
  5310. function urlParse(aUrl) {
  5311. var match = aUrl.match(urlRegexp);
  5312. if (!match) {
  5313. return null;
  5314. }
  5315. return {
  5316. scheme: match[1],
  5317. auth: match[2],
  5318. host: match[3],
  5319. port: match[4],
  5320. path: match[5]
  5321. };
  5322. }
  5323. exports.urlParse = urlParse;
  5324. function urlGenerate(aParsedUrl) {
  5325. var url = '';
  5326. if (aParsedUrl.scheme) {
  5327. url += aParsedUrl.scheme + ':';
  5328. }
  5329. url += '//';
  5330. if (aParsedUrl.auth) {
  5331. url += aParsedUrl.auth + '@';
  5332. }
  5333. if (aParsedUrl.host) {
  5334. url += aParsedUrl.host;
  5335. }
  5336. if (aParsedUrl.port) {
  5337. url += ":" + aParsedUrl.port;
  5338. }
  5339. if (aParsedUrl.path) {
  5340. url += aParsedUrl.path;
  5341. }
  5342. return url;
  5343. }
  5344. exports.urlGenerate = urlGenerate;
  5345. /**
  5346. * Normalizes a path, or the path portion of a URL:
  5347. *
  5348. * - Replaces consecutive slashes with one slash.
  5349. * - Removes unnecessary '.' parts.
  5350. * - Removes unnecessary '<dir>/..' parts.
  5351. *
  5352. * Based on code in the Node.js 'path' core module.
  5353. *
  5354. * @param aPath The path or url to normalize.
  5355. */
  5356. function normalize(aPath) {
  5357. var path = aPath;
  5358. var url = urlParse(aPath);
  5359. if (url) {
  5360. if (!url.path) {
  5361. return aPath;
  5362. }
  5363. path = url.path;
  5364. }
  5365. var isAbsolute = exports.isAbsolute(path);
  5366. var parts = path.split(/\/+/);
  5367. for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
  5368. part = parts[i];
  5369. if (part === '.') {
  5370. parts.splice(i, 1);
  5371. } else if (part === '..') {
  5372. up++;
  5373. } else if (up > 0) {
  5374. if (part === '') {
  5375. // The first part is blank if the path is absolute. Trying to go
  5376. // above the root is a no-op. Therefore we can remove all '..' parts
  5377. // directly after the root.
  5378. parts.splice(i + 1, up);
  5379. up = 0;
  5380. } else {
  5381. parts.splice(i, 2);
  5382. up--;
  5383. }
  5384. }
  5385. }
  5386. path = parts.join('/');
  5387. if (path === '') {
  5388. path = isAbsolute ? '/' : '.';
  5389. }
  5390. if (url) {
  5391. url.path = path;
  5392. return urlGenerate(url);
  5393. }
  5394. return path;
  5395. }
  5396. exports.normalize = normalize;
  5397. /**
  5398. * Joins two paths/URLs.
  5399. *
  5400. * @param aRoot The root path or URL.
  5401. * @param aPath The path or URL to be joined with the root.
  5402. *
  5403. * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
  5404. * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
  5405. * first.
  5406. * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
  5407. * is updated with the result and aRoot is returned. Otherwise the result
  5408. * is returned.
  5409. * - If aPath is absolute, the result is aPath.
  5410. * - Otherwise the two paths are joined with a slash.
  5411. * - Joining for example 'http://' and 'www.example.com' is also supported.
  5412. */
  5413. function join(aRoot, aPath) {
  5414. if (aRoot === "") {
  5415. aRoot = ".";
  5416. }
  5417. if (aPath === "") {
  5418. aPath = ".";
  5419. }
  5420. var aPathUrl = urlParse(aPath);
  5421. var aRootUrl = urlParse(aRoot);
  5422. if (aRootUrl) {
  5423. aRoot = aRootUrl.path || '/';
  5424. }
  5425. // `join(foo, '//www.example.org')`
  5426. if (aPathUrl && !aPathUrl.scheme) {
  5427. if (aRootUrl) {
  5428. aPathUrl.scheme = aRootUrl.scheme;
  5429. }
  5430. return urlGenerate(aPathUrl);
  5431. }
  5432. if (aPathUrl || aPath.match(dataUrlRegexp)) {
  5433. return aPath;
  5434. }
  5435. // `join('http://', 'www.example.com')`
  5436. if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
  5437. aRootUrl.host = aPath;
  5438. return urlGenerate(aRootUrl);
  5439. }
  5440. var joined = aPath.charAt(0) === '/'
  5441. ? aPath
  5442. : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
  5443. if (aRootUrl) {
  5444. aRootUrl.path = joined;
  5445. return urlGenerate(aRootUrl);
  5446. }
  5447. return joined;
  5448. }
  5449. exports.join = join;
  5450. exports.isAbsolute = function (aPath) {
  5451. return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
  5452. };
  5453. /**
  5454. * Make a path relative to a URL or another path.
  5455. *
  5456. * @param aRoot The root path or URL.
  5457. * @param aPath The path or URL to be made relative to aRoot.
  5458. */
  5459. function relative(aRoot, aPath) {
  5460. if (aRoot === "") {
  5461. aRoot = ".";
  5462. }
  5463. aRoot = aRoot.replace(/\/$/, '');
  5464. // It is possible for the path to be above the root. In this case, simply
  5465. // checking whether the root is a prefix of the path won't work. Instead, we
  5466. // need to remove components from the root one by one, until either we find
  5467. // a prefix that fits, or we run out of components to remove.
  5468. var level = 0;
  5469. while (aPath.indexOf(aRoot + '/') !== 0) {
  5470. var index = aRoot.lastIndexOf("/");
  5471. if (index < 0) {
  5472. return aPath;
  5473. }
  5474. // If the only part of the root that is left is the scheme (i.e. http://,
  5475. // file:///, etc.), one or more slashes (/), or simply nothing at all, we
  5476. // have exhausted all components, so the path is not relative to the root.
  5477. aRoot = aRoot.slice(0, index);
  5478. if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
  5479. return aPath;
  5480. }
  5481. ++level;
  5482. }
  5483. // Make sure we add a "../" for each component we removed from the root.
  5484. return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
  5485. }
  5486. exports.relative = relative;
  5487. var supportsNullProto = (function () {
  5488. var obj = Object.create(null);
  5489. return !('__proto__' in obj);
  5490. }());
  5491. function identity (s) {
  5492. return s;
  5493. }
  5494. /**
  5495. * Because behavior goes wacky when you set `__proto__` on objects, we
  5496. * have to prefix all the strings in our set with an arbitrary character.
  5497. *
  5498. * See https://github.com/mozilla/source-map/pull/31 and
  5499. * https://github.com/mozilla/source-map/issues/30
  5500. *
  5501. * @param String aStr
  5502. */
  5503. function toSetString(aStr) {
  5504. if (isProtoString(aStr)) {
  5505. return '$' + aStr;
  5506. }
  5507. return aStr;
  5508. }
  5509. exports.toSetString = supportsNullProto ? identity : toSetString;
  5510. function fromSetString(aStr) {
  5511. if (isProtoString(aStr)) {
  5512. return aStr.slice(1);
  5513. }
  5514. return aStr;
  5515. }
  5516. exports.fromSetString = supportsNullProto ? identity : fromSetString;
  5517. function isProtoString(s) {
  5518. if (!s) {
  5519. return false;
  5520. }
  5521. var length = s.length;
  5522. if (length < 9 /* "__proto__".length */) {
  5523. return false;
  5524. }
  5525. if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
  5526. s.charCodeAt(length - 2) !== 95 /* '_' */ ||
  5527. s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
  5528. s.charCodeAt(length - 4) !== 116 /* 't' */ ||
  5529. s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
  5530. s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
  5531. s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
  5532. s.charCodeAt(length - 8) !== 95 /* '_' */ ||
  5533. s.charCodeAt(length - 9) !== 95 /* '_' */) {
  5534. return false;
  5535. }
  5536. for (var i = length - 10; i >= 0; i--) {
  5537. if (s.charCodeAt(i) !== 36 /* '$' */) {
  5538. return false;
  5539. }
  5540. }
  5541. return true;
  5542. }
  5543. /**
  5544. * Comparator between two mappings where the original positions are compared.
  5545. *
  5546. * Optionally pass in `true` as `onlyCompareGenerated` to consider two
  5547. * mappings with the same original source/line/column, but different generated
  5548. * line and column the same. Useful when searching for a mapping with a
  5549. * stubbed out mapping.
  5550. */
  5551. function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
  5552. var cmp = strcmp(mappingA.source, mappingB.source);
  5553. if (cmp !== 0) {
  5554. return cmp;
  5555. }
  5556. cmp = mappingA.originalLine - mappingB.originalLine;
  5557. if (cmp !== 0) {
  5558. return cmp;
  5559. }
  5560. cmp = mappingA.originalColumn - mappingB.originalColumn;
  5561. if (cmp !== 0 || onlyCompareOriginal) {
  5562. return cmp;
  5563. }
  5564. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  5565. if (cmp !== 0) {
  5566. return cmp;
  5567. }
  5568. cmp = mappingA.generatedLine - mappingB.generatedLine;
  5569. if (cmp !== 0) {
  5570. return cmp;
  5571. }
  5572. return strcmp(mappingA.name, mappingB.name);
  5573. }
  5574. exports.compareByOriginalPositions = compareByOriginalPositions;
  5575. /**
  5576. * Comparator between two mappings with deflated source and name indices where
  5577. * the generated positions are compared.
  5578. *
  5579. * Optionally pass in `true` as `onlyCompareGenerated` to consider two
  5580. * mappings with the same generated line and column, but different
  5581. * source/name/original line and column the same. Useful when searching for a
  5582. * mapping with a stubbed out mapping.
  5583. */
  5584. function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
  5585. var cmp = mappingA.generatedLine - mappingB.generatedLine;
  5586. if (cmp !== 0) {
  5587. return cmp;
  5588. }
  5589. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  5590. if (cmp !== 0 || onlyCompareGenerated) {
  5591. return cmp;
  5592. }
  5593. cmp = strcmp(mappingA.source, mappingB.source);
  5594. if (cmp !== 0) {
  5595. return cmp;
  5596. }
  5597. cmp = mappingA.originalLine - mappingB.originalLine;
  5598. if (cmp !== 0) {
  5599. return cmp;
  5600. }
  5601. cmp = mappingA.originalColumn - mappingB.originalColumn;
  5602. if (cmp !== 0) {
  5603. return cmp;
  5604. }
  5605. return strcmp(mappingA.name, mappingB.name);
  5606. }
  5607. exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
  5608. function strcmp(aStr1, aStr2) {
  5609. if (aStr1 === aStr2) {
  5610. return 0;
  5611. }
  5612. if (aStr1 === null) {
  5613. return 1; // aStr2 !== null
  5614. }
  5615. if (aStr2 === null) {
  5616. return -1; // aStr1 !== null
  5617. }
  5618. if (aStr1 > aStr2) {
  5619. return 1;
  5620. }
  5621. return -1;
  5622. }
  5623. /**
  5624. * Comparator between two mappings with inflated source and name strings where
  5625. * the generated positions are compared.
  5626. */
  5627. function compareByGeneratedPositionsInflated(mappingA, mappingB) {
  5628. var cmp = mappingA.generatedLine - mappingB.generatedLine;
  5629. if (cmp !== 0) {
  5630. return cmp;
  5631. }
  5632. cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  5633. if (cmp !== 0) {
  5634. return cmp;
  5635. }
  5636. cmp = strcmp(mappingA.source, mappingB.source);
  5637. if (cmp !== 0) {
  5638. return cmp;
  5639. }
  5640. cmp = mappingA.originalLine - mappingB.originalLine;
  5641. if (cmp !== 0) {
  5642. return cmp;
  5643. }
  5644. cmp = mappingA.originalColumn - mappingB.originalColumn;
  5645. if (cmp !== 0) {
  5646. return cmp;
  5647. }
  5648. return strcmp(mappingA.name, mappingB.name);
  5649. }
  5650. exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
  5651. /**
  5652. * Strip any JSON XSSI avoidance prefix from the string (as documented
  5653. * in the source maps specification), and then parse the string as
  5654. * JSON.
  5655. */
  5656. function parseSourceMapInput(str) {
  5657. return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
  5658. }
  5659. exports.parseSourceMapInput = parseSourceMapInput;
  5660. /**
  5661. * Compute the URL of a source given the the source root, the source's
  5662. * URL, and the source map's URL.
  5663. */
  5664. function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
  5665. sourceURL = sourceURL || '';
  5666. if (sourceRoot) {
  5667. // This follows what Chrome does.
  5668. if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
  5669. sourceRoot += '/';
  5670. }
  5671. // The spec says:
  5672. // Line 4: An optional source root, useful for relocating source
  5673. // files on a server or removing repeated values in the
  5674. // “sources” entry. This value is prepended to the individual
  5675. // entries in the “source” field.
  5676. sourceURL = sourceRoot + sourceURL;
  5677. }
  5678. // Historically, SourceMapConsumer did not take the sourceMapURL as
  5679. // a parameter. This mode is still somewhat supported, which is why
  5680. // this code block is conditional. However, it's preferable to pass
  5681. // the source map URL to SourceMapConsumer, so that this function
  5682. // can implement the source URL resolution algorithm as outlined in
  5683. // the spec. This block is basically the equivalent of:
  5684. // new URL(sourceURL, sourceMapURL).toString()
  5685. // ... except it avoids using URL, which wasn't available in the
  5686. // older releases of node still supported by this library.
  5687. //
  5688. // The spec says:
  5689. // If the sources are not absolute URLs after prepending of the
  5690. // “sourceRoot”, the sources are resolved relative to the
  5691. // SourceMap (like resolving script src in a html document).
  5692. if (sourceMapURL) {
  5693. var parsed = urlParse(sourceMapURL);
  5694. if (!parsed) {
  5695. throw new Error("sourceMapURL could not be parsed");
  5696. }
  5697. if (parsed.path) {
  5698. // Strip the last path component, but keep the "/".
  5699. var index = parsed.path.lastIndexOf('/');
  5700. if (index >= 0) {
  5701. parsed.path = parsed.path.substring(0, index + 1);
  5702. }
  5703. }
  5704. sourceURL = join(urlGenerate(parsed), sourceURL);
  5705. }
  5706. return normalize(sourceURL);
  5707. }
  5708. exports.computeSourceURL = computeSourceURL;
  5709. });
  5710. var util_1 = util.getArg;
  5711. var util_2 = util.urlParse;
  5712. var util_3 = util.urlGenerate;
  5713. var util_4 = util.normalize;
  5714. var util_5 = util.join;
  5715. var util_6 = util.isAbsolute;
  5716. var util_7 = util.relative;
  5717. var util_8 = util.toSetString;
  5718. var util_9 = util.fromSetString;
  5719. var util_10 = util.compareByOriginalPositions;
  5720. var util_11 = util.compareByGeneratedPositionsDeflated;
  5721. var util_12 = util.compareByGeneratedPositionsInflated;
  5722. var util_13 = util.parseSourceMapInput;
  5723. var util_14 = util.computeSourceURL;
  5724. /* -*- Mode: js; js-indent-level: 2; -*- */
  5725. /*
  5726. * Copyright 2011 Mozilla Foundation and contributors
  5727. * Licensed under the New BSD license. See LICENSE or:
  5728. * http://opensource.org/licenses/BSD-3-Clause
  5729. */
  5730. var has = Object.prototype.hasOwnProperty;
  5731. var hasNativeMap = typeof Map !== "undefined";
  5732. /**
  5733. * A data structure which is a combination of an array and a set. Adding a new
  5734. * member is O(1), testing for membership is O(1), and finding the index of an
  5735. * element is O(1). Removing elements from the set is not supported. Only
  5736. * strings are supported for membership.
  5737. */
  5738. function ArraySet() {
  5739. this._array = [];
  5740. this._set = hasNativeMap ? new Map() : Object.create(null);
  5741. }
  5742. /**
  5743. * Static method for creating ArraySet instances from an existing array.
  5744. */
  5745. ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
  5746. var set = new ArraySet();
  5747. for (var i = 0, len = aArray.length; i < len; i++) {
  5748. set.add(aArray[i], aAllowDuplicates);
  5749. }
  5750. return set;
  5751. };
  5752. /**
  5753. * Return how many unique items are in this ArraySet. If duplicates have been
  5754. * added, than those do not count towards the size.
  5755. *
  5756. * @returns Number
  5757. */
  5758. ArraySet.prototype.size = function ArraySet_size() {
  5759. return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
  5760. };
  5761. /**
  5762. * Add the given string to this set.
  5763. *
  5764. * @param String aStr
  5765. */
  5766. ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
  5767. var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
  5768. var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
  5769. var idx = this._array.length;
  5770. if (!isDuplicate || aAllowDuplicates) {
  5771. this._array.push(aStr);
  5772. }
  5773. if (!isDuplicate) {
  5774. if (hasNativeMap) {
  5775. this._set.set(aStr, idx);
  5776. } else {
  5777. this._set[sStr] = idx;
  5778. }
  5779. }
  5780. };
  5781. /**
  5782. * Is the given string a member of this set?
  5783. *
  5784. * @param String aStr
  5785. */
  5786. ArraySet.prototype.has = function ArraySet_has(aStr) {
  5787. if (hasNativeMap) {
  5788. return this._set.has(aStr);
  5789. } else {
  5790. var sStr = util.toSetString(aStr);
  5791. return has.call(this._set, sStr);
  5792. }
  5793. };
  5794. /**
  5795. * What is the index of the given string in the array?
  5796. *
  5797. * @param String aStr
  5798. */
  5799. ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
  5800. if (hasNativeMap) {
  5801. var idx = this._set.get(aStr);
  5802. if (idx >= 0) {
  5803. return idx;
  5804. }
  5805. } else {
  5806. var sStr = util.toSetString(aStr);
  5807. if (has.call(this._set, sStr)) {
  5808. return this._set[sStr];
  5809. }
  5810. }
  5811. throw new Error('"' + aStr + '" is not in the set.');
  5812. };
  5813. /**
  5814. * What is the element at the given index?
  5815. *
  5816. * @param Number aIdx
  5817. */
  5818. ArraySet.prototype.at = function ArraySet_at(aIdx) {
  5819. if (aIdx >= 0 && aIdx < this._array.length) {
  5820. return this._array[aIdx];
  5821. }
  5822. throw new Error('No element indexed by ' + aIdx);
  5823. };
  5824. /**
  5825. * Returns the array representation of this set (which has the proper indices
  5826. * indicated by indexOf). Note that this is a copy of the internal array used
  5827. * for storing the members so that no one can mess with internal state.
  5828. */
  5829. ArraySet.prototype.toArray = function ArraySet_toArray() {
  5830. return this._array.slice();
  5831. };
  5832. var ArraySet_1 = ArraySet;
  5833. var arraySet = {
  5834. ArraySet: ArraySet_1
  5835. };
  5836. /* -*- Mode: js; js-indent-level: 2; -*- */
  5837. /*
  5838. * Copyright 2014 Mozilla Foundation and contributors
  5839. * Licensed under the New BSD license. See LICENSE or:
  5840. * http://opensource.org/licenses/BSD-3-Clause
  5841. */
  5842. /**
  5843. * Determine whether mappingB is after mappingA with respect to generated
  5844. * position.
  5845. */
  5846. function generatedPositionAfter(mappingA, mappingB) {
  5847. // Optimized for most common case
  5848. var lineA = mappingA.generatedLine;
  5849. var lineB = mappingB.generatedLine;
  5850. var columnA = mappingA.generatedColumn;
  5851. var columnB = mappingB.generatedColumn;
  5852. return lineB > lineA || lineB == lineA && columnB >= columnA ||
  5853. util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
  5854. }
  5855. /**
  5856. * A data structure to provide a sorted view of accumulated mappings in a
  5857. * performance conscious manner. It trades a neglibable overhead in general
  5858. * case for a large speedup in case of mappings being added in order.
  5859. */
  5860. function MappingList() {
  5861. this._array = [];
  5862. this._sorted = true;
  5863. // Serves as infimum
  5864. this._last = {generatedLine: -1, generatedColumn: 0};
  5865. }
  5866. /**
  5867. * Iterate through internal items. This method takes the same arguments that
  5868. * `Array.prototype.forEach` takes.
  5869. *
  5870. * NOTE: The order of the mappings is NOT guaranteed.
  5871. */
  5872. MappingList.prototype.unsortedForEach =
  5873. function MappingList_forEach(aCallback, aThisArg) {
  5874. this._array.forEach(aCallback, aThisArg);
  5875. };
  5876. /**
  5877. * Add the given source mapping.
  5878. *
  5879. * @param Object aMapping
  5880. */
  5881. MappingList.prototype.add = function MappingList_add(aMapping) {
  5882. if (generatedPositionAfter(this._last, aMapping)) {
  5883. this._last = aMapping;
  5884. this._array.push(aMapping);
  5885. } else {
  5886. this._sorted = false;
  5887. this._array.push(aMapping);
  5888. }
  5889. };
  5890. /**
  5891. * Returns the flat, sorted array of mappings. The mappings are sorted by
  5892. * generated position.
  5893. *
  5894. * WARNING: This method returns internal data without copying, for
  5895. * performance. The return value must NOT be mutated, and should be treated as
  5896. * an immutable borrow. If you want to take ownership, you must make your own
  5897. * copy.
  5898. */
  5899. MappingList.prototype.toArray = function MappingList_toArray() {
  5900. if (!this._sorted) {
  5901. this._array.sort(util.compareByGeneratedPositionsInflated);
  5902. this._sorted = true;
  5903. }
  5904. return this._array;
  5905. };
  5906. var MappingList_1 = MappingList;
  5907. var mappingList = {
  5908. MappingList: MappingList_1
  5909. };
  5910. /* -*- Mode: js; js-indent-level: 2; -*- */
  5911. /*
  5912. * Copyright 2011 Mozilla Foundation and contributors
  5913. * Licensed under the New BSD license. See LICENSE or:
  5914. * http://opensource.org/licenses/BSD-3-Clause
  5915. */
  5916. var ArraySet$1 = arraySet.ArraySet;
  5917. var MappingList$1 = mappingList.MappingList;
  5918. /**
  5919. * An instance of the SourceMapGenerator represents a source map which is
  5920. * being built incrementally. You may pass an object with the following
  5921. * properties:
  5922. *
  5923. * - file: The filename of the generated source.
  5924. * - sourceRoot: A root for all relative URLs in this source map.
  5925. */
  5926. function SourceMapGenerator(aArgs) {
  5927. if (!aArgs) {
  5928. aArgs = {};
  5929. }
  5930. this._file = util.getArg(aArgs, 'file', null);
  5931. this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
  5932. this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
  5933. this._sources = new ArraySet$1();
  5934. this._names = new ArraySet$1();
  5935. this._mappings = new MappingList$1();
  5936. this._sourcesContents = null;
  5937. }
  5938. SourceMapGenerator.prototype._version = 3;
  5939. /**
  5940. * Creates a new SourceMapGenerator based on a SourceMapConsumer
  5941. *
  5942. * @param aSourceMapConsumer The SourceMap.
  5943. */
  5944. SourceMapGenerator.fromSourceMap =
  5945. function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
  5946. var sourceRoot = aSourceMapConsumer.sourceRoot;
  5947. var generator = new SourceMapGenerator({
  5948. file: aSourceMapConsumer.file,
  5949. sourceRoot: sourceRoot
  5950. });
  5951. aSourceMapConsumer.eachMapping(function (mapping) {
  5952. var newMapping = {
  5953. generated: {
  5954. line: mapping.generatedLine,
  5955. column: mapping.generatedColumn
  5956. }
  5957. };
  5958. if (mapping.source != null) {
  5959. newMapping.source = mapping.source;
  5960. if (sourceRoot != null) {
  5961. newMapping.source = util.relative(sourceRoot, newMapping.source);
  5962. }
  5963. newMapping.original = {
  5964. line: mapping.originalLine,
  5965. column: mapping.originalColumn
  5966. };
  5967. if (mapping.name != null) {
  5968. newMapping.name = mapping.name;
  5969. }
  5970. }
  5971. generator.addMapping(newMapping);
  5972. });
  5973. aSourceMapConsumer.sources.forEach(function (sourceFile) {
  5974. var sourceRelative = sourceFile;
  5975. if (sourceRoot !== null) {
  5976. sourceRelative = util.relative(sourceRoot, sourceFile);
  5977. }
  5978. if (!generator._sources.has(sourceRelative)) {
  5979. generator._sources.add(sourceRelative);
  5980. }
  5981. var content = aSourceMapConsumer.sourceContentFor(sourceFile);
  5982. if (content != null) {
  5983. generator.setSourceContent(sourceFile, content);
  5984. }
  5985. });
  5986. return generator;
  5987. };
  5988. /**
  5989. * Add a single mapping from original source line and column to the generated
  5990. * source's line and column for this source map being created. The mapping
  5991. * object should have the following properties:
  5992. *
  5993. * - generated: An object with the generated line and column positions.
  5994. * - original: An object with the original line and column positions.
  5995. * - source: The original source file (relative to the sourceRoot).
  5996. * - name: An optional original token name for this mapping.
  5997. */
  5998. SourceMapGenerator.prototype.addMapping =
  5999. function SourceMapGenerator_addMapping(aArgs) {
  6000. var generated = util.getArg(aArgs, 'generated');
  6001. var original = util.getArg(aArgs, 'original', null);
  6002. var source = util.getArg(aArgs, 'source', null);
  6003. var name = util.getArg(aArgs, 'name', null);
  6004. if (!this._skipValidation) {
  6005. this._validateMapping(generated, original, source, name);
  6006. }
  6007. if (source != null) {
  6008. source = String(source);
  6009. if (!this._sources.has(source)) {
  6010. this._sources.add(source);
  6011. }
  6012. }
  6013. if (name != null) {
  6014. name = String(name);
  6015. if (!this._names.has(name)) {
  6016. this._names.add(name);
  6017. }
  6018. }
  6019. this._mappings.add({
  6020. generatedLine: generated.line,
  6021. generatedColumn: generated.column,
  6022. originalLine: original != null && original.line,
  6023. originalColumn: original != null && original.column,
  6024. source: source,
  6025. name: name
  6026. });
  6027. };
  6028. /**
  6029. * Set the source content for a source file.
  6030. */
  6031. SourceMapGenerator.prototype.setSourceContent =
  6032. function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
  6033. var source = aSourceFile;
  6034. if (this._sourceRoot != null) {
  6035. source = util.relative(this._sourceRoot, source);
  6036. }
  6037. if (aSourceContent != null) {
  6038. // Add the source content to the _sourcesContents map.
  6039. // Create a new _sourcesContents map if the property is null.
  6040. if (!this._sourcesContents) {
  6041. this._sourcesContents = Object.create(null);
  6042. }
  6043. this._sourcesContents[util.toSetString(source)] = aSourceContent;
  6044. } else if (this._sourcesContents) {
  6045. // Remove the source file from the _sourcesContents map.
  6046. // If the _sourcesContents map is empty, set the property to null.
  6047. delete this._sourcesContents[util.toSetString(source)];
  6048. if (Object.keys(this._sourcesContents).length === 0) {
  6049. this._sourcesContents = null;
  6050. }
  6051. }
  6052. };
  6053. /**
  6054. * Applies the mappings of a sub-source-map for a specific source file to the
  6055. * source map being generated. Each mapping to the supplied source file is
  6056. * rewritten using the supplied source map. Note: The resolution for the
  6057. * resulting mappings is the minimium of this map and the supplied map.
  6058. *
  6059. * @param aSourceMapConsumer The source map to be applied.
  6060. * @param aSourceFile Optional. The filename of the source file.
  6061. * If omitted, SourceMapConsumer's file property will be used.
  6062. * @param aSourceMapPath Optional. The dirname of the path to the source map
  6063. * to be applied. If relative, it is relative to the SourceMapConsumer.
  6064. * This parameter is needed when the two source maps aren't in the same
  6065. * directory, and the source map to be applied contains relative source
  6066. * paths. If so, those relative source paths need to be rewritten
  6067. * relative to the SourceMapGenerator.
  6068. */
  6069. SourceMapGenerator.prototype.applySourceMap =
  6070. function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
  6071. var sourceFile = aSourceFile;
  6072. // If aSourceFile is omitted, we will use the file property of the SourceMap
  6073. if (aSourceFile == null) {
  6074. if (aSourceMapConsumer.file == null) {
  6075. throw new Error(
  6076. 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
  6077. 'or the source map\'s "file" property. Both were omitted.'
  6078. );
  6079. }
  6080. sourceFile = aSourceMapConsumer.file;
  6081. }
  6082. var sourceRoot = this._sourceRoot;
  6083. // Make "sourceFile" relative if an absolute Url is passed.
  6084. if (sourceRoot != null) {
  6085. sourceFile = util.relative(sourceRoot, sourceFile);
  6086. }
  6087. // Applying the SourceMap can add and remove items from the sources and
  6088. // the names array.
  6089. var newSources = new ArraySet$1();
  6090. var newNames = new ArraySet$1();
  6091. // Find mappings for the "sourceFile"
  6092. this._mappings.unsortedForEach(function (mapping) {
  6093. if (mapping.source === sourceFile && mapping.originalLine != null) {
  6094. // Check if it can be mapped by the source map, then update the mapping.
  6095. var original = aSourceMapConsumer.originalPositionFor({
  6096. line: mapping.originalLine,
  6097. column: mapping.originalColumn
  6098. });
  6099. if (original.source != null) {
  6100. // Copy mapping
  6101. mapping.source = original.source;
  6102. if (aSourceMapPath != null) {
  6103. mapping.source = util.join(aSourceMapPath, mapping.source);
  6104. }
  6105. if (sourceRoot != null) {
  6106. mapping.source = util.relative(sourceRoot, mapping.source);
  6107. }
  6108. mapping.originalLine = original.line;
  6109. mapping.originalColumn = original.column;
  6110. if (original.name != null) {
  6111. mapping.name = original.name;
  6112. }
  6113. }
  6114. }
  6115. var source = mapping.source;
  6116. if (source != null && !newSources.has(source)) {
  6117. newSources.add(source);
  6118. }
  6119. var name = mapping.name;
  6120. if (name != null && !newNames.has(name)) {
  6121. newNames.add(name);
  6122. }
  6123. }, this);
  6124. this._sources = newSources;
  6125. this._names = newNames;
  6126. // Copy sourcesContents of applied map.
  6127. aSourceMapConsumer.sources.forEach(function (sourceFile) {
  6128. var content = aSourceMapConsumer.sourceContentFor(sourceFile);
  6129. if (content != null) {
  6130. if (aSourceMapPath != null) {
  6131. sourceFile = util.join(aSourceMapPath, sourceFile);
  6132. }
  6133. if (sourceRoot != null) {
  6134. sourceFile = util.relative(sourceRoot, sourceFile);
  6135. }
  6136. this.setSourceContent(sourceFile, content);
  6137. }
  6138. }, this);
  6139. };
  6140. /**
  6141. * A mapping can have one of the three levels of data:
  6142. *
  6143. * 1. Just the generated position.
  6144. * 2. The Generated position, original position, and original source.
  6145. * 3. Generated and original position, original source, as well as a name
  6146. * token.
  6147. *
  6148. * To maintain consistency, we validate that any new mapping being added falls
  6149. * in to one of these categories.
  6150. */
  6151. SourceMapGenerator.prototype._validateMapping =
  6152. function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
  6153. aName) {
  6154. // When aOriginal is truthy but has empty values for .line and .column,
  6155. // it is most likely a programmer error. In this case we throw a very
  6156. // specific error message to try to guide them the right way.
  6157. // For example: https://github.com/Polymer/polymer-bundler/pull/519
  6158. if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
  6159. throw new Error(
  6160. 'original.line and original.column are not numbers -- you probably meant to omit ' +
  6161. 'the original mapping entirely and only map the generated position. If so, pass ' +
  6162. 'null for the original mapping instead of an object with empty or null values.'
  6163. );
  6164. }
  6165. if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
  6166. && aGenerated.line > 0 && aGenerated.column >= 0
  6167. && !aOriginal && !aSource && !aName) {
  6168. // Case 1.
  6169. return;
  6170. }
  6171. else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
  6172. && aOriginal && 'line' in aOriginal && 'column' in aOriginal
  6173. && aGenerated.line > 0 && aGenerated.column >= 0
  6174. && aOriginal.line > 0 && aOriginal.column >= 0
  6175. && aSource) {
  6176. // Cases 2 and 3.
  6177. return;
  6178. }
  6179. else {
  6180. throw new Error('Invalid mapping: ' + JSON.stringify({
  6181. generated: aGenerated,
  6182. source: aSource,
  6183. original: aOriginal,
  6184. name: aName
  6185. }));
  6186. }
  6187. };
  6188. /**
  6189. * Serialize the accumulated mappings in to the stream of base 64 VLQs
  6190. * specified by the source map format.
  6191. */
  6192. SourceMapGenerator.prototype._serializeMappings =
  6193. function SourceMapGenerator_serializeMappings() {
  6194. var previousGeneratedColumn = 0;
  6195. var previousGeneratedLine = 1;
  6196. var previousOriginalColumn = 0;
  6197. var previousOriginalLine = 0;
  6198. var previousName = 0;
  6199. var previousSource = 0;
  6200. var result = '';
  6201. var next;
  6202. var mapping;
  6203. var nameIdx;
  6204. var sourceIdx;
  6205. var mappings = this._mappings.toArray();
  6206. for (var i = 0, len = mappings.length; i < len; i++) {
  6207. mapping = mappings[i];
  6208. next = '';
  6209. if (mapping.generatedLine !== previousGeneratedLine) {
  6210. previousGeneratedColumn = 0;
  6211. while (mapping.generatedLine !== previousGeneratedLine) {
  6212. next += ';';
  6213. previousGeneratedLine++;
  6214. }
  6215. }
  6216. else {
  6217. if (i > 0) {
  6218. if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
  6219. continue;
  6220. }
  6221. next += ',';
  6222. }
  6223. }
  6224. next += base64Vlq.encode(mapping.generatedColumn
  6225. - previousGeneratedColumn);
  6226. previousGeneratedColumn = mapping.generatedColumn;
  6227. if (mapping.source != null) {
  6228. sourceIdx = this._sources.indexOf(mapping.source);
  6229. next += base64Vlq.encode(sourceIdx - previousSource);
  6230. previousSource = sourceIdx;
  6231. // lines are stored 0-based in SourceMap spec version 3
  6232. next += base64Vlq.encode(mapping.originalLine - 1
  6233. - previousOriginalLine);
  6234. previousOriginalLine = mapping.originalLine - 1;
  6235. next += base64Vlq.encode(mapping.originalColumn
  6236. - previousOriginalColumn);
  6237. previousOriginalColumn = mapping.originalColumn;
  6238. if (mapping.name != null) {
  6239. nameIdx = this._names.indexOf(mapping.name);
  6240. next += base64Vlq.encode(nameIdx - previousName);
  6241. previousName = nameIdx;
  6242. }
  6243. }
  6244. result += next;
  6245. }
  6246. return result;
  6247. };
  6248. SourceMapGenerator.prototype._generateSourcesContent =
  6249. function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
  6250. return aSources.map(function (source) {
  6251. if (!this._sourcesContents) {
  6252. return null;
  6253. }
  6254. if (aSourceRoot != null) {
  6255. source = util.relative(aSourceRoot, source);
  6256. }
  6257. var key = util.toSetString(source);
  6258. return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
  6259. ? this._sourcesContents[key]
  6260. : null;
  6261. }, this);
  6262. };
  6263. /**
  6264. * Externalize the source map.
  6265. */
  6266. SourceMapGenerator.prototype.toJSON =
  6267. function SourceMapGenerator_toJSON() {
  6268. var map = {
  6269. version: this._version,
  6270. sources: this._sources.toArray(),
  6271. names: this._names.toArray(),
  6272. mappings: this._serializeMappings()
  6273. };
  6274. if (this._file != null) {
  6275. map.file = this._file;
  6276. }
  6277. if (this._sourceRoot != null) {
  6278. map.sourceRoot = this._sourceRoot;
  6279. }
  6280. if (this._sourcesContents) {
  6281. map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
  6282. }
  6283. return map;
  6284. };
  6285. /**
  6286. * Render the source map being generated to a string.
  6287. */
  6288. SourceMapGenerator.prototype.toString =
  6289. function SourceMapGenerator_toString() {
  6290. return JSON.stringify(this.toJSON());
  6291. };
  6292. var SourceMapGenerator_1 = SourceMapGenerator;
  6293. var sourceMapGenerator = {
  6294. SourceMapGenerator: SourceMapGenerator_1
  6295. };
  6296. var SourceMapGenerator$1 = sourceMapGenerator.SourceMapGenerator;
  6297. var trackNodes = {
  6298. Atrule: true,
  6299. Selector: true,
  6300. Declaration: true
  6301. };
  6302. var sourceMap = function generateSourceMap(handlers) {
  6303. var map = new SourceMapGenerator$1();
  6304. var line = 1;
  6305. var column = 0;
  6306. var generated = {
  6307. line: 1,
  6308. column: 0
  6309. };
  6310. var original = {
  6311. line: 0, // should be zero to add first mapping
  6312. column: 0
  6313. };
  6314. var sourceMappingActive = false;
  6315. var activatedGenerated = {
  6316. line: 1,
  6317. column: 0
  6318. };
  6319. var activatedMapping = {
  6320. generated: activatedGenerated
  6321. };
  6322. var handlersNode = handlers.node;
  6323. handlers.node = function(node) {
  6324. if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
  6325. var nodeLine = node.loc.start.line;
  6326. var nodeColumn = node.loc.start.column - 1;
  6327. if (original.line !== nodeLine ||
  6328. original.column !== nodeColumn) {
  6329. original.line = nodeLine;
  6330. original.column = nodeColumn;
  6331. generated.line = line;
  6332. generated.column = column;
  6333. if (sourceMappingActive) {
  6334. sourceMappingActive = false;
  6335. if (generated.line !== activatedGenerated.line ||
  6336. generated.column !== activatedGenerated.column) {
  6337. map.addMapping(activatedMapping);
  6338. }
  6339. }
  6340. sourceMappingActive = true;
  6341. map.addMapping({
  6342. source: node.loc.source,
  6343. original: original,
  6344. generated: generated
  6345. });
  6346. }
  6347. }
  6348. handlersNode.call(this, node);
  6349. if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
  6350. activatedGenerated.line = line;
  6351. activatedGenerated.column = column;
  6352. }
  6353. };
  6354. var handlersChunk = handlers.chunk;
  6355. handlers.chunk = function(chunk) {
  6356. for (var i = 0; i < chunk.length; i++) {
  6357. if (chunk.charCodeAt(i) === 10) { // \n
  6358. line++;
  6359. column = 0;
  6360. } else {
  6361. column++;
  6362. }
  6363. }
  6364. handlersChunk(chunk);
  6365. };
  6366. var handlersResult = handlers.result;
  6367. handlers.result = function() {
  6368. if (sourceMappingActive) {
  6369. map.addMapping(activatedMapping);
  6370. }
  6371. return {
  6372. css: handlersResult(),
  6373. map: map
  6374. };
  6375. };
  6376. return handlers;
  6377. };
  6378. var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
  6379. function processChildren(node, delimeter) {
  6380. var list = node.children;
  6381. var prev = null;
  6382. if (typeof delimeter !== 'function') {
  6383. list.forEach(this.node, this);
  6384. } else {
  6385. list.forEach(function(node) {
  6386. if (prev !== null) {
  6387. delimeter.call(this, prev);
  6388. }
  6389. this.node(node);
  6390. prev = node;
  6391. }, this);
  6392. }
  6393. }
  6394. var create$1 = function createGenerator(config) {
  6395. function processNode(node) {
  6396. if (hasOwnProperty$3.call(types, node.type)) {
  6397. types[node.type].call(this, node);
  6398. } else {
  6399. throw new Error('Unknown node type: ' + node.type);
  6400. }
  6401. }
  6402. var types = {};
  6403. if (config.node) {
  6404. for (var name in config.node) {
  6405. types[name] = config.node[name].generate;
  6406. }
  6407. }
  6408. return function(node, options) {
  6409. var buffer = '';
  6410. var handlers = {
  6411. children: processChildren,
  6412. node: processNode,
  6413. chunk: function(chunk) {
  6414. buffer += chunk;
  6415. },
  6416. result: function() {
  6417. return buffer;
  6418. }
  6419. };
  6420. if (options) {
  6421. if (typeof options.decorator === 'function') {
  6422. handlers = options.decorator(handlers);
  6423. }
  6424. if (options.sourceMap) {
  6425. handlers = sourceMap(handlers);
  6426. }
  6427. }
  6428. handlers.node(node);
  6429. return handlers.result();
  6430. };
  6431. };
  6432. var create$2 = function createConvertors(walk) {
  6433. return {
  6434. fromPlainObject: function(ast) {
  6435. walk(ast, {
  6436. enter: function(node) {
  6437. if (node.children && node.children instanceof List_1 === false) {
  6438. node.children = new List_1().fromArray(node.children);
  6439. }
  6440. }
  6441. });
  6442. return ast;
  6443. },
  6444. toPlainObject: function(ast) {
  6445. walk(ast, {
  6446. leave: function(node) {
  6447. if (node.children && node.children instanceof List_1) {
  6448. node.children = node.children.toArray();
  6449. }
  6450. }
  6451. });
  6452. return ast;
  6453. }
  6454. };
  6455. };
  6456. var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
  6457. var noop$3 = function() {};
  6458. function ensureFunction$1(value) {
  6459. return typeof value === 'function' ? value : noop$3;
  6460. }
  6461. function invokeForType(fn, type) {
  6462. return function(node, item, list) {
  6463. if (node.type === type) {
  6464. fn.call(this, node, item, list);
  6465. }
  6466. };
  6467. }
  6468. function getWalkersFromStructure(name, nodeType) {
  6469. var structure = nodeType.structure;
  6470. var walkers = [];
  6471. for (var key in structure) {
  6472. if (hasOwnProperty$4.call(structure, key) === false) {
  6473. continue;
  6474. }
  6475. var fieldTypes = structure[key];
  6476. var walker = {
  6477. name: key,
  6478. type: false,
  6479. nullable: false
  6480. };
  6481. if (!Array.isArray(structure[key])) {
  6482. fieldTypes = [structure[key]];
  6483. }
  6484. for (var i = 0; i < fieldTypes.length; i++) {
  6485. var fieldType = fieldTypes[i];
  6486. if (fieldType === null) {
  6487. walker.nullable = true;
  6488. } else if (typeof fieldType === 'string') {
  6489. walker.type = 'node';
  6490. } else if (Array.isArray(fieldType)) {
  6491. walker.type = 'list';
  6492. }
  6493. }
  6494. if (walker.type) {
  6495. walkers.push(walker);
  6496. }
  6497. }
  6498. if (walkers.length) {
  6499. return {
  6500. context: nodeType.walkContext,
  6501. fields: walkers
  6502. };
  6503. }
  6504. return null;
  6505. }
  6506. function getTypesFromConfig(config) {
  6507. var types = {};
  6508. for (var name in config.node) {
  6509. if (hasOwnProperty$4.call(config.node, name)) {
  6510. var nodeType = config.node[name];
  6511. if (!nodeType.structure) {
  6512. throw new Error('Missed `structure` field in `' + name + '` node type definition');
  6513. }
  6514. types[name] = getWalkersFromStructure(name, nodeType);
  6515. }
  6516. }
  6517. return types;
  6518. }
  6519. function createTypeIterator(config, reverse) {
  6520. var fields = config.fields.slice();
  6521. var contextName = config.context;
  6522. var useContext = typeof contextName === 'string';
  6523. if (reverse) {
  6524. fields.reverse();
  6525. }
  6526. return function(node, context, walk) {
  6527. var prevContextValue;
  6528. if (useContext) {
  6529. prevContextValue = context[contextName];
  6530. context[contextName] = node;
  6531. }
  6532. for (var i = 0; i < fields.length; i++) {
  6533. var field = fields[i];
  6534. var ref = node[field.name];
  6535. if (!field.nullable || ref) {
  6536. if (field.type === 'list') {
  6537. if (reverse) {
  6538. ref.forEachRight(walk);
  6539. } else {
  6540. ref.forEach(walk);
  6541. }
  6542. } else {
  6543. walk(ref);
  6544. }
  6545. }
  6546. }
  6547. if (useContext) {
  6548. context[contextName] = prevContextValue;
  6549. }
  6550. };
  6551. }
  6552. function createFastTraveralMap(iterators) {
  6553. return {
  6554. Atrule: {
  6555. StyleSheet: iterators.StyleSheet,
  6556. Atrule: iterators.Atrule,
  6557. Rule: iterators.Rule,
  6558. Block: iterators.Block
  6559. },
  6560. Rule: {
  6561. StyleSheet: iterators.StyleSheet,
  6562. Atrule: iterators.Atrule,
  6563. Rule: iterators.Rule,
  6564. Block: iterators.Block
  6565. },
  6566. Declaration: {
  6567. StyleSheet: iterators.StyleSheet,
  6568. Atrule: iterators.Atrule,
  6569. Rule: iterators.Rule,
  6570. Block: iterators.Block
  6571. }
  6572. };
  6573. }
  6574. var create$3 = function createWalker(config) {
  6575. var types = getTypesFromConfig(config);
  6576. var iteratorsNatural = {};
  6577. var iteratorsReverse = {};
  6578. for (var name in types) {
  6579. if (hasOwnProperty$4.call(types, name) && types[name] !== null) {
  6580. iteratorsNatural[name] = createTypeIterator(types[name], false);
  6581. iteratorsReverse[name] = createTypeIterator(types[name], true);
  6582. }
  6583. }
  6584. var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
  6585. var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
  6586. var walk = function(root, options) {
  6587. function walkNode(node, item, list) {
  6588. enter.call(context, node, item, list);
  6589. if (iterators.hasOwnProperty(node.type)) {
  6590. iterators[node.type](node, context, walkNode);
  6591. }
  6592. leave.call(context, node, item, list);
  6593. }
  6594. var enter = noop$3;
  6595. var leave = noop$3;
  6596. var iterators = iteratorsNatural;
  6597. var context = {
  6598. root: root,
  6599. stylesheet: null,
  6600. atrule: null,
  6601. atrulePrelude: null,
  6602. rule: null,
  6603. selector: null,
  6604. block: null,
  6605. declaration: null,
  6606. function: null
  6607. };
  6608. if (typeof options === 'function') {
  6609. enter = options;
  6610. } else if (options) {
  6611. enter = ensureFunction$1(options.enter);
  6612. leave = ensureFunction$1(options.leave);
  6613. if (options.reverse) {
  6614. iterators = iteratorsReverse;
  6615. }
  6616. if (options.visit) {
  6617. if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
  6618. iterators = options.reverse
  6619. ? fastTraversalIteratorsReverse[options.visit]
  6620. : fastTraversalIteratorsNatural[options.visit];
  6621. } else if (!types.hasOwnProperty(options.visit)) {
  6622. throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
  6623. }
  6624. enter = invokeForType(enter, options.visit);
  6625. leave = invokeForType(leave, options.visit);
  6626. }
  6627. }
  6628. if (enter === noop$3 && leave === noop$3) {
  6629. throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
  6630. }
  6631. // swap handlers in reverse mode to invert visit order
  6632. if (options.reverse) {
  6633. var tmp = enter;
  6634. enter = leave;
  6635. leave = tmp;
  6636. }
  6637. walkNode(root);
  6638. };
  6639. walk.find = function(ast, fn) {
  6640. var found = null;
  6641. walk(ast, function(node, item, list) {
  6642. if (found === null && fn.call(this, node, item, list)) {
  6643. found = node;
  6644. }
  6645. });
  6646. return found;
  6647. };
  6648. walk.findLast = function(ast, fn) {
  6649. var found = null;
  6650. walk(ast, {
  6651. reverse: true,
  6652. enter: function(node, item, list) {
  6653. if (found === null && fn.call(this, node, item, list)) {
  6654. found = node;
  6655. }
  6656. }
  6657. });
  6658. return found;
  6659. };
  6660. walk.findAll = function(ast, fn) {
  6661. var found = [];
  6662. walk(ast, function(node, item, list) {
  6663. if (fn.call(this, node, item, list)) {
  6664. found.push(node);
  6665. }
  6666. });
  6667. return found;
  6668. };
  6669. return walk;
  6670. };
  6671. var clone = function clone(node) {
  6672. var result = {};
  6673. for (var key in node) {
  6674. var value = node[key];
  6675. if (value) {
  6676. if (Array.isArray(value) || value instanceof List_1) {
  6677. value = value.map(clone);
  6678. } else if (value.constructor === Object) {
  6679. value = clone(value);
  6680. }
  6681. }
  6682. result[key] = value;
  6683. }
  6684. return result;
  6685. };
  6686. var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
  6687. var shape = {
  6688. generic: true,
  6689. types: {},
  6690. properties: {},
  6691. parseContext: {},
  6692. scope: {},
  6693. atrule: ['parse'],
  6694. pseudo: ['parse'],
  6695. node: ['name', 'structure', 'parse', 'generate', 'walkContext']
  6696. };
  6697. function isObject(value) {
  6698. return value && value.constructor === Object;
  6699. }
  6700. function copy(value) {
  6701. if (isObject(value)) {
  6702. var res = {};
  6703. for (var key in value) {
  6704. if (hasOwnProperty$5.call(value, key)) {
  6705. res[key] = value[key];
  6706. }
  6707. }
  6708. return res;
  6709. } else {
  6710. return value;
  6711. }
  6712. }
  6713. function extend(dest, src) {
  6714. for (var key in src) {
  6715. if (hasOwnProperty$5.call(src, key)) {
  6716. if (isObject(dest[key])) {
  6717. extend(dest[key], copy(src[key]));
  6718. } else {
  6719. dest[key] = copy(src[key]);
  6720. }
  6721. }
  6722. }
  6723. }
  6724. function mix(dest, src, shape) {
  6725. for (var key in shape) {
  6726. if (hasOwnProperty$5.call(shape, key) === false) {
  6727. continue;
  6728. }
  6729. if (shape[key] === true) {
  6730. if (key in src) {
  6731. if (hasOwnProperty$5.call(src, key)) {
  6732. dest[key] = copy(src[key]);
  6733. }
  6734. }
  6735. } else if (shape[key]) {
  6736. if (isObject(shape[key])) {
  6737. var res = {};
  6738. extend(res, dest[key]);
  6739. extend(res, src[key]);
  6740. dest[key] = res;
  6741. } else if (Array.isArray(shape[key])) {
  6742. var res = {};
  6743. var innerShape = shape[key].reduce(function(s, k) {
  6744. s[k] = true;
  6745. return s;
  6746. }, {});
  6747. for (var name in dest[key]) {
  6748. if (hasOwnProperty$5.call(dest[key], name)) {
  6749. res[name] = {};
  6750. if (dest[key] && dest[key][name]) {
  6751. mix(res[name], dest[key][name], innerShape);
  6752. }
  6753. }
  6754. }
  6755. for (var name in src[key]) {
  6756. if (hasOwnProperty$5.call(src[key], name)) {
  6757. if (!res[name]) {
  6758. res[name] = {};
  6759. }
  6760. if (src[key] && src[key][name]) {
  6761. mix(res[name], src[key][name], innerShape);
  6762. }
  6763. }
  6764. }
  6765. dest[key] = res;
  6766. }
  6767. }
  6768. }
  6769. return dest;
  6770. }
  6771. var mix_1 = function(dest, src) {
  6772. return mix(dest, src, shape);
  6773. };
  6774. function assign(dest, src) {
  6775. for (var key in src) {
  6776. dest[key] = src[key];
  6777. }
  6778. return dest;
  6779. }
  6780. function createSyntax(config) {
  6781. var parse = create(config);
  6782. var walk = create$3(config);
  6783. var generate = create$1(config);
  6784. var convert = create$2(walk);
  6785. var syntax = {
  6786. List: List_1,
  6787. SyntaxError: _SyntaxError,
  6788. TokenStream: TokenStream_1,
  6789. Lexer: Lexer_1,
  6790. vendorPrefix: names.vendorPrefix,
  6791. keyword: names.keyword,
  6792. property: names.property,
  6793. isCustomProperty: names.isCustomProperty,
  6794. definitionSyntax: definitionSyntax,
  6795. lexer: null,
  6796. createLexer: function(config) {
  6797. return new Lexer_1(config, syntax, syntax.lexer.structure);
  6798. },
  6799. tokenize: tokenizer,
  6800. parse: parse,
  6801. walk: walk,
  6802. generate: generate,
  6803. find: walk.find,
  6804. findLast: walk.findLast,
  6805. findAll: walk.findAll,
  6806. clone: clone,
  6807. fromPlainObject: convert.fromPlainObject,
  6808. toPlainObject: convert.toPlainObject,
  6809. createSyntax: function(config) {
  6810. return createSyntax(mix_1({}, config));
  6811. },
  6812. fork: function(extension) {
  6813. var base = mix_1({}, config); // copy of config
  6814. return createSyntax(
  6815. typeof extension === 'function'
  6816. ? extension(base, assign)
  6817. : mix_1(base, extension)
  6818. );
  6819. }
  6820. };
  6821. syntax.lexer = new Lexer_1({
  6822. generic: true,
  6823. types: config.types,
  6824. properties: config.properties,
  6825. node: config.node
  6826. }, syntax);
  6827. return syntax;
  6828. }
  6829. var create_1 = function(config) {
  6830. return createSyntax(mix_1({}, config));
  6831. };
  6832. var create$4 = {
  6833. create: create_1
  6834. };
  6835. var generic$1 = true;
  6836. var types = {
  6837. "absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large",
  6838. "alpha-value": "<number>|<percentage>",
  6839. "angle-percentage": "<angle>|<percentage>",
  6840. "angular-color-hint": "<angle-percentage>",
  6841. "angular-color-stop": "<color>&&<color-stop-angle>?",
  6842. "angular-color-stop-list": "[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>",
  6843. "animateable-feature": "scroll-position|contents|<custom-ident>",
  6844. attachment: "scroll|fixed|local",
  6845. "attr()": "attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )",
  6846. "attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='",
  6847. "attr-modifier": "i|s",
  6848. "attribute-selector": "'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'",
  6849. "auto-repeat": "repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )",
  6850. "auto-track-list": "[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",
  6851. "baseline-position": "[first|last]? baseline",
  6852. "basic-shape": "<inset()>|<circle()>|<ellipse()>|<polygon()>",
  6853. "bg-image": "none|<image>",
  6854. "bg-layer": "<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
  6855. "bg-position": "[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]",
  6856. "bg-size": "[<length-percentage>|auto]{1,2}|cover|contain",
  6857. "blur()": "blur( <length> )",
  6858. "blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",
  6859. box: "border-box|padding-box|content-box",
  6860. "brightness()": "brightness( <number-percentage> )",
  6861. "calc()": "calc( <calc-sum> )",
  6862. "calc-sum": "<calc-product> [['+'|'-'] <calc-product>]*",
  6863. "calc-product": "<calc-value> ['*' <calc-value>|'/' <number>]*",
  6864. "calc-value": "<number>|<dimension>|<percentage>|( <calc-sum> )",
  6865. "cf-final-image": "<image>|<color>",
  6866. "cf-mixing-image": "<percentage>?&&<image>",
  6867. "circle()": "circle( [<shape-radius>]? [at <position>]? )",
  6868. "clamp()": "clamp( <calc-sum>#{3} )",
  6869. "class-selector": "'.' <ident-token>",
  6870. "clip-source": "<url>",
  6871. color: "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hex-color>|<named-color>|currentcolor|<deprecated-system-color>",
  6872. "color-stop": "<color-stop-length>|<color-stop-angle>",
  6873. "color-stop-angle": "<angle-percentage>{1,2}",
  6874. "color-stop-length": "<length-percentage>{1,2}",
  6875. "color-stop-list": "[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>",
  6876. combinator: "'>'|'+'|'~'|['||']",
  6877. "common-lig-values": "[common-ligatures|no-common-ligatures]",
  6878. compat: "searchfield|textarea|push-button|button-bevel|slider-horizontal|checkbox|radio|square-button|menulist|menulist-button|listbox|meter|progress-bar",
  6879. "composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor",
  6880. "compositing-operator": "add|subtract|intersect|exclude",
  6881. "compound-selector": "[<type-selector>? <subclass-selector>* [<pseudo-element-selector> <pseudo-class-selector>*]*]!",
  6882. "compound-selector-list": "<compound-selector>#",
  6883. "complex-selector": "<compound-selector> [<combinator>? <compound-selector>]*",
  6884. "complex-selector-list": "<complex-selector>#",
  6885. "conic-gradient()": "conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )",
  6886. "contextual-alt-values": "[contextual|no-contextual]",
  6887. "content-distribution": "space-between|space-around|space-evenly|stretch",
  6888. "content-list": "[<string>|contents|<url>|<quote>|<attr()>|counter( <ident> , <'list-style-type'>? )]+",
  6889. "content-position": "center|start|end|flex-start|flex-end",
  6890. "content-replacement": "<image>",
  6891. "contrast()": "contrast( [<number-percentage>] )",
  6892. "counter()": "counter( <custom-ident> , [<counter-style>|none]? )",
  6893. "counter-style": "<counter-style-name>|symbols( )",
  6894. "counter-style-name": "<custom-ident>",
  6895. "counters()": "counters( <custom-ident> , <string> , [<counter-style>|none]? )",
  6896. "cross-fade()": "cross-fade( <cf-mixing-image> , <cf-final-image>? )",
  6897. "cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number> , <number> , <number> , <number> )",
  6898. "deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText",
  6899. "discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]",
  6900. "display-box": "contents|none",
  6901. "display-inside": "flow|flow-root|table|flex|grid|ruby",
  6902. "display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container",
  6903. "display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid",
  6904. "display-listitem": "<display-outside>?&&[flow|flow-root]?&&list-item",
  6905. "display-outside": "block|inline|run-in",
  6906. "drop-shadow()": "drop-shadow( <length>{2,3} <color>? )",
  6907. "east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]",
  6908. "east-asian-width-values": "[full-width|proportional-width]",
  6909. "element()": "element( <id-selector> )",
  6910. "ellipse()": "ellipse( [<shape-radius>{2}]? [at <position>]? )",
  6911. "ending-shape": "circle|ellipse",
  6912. "env()": "env( <custom-ident> , <declaration-value>? )",
  6913. "explicit-track-list": "[<line-names>? <track-size>]+ <line-names>?",
  6914. "family-name": "<string>|<custom-ident>+",
  6915. "feature-tag-value": "<string> [<integer>|on|off]?",
  6916. "feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation",
  6917. "feature-value-block": "<feature-type> '{' <feature-value-declaration-list> '}'",
  6918. "feature-value-block-list": "<feature-value-block>+",
  6919. "feature-value-declaration": "<custom-ident> : <integer>+ ;",
  6920. "feature-value-declaration-list": "<feature-value-declaration>",
  6921. "feature-value-name": "<custom-ident>",
  6922. "fill-rule": "nonzero|evenodd",
  6923. "filter-function": "<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>",
  6924. "filter-function-list": "[<filter-function>|<url>]+",
  6925. "final-bg-layer": "<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
  6926. "fit-content()": "fit-content( [<length>|<percentage>] )",
  6927. "fixed-breadth": "<length-percentage>",
  6928. "fixed-repeat": "repeat( [<positive-integer>] , [<line-names>? <fixed-size>]+ <line-names>? )",
  6929. "fixed-size": "<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )",
  6930. "font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>",
  6931. "font-variant-css21": "[normal|small-caps]",
  6932. "font-weight-absolute": "normal|bold|<number>",
  6933. "frequency-percentage": "<frequency>|<percentage>",
  6934. "general-enclosed": "[<function-token> <any-value> )]|( <ident> <any-value> )",
  6935. "generic-family": "serif|sans-serif|cursive|fantasy|monospace|-apple-system",
  6936. "generic-name": "serif|sans-serif|cursive|fantasy|monospace",
  6937. "geometry-box": "<shape-box>|fill-box|stroke-box|view-box",
  6938. gradient: "<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<-legacy-gradient>",
  6939. "grayscale()": "grayscale( <number-percentage> )",
  6940. "grid-line": "auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]",
  6941. "historical-lig-values": "[historical-ligatures|no-historical-ligatures]",
  6942. "hsl()": "hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )",
  6943. "hsla()": "hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",
  6944. hue: "<number>|<angle>",
  6945. "hue-rotate()": "hue-rotate( <angle> )",
  6946. image: "<url>|<image()>|<image-set()>|<element()>|<cross-fade()>|<gradient>",
  6947. "image()": "image( <image-tags>? [<image-src>? , <color>?]! )",
  6948. "image-set()": "image-set( <image-set-option># )",
  6949. "image-set-option": "[<image>|<string>] <resolution>",
  6950. "image-src": "<url>|<string>",
  6951. "image-tags": "ltr|rtl",
  6952. "inflexible-breadth": "<length>|<percentage>|min-content|max-content|auto",
  6953. "inset()": "inset( <length-percentage>{1,4} [round <'border-radius'>]? )",
  6954. "invert()": "invert( <number-percentage> )",
  6955. "keyframes-name": "<custom-ident>|<string>",
  6956. "keyframe-block": "<keyframe-selector># { <declaration-list> }",
  6957. "keyframe-block-list": "<keyframe-block>+",
  6958. "keyframe-selector": "from|to|<percentage>",
  6959. "leader()": "leader( <leader-type> )",
  6960. "leader-type": "dotted|solid|space|<string>",
  6961. "length-percentage": "<length>|<percentage>",
  6962. "line-names": "'[' <custom-ident>* ']'",
  6963. "line-name-list": "[<line-names>|<name-repeat>]+",
  6964. "line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset",
  6965. "line-width": "<length>|thin|medium|thick",
  6966. "linear-color-hint": "<length-percentage>",
  6967. "linear-color-stop": "<color> <color-stop-length>?",
  6968. "linear-gradient()": "linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
  6969. "mask-layer": "<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>",
  6970. "mask-position": "[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?",
  6971. "mask-reference": "none|<image>|<mask-source>",
  6972. "mask-source": "<url>",
  6973. "masking-mode": "alpha|luminance|match-source",
  6974. "matrix()": "matrix( <number>#{6} )",
  6975. "matrix3d()": "matrix3d( <number>#{16} )",
  6976. "max()": "max( <calc-sum># )",
  6977. "media-and": "<media-in-parens> [and <media-in-parens>]+",
  6978. "media-condition": "<media-not>|<media-and>|<media-or>|<media-in-parens>",
  6979. "media-condition-without-or": "<media-not>|<media-and>|<media-in-parens>",
  6980. "media-feature": "( [<mf-plain>|<mf-boolean>|<mf-range>] )",
  6981. "media-in-parens": "( <media-condition> )|<media-feature>|<general-enclosed>",
  6982. "media-not": "not <media-in-parens>",
  6983. "media-or": "<media-in-parens> [or <media-in-parens>]+",
  6984. "media-query": "<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?",
  6985. "media-query-list": "<media-query>#",
  6986. "media-type": "<ident>",
  6987. "mf-boolean": "<mf-name>",
  6988. "mf-name": "<ident>",
  6989. "mf-plain": "<mf-name> : <mf-value>",
  6990. "mf-range": "<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>",
  6991. "mf-value": "<number>|<dimension>|<ident>|<ratio>",
  6992. "min()": "min( <calc-sum># )",
  6993. "minmax()": "minmax( [<length>|<percentage>|<flex>|min-content|max-content|auto] , [<length>|<percentage>|<flex>|min-content|max-content|auto] )",
  6994. "named-color": "transparent|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|<-non-standard-color>",
  6995. "namespace-prefix": "<ident>",
  6996. "ns-prefix": "[<ident-token>|'*']? '|'",
  6997. "number-percentage": "<number>|<percentage>",
  6998. "numeric-figure-values": "[lining-nums|oldstyle-nums]",
  6999. "numeric-fraction-values": "[diagonal-fractions|stacked-fractions]",
  7000. "numeric-spacing-values": "[proportional-nums|tabular-nums]",
  7001. nth: "<an-plus-b>|even|odd",
  7002. "opacity()": "opacity( [<number-percentage>] )",
  7003. "overflow-position": "unsafe|safe",
  7004. "outline-radius": "<length>|<percentage>",
  7005. "page-body": "<declaration>? [; <page-body>]?|<page-margin-box> <page-body>",
  7006. "page-margin-box": "<page-margin-box-type> '{' <declaration-list> '}'",
  7007. "page-margin-box-type": "@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom",
  7008. "page-selector-list": "[<page-selector>#]?",
  7009. "page-selector": "<pseudo-page>+|<ident> <pseudo-page>*",
  7010. "perspective()": "perspective( <length> )",
  7011. "polygon()": "polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )",
  7012. position: "[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]",
  7013. "pseudo-class-selector": "':' <ident-token>|':' <function-token> <any-value> ')'",
  7014. "pseudo-element-selector": "':' <pseudo-class-selector>",
  7015. "pseudo-page": ": [left|right|first|blank]",
  7016. quote: "open-quote|close-quote|no-open-quote|no-close-quote",
  7017. "radial-gradient()": "radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
  7018. "relative-selector": "<combinator>? <complex-selector>",
  7019. "relative-selector-list": "<relative-selector>#",
  7020. "relative-size": "larger|smaller",
  7021. "repeat-style": "repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}",
  7022. "repeating-linear-gradient()": "repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
  7023. "repeating-radial-gradient()": "repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
  7024. "rgb()": "rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )",
  7025. "rgba()": "rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )",
  7026. "rotate()": "rotate( [<angle>|<zero>] )",
  7027. "rotate3d()": "rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )",
  7028. "rotateX()": "rotateX( [<angle>|<zero>] )",
  7029. "rotateY()": "rotateY( [<angle>|<zero>] )",
  7030. "rotateZ()": "rotateZ( [<angle>|<zero>] )",
  7031. "saturate()": "saturate( <number-percentage> )",
  7032. "scale()": "scale( <number> , <number>? )",
  7033. "scale3d()": "scale3d( <number> , <number> , <number> )",
  7034. "scaleX()": "scaleX( <number> )",
  7035. "scaleY()": "scaleY( <number> )",
  7036. "scaleZ()": "scaleZ( <number> )",
  7037. "self-position": "center|start|end|self-start|self-end|flex-start|flex-end",
  7038. "shape-radius": "<length-percentage>|closest-side|farthest-side",
  7039. "skew()": "skew( [<angle>|<zero>] , [<angle>|<zero>]? )",
  7040. "skewX()": "skewX( [<angle>|<zero>] )",
  7041. "skewY()": "skewY( [<angle>|<zero>] )",
  7042. "sepia()": "sepia( <number-percentage> )",
  7043. shadow: "inset?&&<length>{2,4}&&<color>?",
  7044. "shadow-t": "[<length>{2,3}&&<color>?]",
  7045. shape: "rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )",
  7046. "shape-box": "<box>|margin-box",
  7047. "side-or-corner": "[left|right]||[top|bottom]",
  7048. "single-animation": "<time>||<timing-function>||<time>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]",
  7049. "single-animation-direction": "normal|reverse|alternate|alternate-reverse",
  7050. "single-animation-fill-mode": "none|forwards|backwards|both",
  7051. "single-animation-iteration-count": "infinite|<number>",
  7052. "single-animation-play-state": "running|paused",
  7053. "single-transition": "[none|<single-transition-property>]||<time>||<timing-function>||<time>",
  7054. "single-transition-property": "all|<custom-ident>",
  7055. size: "closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}",
  7056. "step-position": "jump-start|jump-end|jump-none|jump-both|start|end",
  7057. "step-timing-function": "step-start|step-end|steps( <integer> [, <step-position>]? )",
  7058. "subclass-selector": "<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>",
  7059. "supports-condition": "not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*",
  7060. "supports-in-parens": "( <supports-condition> )|<supports-feature>|<general-enclosed>",
  7061. "supports-feature": "<supports-decl>|<supports-selector-fn>",
  7062. "supports-decl": "( <declaration> )",
  7063. "supports-selector-fn": "selector( <complex-selector> )",
  7064. symbol: "<string>|<image>|<custom-ident>",
  7065. target: "<target-counter()>|<target-counters()>|<target-text()>",
  7066. "target-counter()": "target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )",
  7067. "target-counters()": "target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )",
  7068. "target-text()": "target-text( [<string>|<url>] , [content|before|after|first-letter]? )",
  7069. "time-percentage": "<time>|<percentage>",
  7070. "timing-function": "linear|<cubic-bezier-timing-function>|<step-timing-function>",
  7071. "track-breadth": "<length-percentage>|<flex>|min-content|max-content|auto",
  7072. "track-list": "[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?",
  7073. "track-repeat": "repeat( [<positive-integer>] , [<line-names>? <track-size>]+ <line-names>? )",
  7074. "track-size": "<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( [<length>|<percentage>] )",
  7075. "transform-function": "<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>",
  7076. "transform-list": "<transform-function>+",
  7077. "translate()": "translate( <length-percentage> , <length-percentage>? )",
  7078. "translate3d()": "translate3d( <length-percentage> , <length-percentage> , <length> )",
  7079. "translateX()": "translateX( <length-percentage> )",
  7080. "translateY()": "translateY( <length-percentage> )",
  7081. "translateZ()": "translateZ( <length> )",
  7082. "type-or-unit": "string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%",
  7083. "type-selector": "<wq-name>|<ns-prefix>? '*'",
  7084. "var()": "var( <custom-property-name> , <declaration-value>? )",
  7085. "viewport-length": "auto|<length-percentage>",
  7086. "wq-name": "<ns-prefix>? <ident-token>",
  7087. "-legacy-gradient": "<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>",
  7088. "-legacy-linear-gradient": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )",
  7089. "-legacy-repeating-linear-gradient": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )",
  7090. "-legacy-linear-gradient-arguments": "[<angle>|<side-or-corner>]? , <color-stop-list>",
  7091. "-legacy-radial-gradient": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )",
  7092. "-legacy-repeating-radial-gradient": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )",
  7093. "-legacy-radial-gradient-arguments": "[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>",
  7094. "-legacy-radial-gradient-size": "closest-side|closest-corner|farthest-side|farthest-corner|contain|cover",
  7095. "-legacy-radial-gradient-shape": "circle|ellipse",
  7096. "-non-standard-font": "-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body",
  7097. "-non-standard-color": "-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text",
  7098. "-non-standard-image-rendering": "optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast",
  7099. "-non-standard-overflow": "-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable",
  7100. "-non-standard-width": "min-intrinsic|intrinsic|-moz-min-content|-moz-max-content|-webkit-min-content|-webkit-max-content",
  7101. "-webkit-gradient()": "-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )",
  7102. "-webkit-gradient-color-stop": "from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )",
  7103. "-webkit-gradient-point": "[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]",
  7104. "-webkit-gradient-radius": "<length>|<percentage>",
  7105. "-webkit-gradient-type": "linear|radial",
  7106. "-webkit-mask-box-repeat": "repeat|stretch|round",
  7107. "-webkit-mask-clip-style": "border|border-box|padding|padding-box|content|content-box|text",
  7108. "-ms-filter-function-list": "<-ms-filter-function>+",
  7109. "-ms-filter-function": "<-ms-filter-function-progid>|<-ms-filter-function-legacy>",
  7110. "-ms-filter-function-progid": "'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]",
  7111. "-ms-filter-function-legacy": "<ident-token>|<function-token> <any-value>? )",
  7112. "-ms-filter": "<string>",
  7113. age: "child|young|old",
  7114. "attr-name": "<wq-name>",
  7115. "attr-fallback": "<any-value>",
  7116. "border-radius": "<length-percentage>{1,2}",
  7117. bottom: "<length>|auto",
  7118. "generic-voice": "[<age>? <gender> <integer>?]",
  7119. gender: "male|female|neutral",
  7120. left: "<length>|auto",
  7121. "mask-image": "<mask-reference>#",
  7122. "name-repeat": "repeat( [<positive-integer>|auto-fill] , <line-names>+ )",
  7123. paint: "none|<color>|<url> [none|<color>]?|context-fill|context-stroke",
  7124. "path()": "path( <string> )",
  7125. ratio: "<integer> / <integer>",
  7126. right: "<length>|auto",
  7127. "svg-length": "<percentage>|<length>|<number>",
  7128. "svg-writing-mode": "lr-tb|rl-tb|tb-rl|lr|rl|tb",
  7129. top: "<length>|auto",
  7130. x: "<number>",
  7131. y: "<number>",
  7132. declaration: "<ident-token> : <declaration-value>? ['!' important]?",
  7133. "declaration-list": "[<declaration>? ';']* <declaration>?",
  7134. url: "url( <string> <url-modifier>* )|<url-token>",
  7135. "url-modifier": "<ident>|<function-token> <any-value> )",
  7136. "number-zero-one": "<number [0,1]>",
  7137. "number-one-or-greater": "<number [1,∞]>",
  7138. "positive-integer": "<integer [0,∞]>"
  7139. };
  7140. var properties$1 = {
  7141. "--*": "<declaration-value>",
  7142. "-ms-accelerator": "false|true",
  7143. "-ms-block-progression": "tb|rl|bt|lr",
  7144. "-ms-content-zoom-chaining": "none|chained",
  7145. "-ms-content-zooming": "none|zoom",
  7146. "-ms-content-zoom-limit": "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
  7147. "-ms-content-zoom-limit-max": "<percentage>",
  7148. "-ms-content-zoom-limit-min": "<percentage>",
  7149. "-ms-content-zoom-snap": "<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>",
  7150. "-ms-content-zoom-snap-points": "snapInterval( <percentage> , <percentage> )|snapList( <percentage># )",
  7151. "-ms-content-zoom-snap-type": "none|proximity|mandatory",
  7152. "-ms-filter": "<string>",
  7153. "-ms-flow-from": "[none|<custom-ident>]#",
  7154. "-ms-flow-into": "[none|<custom-ident>]#",
  7155. "-ms-high-contrast-adjust": "auto|none",
  7156. "-ms-hyphenate-limit-chars": "auto|<integer>{1,3}",
  7157. "-ms-hyphenate-limit-lines": "no-limit|<integer>",
  7158. "-ms-hyphenate-limit-zone": "<percentage>|<length>",
  7159. "-ms-ime-align": "auto|after",
  7160. "-ms-overflow-style": "auto|none|scrollbar|-ms-autohiding-scrollbar",
  7161. "-ms-scrollbar-3dlight-color": "<color>",
  7162. "-ms-scrollbar-arrow-color": "<color>",
  7163. "-ms-scrollbar-base-color": "<color>",
  7164. "-ms-scrollbar-darkshadow-color": "<color>",
  7165. "-ms-scrollbar-face-color": "<color>",
  7166. "-ms-scrollbar-highlight-color": "<color>",
  7167. "-ms-scrollbar-shadow-color": "<color>",
  7168. "-ms-scrollbar-track-color": "<color>",
  7169. "-ms-scroll-chaining": "chained|none",
  7170. "-ms-scroll-limit": "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
  7171. "-ms-scroll-limit-x-max": "auto|<length>",
  7172. "-ms-scroll-limit-x-min": "<length>",
  7173. "-ms-scroll-limit-y-max": "auto|<length>",
  7174. "-ms-scroll-limit-y-min": "<length>",
  7175. "-ms-scroll-rails": "none|railed",
  7176. "-ms-scroll-snap-points-x": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
  7177. "-ms-scroll-snap-points-y": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
  7178. "-ms-scroll-snap-type": "none|proximity|mandatory",
  7179. "-ms-scroll-snap-x": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
  7180. "-ms-scroll-snap-y": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
  7181. "-ms-scroll-translation": "none|vertical-to-horizontal",
  7182. "-ms-text-autospace": "none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space",
  7183. "-ms-touch-select": "grippers|none",
  7184. "-ms-user-select": "none|element|text",
  7185. "-ms-wrap-flow": "auto|both|start|end|maximum|clear",
  7186. "-ms-wrap-margin": "<length>",
  7187. "-ms-wrap-through": "wrap|none",
  7188. "-moz-appearance": "none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized",
  7189. "-moz-binding": "<url>|none",
  7190. "-moz-border-bottom-colors": "<color>+|none",
  7191. "-moz-border-left-colors": "<color>+|none",
  7192. "-moz-border-right-colors": "<color>+|none",
  7193. "-moz-border-top-colors": "<color>+|none",
  7194. "-moz-context-properties": "none|[fill|fill-opacity|stroke|stroke-opacity]#",
  7195. "-moz-float-edge": "border-box|content-box|margin-box|padding-box",
  7196. "-moz-force-broken-image-icon": "<integer>",
  7197. "-moz-image-region": "<shape>|auto",
  7198. "-moz-orient": "inline|block|horizontal|vertical",
  7199. "-moz-outline-radius": "<outline-radius>{1,4} [/ <outline-radius>{1,4}]?",
  7200. "-moz-outline-radius-bottomleft": "<outline-radius>",
  7201. "-moz-outline-radius-bottomright": "<outline-radius>",
  7202. "-moz-outline-radius-topleft": "<outline-radius>",
  7203. "-moz-outline-radius-topright": "<outline-radius>",
  7204. "-moz-stack-sizing": "ignore|stretch-to-fit",
  7205. "-moz-text-blink": "none|blink",
  7206. "-moz-user-focus": "ignore|normal|select-after|select-before|select-menu|select-same|select-all|none",
  7207. "-moz-user-input": "auto|none|enabled|disabled",
  7208. "-moz-user-modify": "read-only|read-write|write-only",
  7209. "-moz-window-dragging": "drag|no-drag",
  7210. "-moz-window-shadow": "default|menu|tooltip|sheet|none",
  7211. "-webkit-appearance": "none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|listbox|listitem|media-fullscreen-button|media-mute-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield",
  7212. "-webkit-border-before": "<'border-width'>||<'border-style'>||<'color'>",
  7213. "-webkit-border-before-color": "<'color'>",
  7214. "-webkit-border-before-style": "<'border-style'>",
  7215. "-webkit-border-before-width": "<'border-width'>",
  7216. "-webkit-box-reflect": "[above|below|right|left]? <length>? <image>?",
  7217. "-webkit-line-clamp": "none|<integer>",
  7218. "-webkit-mask": "[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#",
  7219. "-webkit-mask-attachment": "<attachment>#",
  7220. "-webkit-mask-clip": "[<box>|border|padding|content|text]#",
  7221. "-webkit-mask-composite": "<composite-style>#",
  7222. "-webkit-mask-image": "<mask-reference>#",
  7223. "-webkit-mask-origin": "[<box>|border|padding|content]#",
  7224. "-webkit-mask-position": "<position>#",
  7225. "-webkit-mask-position-x": "[<length-percentage>|left|center|right]#",
  7226. "-webkit-mask-position-y": "[<length-percentage>|top|center|bottom]#",
  7227. "-webkit-mask-repeat": "<repeat-style>#",
  7228. "-webkit-mask-repeat-x": "repeat|no-repeat|space|round",
  7229. "-webkit-mask-repeat-y": "repeat|no-repeat|space|round",
  7230. "-webkit-mask-size": "<bg-size>#",
  7231. "-webkit-overflow-scrolling": "auto|touch",
  7232. "-webkit-tap-highlight-color": "<color>",
  7233. "-webkit-text-fill-color": "<color>",
  7234. "-webkit-text-stroke": "<length>||<color>",
  7235. "-webkit-text-stroke-color": "<color>",
  7236. "-webkit-text-stroke-width": "<length>",
  7237. "-webkit-touch-callout": "default|none",
  7238. "-webkit-user-modify": "read-only|read-write|read-write-plaintext-only",
  7239. "align-content": "normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>",
  7240. "align-items": "normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]",
  7241. "align-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>",
  7242. all: "initial|inherit|unset|revert",
  7243. animation: "<single-animation>#",
  7244. "animation-delay": "<time>#",
  7245. "animation-direction": "<single-animation-direction>#",
  7246. "animation-duration": "<time>#",
  7247. "animation-fill-mode": "<single-animation-fill-mode>#",
  7248. "animation-iteration-count": "<single-animation-iteration-count>#",
  7249. "animation-name": "[none|<keyframes-name>]#",
  7250. "animation-play-state": "<single-animation-play-state>#",
  7251. "animation-timing-function": "<timing-function>#",
  7252. appearance: "none|auto|button|textfield|<compat>",
  7253. azimuth: "<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards",
  7254. "backdrop-filter": "none|<filter-function-list>",
  7255. "backface-visibility": "visible|hidden",
  7256. background: "[<bg-layer> ,]* <final-bg-layer>",
  7257. "background-attachment": "<attachment>#",
  7258. "background-blend-mode": "<blend-mode>#",
  7259. "background-clip": "<box>#",
  7260. "background-color": "<color>",
  7261. "background-image": "<bg-image>#",
  7262. "background-origin": "<box>#",
  7263. "background-position": "<bg-position>#",
  7264. "background-position-x": "[center|[left|right|x-start|x-end]? <length-percentage>?]#",
  7265. "background-position-y": "[center|[top|bottom|y-start|y-end]? <length-percentage>?]#",
  7266. "background-repeat": "<repeat-style>#",
  7267. "background-size": "<bg-size>#",
  7268. "block-overflow": "clip|ellipsis|<string>",
  7269. "block-size": "<'width'>",
  7270. border: "<line-width>||<line-style>||<color>",
  7271. "border-block": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7272. "border-block-color": "<'border-top-color'>{1,2}",
  7273. "border-block-style": "<'border-top-style'>",
  7274. "border-block-width": "<'border-top-width'>",
  7275. "border-block-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7276. "border-block-end-color": "<'border-top-color'>",
  7277. "border-block-end-style": "<'border-top-style'>",
  7278. "border-block-end-width": "<'border-top-width'>",
  7279. "border-block-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7280. "border-block-start-color": "<'border-top-color'>",
  7281. "border-block-start-style": "<'border-top-style'>",
  7282. "border-block-start-width": "<'border-top-width'>",
  7283. "border-bottom": "<line-width>||<line-style>||<color>",
  7284. "border-bottom-color": "<'border-top-color'>",
  7285. "border-bottom-left-radius": "<length-percentage>{1,2}",
  7286. "border-bottom-right-radius": "<length-percentage>{1,2}",
  7287. "border-bottom-style": "<line-style>",
  7288. "border-bottom-width": "<line-width>",
  7289. "border-collapse": "collapse|separate",
  7290. "border-color": "<color>{1,4}",
  7291. "border-end-end-radius": "<length-percentage>{1,2}",
  7292. "border-end-start-radius": "<length-percentage>{1,2}",
  7293. "border-image": "<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>",
  7294. "border-image-outset": "[<length>|<number>]{1,4}",
  7295. "border-image-repeat": "[stretch|repeat|round|space]{1,2}",
  7296. "border-image-slice": "<number-percentage>{1,4}&&fill?",
  7297. "border-image-source": "none|<image>",
  7298. "border-image-width": "[<length-percentage>|<number>|auto]{1,4}",
  7299. "border-inline": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7300. "border-inline-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7301. "border-inline-color": "<'border-top-color'>{1,2}",
  7302. "border-inline-style": "<'border-top-style'>",
  7303. "border-inline-width": "<'border-top-width'>",
  7304. "border-inline-end-color": "<'border-top-color'>",
  7305. "border-inline-end-style": "<'border-top-style'>",
  7306. "border-inline-end-width": "<'border-top-width'>",
  7307. "border-inline-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
  7308. "border-inline-start-color": "<'border-top-color'>",
  7309. "border-inline-start-style": "<'border-top-style'>",
  7310. "border-inline-start-width": "<'border-top-width'>",
  7311. "border-left": "<line-width>||<line-style>||<color>",
  7312. "border-left-color": "<color>",
  7313. "border-left-style": "<line-style>",
  7314. "border-left-width": "<line-width>",
  7315. "border-radius": "<length-percentage>{1,4} [/ <length-percentage>{1,4}]?",
  7316. "border-right": "<line-width>||<line-style>||<color>",
  7317. "border-right-color": "<color>",
  7318. "border-right-style": "<line-style>",
  7319. "border-right-width": "<line-width>",
  7320. "border-spacing": "<length> <length>?",
  7321. "border-start-end-radius": "<length-percentage>{1,2}",
  7322. "border-start-start-radius": "<length-percentage>{1,2}",
  7323. "border-style": "<line-style>{1,4}",
  7324. "border-top": "<line-width>||<line-style>||<color>",
  7325. "border-top-color": "<color>",
  7326. "border-top-left-radius": "<length-percentage>{1,2}",
  7327. "border-top-right-radius": "<length-percentage>{1,2}",
  7328. "border-top-style": "<line-style>",
  7329. "border-top-width": "<line-width>",
  7330. "border-width": "<line-width>{1,4}",
  7331. bottom: "<length>|<percentage>|auto",
  7332. "box-align": "start|center|end|baseline|stretch",
  7333. "box-decoration-break": "slice|clone",
  7334. "box-direction": "normal|reverse|inherit",
  7335. "box-flex": "<number>",
  7336. "box-flex-group": "<integer>",
  7337. "box-lines": "single|multiple",
  7338. "box-ordinal-group": "<integer>",
  7339. "box-orient": "horizontal|vertical|inline-axis|block-axis|inherit",
  7340. "box-pack": "start|center|end|justify",
  7341. "box-shadow": "none|<shadow>#",
  7342. "box-sizing": "content-box|border-box",
  7343. "break-after": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
  7344. "break-before": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
  7345. "break-inside": "auto|avoid|avoid-page|avoid-column|avoid-region",
  7346. "caption-side": "top|bottom|block-start|block-end|inline-start|inline-end",
  7347. "caret-color": "auto|<color>",
  7348. clear: "none|left|right|both|inline-start|inline-end",
  7349. clip: "<shape>|auto",
  7350. "clip-path": "<clip-source>|[<basic-shape>||<geometry-box>]|none",
  7351. color: "<color>",
  7352. "color-adjust": "economy|exact",
  7353. "column-count": "<integer>|auto",
  7354. "column-fill": "auto|balance|balance-all",
  7355. "column-gap": "normal|<length-percentage>",
  7356. "column-rule": "<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>",
  7357. "column-rule-color": "<color>",
  7358. "column-rule-style": "<'border-style'>",
  7359. "column-rule-width": "<'border-width'>",
  7360. "column-span": "none|all",
  7361. "column-width": "<length>|auto",
  7362. columns: "<'column-width'>||<'column-count'>",
  7363. contain: "none|strict|content|[size||layout||style||paint]",
  7364. content: "normal|none|[<content-replacement>|<content-list>] [/ <string>]?",
  7365. "counter-increment": "[<custom-ident> <integer>?]+|none",
  7366. "counter-reset": "[<custom-ident> <integer>?]+|none",
  7367. "counter-set": "[<custom-ident> <integer>?]+|none",
  7368. cursor: "[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",
  7369. direction: "ltr|rtl",
  7370. display: "none|inline|block|list-item|inline-list-item|inline-block|inline-table|table|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|flex|inline-flex|grid|inline-grid|run-in|ruby|ruby-base|ruby-text|ruby-base-container|ruby-text-container|contents|-ms-flexbox|-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box",
  7371. "empty-cells": "show|hide",
  7372. filter: "none|<filter-function-list>|<-ms-filter-function-list>",
  7373. flex: "none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]",
  7374. "flex-basis": "content|<'width'>",
  7375. "flex-direction": "row|row-reverse|column|column-reverse",
  7376. "flex-flow": "<'flex-direction'>||<'flex-wrap'>",
  7377. "flex-grow": "<number>",
  7378. "flex-shrink": "<number>",
  7379. "flex-wrap": "nowrap|wrap|wrap-reverse",
  7380. float: "left|right|none|inline-start|inline-end",
  7381. font: "[[<'font-style'>||<font-variant-css21>||<'font-weight'>||<'font-stretch'>]? <'font-size'> [/ <'line-height'>]? <'font-family'>]|caption|icon|menu|message-box|small-caption|status-bar",
  7382. "font-family": "[<family-name>|<generic-family>]#",
  7383. "font-feature-settings": "normal|<feature-tag-value>#",
  7384. "font-kerning": "auto|normal|none",
  7385. "font-language-override": "normal|<string>",
  7386. "font-optical-sizing": "auto|none",
  7387. "font-variation-settings": "normal|[<string> <number>]#",
  7388. "font-size": "<absolute-size>|<relative-size>|<length-percentage>",
  7389. "font-size-adjust": "none|<number>",
  7390. "font-stretch": "<font-stretch-absolute>",
  7391. "font-style": "normal|italic|oblique <angle>?",
  7392. "font-synthesis": "none|[weight||style]",
  7393. "font-variant": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]",
  7394. "font-variant-alternates": "normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]",
  7395. "font-variant-caps": "normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps",
  7396. "font-variant-east-asian": "normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]",
  7397. "font-variant-ligatures": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]",
  7398. "font-variant-numeric": "normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]",
  7399. "font-variant-position": "normal|sub|super",
  7400. "font-weight": "<font-weight-absolute>|bolder|lighter",
  7401. gap: "<'row-gap'> <'column-gap'>?",
  7402. grid: "<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>",
  7403. "grid-area": "<grid-line> [/ <grid-line>]{0,3}",
  7404. "grid-auto-columns": "<track-size>+",
  7405. "grid-auto-flow": "[row|column]||dense",
  7406. "grid-auto-rows": "<track-size>+",
  7407. "grid-column": "<grid-line> [/ <grid-line>]?",
  7408. "grid-column-end": "<grid-line>",
  7409. "grid-column-gap": "<length-percentage>",
  7410. "grid-column-start": "<grid-line>",
  7411. "grid-gap": "<'grid-row-gap'> <'grid-column-gap'>?",
  7412. "grid-row": "<grid-line> [/ <grid-line>]?",
  7413. "grid-row-end": "<grid-line>",
  7414. "grid-row-gap": "<length-percentage>",
  7415. "grid-row-start": "<grid-line>",
  7416. "grid-template": "none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?",
  7417. "grid-template-areas": "none|<string>+",
  7418. "grid-template-columns": "none|<track-list>|<auto-track-list>",
  7419. "grid-template-rows": "none|<track-list>|<auto-track-list>",
  7420. "hanging-punctuation": "none|[first||[force-end|allow-end]||last]",
  7421. height: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
  7422. hyphens: "none|manual|auto",
  7423. "image-orientation": "from-image|<angle>|[<angle>? flip]",
  7424. "image-rendering": "auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>",
  7425. "image-resolution": "[from-image||<resolution>]&&snap?",
  7426. "ime-mode": "auto|normal|active|inactive|disabled",
  7427. "initial-letter": "normal|[<number> <integer>?]",
  7428. "initial-letter-align": "[auto|alphabetic|hanging|ideographic]",
  7429. "inline-size": "<'width'>",
  7430. inset: "<'top'>{1,4}",
  7431. "inset-block": "<'top'>{1,2}",
  7432. "inset-block-end": "<'top'>",
  7433. "inset-block-start": "<'top'>",
  7434. "inset-inline": "<'top'>{1,2}",
  7435. "inset-inline-end": "<'top'>",
  7436. "inset-inline-start": "<'top'>",
  7437. isolation: "auto|isolate",
  7438. "justify-content": "normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]",
  7439. "justify-items": "normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]",
  7440. "justify-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]",
  7441. left: "<length>|<percentage>|auto",
  7442. "letter-spacing": "normal|<length-percentage>",
  7443. "line-break": "auto|loose|normal|strict",
  7444. "line-clamp": "none|<integer>",
  7445. "line-height": "normal|<number>|<length>|<percentage>",
  7446. "line-height-step": "<length>",
  7447. "list-style": "<'list-style-type'>||<'list-style-position'>||<'list-style-image'>",
  7448. "list-style-image": "<url>|none",
  7449. "list-style-position": "inside|outside",
  7450. "list-style-type": "<counter-style>|<string>|none",
  7451. margin: "[<length>|<percentage>|auto]{1,4}",
  7452. "margin-block": "<'margin-left'>{1,2}",
  7453. "margin-block-end": "<'margin-left'>",
  7454. "margin-block-start": "<'margin-left'>",
  7455. "margin-bottom": "<length>|<percentage>|auto",
  7456. "margin-inline": "<'margin-left'>{1,2}",
  7457. "margin-inline-end": "<'margin-left'>",
  7458. "margin-inline-start": "<'margin-left'>",
  7459. "margin-left": "<length>|<percentage>|auto",
  7460. "margin-right": "<length>|<percentage>|auto",
  7461. "margin-top": "<length>|<percentage>|auto",
  7462. mask: "<mask-layer>#",
  7463. "mask-border": "<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>",
  7464. "mask-border-mode": "luminance|alpha",
  7465. "mask-border-outset": "[<length>|<number>]{1,4}",
  7466. "mask-border-repeat": "[stretch|repeat|round|space]{1,2}",
  7467. "mask-border-slice": "<number-percentage>{1,4} fill?",
  7468. "mask-border-source": "none|<image>",
  7469. "mask-border-width": "[<length-percentage>|<number>|auto]{1,4}",
  7470. "mask-clip": "[<geometry-box>|no-clip]#",
  7471. "mask-composite": "<compositing-operator>#",
  7472. "mask-image": "<mask-reference>#",
  7473. "mask-mode": "<masking-mode>#",
  7474. "mask-origin": "<geometry-box>#",
  7475. "mask-position": "<position>#",
  7476. "mask-repeat": "<repeat-style>#",
  7477. "mask-size": "<bg-size>#",
  7478. "mask-type": "luminance|alpha",
  7479. "max-block-size": "<'max-width'>",
  7480. "max-height": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available",
  7481. "max-inline-size": "<'max-width'>",
  7482. "max-lines": "none|<integer>",
  7483. "max-width": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
  7484. "min-block-size": "<'min-width'>",
  7485. "min-height": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available",
  7486. "min-inline-size": "<'min-width'>",
  7487. "min-width": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
  7488. "mix-blend-mode": "<blend-mode>",
  7489. "object-fit": "fill|contain|cover|none|scale-down",
  7490. "object-position": "<position>",
  7491. offset: "[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?",
  7492. "offset-anchor": "auto|<position>",
  7493. "offset-distance": "<length-percentage>",
  7494. "offset-path": "none|ray( [<angle>&&<size>?&&contain?] )|<path()>|<url>|[<basic-shape>||<geometry-box>]",
  7495. "offset-position": "auto|<position>",
  7496. "offset-rotate": "[auto|reverse]||<angle>",
  7497. opacity: "<number-zero-one>",
  7498. order: "<integer>",
  7499. orphans: "<integer>",
  7500. outline: "[<'outline-color'>||<'outline-style'>||<'outline-width'>]",
  7501. "outline-color": "<color>|invert",
  7502. "outline-offset": "<length>",
  7503. "outline-style": "auto|<'border-style'>",
  7504. "outline-width": "<line-width>",
  7505. overflow: "[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>",
  7506. "overflow-anchor": "auto|none",
  7507. "overflow-block": "visible|hidden|clip|scroll|auto",
  7508. "overflow-clip-box": "padding-box|content-box",
  7509. "overflow-inline": "visible|hidden|clip|scroll|auto",
  7510. "overflow-wrap": "normal|break-word|anywhere",
  7511. "overflow-x": "visible|hidden|clip|scroll|auto",
  7512. "overflow-y": "visible|hidden|clip|scroll|auto",
  7513. "overscroll-behavior": "[contain|none|auto]{1,2}",
  7514. "overscroll-behavior-x": "contain|none|auto",
  7515. "overscroll-behavior-y": "contain|none|auto",
  7516. padding: "[<length>|<percentage>]{1,4}",
  7517. "padding-block": "<'padding-left'>{1,2}",
  7518. "padding-block-end": "<'padding-left'>",
  7519. "padding-block-start": "<'padding-left'>",
  7520. "padding-bottom": "<length>|<percentage>",
  7521. "padding-inline": "<'padding-left'>{1,2}",
  7522. "padding-inline-end": "<'padding-left'>",
  7523. "padding-inline-start": "<'padding-left'>",
  7524. "padding-left": "<length>|<percentage>",
  7525. "padding-right": "<length>|<percentage>",
  7526. "padding-top": "<length>|<percentage>",
  7527. "page-break-after": "auto|always|avoid|left|right|recto|verso",
  7528. "page-break-before": "auto|always|avoid|left|right|recto|verso",
  7529. "page-break-inside": "auto|avoid",
  7530. "paint-order": "normal|[fill||stroke||markers]",
  7531. perspective: "none|<length>",
  7532. "perspective-origin": "<position>",
  7533. "place-content": "<'align-content'> <'justify-content'>?",
  7534. "place-items": "<'align-items'> <'justify-items'>?",
  7535. "place-self": "<'align-self'> <'justify-self'>?",
  7536. "pointer-events": "auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",
  7537. position: "static|relative|absolute|sticky|fixed|-webkit-sticky",
  7538. quotes: "none|[<string> <string>]+",
  7539. resize: "none|both|horizontal|vertical|block|inline",
  7540. right: "<length>|<percentage>|auto",
  7541. rotate: "none|<angle>|[x|y|z|<number>{3}]&&<angle>",
  7542. "row-gap": "normal|<length-percentage>",
  7543. "ruby-align": "start|center|space-between|space-around",
  7544. "ruby-merge": "separate|collapse|auto",
  7545. "ruby-position": "over|under|inter-character",
  7546. scale: "none|<number>{1,3}",
  7547. "scrollbar-color": "auto|dark|light|<color>{2}",
  7548. "scrollbar-width": "auto|thin|none",
  7549. "scroll-behavior": "auto|smooth",
  7550. "scroll-margin": "<length>{1,4}",
  7551. "scroll-margin-block": "<length>{1,2}",
  7552. "scroll-margin-block-start": "<length>",
  7553. "scroll-margin-block-end": "<length>",
  7554. "scroll-margin-bottom": "<length>",
  7555. "scroll-margin-inline": "<length>{1,2}",
  7556. "scroll-margin-inline-start": "<length>",
  7557. "scroll-margin-inline-end": "<length>",
  7558. "scroll-margin-left": "<length>",
  7559. "scroll-margin-right": "<length>",
  7560. "scroll-margin-top": "<length>",
  7561. "scroll-padding": "[auto|<length-percentage>]{1,4}",
  7562. "scroll-padding-block": "[auto|<length-percentage>]{1,2}",
  7563. "scroll-padding-block-start": "auto|<length-percentage>",
  7564. "scroll-padding-block-end": "auto|<length-percentage>",
  7565. "scroll-padding-bottom": "auto|<length-percentage>",
  7566. "scroll-padding-inline": "[auto|<length-percentage>]{1,2}",
  7567. "scroll-padding-inline-start": "auto|<length-percentage>",
  7568. "scroll-padding-inline-end": "auto|<length-percentage>",
  7569. "scroll-padding-left": "auto|<length-percentage>",
  7570. "scroll-padding-right": "auto|<length-percentage>",
  7571. "scroll-padding-top": "auto|<length-percentage>",
  7572. "scroll-snap-align": "[none|start|end|center]{1,2}",
  7573. "scroll-snap-coordinate": "none|<position>#",
  7574. "scroll-snap-destination": "<position>",
  7575. "scroll-snap-points-x": "none|repeat( <length-percentage> )",
  7576. "scroll-snap-points-y": "none|repeat( <length-percentage> )",
  7577. "scroll-snap-stop": "normal|always",
  7578. "scroll-snap-type": "none|[x|y|block|inline|both] [mandatory|proximity]?",
  7579. "scroll-snap-type-x": "none|mandatory|proximity",
  7580. "scroll-snap-type-y": "none|mandatory|proximity",
  7581. "shape-image-threshold": "<number>",
  7582. "shape-margin": "<length-percentage>",
  7583. "shape-outside": "none|<shape-box>||<basic-shape>|<image>",
  7584. "tab-size": "<integer>|<length>",
  7585. "table-layout": "auto|fixed",
  7586. "text-align": "start|end|left|right|center|justify|match-parent",
  7587. "text-align-last": "auto|start|end|left|right|center|justify",
  7588. "text-combine-upright": "none|all|[digits <integer>?]",
  7589. "text-decoration": "<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>",
  7590. "text-decoration-color": "<color>",
  7591. "text-decoration-line": "none|[underline||overline||line-through||blink]",
  7592. "text-decoration-skip": "none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]",
  7593. "text-decoration-skip-ink": "auto|none",
  7594. "text-decoration-style": "solid|double|dotted|dashed|wavy",
  7595. "text-emphasis": "<'text-emphasis-style'>||<'text-emphasis-color'>",
  7596. "text-emphasis-color": "<color>",
  7597. "text-emphasis-position": "[over|under]&&[right|left]",
  7598. "text-emphasis-style": "none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>",
  7599. "text-indent": "<length-percentage>&&hanging?&&each-line?",
  7600. "text-justify": "auto|inter-character|inter-word|none",
  7601. "text-orientation": "mixed|upright|sideways",
  7602. "text-overflow": "[clip|ellipsis|<string>]{1,2}",
  7603. "text-rendering": "auto|optimizeSpeed|optimizeLegibility|geometricPrecision",
  7604. "text-shadow": "none|<shadow-t>#",
  7605. "text-size-adjust": "none|auto|<percentage>",
  7606. "text-transform": "none|capitalize|uppercase|lowercase|full-width|full-size-kana",
  7607. "text-underline-position": "auto|[under||[left|right]]",
  7608. top: "<length>|<percentage>|auto",
  7609. "touch-action": "auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",
  7610. transform: "none|<transform-list>",
  7611. "transform-box": "border-box|fill-box|view-box",
  7612. "transform-origin": "[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?",
  7613. "transform-style": "flat|preserve-3d",
  7614. transition: "<single-transition>#",
  7615. "transition-delay": "<time>#",
  7616. "transition-duration": "<time>#",
  7617. "transition-property": "none|<single-transition-property>#",
  7618. "transition-timing-function": "<timing-function>#",
  7619. translate: "none|<length-percentage> [<length-percentage> <length>?]?",
  7620. "unicode-bidi": "normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate",
  7621. "user-select": "auto|text|none|contain|all",
  7622. "vertical-align": "baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>",
  7623. visibility: "visible|hidden|collapse",
  7624. "white-space": "normal|pre|nowrap|pre-wrap|pre-line",
  7625. widows: "<integer>",
  7626. width: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
  7627. "will-change": "auto|<animateable-feature>#",
  7628. "word-break": "normal|break-all|keep-all|break-word",
  7629. "word-spacing": "normal|<length-percentage>",
  7630. "word-wrap": "normal|break-word",
  7631. "writing-mode": "horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>",
  7632. "z-index": "auto|<integer>",
  7633. zoom: "normal|reset|<number>|<percentage>",
  7634. "-moz-background-clip": "padding|border",
  7635. "-moz-border-radius-bottomleft": "<'border-bottom-left-radius'>",
  7636. "-moz-border-radius-bottomright": "<'border-bottom-right-radius'>",
  7637. "-moz-border-radius-topleft": "<'border-top-left-radius'>",
  7638. "-moz-border-radius-topright": "<'border-bottom-right-radius'>",
  7639. "-moz-osx-font-smoothing": "auto|grayscale",
  7640. "-moz-user-select": "none|text|all|-moz-none",
  7641. "-ms-flex-align": "start|end|center|baseline|stretch",
  7642. "-ms-flex-item-align": "auto|start|end|center|baseline|stretch",
  7643. "-ms-flex-line-pack": "start|end|center|justify|distribute|stretch",
  7644. "-ms-flex-negative": "<'flex-shrink'>",
  7645. "-ms-flex-pack": "start|end|center|justify|distribute",
  7646. "-ms-flex-order": "<integer>",
  7647. "-ms-flex-positive": "<'flex-grow'>",
  7648. "-ms-flex-preferred-size": "<'flex-basis'>",
  7649. "-ms-interpolation-mode": "nearest-neighbor|bicubic",
  7650. "-ms-grid-column-align": "start|end|center|stretch",
  7651. "-ms-grid-row-align": "start|end|center|stretch",
  7652. "-webkit-background-clip": "[<box>|border|padding|content|text]#",
  7653. "-webkit-column-break-after": "always|auto|avoid",
  7654. "-webkit-column-break-before": "always|auto|avoid",
  7655. "-webkit-column-break-inside": "always|auto|avoid",
  7656. "-webkit-font-smoothing": "auto|none|antialiased|subpixel-antialiased",
  7657. "-webkit-mask-box-image": "[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?",
  7658. "-webkit-print-color-adjust": "economy|exact",
  7659. "-webkit-text-security": "none|circle|disc|square",
  7660. "-webkit-user-drag": "none|element|auto",
  7661. "-webkit-user-select": "auto|none|text|all",
  7662. "alignment-baseline": "auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical",
  7663. "baseline-shift": "baseline|sub|super|<svg-length>",
  7664. behavior: "<url>+",
  7665. "clip-rule": "nonzero|evenodd",
  7666. cue: "<'cue-before'> <'cue-after'>?",
  7667. "cue-after": "<url> <decibel>?|none",
  7668. "cue-before": "<url> <decibel>?|none",
  7669. "dominant-baseline": "auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge",
  7670. fill: "<paint>",
  7671. "fill-opacity": "<number-zero-one>",
  7672. "fill-rule": "nonzero|evenodd",
  7673. "glyph-orientation-horizontal": "<angle>",
  7674. "glyph-orientation-vertical": "<angle>",
  7675. kerning: "auto|<svg-length>",
  7676. marker: "none|<url>",
  7677. "marker-end": "none|<url>",
  7678. "marker-mid": "none|<url>",
  7679. "marker-start": "none|<url>",
  7680. pause: "<'pause-before'> <'pause-after'>?",
  7681. "pause-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
  7682. "pause-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
  7683. rest: "<'rest-before'> <'rest-after'>?",
  7684. "rest-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
  7685. "rest-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
  7686. "shape-rendering": "auto|optimizeSpeed|crispEdges|geometricPrecision",
  7687. src: "[<url> [format( <string># )]?|local( <family-name> )]#",
  7688. speak: "auto|none|normal",
  7689. "speak-as": "normal|spell-out||digits||[literal-punctuation|no-punctuation]",
  7690. stroke: "<paint>",
  7691. "stroke-dasharray": "none|[<svg-length>+]#",
  7692. "stroke-dashoffset": "<svg-length>",
  7693. "stroke-linecap": "butt|round|square",
  7694. "stroke-linejoin": "miter|round|bevel",
  7695. "stroke-miterlimit": "<number-one-or-greater>",
  7696. "stroke-opacity": "<number-zero-one>",
  7697. "stroke-width": "<svg-length>",
  7698. "text-anchor": "start|middle|end",
  7699. "unicode-range": "<urange>#",
  7700. "voice-balance": "<number>|left|center|right|leftwards|rightwards",
  7701. "voice-duration": "auto|<time>",
  7702. "voice-family": "[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve",
  7703. "voice-pitch": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
  7704. "voice-range": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
  7705. "voice-rate": "[normal|x-slow|slow|medium|fast|x-fast]||<percentage>",
  7706. "voice-stress": "normal|strong|moderate|none|reduced",
  7707. "voice-volume": "silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]"
  7708. };
  7709. var defaultSyntax = {
  7710. generic: generic$1,
  7711. types: types,
  7712. properties: properties$1
  7713. };
  7714. var defaultSyntax$1 = /*#__PURE__*/Object.freeze({
  7715. __proto__: null,
  7716. generic: generic$1,
  7717. types: types,
  7718. properties: properties$1,
  7719. 'default': defaultSyntax
  7720. });
  7721. var cmpChar$3 = tokenizer.cmpChar;
  7722. var isDigit$4 = tokenizer.isDigit;
  7723. var TYPE$9 = tokenizer.TYPE;
  7724. var WHITESPACE$4 = TYPE$9.WhiteSpace;
  7725. var COMMENT$3 = TYPE$9.Comment;
  7726. var IDENT$3 = TYPE$9.Ident;
  7727. var NUMBER$3 = TYPE$9.Number;
  7728. var DIMENSION$2 = TYPE$9.Dimension;
  7729. var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
  7730. var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
  7731. var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
  7732. var DISALLOW_SIGN$1 = true;
  7733. var ALLOW_SIGN$1 = false;
  7734. function checkInteger$1(offset, disallowSign) {
  7735. var pos = this.scanner.tokenStart + offset;
  7736. var code = this.scanner.source.charCodeAt(pos);
  7737. if (code === PLUSSIGN$3 || code === HYPHENMINUS$3) {
  7738. if (disallowSign) {
  7739. this.error('Number sign is not allowed');
  7740. }
  7741. pos++;
  7742. }
  7743. for (; pos < this.scanner.tokenEnd; pos++) {
  7744. if (!isDigit$4(this.scanner.source.charCodeAt(pos))) {
  7745. this.error('Integer is expected', pos);
  7746. }
  7747. }
  7748. }
  7749. function checkTokenIsInteger(disallowSign) {
  7750. return checkInteger$1.call(this, 0, disallowSign);
  7751. }
  7752. function expectCharCode(offset, code) {
  7753. if (!cmpChar$3(this.scanner.source, this.scanner.tokenStart + offset, code)) {
  7754. var msg = '';
  7755. switch (code) {
  7756. case N$4:
  7757. msg = 'N is expected';
  7758. break;
  7759. case HYPHENMINUS$3:
  7760. msg = 'HyphenMinus is expected';
  7761. break;
  7762. }
  7763. this.error(msg, this.scanner.tokenStart + offset);
  7764. }
  7765. }
  7766. // ... <signed-integer>
  7767. // ... ['+' | '-'] <signless-integer>
  7768. function consumeB$1() {
  7769. var offset = 0;
  7770. var sign = 0;
  7771. var type = this.scanner.tokenType;
  7772. while (type === WHITESPACE$4 || type === COMMENT$3) {
  7773. type = this.scanner.lookupType(++offset);
  7774. }
  7775. if (type !== NUMBER$3) {
  7776. if (this.scanner.isDelim(PLUSSIGN$3, offset) ||
  7777. this.scanner.isDelim(HYPHENMINUS$3, offset)) {
  7778. sign = this.scanner.isDelim(PLUSSIGN$3, offset) ? PLUSSIGN$3 : HYPHENMINUS$3;
  7779. do {
  7780. type = this.scanner.lookupType(++offset);
  7781. } while (type === WHITESPACE$4 || type === COMMENT$3);
  7782. if (type !== NUMBER$3) {
  7783. this.scanner.skip(offset);
  7784. checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
  7785. }
  7786. } else {
  7787. return null;
  7788. }
  7789. }
  7790. if (offset > 0) {
  7791. this.scanner.skip(offset);
  7792. }
  7793. if (sign === 0) {
  7794. type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
  7795. if (type !== PLUSSIGN$3 && type !== HYPHENMINUS$3) {
  7796. this.error('Number sign is expected');
  7797. }
  7798. }
  7799. checkTokenIsInteger.call(this, sign !== 0);
  7800. return sign === HYPHENMINUS$3 ? '-' + this.consume(NUMBER$3) : this.consume(NUMBER$3);
  7801. }
  7802. // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
  7803. var AnPlusB = {
  7804. name: 'AnPlusB',
  7805. structure: {
  7806. a: [String, null],
  7807. b: [String, null]
  7808. },
  7809. parse: function() {
  7810. /* eslint-disable brace-style*/
  7811. var start = this.scanner.tokenStart;
  7812. var a = null;
  7813. var b = null;
  7814. // <integer>
  7815. if (this.scanner.tokenType === NUMBER$3) {
  7816. checkTokenIsInteger.call(this, ALLOW_SIGN$1);
  7817. b = this.consume(NUMBER$3);
  7818. }
  7819. // -n
  7820. // -n <signed-integer>
  7821. // -n ['+' | '-'] <signless-integer>
  7822. // -n- <signless-integer>
  7823. // <dashndashdigit-ident>
  7824. else if (this.scanner.tokenType === IDENT$3 && cmpChar$3(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$3)) {
  7825. a = '-1';
  7826. expectCharCode.call(this, 1, N$4);
  7827. switch (this.scanner.getTokenLength()) {
  7828. // -n
  7829. // -n <signed-integer>
  7830. // -n ['+' | '-'] <signless-integer>
  7831. case 2:
  7832. this.scanner.next();
  7833. b = consumeB$1.call(this);
  7834. break;
  7835. // -n- <signless-integer>
  7836. case 3:
  7837. expectCharCode.call(this, 2, HYPHENMINUS$3);
  7838. this.scanner.next();
  7839. this.scanner.skipSC();
  7840. checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
  7841. b = '-' + this.consume(NUMBER$3);
  7842. break;
  7843. // <dashndashdigit-ident>
  7844. default:
  7845. expectCharCode.call(this, 2, HYPHENMINUS$3);
  7846. checkInteger$1.call(this, 3, DISALLOW_SIGN$1);
  7847. this.scanner.next();
  7848. b = this.scanner.substrToCursor(start + 2);
  7849. }
  7850. }
  7851. // '+'? n
  7852. // '+'? n <signed-integer>
  7853. // '+'? n ['+' | '-'] <signless-integer>
  7854. // '+'? n- <signless-integer>
  7855. // '+'? <ndashdigit-ident>
  7856. else if (this.scanner.tokenType === IDENT$3 || (this.scanner.isDelim(PLUSSIGN$3) && this.scanner.lookupType(1) === IDENT$3)) {
  7857. var sign = 0;
  7858. a = '1';
  7859. // just ignore a plus
  7860. if (this.scanner.isDelim(PLUSSIGN$3)) {
  7861. sign = 1;
  7862. this.scanner.next();
  7863. }
  7864. expectCharCode.call(this, 0, N$4);
  7865. switch (this.scanner.getTokenLength()) {
  7866. // '+'? n
  7867. // '+'? n <signed-integer>
  7868. // '+'? n ['+' | '-'] <signless-integer>
  7869. case 1:
  7870. this.scanner.next();
  7871. b = consumeB$1.call(this);
  7872. break;
  7873. // '+'? n- <signless-integer>
  7874. case 2:
  7875. expectCharCode.call(this, 1, HYPHENMINUS$3);
  7876. this.scanner.next();
  7877. this.scanner.skipSC();
  7878. checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
  7879. b = '-' + this.consume(NUMBER$3);
  7880. break;
  7881. // '+'? <ndashdigit-ident>
  7882. default:
  7883. expectCharCode.call(this, 1, HYPHENMINUS$3);
  7884. checkInteger$1.call(this, 2, DISALLOW_SIGN$1);
  7885. this.scanner.next();
  7886. b = this.scanner.substrToCursor(start + sign + 1);
  7887. }
  7888. }
  7889. // <ndashdigit-dimension>
  7890. // <ndash-dimension> <signless-integer>
  7891. // <n-dimension>
  7892. // <n-dimension> <signed-integer>
  7893. // <n-dimension> ['+' | '-'] <signless-integer>
  7894. else if (this.scanner.tokenType === DIMENSION$2) {
  7895. var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
  7896. var sign = code === PLUSSIGN$3 || code === HYPHENMINUS$3;
  7897. for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
  7898. if (!isDigit$4(this.scanner.source.charCodeAt(i))) {
  7899. break;
  7900. }
  7901. }
  7902. if (i === this.scanner.tokenStart + sign) {
  7903. this.error('Integer is expected', this.scanner.tokenStart + sign);
  7904. }
  7905. expectCharCode.call(this, i - this.scanner.tokenStart, N$4);
  7906. a = this.scanner.source.substring(start, i);
  7907. // <n-dimension>
  7908. // <n-dimension> <signed-integer>
  7909. // <n-dimension> ['+' | '-'] <signless-integer>
  7910. if (i + 1 === this.scanner.tokenEnd) {
  7911. this.scanner.next();
  7912. b = consumeB$1.call(this);
  7913. } else {
  7914. expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$3);
  7915. // <ndash-dimension> <signless-integer>
  7916. if (i + 2 === this.scanner.tokenEnd) {
  7917. this.scanner.next();
  7918. this.scanner.skipSC();
  7919. checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
  7920. b = '-' + this.consume(NUMBER$3);
  7921. }
  7922. // <ndashdigit-dimension>
  7923. else {
  7924. checkInteger$1.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN$1);
  7925. this.scanner.next();
  7926. b = this.scanner.substrToCursor(i + 1);
  7927. }
  7928. }
  7929. } else {
  7930. this.error();
  7931. }
  7932. if (a !== null && a.charCodeAt(0) === PLUSSIGN$3) {
  7933. a = a.substr(1);
  7934. }
  7935. if (b !== null && b.charCodeAt(0) === PLUSSIGN$3) {
  7936. b = b.substr(1);
  7937. }
  7938. return {
  7939. type: 'AnPlusB',
  7940. loc: this.getLocation(start, this.scanner.tokenStart),
  7941. a: a,
  7942. b: b
  7943. };
  7944. },
  7945. generate: function(node) {
  7946. var a = node.a !== null && node.a !== undefined;
  7947. var b = node.b !== null && node.b !== undefined;
  7948. if (a) {
  7949. this.chunk(
  7950. node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
  7951. node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
  7952. node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
  7953. node.a + 'n' // eslint-disable-line operator-linebreak, indent
  7954. );
  7955. if (b) {
  7956. b = String(node.b);
  7957. if (b.charAt(0) === '-' || b.charAt(0) === '+') {
  7958. this.chunk(b.charAt(0));
  7959. this.chunk(b.substr(1));
  7960. } else {
  7961. this.chunk('+');
  7962. this.chunk(b);
  7963. }
  7964. }
  7965. } else {
  7966. this.chunk(String(node.b));
  7967. }
  7968. }
  7969. };
  7970. var TYPE$a = tokenizer.TYPE;
  7971. var WhiteSpace = TYPE$a.WhiteSpace;
  7972. var Semicolon = TYPE$a.Semicolon;
  7973. var LeftCurlyBracket = TYPE$a.LeftCurlyBracket;
  7974. var Delim = TYPE$a.Delim;
  7975. var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
  7976. function getOffsetExcludeWS() {
  7977. if (this.scanner.tokenIndex > 0) {
  7978. if (this.scanner.lookupType(-1) === WhiteSpace) {
  7979. return this.scanner.tokenIndex > 1
  7980. ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
  7981. : this.scanner.firstCharOffset;
  7982. }
  7983. }
  7984. return this.scanner.tokenStart;
  7985. }
  7986. // 0, 0, false
  7987. function balanceEnd() {
  7988. return 0;
  7989. }
  7990. // LEFTCURLYBRACKET, 0, false
  7991. function leftCurlyBracket(tokenType) {
  7992. return tokenType === LeftCurlyBracket ? 1 : 0;
  7993. }
  7994. // LEFTCURLYBRACKET, SEMICOLON, false
  7995. function leftCurlyBracketOrSemicolon(tokenType) {
  7996. return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
  7997. }
  7998. // EXCLAMATIONMARK, SEMICOLON, false
  7999. function exclamationMarkOrSemicolon(tokenType, source, offset) {
  8000. if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$1) {
  8001. return 1;
  8002. }
  8003. return tokenType === Semicolon ? 1 : 0;
  8004. }
  8005. // 0, SEMICOLON, true
  8006. function semicolonIncluded(tokenType) {
  8007. return tokenType === Semicolon ? 2 : 0;
  8008. }
  8009. var Raw = {
  8010. name: 'Raw',
  8011. structure: {
  8012. value: String
  8013. },
  8014. parse: function(startToken, mode, excludeWhiteSpace) {
  8015. var startOffset = this.scanner.getTokenStart(startToken);
  8016. var endOffset;
  8017. this.scanner.skip(
  8018. this.scanner.getRawLength(startToken, mode || balanceEnd)
  8019. );
  8020. if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
  8021. endOffset = getOffsetExcludeWS.call(this);
  8022. } else {
  8023. endOffset = this.scanner.tokenStart;
  8024. }
  8025. return {
  8026. type: 'Raw',
  8027. loc: this.getLocation(startOffset, endOffset),
  8028. value: this.scanner.source.substring(startOffset, endOffset)
  8029. };
  8030. },
  8031. generate: function(node) {
  8032. this.chunk(node.value);
  8033. },
  8034. mode: {
  8035. default: balanceEnd,
  8036. leftCurlyBracket: leftCurlyBracket,
  8037. leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
  8038. exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
  8039. semicolonIncluded: semicolonIncluded
  8040. }
  8041. };
  8042. var TYPE$b = tokenizer.TYPE;
  8043. var rawMode = Raw.mode;
  8044. var ATKEYWORD = TYPE$b.AtKeyword;
  8045. var SEMICOLON = TYPE$b.Semicolon;
  8046. var LEFTCURLYBRACKET$1 = TYPE$b.LeftCurlyBracket;
  8047. var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
  8048. function consumeRaw(startToken) {
  8049. return this.Raw(startToken, rawMode.leftCurlyBracketOrSemicolon, true);
  8050. }
  8051. function isDeclarationBlockAtrule() {
  8052. for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
  8053. if (type === RIGHTCURLYBRACKET$1) {
  8054. return true;
  8055. }
  8056. if (type === LEFTCURLYBRACKET$1 ||
  8057. type === ATKEYWORD) {
  8058. return false;
  8059. }
  8060. }
  8061. return false;
  8062. }
  8063. var Atrule = {
  8064. name: 'Atrule',
  8065. structure: {
  8066. name: String,
  8067. prelude: ['AtrulePrelude', 'Raw', null],
  8068. block: ['Block', null]
  8069. },
  8070. parse: function() {
  8071. var start = this.scanner.tokenStart;
  8072. var name;
  8073. var nameLowerCase;
  8074. var prelude = null;
  8075. var block = null;
  8076. this.eat(ATKEYWORD);
  8077. name = this.scanner.substrToCursor(start + 1);
  8078. nameLowerCase = name.toLowerCase();
  8079. this.scanner.skipSC();
  8080. // parse prelude
  8081. if (this.scanner.eof === false &&
  8082. this.scanner.tokenType !== LEFTCURLYBRACKET$1 &&
  8083. this.scanner.tokenType !== SEMICOLON) {
  8084. if (this.parseAtrulePrelude) {
  8085. prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
  8086. // turn empty AtrulePrelude into null
  8087. if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
  8088. prelude = null;
  8089. }
  8090. } else {
  8091. prelude = consumeRaw.call(this, this.scanner.tokenIndex);
  8092. }
  8093. this.scanner.skipSC();
  8094. }
  8095. switch (this.scanner.tokenType) {
  8096. case SEMICOLON:
  8097. this.scanner.next();
  8098. break;
  8099. case LEFTCURLYBRACKET$1:
  8100. if (this.atrule.hasOwnProperty(nameLowerCase) &&
  8101. typeof this.atrule[nameLowerCase].block === 'function') {
  8102. block = this.atrule[nameLowerCase].block.call(this);
  8103. } else {
  8104. // TODO: should consume block content as Raw?
  8105. block = this.Block(isDeclarationBlockAtrule.call(this));
  8106. }
  8107. break;
  8108. }
  8109. return {
  8110. type: 'Atrule',
  8111. loc: this.getLocation(start, this.scanner.tokenStart),
  8112. name: name,
  8113. prelude: prelude,
  8114. block: block
  8115. };
  8116. },
  8117. generate: function(node) {
  8118. this.chunk('@');
  8119. this.chunk(node.name);
  8120. if (node.prelude !== null) {
  8121. this.chunk(' ');
  8122. this.node(node.prelude);
  8123. }
  8124. if (node.block) {
  8125. this.node(node.block);
  8126. } else {
  8127. this.chunk(';');
  8128. }
  8129. },
  8130. walkContext: 'atrule'
  8131. };
  8132. var TYPE$c = tokenizer.TYPE;
  8133. var SEMICOLON$1 = TYPE$c.Semicolon;
  8134. var LEFTCURLYBRACKET$2 = TYPE$c.LeftCurlyBracket;
  8135. var AtrulePrelude = {
  8136. name: 'AtrulePrelude',
  8137. structure: {
  8138. children: [[]]
  8139. },
  8140. parse: function(name) {
  8141. var children = null;
  8142. if (name !== null) {
  8143. name = name.toLowerCase();
  8144. }
  8145. this.scanner.skipSC();
  8146. if (this.atrule.hasOwnProperty(name) &&
  8147. typeof this.atrule[name].prelude === 'function') {
  8148. // custom consumer
  8149. children = this.atrule[name].prelude.call(this);
  8150. } else {
  8151. // default consumer
  8152. children = this.readSequence(this.scope.AtrulePrelude);
  8153. }
  8154. this.scanner.skipSC();
  8155. if (this.scanner.eof !== true &&
  8156. this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
  8157. this.scanner.tokenType !== SEMICOLON$1) {
  8158. this.error('Semicolon or block is expected');
  8159. }
  8160. if (children === null) {
  8161. children = this.createList();
  8162. }
  8163. return {
  8164. type: 'AtrulePrelude',
  8165. loc: this.getLocationFromList(children),
  8166. children: children
  8167. };
  8168. },
  8169. generate: function(node) {
  8170. this.children(node);
  8171. },
  8172. walkContext: 'atrulePrelude'
  8173. };
  8174. var TYPE$d = tokenizer.TYPE;
  8175. var IDENT$4 = TYPE$d.Ident;
  8176. var STRING = TYPE$d.String;
  8177. var COLON = TYPE$d.Colon;
  8178. var LEFTSQUAREBRACKET$1 = TYPE$d.LeftSquareBracket;
  8179. var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
  8180. var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
  8181. var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
  8182. var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
  8183. var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
  8184. var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
  8185. var TILDE = 0x007E; // U+007E TILDE (~)
  8186. function getAttributeName() {
  8187. if (this.scanner.eof) {
  8188. this.error('Unexpected end of input');
  8189. }
  8190. var start = this.scanner.tokenStart;
  8191. var expectIdent = false;
  8192. var checkColon = true;
  8193. if (this.scanner.isDelim(ASTERISK$1)) {
  8194. expectIdent = true;
  8195. checkColon = false;
  8196. this.scanner.next();
  8197. } else if (!this.scanner.isDelim(VERTICALLINE$1)) {
  8198. this.eat(IDENT$4);
  8199. }
  8200. if (this.scanner.isDelim(VERTICALLINE$1)) {
  8201. if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
  8202. this.scanner.next();
  8203. this.eat(IDENT$4);
  8204. } else if (expectIdent) {
  8205. this.error('Identifier is expected', this.scanner.tokenEnd);
  8206. }
  8207. } else if (expectIdent) {
  8208. this.error('Vertical line is expected');
  8209. }
  8210. if (checkColon && this.scanner.tokenType === COLON) {
  8211. this.scanner.next();
  8212. this.eat(IDENT$4);
  8213. }
  8214. return {
  8215. type: 'Identifier',
  8216. loc: this.getLocation(start, this.scanner.tokenStart),
  8217. name: this.scanner.substrToCursor(start)
  8218. };
  8219. }
  8220. function getOperator() {
  8221. var start = this.scanner.tokenStart;
  8222. var code = this.scanner.source.charCodeAt(start);
  8223. if (code !== EQUALSSIGN && // =
  8224. code !== TILDE && // ~=
  8225. code !== CIRCUMFLEXACCENT && // ^=
  8226. code !== DOLLARSIGN && // $=
  8227. code !== ASTERISK$1 && // *=
  8228. code !== VERTICALLINE$1 // |=
  8229. ) {
  8230. this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
  8231. }
  8232. this.scanner.next();
  8233. if (code !== EQUALSSIGN) {
  8234. if (!this.scanner.isDelim(EQUALSSIGN)) {
  8235. this.error('Equal sign is expected');
  8236. }
  8237. this.scanner.next();
  8238. }
  8239. return this.scanner.substrToCursor(start);
  8240. }
  8241. // '[' <wq-name> ']'
  8242. // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
  8243. var AttributeSelector = {
  8244. name: 'AttributeSelector',
  8245. structure: {
  8246. name: 'Identifier',
  8247. matcher: [String, null],
  8248. value: ['String', 'Identifier', null],
  8249. flags: [String, null]
  8250. },
  8251. parse: function() {
  8252. var start = this.scanner.tokenStart;
  8253. var name;
  8254. var matcher = null;
  8255. var value = null;
  8256. var flags = null;
  8257. this.eat(LEFTSQUAREBRACKET$1);
  8258. this.scanner.skipSC();
  8259. name = getAttributeName.call(this);
  8260. this.scanner.skipSC();
  8261. if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
  8262. // avoid case `[name i]`
  8263. if (this.scanner.tokenType !== IDENT$4) {
  8264. matcher = getOperator.call(this);
  8265. this.scanner.skipSC();
  8266. value = this.scanner.tokenType === STRING
  8267. ? this.String()
  8268. : this.Identifier();
  8269. this.scanner.skipSC();
  8270. }
  8271. // attribute flags
  8272. if (this.scanner.tokenType === IDENT$4) {
  8273. flags = this.scanner.getTokenValue();
  8274. this.scanner.next();
  8275. this.scanner.skipSC();
  8276. }
  8277. }
  8278. this.eat(RIGHTSQUAREBRACKET$1);
  8279. return {
  8280. type: 'AttributeSelector',
  8281. loc: this.getLocation(start, this.scanner.tokenStart),
  8282. name: name,
  8283. matcher: matcher,
  8284. value: value,
  8285. flags: flags
  8286. };
  8287. },
  8288. generate: function(node) {
  8289. var flagsPrefix = ' ';
  8290. this.chunk('[');
  8291. this.node(node.name);
  8292. if (node.matcher !== null) {
  8293. this.chunk(node.matcher);
  8294. if (node.value !== null) {
  8295. this.node(node.value);
  8296. // space between string and flags is not required
  8297. if (node.value.type === 'String') {
  8298. flagsPrefix = '';
  8299. }
  8300. }
  8301. }
  8302. if (node.flags !== null) {
  8303. this.chunk(flagsPrefix);
  8304. this.chunk(node.flags);
  8305. }
  8306. this.chunk(']');
  8307. }
  8308. };
  8309. var TYPE$e = tokenizer.TYPE;
  8310. var rawMode$1 = Raw.mode;
  8311. var WHITESPACE$5 = TYPE$e.WhiteSpace;
  8312. var COMMENT$4 = TYPE$e.Comment;
  8313. var SEMICOLON$2 = TYPE$e.Semicolon;
  8314. var ATKEYWORD$1 = TYPE$e.AtKeyword;
  8315. var LEFTCURLYBRACKET$3 = TYPE$e.LeftCurlyBracket;
  8316. var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
  8317. function consumeRaw$1(startToken) {
  8318. return this.Raw(startToken, null, true);
  8319. }
  8320. function consumeRule() {
  8321. return this.parseWithFallback(this.Rule, consumeRaw$1);
  8322. }
  8323. function consumeRawDeclaration(startToken) {
  8324. return this.Raw(startToken, rawMode$1.semicolonIncluded, true);
  8325. }
  8326. function consumeDeclaration() {
  8327. if (this.scanner.tokenType === SEMICOLON$2) {
  8328. return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
  8329. }
  8330. var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
  8331. if (this.scanner.tokenType === SEMICOLON$2) {
  8332. this.scanner.next();
  8333. }
  8334. return node;
  8335. }
  8336. var Block = {
  8337. name: 'Block',
  8338. structure: {
  8339. children: [[
  8340. 'Atrule',
  8341. 'Rule',
  8342. 'Declaration'
  8343. ]]
  8344. },
  8345. parse: function(isDeclaration) {
  8346. var consumer = isDeclaration ? consumeDeclaration : consumeRule;
  8347. var start = this.scanner.tokenStart;
  8348. var children = this.createList();
  8349. this.eat(LEFTCURLYBRACKET$3);
  8350. scan:
  8351. while (!this.scanner.eof) {
  8352. switch (this.scanner.tokenType) {
  8353. case RIGHTCURLYBRACKET$2:
  8354. break scan;
  8355. case WHITESPACE$5:
  8356. case COMMENT$4:
  8357. this.scanner.next();
  8358. break;
  8359. case ATKEYWORD$1:
  8360. children.push(this.parseWithFallback(this.Atrule, consumeRaw$1));
  8361. break;
  8362. default:
  8363. children.push(consumer.call(this));
  8364. }
  8365. }
  8366. if (!this.scanner.eof) {
  8367. this.eat(RIGHTCURLYBRACKET$2);
  8368. }
  8369. return {
  8370. type: 'Block',
  8371. loc: this.getLocation(start, this.scanner.tokenStart),
  8372. children: children
  8373. };
  8374. },
  8375. generate: function(node) {
  8376. this.chunk('{');
  8377. this.children(node, function(prev) {
  8378. if (prev.type === 'Declaration') {
  8379. this.chunk(';');
  8380. }
  8381. });
  8382. this.chunk('}');
  8383. },
  8384. walkContext: 'block'
  8385. };
  8386. var TYPE$f = tokenizer.TYPE;
  8387. var LEFTSQUAREBRACKET$2 = TYPE$f.LeftSquareBracket;
  8388. var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
  8389. var Brackets = {
  8390. name: 'Brackets',
  8391. structure: {
  8392. children: [[]]
  8393. },
  8394. parse: function(readSequence, recognizer) {
  8395. var start = this.scanner.tokenStart;
  8396. var children = null;
  8397. this.eat(LEFTSQUAREBRACKET$2);
  8398. children = readSequence.call(this, recognizer);
  8399. if (!this.scanner.eof) {
  8400. this.eat(RIGHTSQUAREBRACKET$2);
  8401. }
  8402. return {
  8403. type: 'Brackets',
  8404. loc: this.getLocation(start, this.scanner.tokenStart),
  8405. children: children
  8406. };
  8407. },
  8408. generate: function(node) {
  8409. this.chunk('[');
  8410. this.children(node);
  8411. this.chunk(']');
  8412. }
  8413. };
  8414. var CDC = tokenizer.TYPE.CDC;
  8415. var CDC_1 = {
  8416. name: 'CDC',
  8417. structure: [],
  8418. parse: function() {
  8419. var start = this.scanner.tokenStart;
  8420. this.eat(CDC); // -->
  8421. return {
  8422. type: 'CDC',
  8423. loc: this.getLocation(start, this.scanner.tokenStart)
  8424. };
  8425. },
  8426. generate: function() {
  8427. this.chunk('-->');
  8428. }
  8429. };
  8430. var CDO = tokenizer.TYPE.CDO;
  8431. var CDO_1 = {
  8432. name: 'CDO',
  8433. structure: [],
  8434. parse: function() {
  8435. var start = this.scanner.tokenStart;
  8436. this.eat(CDO); // <!--
  8437. return {
  8438. type: 'CDO',
  8439. loc: this.getLocation(start, this.scanner.tokenStart)
  8440. };
  8441. },
  8442. generate: function() {
  8443. this.chunk('<!--');
  8444. }
  8445. };
  8446. var TYPE$g = tokenizer.TYPE;
  8447. var IDENT$5 = TYPE$g.Ident;
  8448. var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
  8449. // '.' ident
  8450. var ClassSelector = {
  8451. name: 'ClassSelector',
  8452. structure: {
  8453. name: String
  8454. },
  8455. parse: function() {
  8456. if (!this.scanner.isDelim(FULLSTOP)) {
  8457. this.error('Full stop is expected');
  8458. }
  8459. this.scanner.next();
  8460. return {
  8461. type: 'ClassSelector',
  8462. loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
  8463. name: this.consume(IDENT$5)
  8464. };
  8465. },
  8466. generate: function(node) {
  8467. this.chunk('.');
  8468. this.chunk(node.name);
  8469. }
  8470. };
  8471. var TYPE$h = tokenizer.TYPE;
  8472. var IDENT$6 = TYPE$h.Ident;
  8473. var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
  8474. var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
  8475. var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
  8476. var TILDE$1 = 0x007E; // U+007E TILDE (~)
  8477. // + | > | ~ | /deep/
  8478. var Combinator = {
  8479. name: 'Combinator',
  8480. structure: {
  8481. name: String
  8482. },
  8483. parse: function() {
  8484. var start = this.scanner.tokenStart;
  8485. var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
  8486. switch (code) {
  8487. case GREATERTHANSIGN$1:
  8488. case PLUSSIGN$4:
  8489. case TILDE$1:
  8490. this.scanner.next();
  8491. break;
  8492. case SOLIDUS:
  8493. this.scanner.next();
  8494. if (this.scanner.tokenType !== IDENT$6 || this.scanner.lookupValue(0, 'deep') === false) {
  8495. this.error('Identifier `deep` is expected');
  8496. }
  8497. this.scanner.next();
  8498. if (!this.scanner.isDelim(SOLIDUS)) {
  8499. this.error('Solidus is expected');
  8500. }
  8501. this.scanner.next();
  8502. break;
  8503. default:
  8504. this.error('Combinator is expected');
  8505. }
  8506. return {
  8507. type: 'Combinator',
  8508. loc: this.getLocation(start, this.scanner.tokenStart),
  8509. name: this.scanner.substrToCursor(start)
  8510. };
  8511. },
  8512. generate: function(node) {
  8513. this.chunk(node.name);
  8514. }
  8515. };
  8516. var TYPE$i = tokenizer.TYPE;
  8517. var COMMENT$5 = TYPE$i.Comment;
  8518. var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
  8519. var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
  8520. // '/*' .* '*/'
  8521. var Comment = {
  8522. name: 'Comment',
  8523. structure: {
  8524. value: String
  8525. },
  8526. parse: function() {
  8527. var start = this.scanner.tokenStart;
  8528. var end = this.scanner.tokenEnd;
  8529. this.eat(COMMENT$5);
  8530. if ((end - start + 2) >= 2 &&
  8531. this.scanner.source.charCodeAt(end - 2) === ASTERISK$2 &&
  8532. this.scanner.source.charCodeAt(end - 1) === SOLIDUS$1) {
  8533. end -= 2;
  8534. }
  8535. return {
  8536. type: 'Comment',
  8537. loc: this.getLocation(start, this.scanner.tokenStart),
  8538. value: this.scanner.source.substring(start + 2, end)
  8539. };
  8540. },
  8541. generate: function(node) {
  8542. this.chunk('/*');
  8543. this.chunk(node.value);
  8544. this.chunk('*/');
  8545. }
  8546. };
  8547. var isCustomProperty$1 = names.isCustomProperty;
  8548. var TYPE$j = tokenizer.TYPE;
  8549. var rawMode$2 = Raw.mode;
  8550. var IDENT$7 = TYPE$j.Ident;
  8551. var HASH$1 = TYPE$j.Hash;
  8552. var COLON$1 = TYPE$j.Colon;
  8553. var SEMICOLON$3 = TYPE$j.Semicolon;
  8554. var DELIM$2 = TYPE$j.Delim;
  8555. var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
  8556. var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
  8557. var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
  8558. var AMPERSAND$1 = 0x0026; // U+0026 ANPERSAND (&)
  8559. var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
  8560. var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
  8561. var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
  8562. function consumeValueRaw(startToken) {
  8563. return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, true);
  8564. }
  8565. function consumeCustomPropertyRaw(startToken) {
  8566. return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, false);
  8567. }
  8568. function consumeValue() {
  8569. var startValueToken = this.scanner.tokenIndex;
  8570. var value = this.Value();
  8571. if (value.type !== 'Raw' &&
  8572. this.scanner.eof === false &&
  8573. this.scanner.tokenType !== SEMICOLON$3 &&
  8574. this.scanner.isDelim(EXCLAMATIONMARK$2) === false &&
  8575. this.scanner.isBalanceEdge(startValueToken) === false) {
  8576. this.error();
  8577. }
  8578. return value;
  8579. }
  8580. var Declaration = {
  8581. name: 'Declaration',
  8582. structure: {
  8583. important: [Boolean, String],
  8584. property: String,
  8585. value: ['Value', 'Raw']
  8586. },
  8587. parse: function() {
  8588. var start = this.scanner.tokenStart;
  8589. var startToken = this.scanner.tokenIndex;
  8590. var property = readProperty$1.call(this);
  8591. var customProperty = isCustomProperty$1(property);
  8592. var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
  8593. var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
  8594. var important = false;
  8595. var value;
  8596. this.scanner.skipSC();
  8597. this.eat(COLON$1);
  8598. if (!customProperty) {
  8599. this.scanner.skipSC();
  8600. }
  8601. if (parseValue) {
  8602. value = this.parseWithFallback(consumeValue, consumeRaw);
  8603. } else {
  8604. value = consumeRaw.call(this, this.scanner.tokenIndex);
  8605. }
  8606. if (this.scanner.isDelim(EXCLAMATIONMARK$2)) {
  8607. important = getImportant.call(this);
  8608. this.scanner.skipSC();
  8609. }
  8610. // Do not include semicolon to range per spec
  8611. // https://drafts.csswg.org/css-syntax/#declaration-diagram
  8612. if (this.scanner.eof === false &&
  8613. this.scanner.tokenType !== SEMICOLON$3 &&
  8614. this.scanner.isBalanceEdge(startToken) === false) {
  8615. this.error();
  8616. }
  8617. return {
  8618. type: 'Declaration',
  8619. loc: this.getLocation(start, this.scanner.tokenStart),
  8620. important: important,
  8621. property: property,
  8622. value: value
  8623. };
  8624. },
  8625. generate: function(node) {
  8626. this.chunk(node.property);
  8627. this.chunk(':');
  8628. this.node(node.value);
  8629. if (node.important) {
  8630. this.chunk(node.important === true ? '!important' : '!' + node.important);
  8631. }
  8632. },
  8633. walkContext: 'declaration'
  8634. };
  8635. function readProperty$1() {
  8636. var start = this.scanner.tokenStart;
  8637. // hacks
  8638. if (this.scanner.tokenType === DELIM$2) {
  8639. switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
  8640. case ASTERISK$3:
  8641. case DOLLARSIGN$1:
  8642. case PLUSSIGN$5:
  8643. case NUMBERSIGN$2:
  8644. case AMPERSAND$1:
  8645. this.scanner.next();
  8646. break;
  8647. // TODO: not sure we should support this hack
  8648. case SOLIDUS$2:
  8649. this.scanner.next();
  8650. if (this.scanner.isDelim(SOLIDUS$2)) {
  8651. this.scanner.next();
  8652. }
  8653. break;
  8654. }
  8655. }
  8656. if (this.scanner.tokenType === HASH$1) {
  8657. this.eat(HASH$1);
  8658. } else {
  8659. this.eat(IDENT$7);
  8660. }
  8661. return this.scanner.substrToCursor(start);
  8662. }
  8663. // ! ws* important
  8664. function getImportant() {
  8665. this.eat(DELIM$2);
  8666. this.scanner.skipSC();
  8667. var important = this.consume(IDENT$7);
  8668. // store original value in case it differ from `important`
  8669. // for better original source restoring and hacks like `!ie` support
  8670. return important === 'important' ? true : important;
  8671. }
  8672. var TYPE$k = tokenizer.TYPE;
  8673. var rawMode$3 = Raw.mode;
  8674. var WHITESPACE$6 = TYPE$k.WhiteSpace;
  8675. var COMMENT$6 = TYPE$k.Comment;
  8676. var SEMICOLON$4 = TYPE$k.Semicolon;
  8677. function consumeRaw$2(startToken) {
  8678. return this.Raw(startToken, rawMode$3.semicolonIncluded, true);
  8679. }
  8680. var DeclarationList = {
  8681. name: 'DeclarationList',
  8682. structure: {
  8683. children: [[
  8684. 'Declaration'
  8685. ]]
  8686. },
  8687. parse: function() {
  8688. var children = this.createList();
  8689. scan:
  8690. while (!this.scanner.eof) {
  8691. switch (this.scanner.tokenType) {
  8692. case WHITESPACE$6:
  8693. case COMMENT$6:
  8694. case SEMICOLON$4:
  8695. this.scanner.next();
  8696. break;
  8697. default:
  8698. children.push(this.parseWithFallback(this.Declaration, consumeRaw$2));
  8699. }
  8700. }
  8701. return {
  8702. type: 'DeclarationList',
  8703. loc: this.getLocationFromList(children),
  8704. children: children
  8705. };
  8706. },
  8707. generate: function(node) {
  8708. this.children(node, function(prev) {
  8709. if (prev.type === 'Declaration') {
  8710. this.chunk(';');
  8711. }
  8712. });
  8713. }
  8714. };
  8715. var consumeNumber$3 = utils.consumeNumber;
  8716. var TYPE$l = tokenizer.TYPE;
  8717. var DIMENSION$3 = TYPE$l.Dimension;
  8718. var Dimension = {
  8719. name: 'Dimension',
  8720. structure: {
  8721. value: String,
  8722. unit: String
  8723. },
  8724. parse: function() {
  8725. var start = this.scanner.tokenStart;
  8726. var numberEnd = consumeNumber$3(this.scanner.source, start);
  8727. this.eat(DIMENSION$3);
  8728. return {
  8729. type: 'Dimension',
  8730. loc: this.getLocation(start, this.scanner.tokenStart),
  8731. value: this.scanner.source.substring(start, numberEnd),
  8732. unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
  8733. };
  8734. },
  8735. generate: function(node) {
  8736. this.chunk(node.value);
  8737. this.chunk(node.unit);
  8738. }
  8739. };
  8740. var TYPE$m = tokenizer.TYPE;
  8741. var RIGHTPARENTHESIS$2 = TYPE$m.RightParenthesis;
  8742. // <function-token> <sequence> )
  8743. var _Function = {
  8744. name: 'Function',
  8745. structure: {
  8746. name: String,
  8747. children: [[]]
  8748. },
  8749. parse: function(readSequence, recognizer) {
  8750. var start = this.scanner.tokenStart;
  8751. var name = this.consumeFunctionName();
  8752. var nameLowerCase = name.toLowerCase();
  8753. var children;
  8754. children = recognizer.hasOwnProperty(nameLowerCase)
  8755. ? recognizer[nameLowerCase].call(this, recognizer)
  8756. : readSequence.call(this, recognizer);
  8757. if (!this.scanner.eof) {
  8758. this.eat(RIGHTPARENTHESIS$2);
  8759. }
  8760. return {
  8761. type: 'Function',
  8762. loc: this.getLocation(start, this.scanner.tokenStart),
  8763. name: name,
  8764. children: children
  8765. };
  8766. },
  8767. generate: function(node) {
  8768. this.chunk(node.name);
  8769. this.chunk('(');
  8770. this.children(node);
  8771. this.chunk(')');
  8772. },
  8773. walkContext: 'function'
  8774. };
  8775. var TYPE$n = tokenizer.TYPE;
  8776. var HASH$2 = TYPE$n.Hash;
  8777. // '#' ident
  8778. var HexColor = {
  8779. name: 'HexColor',
  8780. structure: {
  8781. value: String
  8782. },
  8783. parse: function() {
  8784. var start = this.scanner.tokenStart;
  8785. this.eat(HASH$2);
  8786. return {
  8787. type: 'HexColor',
  8788. loc: this.getLocation(start, this.scanner.tokenStart),
  8789. value: this.scanner.substrToCursor(start + 1)
  8790. };
  8791. },
  8792. generate: function(node) {
  8793. this.chunk('#');
  8794. this.chunk(node.value);
  8795. }
  8796. };
  8797. var TYPE$o = tokenizer.TYPE;
  8798. var IDENT$8 = TYPE$o.Ident;
  8799. var Identifier = {
  8800. name: 'Identifier',
  8801. structure: {
  8802. name: String
  8803. },
  8804. parse: function() {
  8805. return {
  8806. type: 'Identifier',
  8807. loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
  8808. name: this.consume(IDENT$8)
  8809. };
  8810. },
  8811. generate: function(node) {
  8812. this.chunk(node.name);
  8813. }
  8814. };
  8815. var TYPE$p = tokenizer.TYPE;
  8816. var HASH$3 = TYPE$p.Hash;
  8817. // <hash-token>
  8818. var IdSelector = {
  8819. name: 'IdSelector',
  8820. structure: {
  8821. name: String
  8822. },
  8823. parse: function() {
  8824. var start = this.scanner.tokenStart;
  8825. // TODO: check value is an ident
  8826. this.eat(HASH$3);
  8827. return {
  8828. type: 'IdSelector',
  8829. loc: this.getLocation(start, this.scanner.tokenStart),
  8830. name: this.scanner.substrToCursor(start + 1)
  8831. };
  8832. },
  8833. generate: function(node) {
  8834. this.chunk('#');
  8835. this.chunk(node.name);
  8836. }
  8837. };
  8838. var TYPE$q = tokenizer.TYPE;
  8839. var IDENT$9 = TYPE$q.Ident;
  8840. var NUMBER$4 = TYPE$q.Number;
  8841. var DIMENSION$4 = TYPE$q.Dimension;
  8842. var LEFTPARENTHESIS$2 = TYPE$q.LeftParenthesis;
  8843. var RIGHTPARENTHESIS$3 = TYPE$q.RightParenthesis;
  8844. var COLON$2 = TYPE$q.Colon;
  8845. var DELIM$3 = TYPE$q.Delim;
  8846. var MediaFeature = {
  8847. name: 'MediaFeature',
  8848. structure: {
  8849. name: String,
  8850. value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
  8851. },
  8852. parse: function() {
  8853. var start = this.scanner.tokenStart;
  8854. var name;
  8855. var value = null;
  8856. this.eat(LEFTPARENTHESIS$2);
  8857. this.scanner.skipSC();
  8858. name = this.consume(IDENT$9);
  8859. this.scanner.skipSC();
  8860. if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
  8861. this.eat(COLON$2);
  8862. this.scanner.skipSC();
  8863. switch (this.scanner.tokenType) {
  8864. case NUMBER$4:
  8865. if (this.lookupNonWSType(1) === DELIM$3) {
  8866. value = this.Ratio();
  8867. } else {
  8868. value = this.Number();
  8869. }
  8870. break;
  8871. case DIMENSION$4:
  8872. value = this.Dimension();
  8873. break;
  8874. case IDENT$9:
  8875. value = this.Identifier();
  8876. break;
  8877. default:
  8878. this.error('Number, dimension, ratio or identifier is expected');
  8879. }
  8880. this.scanner.skipSC();
  8881. }
  8882. this.eat(RIGHTPARENTHESIS$3);
  8883. return {
  8884. type: 'MediaFeature',
  8885. loc: this.getLocation(start, this.scanner.tokenStart),
  8886. name: name,
  8887. value: value
  8888. };
  8889. },
  8890. generate: function(node) {
  8891. this.chunk('(');
  8892. this.chunk(node.name);
  8893. if (node.value !== null) {
  8894. this.chunk(':');
  8895. this.node(node.value);
  8896. }
  8897. this.chunk(')');
  8898. }
  8899. };
  8900. var TYPE$r = tokenizer.TYPE;
  8901. var WHITESPACE$7 = TYPE$r.WhiteSpace;
  8902. var COMMENT$7 = TYPE$r.Comment;
  8903. var IDENT$a = TYPE$r.Ident;
  8904. var LEFTPARENTHESIS$3 = TYPE$r.LeftParenthesis;
  8905. var MediaQuery = {
  8906. name: 'MediaQuery',
  8907. structure: {
  8908. children: [[
  8909. 'Identifier',
  8910. 'MediaFeature',
  8911. 'WhiteSpace'
  8912. ]]
  8913. },
  8914. parse: function() {
  8915. this.scanner.skipSC();
  8916. var children = this.createList();
  8917. var child = null;
  8918. var space = null;
  8919. scan:
  8920. while (!this.scanner.eof) {
  8921. switch (this.scanner.tokenType) {
  8922. case COMMENT$7:
  8923. this.scanner.next();
  8924. continue;
  8925. case WHITESPACE$7:
  8926. space = this.WhiteSpace();
  8927. continue;
  8928. case IDENT$a:
  8929. child = this.Identifier();
  8930. break;
  8931. case LEFTPARENTHESIS$3:
  8932. child = this.MediaFeature();
  8933. break;
  8934. default:
  8935. break scan;
  8936. }
  8937. if (space !== null) {
  8938. children.push(space);
  8939. space = null;
  8940. }
  8941. children.push(child);
  8942. }
  8943. if (child === null) {
  8944. this.error('Identifier or parenthesis is expected');
  8945. }
  8946. return {
  8947. type: 'MediaQuery',
  8948. loc: this.getLocationFromList(children),
  8949. children: children
  8950. };
  8951. },
  8952. generate: function(node) {
  8953. this.children(node);
  8954. }
  8955. };
  8956. var COMMA$1 = tokenizer.TYPE.Comma;
  8957. var MediaQueryList = {
  8958. name: 'MediaQueryList',
  8959. structure: {
  8960. children: [[
  8961. 'MediaQuery'
  8962. ]]
  8963. },
  8964. parse: function(relative) {
  8965. var children = this.createList();
  8966. this.scanner.skipSC();
  8967. while (!this.scanner.eof) {
  8968. children.push(this.MediaQuery(relative));
  8969. if (this.scanner.tokenType !== COMMA$1) {
  8970. break;
  8971. }
  8972. this.scanner.next();
  8973. }
  8974. return {
  8975. type: 'MediaQueryList',
  8976. loc: this.getLocationFromList(children),
  8977. children: children
  8978. };
  8979. },
  8980. generate: function(node) {
  8981. this.children(node, function() {
  8982. this.chunk(',');
  8983. });
  8984. }
  8985. };
  8986. var Nth = {
  8987. name: 'Nth',
  8988. structure: {
  8989. nth: ['AnPlusB', 'Identifier'],
  8990. selector: ['SelectorList', null]
  8991. },
  8992. parse: function(allowOfClause) {
  8993. this.scanner.skipSC();
  8994. var start = this.scanner.tokenStart;
  8995. var end = start;
  8996. var selector = null;
  8997. var query;
  8998. if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
  8999. query = this.Identifier();
  9000. } else {
  9001. query = this.AnPlusB();
  9002. }
  9003. this.scanner.skipSC();
  9004. if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
  9005. this.scanner.next();
  9006. selector = this.SelectorList();
  9007. if (this.needPositions) {
  9008. end = this.getLastListNode(selector.children).loc.end.offset;
  9009. }
  9010. } else {
  9011. if (this.needPositions) {
  9012. end = query.loc.end.offset;
  9013. }
  9014. }
  9015. return {
  9016. type: 'Nth',
  9017. loc: this.getLocation(start, end),
  9018. nth: query,
  9019. selector: selector
  9020. };
  9021. },
  9022. generate: function(node) {
  9023. this.node(node.nth);
  9024. if (node.selector !== null) {
  9025. this.chunk(' of ');
  9026. this.node(node.selector);
  9027. }
  9028. }
  9029. };
  9030. var NUMBER$5 = tokenizer.TYPE.Number;
  9031. var _Number = {
  9032. name: 'Number',
  9033. structure: {
  9034. value: String
  9035. },
  9036. parse: function() {
  9037. return {
  9038. type: 'Number',
  9039. loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
  9040. value: this.consume(NUMBER$5)
  9041. };
  9042. },
  9043. generate: function(node) {
  9044. this.chunk(node.value);
  9045. }
  9046. };
  9047. // '/' | '*' | ',' | ':' | '+' | '-'
  9048. var Operator = {
  9049. name: 'Operator',
  9050. structure: {
  9051. value: String
  9052. },
  9053. parse: function() {
  9054. var start = this.scanner.tokenStart;
  9055. this.scanner.next();
  9056. return {
  9057. type: 'Operator',
  9058. loc: this.getLocation(start, this.scanner.tokenStart),
  9059. value: this.scanner.substrToCursor(start)
  9060. };
  9061. },
  9062. generate: function(node) {
  9063. this.chunk(node.value);
  9064. }
  9065. };
  9066. var TYPE$s = tokenizer.TYPE;
  9067. var LEFTPARENTHESIS$4 = TYPE$s.LeftParenthesis;
  9068. var RIGHTPARENTHESIS$4 = TYPE$s.RightParenthesis;
  9069. var Parentheses = {
  9070. name: 'Parentheses',
  9071. structure: {
  9072. children: [[]]
  9073. },
  9074. parse: function(readSequence, recognizer) {
  9075. var start = this.scanner.tokenStart;
  9076. var children = null;
  9077. this.eat(LEFTPARENTHESIS$4);
  9078. children = readSequence.call(this, recognizer);
  9079. if (!this.scanner.eof) {
  9080. this.eat(RIGHTPARENTHESIS$4);
  9081. }
  9082. return {
  9083. type: 'Parentheses',
  9084. loc: this.getLocation(start, this.scanner.tokenStart),
  9085. children: children
  9086. };
  9087. },
  9088. generate: function(node) {
  9089. this.chunk('(');
  9090. this.children(node);
  9091. this.chunk(')');
  9092. }
  9093. };
  9094. var consumeNumber$4 = utils.consumeNumber;
  9095. var TYPE$t = tokenizer.TYPE;
  9096. var PERCENTAGE$1 = TYPE$t.Percentage;
  9097. var Percentage = {
  9098. name: 'Percentage',
  9099. structure: {
  9100. value: String
  9101. },
  9102. parse: function() {
  9103. var start = this.scanner.tokenStart;
  9104. var numberEnd = consumeNumber$4(this.scanner.source, start);
  9105. this.eat(PERCENTAGE$1);
  9106. return {
  9107. type: 'Percentage',
  9108. loc: this.getLocation(start, this.scanner.tokenStart),
  9109. value: this.scanner.source.substring(start, numberEnd)
  9110. };
  9111. },
  9112. generate: function(node) {
  9113. this.chunk(node.value);
  9114. this.chunk('%');
  9115. }
  9116. };
  9117. var TYPE$u = tokenizer.TYPE;
  9118. var IDENT$b = TYPE$u.Ident;
  9119. var FUNCTION$1 = TYPE$u.Function;
  9120. var COLON$3 = TYPE$u.Colon;
  9121. var RIGHTPARENTHESIS$5 = TYPE$u.RightParenthesis;
  9122. // : [ <ident> | <function-token> <any-value>? ) ]
  9123. var PseudoClassSelector = {
  9124. name: 'PseudoClassSelector',
  9125. structure: {
  9126. name: String,
  9127. children: [['Raw'], null]
  9128. },
  9129. parse: function() {
  9130. var start = this.scanner.tokenStart;
  9131. var children = null;
  9132. var name;
  9133. var nameLowerCase;
  9134. this.eat(COLON$3);
  9135. if (this.scanner.tokenType === FUNCTION$1) {
  9136. name = this.consumeFunctionName();
  9137. nameLowerCase = name.toLowerCase();
  9138. if (this.pseudo.hasOwnProperty(nameLowerCase)) {
  9139. this.scanner.skipSC();
  9140. children = this.pseudo[nameLowerCase].call(this);
  9141. this.scanner.skipSC();
  9142. } else {
  9143. children = this.createList();
  9144. children.push(
  9145. this.Raw(this.scanner.tokenIndex, null, false)
  9146. );
  9147. }
  9148. this.eat(RIGHTPARENTHESIS$5);
  9149. } else {
  9150. name = this.consume(IDENT$b);
  9151. }
  9152. return {
  9153. type: 'PseudoClassSelector',
  9154. loc: this.getLocation(start, this.scanner.tokenStart),
  9155. name: name,
  9156. children: children
  9157. };
  9158. },
  9159. generate: function(node) {
  9160. this.chunk(':');
  9161. this.chunk(node.name);
  9162. if (node.children !== null) {
  9163. this.chunk('(');
  9164. this.children(node);
  9165. this.chunk(')');
  9166. }
  9167. },
  9168. walkContext: 'function'
  9169. };
  9170. var TYPE$v = tokenizer.TYPE;
  9171. var IDENT$c = TYPE$v.Ident;
  9172. var FUNCTION$2 = TYPE$v.Function;
  9173. var COLON$4 = TYPE$v.Colon;
  9174. var RIGHTPARENTHESIS$6 = TYPE$v.RightParenthesis;
  9175. // :: [ <ident> | <function-token> <any-value>? ) ]
  9176. var PseudoElementSelector = {
  9177. name: 'PseudoElementSelector',
  9178. structure: {
  9179. name: String,
  9180. children: [['Raw'], null]
  9181. },
  9182. parse: function() {
  9183. var start = this.scanner.tokenStart;
  9184. var children = null;
  9185. var name;
  9186. var nameLowerCase;
  9187. this.eat(COLON$4);
  9188. this.eat(COLON$4);
  9189. if (this.scanner.tokenType === FUNCTION$2) {
  9190. name = this.consumeFunctionName();
  9191. nameLowerCase = name.toLowerCase();
  9192. if (this.pseudo.hasOwnProperty(nameLowerCase)) {
  9193. this.scanner.skipSC();
  9194. children = this.pseudo[nameLowerCase].call(this);
  9195. this.scanner.skipSC();
  9196. } else {
  9197. children = this.createList();
  9198. children.push(
  9199. this.Raw(this.scanner.tokenIndex, null, false)
  9200. );
  9201. }
  9202. this.eat(RIGHTPARENTHESIS$6);
  9203. } else {
  9204. name = this.consume(IDENT$c);
  9205. }
  9206. return {
  9207. type: 'PseudoElementSelector',
  9208. loc: this.getLocation(start, this.scanner.tokenStart),
  9209. name: name,
  9210. children: children
  9211. };
  9212. },
  9213. generate: function(node) {
  9214. this.chunk('::');
  9215. this.chunk(node.name);
  9216. if (node.children !== null) {
  9217. this.chunk('(');
  9218. this.children(node);
  9219. this.chunk(')');
  9220. }
  9221. },
  9222. walkContext: 'function'
  9223. };
  9224. var isDigit$5 = tokenizer.isDigit;
  9225. var TYPE$w = tokenizer.TYPE;
  9226. var NUMBER$6 = TYPE$w.Number;
  9227. var DELIM$4 = TYPE$w.Delim;
  9228. var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
  9229. var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
  9230. // Terms of <ratio> should be a positive numbers (not zero or negative)
  9231. // (see https://drafts.csswg.org/mediaqueries-3/#values)
  9232. // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
  9233. // and this is using by various sites. Therefore we relax checking on parse
  9234. // to test a term is unsigned number without an exponent part.
  9235. // Additional checking may be applied on lexer validation.
  9236. function consumeNumber$5() {
  9237. this.scanner.skipWS();
  9238. var value = this.consume(NUMBER$6);
  9239. for (var i = 0; i < value.length; i++) {
  9240. var code = value.charCodeAt(i);
  9241. if (!isDigit$5(code) && code !== FULLSTOP$1) {
  9242. this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
  9243. }
  9244. }
  9245. if (Number(value) === 0) {
  9246. this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
  9247. }
  9248. return value;
  9249. }
  9250. // <positive-integer> S* '/' S* <positive-integer>
  9251. var Ratio = {
  9252. name: 'Ratio',
  9253. structure: {
  9254. left: String,
  9255. right: String
  9256. },
  9257. parse: function() {
  9258. var start = this.scanner.tokenStart;
  9259. var left = consumeNumber$5.call(this);
  9260. var right;
  9261. this.scanner.skipWS();
  9262. if (!this.scanner.isDelim(SOLIDUS$3)) {
  9263. this.error('Solidus is expected');
  9264. }
  9265. this.eat(DELIM$4);
  9266. right = consumeNumber$5.call(this);
  9267. return {
  9268. type: 'Ratio',
  9269. loc: this.getLocation(start, this.scanner.tokenStart),
  9270. left: left,
  9271. right: right
  9272. };
  9273. },
  9274. generate: function(node) {
  9275. this.chunk(node.left);
  9276. this.chunk('/');
  9277. this.chunk(node.right);
  9278. }
  9279. };
  9280. var TYPE$x = tokenizer.TYPE;
  9281. var rawMode$4 = Raw.mode;
  9282. var LEFTCURLYBRACKET$4 = TYPE$x.LeftCurlyBracket;
  9283. function consumeRaw$3(startToken) {
  9284. return this.Raw(startToken, rawMode$4.leftCurlyBracket, true);
  9285. }
  9286. function consumePrelude() {
  9287. var prelude = this.SelectorList();
  9288. if (prelude.type !== 'Raw' &&
  9289. this.scanner.eof === false &&
  9290. this.scanner.tokenType !== LEFTCURLYBRACKET$4) {
  9291. this.error();
  9292. }
  9293. return prelude;
  9294. }
  9295. var Rule = {
  9296. name: 'Rule',
  9297. structure: {
  9298. prelude: ['SelectorList', 'Raw'],
  9299. block: ['Block']
  9300. },
  9301. parse: function() {
  9302. var startToken = this.scanner.tokenIndex;
  9303. var startOffset = this.scanner.tokenStart;
  9304. var prelude;
  9305. var block;
  9306. if (this.parseRulePrelude) {
  9307. prelude = this.parseWithFallback(consumePrelude, consumeRaw$3);
  9308. } else {
  9309. prelude = consumeRaw$3.call(this, startToken);
  9310. }
  9311. block = this.Block(true);
  9312. return {
  9313. type: 'Rule',
  9314. loc: this.getLocation(startOffset, this.scanner.tokenStart),
  9315. prelude: prelude,
  9316. block: block
  9317. };
  9318. },
  9319. generate: function(node) {
  9320. this.node(node.prelude);
  9321. this.node(node.block);
  9322. },
  9323. walkContext: 'rule'
  9324. };
  9325. var Selector = {
  9326. name: 'Selector',
  9327. structure: {
  9328. children: [[
  9329. 'TypeSelector',
  9330. 'IdSelector',
  9331. 'ClassSelector',
  9332. 'AttributeSelector',
  9333. 'PseudoClassSelector',
  9334. 'PseudoElementSelector',
  9335. 'Combinator',
  9336. 'WhiteSpace'
  9337. ]]
  9338. },
  9339. parse: function() {
  9340. var children = this.readSequence(this.scope.Selector);
  9341. // nothing were consumed
  9342. if (this.getFirstListNode(children) === null) {
  9343. this.error('Selector is expected');
  9344. }
  9345. return {
  9346. type: 'Selector',
  9347. loc: this.getLocationFromList(children),
  9348. children: children
  9349. };
  9350. },
  9351. generate: function(node) {
  9352. this.children(node);
  9353. }
  9354. };
  9355. var TYPE$y = tokenizer.TYPE;
  9356. var COMMA$2 = TYPE$y.Comma;
  9357. var SelectorList = {
  9358. name: 'SelectorList',
  9359. structure: {
  9360. children: [[
  9361. 'Selector',
  9362. 'Raw'
  9363. ]]
  9364. },
  9365. parse: function() {
  9366. var children = this.createList();
  9367. while (!this.scanner.eof) {
  9368. children.push(this.Selector());
  9369. if (this.scanner.tokenType === COMMA$2) {
  9370. this.scanner.next();
  9371. continue;
  9372. }
  9373. break;
  9374. }
  9375. return {
  9376. type: 'SelectorList',
  9377. loc: this.getLocationFromList(children),
  9378. children: children
  9379. };
  9380. },
  9381. generate: function(node) {
  9382. this.children(node, function() {
  9383. this.chunk(',');
  9384. });
  9385. },
  9386. walkContext: 'selector'
  9387. };
  9388. var STRING$1 = tokenizer.TYPE.String;
  9389. var _String = {
  9390. name: 'String',
  9391. structure: {
  9392. value: String
  9393. },
  9394. parse: function() {
  9395. return {
  9396. type: 'String',
  9397. loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
  9398. value: this.consume(STRING$1)
  9399. };
  9400. },
  9401. generate: function(node) {
  9402. this.chunk(node.value);
  9403. }
  9404. };
  9405. var TYPE$z = tokenizer.TYPE;
  9406. var WHITESPACE$8 = TYPE$z.WhiteSpace;
  9407. var COMMENT$8 = TYPE$z.Comment;
  9408. var ATKEYWORD$2 = TYPE$z.AtKeyword;
  9409. var CDO$1 = TYPE$z.CDO;
  9410. var CDC$1 = TYPE$z.CDC;
  9411. var EXCLAMATIONMARK$3 = 0x0021; // U+0021 EXCLAMATION MARK (!)
  9412. function consumeRaw$4(startToken) {
  9413. return this.Raw(startToken, null, false);
  9414. }
  9415. var StyleSheet = {
  9416. name: 'StyleSheet',
  9417. structure: {
  9418. children: [[
  9419. 'Comment',
  9420. 'CDO',
  9421. 'CDC',
  9422. 'Atrule',
  9423. 'Rule',
  9424. 'Raw'
  9425. ]]
  9426. },
  9427. parse: function() {
  9428. var start = this.scanner.tokenStart;
  9429. var children = this.createList();
  9430. var child;
  9431. scan:
  9432. while (!this.scanner.eof) {
  9433. switch (this.scanner.tokenType) {
  9434. case WHITESPACE$8:
  9435. this.scanner.next();
  9436. continue;
  9437. case COMMENT$8:
  9438. // ignore comments except exclamation comments (i.e. /*! .. */) on top level
  9439. if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
  9440. this.scanner.next();
  9441. continue;
  9442. }
  9443. child = this.Comment();
  9444. break;
  9445. case CDO$1: // <!--
  9446. child = this.CDO();
  9447. break;
  9448. case CDC$1: // -->
  9449. child = this.CDC();
  9450. break;
  9451. // CSS Syntax Module Level 3
  9452. // §2.2 Error handling
  9453. // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
  9454. case ATKEYWORD$2:
  9455. child = this.parseWithFallback(this.Atrule, consumeRaw$4);
  9456. break;
  9457. // Anything else starts a qualified rule ...
  9458. default:
  9459. child = this.parseWithFallback(this.Rule, consumeRaw$4);
  9460. }
  9461. children.push(child);
  9462. }
  9463. return {
  9464. type: 'StyleSheet',
  9465. loc: this.getLocation(start, this.scanner.tokenStart),
  9466. children: children
  9467. };
  9468. },
  9469. generate: function(node) {
  9470. this.children(node);
  9471. },
  9472. walkContext: 'stylesheet'
  9473. };
  9474. var TYPE$A = tokenizer.TYPE;
  9475. var IDENT$d = TYPE$A.Ident;
  9476. var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
  9477. var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
  9478. function eatIdentifierOrAsterisk() {
  9479. if (this.scanner.tokenType !== IDENT$d &&
  9480. this.scanner.isDelim(ASTERISK$4) === false) {
  9481. this.error('Identifier or asterisk is expected');
  9482. }
  9483. this.scanner.next();
  9484. }
  9485. // ident
  9486. // ident|ident
  9487. // ident|*
  9488. // *
  9489. // *|ident
  9490. // *|*
  9491. // |ident
  9492. // |*
  9493. var TypeSelector = {
  9494. name: 'TypeSelector',
  9495. structure: {
  9496. name: String
  9497. },
  9498. parse: function() {
  9499. var start = this.scanner.tokenStart;
  9500. if (this.scanner.isDelim(VERTICALLINE$2)) {
  9501. this.scanner.next();
  9502. eatIdentifierOrAsterisk.call(this);
  9503. } else {
  9504. eatIdentifierOrAsterisk.call(this);
  9505. if (this.scanner.isDelim(VERTICALLINE$2)) {
  9506. this.scanner.next();
  9507. eatIdentifierOrAsterisk.call(this);
  9508. }
  9509. }
  9510. return {
  9511. type: 'TypeSelector',
  9512. loc: this.getLocation(start, this.scanner.tokenStart),
  9513. name: this.scanner.substrToCursor(start)
  9514. };
  9515. },
  9516. generate: function(node) {
  9517. this.chunk(node.name);
  9518. }
  9519. };
  9520. var isHexDigit$4 = tokenizer.isHexDigit;
  9521. var cmpChar$4 = tokenizer.cmpChar;
  9522. var TYPE$B = tokenizer.TYPE;
  9523. var NAME$3 = tokenizer.NAME;
  9524. var IDENT$e = TYPE$B.Ident;
  9525. var NUMBER$7 = TYPE$B.Number;
  9526. var DIMENSION$5 = TYPE$B.Dimension;
  9527. var PLUSSIGN$6 = 0x002B; // U+002B PLUS SIGN (+)
  9528. var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
  9529. var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
  9530. var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
  9531. function eatHexSequence(offset, allowDash) {
  9532. for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
  9533. var code = this.scanner.source.charCodeAt(pos);
  9534. if (code === HYPHENMINUS$4 && allowDash && len !== 0) {
  9535. if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
  9536. this.error();
  9537. }
  9538. return -1;
  9539. }
  9540. if (!isHexDigit$4(code)) {
  9541. this.error(
  9542. allowDash && len !== 0
  9543. ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
  9544. : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
  9545. pos
  9546. );
  9547. }
  9548. if (++len > 6) {
  9549. this.error('Too many hex digits', pos);
  9550. } }
  9551. this.scanner.next();
  9552. return len;
  9553. }
  9554. function eatQuestionMarkSequence(max) {
  9555. var count = 0;
  9556. while (this.scanner.isDelim(QUESTIONMARK$2)) {
  9557. if (++count > max) {
  9558. this.error('Too many question marks');
  9559. }
  9560. this.scanner.next();
  9561. }
  9562. }
  9563. function startsWith$1(code) {
  9564. if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
  9565. this.error(NAME$3[code] + ' is expected');
  9566. }
  9567. }
  9568. // https://drafts.csswg.org/css-syntax/#urange
  9569. // Informally, the <urange> production has three forms:
  9570. // U+0001
  9571. // Defines a range consisting of a single code point, in this case the code point "1".
  9572. // U+0001-00ff
  9573. // Defines a range of codepoints between the first and the second value, in this case
  9574. // the range between "1" and "ff" (255 in decimal) inclusive.
  9575. // U+00??
  9576. // Defines a range of codepoints where the "?" characters range over all hex digits,
  9577. // in this case defining the same as the value U+0000-00ff.
  9578. // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
  9579. //
  9580. // <urange> =
  9581. // u '+' <ident-token> '?'* |
  9582. // u <dimension-token> '?'* |
  9583. // u <number-token> '?'* |
  9584. // u <number-token> <dimension-token> |
  9585. // u <number-token> <number-token> |
  9586. // u '+' '?'+
  9587. function scanUnicodeRange() {
  9588. var hexLength = 0;
  9589. // u '+' <ident-token> '?'*
  9590. // u '+' '?'+
  9591. if (this.scanner.isDelim(PLUSSIGN$6)) {
  9592. this.scanner.next();
  9593. if (this.scanner.tokenType === IDENT$e) {
  9594. hexLength = eatHexSequence.call(this, 0, true);
  9595. if (hexLength > 0) {
  9596. eatQuestionMarkSequence.call(this, 6 - hexLength);
  9597. }
  9598. return;
  9599. }
  9600. if (this.scanner.isDelim(QUESTIONMARK$2)) {
  9601. this.scanner.next();
  9602. eatQuestionMarkSequence.call(this, 5);
  9603. return;
  9604. }
  9605. this.error('Hex digit or question mark is expected');
  9606. return;
  9607. }
  9608. // u <number-token> '?'*
  9609. // u <number-token> <dimension-token>
  9610. // u <number-token> <number-token>
  9611. if (this.scanner.tokenType === NUMBER$7) {
  9612. startsWith$1.call(this, PLUSSIGN$6);
  9613. hexLength = eatHexSequence.call(this, 1, true);
  9614. if (this.scanner.isDelim(QUESTIONMARK$2)) {
  9615. eatQuestionMarkSequence.call(this, 6 - hexLength);
  9616. return;
  9617. }
  9618. if (this.scanner.tokenType === DIMENSION$5 ||
  9619. this.scanner.tokenType === NUMBER$7) {
  9620. startsWith$1.call(this, HYPHENMINUS$4);
  9621. eatHexSequence.call(this, 1, false);
  9622. return;
  9623. }
  9624. return;
  9625. }
  9626. // u <dimension-token> '?'*
  9627. if (this.scanner.tokenType === DIMENSION$5) {
  9628. startsWith$1.call(this, PLUSSIGN$6);
  9629. hexLength = eatHexSequence.call(this, 1, true);
  9630. if (hexLength > 0) {
  9631. eatQuestionMarkSequence.call(this, 6 - hexLength);
  9632. }
  9633. return;
  9634. }
  9635. this.error();
  9636. }
  9637. var UnicodeRange = {
  9638. name: 'UnicodeRange',
  9639. structure: {
  9640. value: String
  9641. },
  9642. parse: function() {
  9643. var start = this.scanner.tokenStart;
  9644. // U or u
  9645. if (!cmpChar$4(this.scanner.source, start, U$1)) {
  9646. this.error('U is expected');
  9647. }
  9648. if (!cmpChar$4(this.scanner.source, start + 1, PLUSSIGN$6)) {
  9649. this.error('Plus sign is expected');
  9650. }
  9651. this.scanner.next();
  9652. scanUnicodeRange.call(this);
  9653. return {
  9654. type: 'UnicodeRange',
  9655. loc: this.getLocation(start, this.scanner.tokenStart),
  9656. value: this.scanner.substrToCursor(start)
  9657. };
  9658. },
  9659. generate: function(node) {
  9660. this.chunk(node.value);
  9661. }
  9662. };
  9663. var isWhiteSpace$2 = tokenizer.isWhiteSpace;
  9664. var cmpStr$4 = tokenizer.cmpStr;
  9665. var TYPE$C = tokenizer.TYPE;
  9666. var FUNCTION$3 = TYPE$C.Function;
  9667. var URL$1 = TYPE$C.Url;
  9668. var RIGHTPARENTHESIS$7 = TYPE$C.RightParenthesis;
  9669. // <url-token> | <function-token> <string> )
  9670. var Url = {
  9671. name: 'Url',
  9672. structure: {
  9673. value: ['String', 'Raw']
  9674. },
  9675. parse: function() {
  9676. var start = this.scanner.tokenStart;
  9677. var value;
  9678. switch (this.scanner.tokenType) {
  9679. case URL$1:
  9680. var rawStart = start + 4;
  9681. var rawEnd = this.scanner.tokenEnd - 1;
  9682. while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawStart))) {
  9683. rawStart++;
  9684. }
  9685. while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawEnd - 1))) {
  9686. rawEnd--;
  9687. }
  9688. value = {
  9689. type: 'Raw',
  9690. loc: this.getLocation(rawStart, rawEnd),
  9691. value: this.scanner.source.substring(rawStart, rawEnd)
  9692. };
  9693. this.eat(URL$1);
  9694. break;
  9695. case FUNCTION$3:
  9696. if (!cmpStr$4(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
  9697. this.error('Function name must be `url`');
  9698. }
  9699. this.eat(FUNCTION$3);
  9700. this.scanner.skipSC();
  9701. value = this.String();
  9702. this.scanner.skipSC();
  9703. this.eat(RIGHTPARENTHESIS$7);
  9704. break;
  9705. default:
  9706. this.error('Url or Function is expected');
  9707. }
  9708. return {
  9709. type: 'Url',
  9710. loc: this.getLocation(start, this.scanner.tokenStart),
  9711. value: value
  9712. };
  9713. },
  9714. generate: function(node) {
  9715. this.chunk('url');
  9716. this.chunk('(');
  9717. this.node(node.value);
  9718. this.chunk(')');
  9719. }
  9720. };
  9721. var Value = {
  9722. name: 'Value',
  9723. structure: {
  9724. children: [[]]
  9725. },
  9726. parse: function() {
  9727. var start = this.scanner.tokenStart;
  9728. var children = this.readSequence(this.scope.Value);
  9729. return {
  9730. type: 'Value',
  9731. loc: this.getLocation(start, this.scanner.tokenStart),
  9732. children: children
  9733. };
  9734. },
  9735. generate: function(node) {
  9736. this.children(node);
  9737. }
  9738. };
  9739. var WHITESPACE$9 = tokenizer.TYPE.WhiteSpace;
  9740. var SPACE$2 = Object.freeze({
  9741. type: 'WhiteSpace',
  9742. loc: null,
  9743. value: ' '
  9744. });
  9745. var WhiteSpace$1 = {
  9746. name: 'WhiteSpace',
  9747. structure: {
  9748. value: String
  9749. },
  9750. parse: function() {
  9751. this.eat(WHITESPACE$9);
  9752. return SPACE$2;
  9753. // return {
  9754. // type: 'WhiteSpace',
  9755. // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
  9756. // value: this.consume(WHITESPACE)
  9757. // };
  9758. },
  9759. generate: function(node) {
  9760. this.chunk(node.value);
  9761. }
  9762. };
  9763. var node = {
  9764. AnPlusB: AnPlusB,
  9765. Atrule: Atrule,
  9766. AtrulePrelude: AtrulePrelude,
  9767. AttributeSelector: AttributeSelector,
  9768. Block: Block,
  9769. Brackets: Brackets,
  9770. CDC: CDC_1,
  9771. CDO: CDO_1,
  9772. ClassSelector: ClassSelector,
  9773. Combinator: Combinator,
  9774. Comment: Comment,
  9775. Declaration: Declaration,
  9776. DeclarationList: DeclarationList,
  9777. Dimension: Dimension,
  9778. Function: _Function,
  9779. HexColor: HexColor,
  9780. Identifier: Identifier,
  9781. IdSelector: IdSelector,
  9782. MediaFeature: MediaFeature,
  9783. MediaQuery: MediaQuery,
  9784. MediaQueryList: MediaQueryList,
  9785. Nth: Nth,
  9786. Number: _Number,
  9787. Operator: Operator,
  9788. Parentheses: Parentheses,
  9789. Percentage: Percentage,
  9790. PseudoClassSelector: PseudoClassSelector,
  9791. PseudoElementSelector: PseudoElementSelector,
  9792. Ratio: Ratio,
  9793. Raw: Raw,
  9794. Rule: Rule,
  9795. Selector: Selector,
  9796. SelectorList: SelectorList,
  9797. String: _String,
  9798. StyleSheet: StyleSheet,
  9799. TypeSelector: TypeSelector,
  9800. UnicodeRange: UnicodeRange,
  9801. Url: Url,
  9802. Value: Value,
  9803. WhiteSpace: WhiteSpace$1
  9804. };
  9805. var data = getCjsExportFromNamespace(defaultSyntax$1);
  9806. var lexer = {
  9807. generic: true,
  9808. types: data.types,
  9809. properties: data.properties,
  9810. node: node
  9811. };
  9812. var cmpChar$5 = tokenizer.cmpChar;
  9813. var cmpStr$5 = tokenizer.cmpStr;
  9814. var TYPE$D = tokenizer.TYPE;
  9815. var IDENT$f = TYPE$D.Ident;
  9816. var STRING$2 = TYPE$D.String;
  9817. var NUMBER$8 = TYPE$D.Number;
  9818. var FUNCTION$4 = TYPE$D.Function;
  9819. var URL$2 = TYPE$D.Url;
  9820. var HASH$4 = TYPE$D.Hash;
  9821. var DIMENSION$6 = TYPE$D.Dimension;
  9822. var PERCENTAGE$2 = TYPE$D.Percentage;
  9823. var LEFTPARENTHESIS$5 = TYPE$D.LeftParenthesis;
  9824. var LEFTSQUAREBRACKET$3 = TYPE$D.LeftSquareBracket;
  9825. var COMMA$3 = TYPE$D.Comma;
  9826. var DELIM$5 = TYPE$D.Delim;
  9827. var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
  9828. var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
  9829. var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
  9830. var HYPHENMINUS$5 = 0x002D; // U+002D HYPHEN-MINUS (-)
  9831. var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
  9832. var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
  9833. var _default = function defaultRecognizer(context) {
  9834. switch (this.scanner.tokenType) {
  9835. case HASH$4:
  9836. return this.HexColor();
  9837. case COMMA$3:
  9838. context.space = null;
  9839. context.ignoreWSAfter = true;
  9840. return this.Operator();
  9841. case LEFTPARENTHESIS$5:
  9842. return this.Parentheses(this.readSequence, context.recognizer);
  9843. case LEFTSQUAREBRACKET$3:
  9844. return this.Brackets(this.readSequence, context.recognizer);
  9845. case STRING$2:
  9846. return this.String();
  9847. case DIMENSION$6:
  9848. return this.Dimension();
  9849. case PERCENTAGE$2:
  9850. return this.Percentage();
  9851. case NUMBER$8:
  9852. return this.Number();
  9853. case FUNCTION$4:
  9854. return cmpStr$5(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
  9855. ? this.Url()
  9856. : this.Function(this.readSequence, context.recognizer);
  9857. case URL$2:
  9858. return this.Url();
  9859. case IDENT$f:
  9860. // check for unicode range, it should start with u+ or U+
  9861. if (cmpChar$5(this.scanner.source, this.scanner.tokenStart, U$2) &&
  9862. cmpChar$5(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$7)) {
  9863. return this.UnicodeRange();
  9864. } else {
  9865. return this.Identifier();
  9866. }
  9867. case DELIM$5:
  9868. var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
  9869. if (code === SOLIDUS$4 ||
  9870. code === ASTERISK$5 ||
  9871. code === PLUSSIGN$7 ||
  9872. code === HYPHENMINUS$5) {
  9873. return this.Operator(); // TODO: replace with Delim
  9874. }
  9875. // TODO: produce a node with Delim node type
  9876. if (code === NUMBERSIGN$3) {
  9877. this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
  9878. }
  9879. break;
  9880. }
  9881. };
  9882. var atrulePrelude = {
  9883. getNode: _default
  9884. };
  9885. var TYPE$E = tokenizer.TYPE;
  9886. var DELIM$6 = TYPE$E.Delim;
  9887. var IDENT$g = TYPE$E.Ident;
  9888. var DIMENSION$7 = TYPE$E.Dimension;
  9889. var PERCENTAGE$3 = TYPE$E.Percentage;
  9890. var NUMBER$9 = TYPE$E.Number;
  9891. var HASH$5 = TYPE$E.Hash;
  9892. var COLON$5 = TYPE$E.Colon;
  9893. var LEFTSQUAREBRACKET$4 = TYPE$E.LeftSquareBracket;
  9894. var NUMBERSIGN$4 = 0x0023; // U+0023 NUMBER SIGN (#)
  9895. var ASTERISK$6 = 0x002A; // U+002A ASTERISK (*)
  9896. var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
  9897. var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
  9898. var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
  9899. var GREATERTHANSIGN$2 = 0x003E; // U+003E GREATER-THAN SIGN (>)
  9900. var VERTICALLINE$3 = 0x007C; // U+007C VERTICAL LINE (|)
  9901. var TILDE$2 = 0x007E; // U+007E TILDE (~)
  9902. function getNode(context) {
  9903. switch (this.scanner.tokenType) {
  9904. case LEFTSQUAREBRACKET$4:
  9905. return this.AttributeSelector();
  9906. case HASH$5:
  9907. return this.IdSelector();
  9908. case COLON$5:
  9909. if (this.scanner.lookupType(1) === COLON$5) {
  9910. return this.PseudoElementSelector();
  9911. } else {
  9912. return this.PseudoClassSelector();
  9913. }
  9914. case IDENT$g:
  9915. return this.TypeSelector();
  9916. case NUMBER$9:
  9917. case PERCENTAGE$3:
  9918. return this.Percentage();
  9919. case DIMENSION$7:
  9920. // throws when .123ident
  9921. if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP$2) {
  9922. this.error('Identifier is expected', this.scanner.tokenStart + 1);
  9923. }
  9924. break;
  9925. case DELIM$6:
  9926. var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
  9927. switch (code) {
  9928. case PLUSSIGN$8:
  9929. case GREATERTHANSIGN$2:
  9930. case TILDE$2:
  9931. context.space = null;
  9932. context.ignoreWSAfter = true;
  9933. return this.Combinator();
  9934. case SOLIDUS$5: // /deep/
  9935. return this.Combinator();
  9936. case FULLSTOP$2:
  9937. return this.ClassSelector();
  9938. case ASTERISK$6:
  9939. case VERTICALLINE$3:
  9940. return this.TypeSelector();
  9941. case NUMBERSIGN$4:
  9942. return this.IdSelector();
  9943. }
  9944. break;
  9945. }
  9946. }
  9947. var selector = {
  9948. getNode: getNode
  9949. };
  9950. // https://drafts.csswg.org/css-images-4/#element-notation
  9951. // https://developer.mozilla.org/en-US/docs/Web/CSS/element
  9952. var element = function() {
  9953. this.scanner.skipSC();
  9954. var children = this.createSingleNodeList(
  9955. this.IdSelector()
  9956. );
  9957. this.scanner.skipSC();
  9958. return children;
  9959. };
  9960. // legacy IE function
  9961. // expression( <any-value> )
  9962. var expression = function() {
  9963. return this.createSingleNodeList(
  9964. this.Raw(this.scanner.tokenIndex, null, false)
  9965. );
  9966. };
  9967. var TYPE$F = tokenizer.TYPE;
  9968. var rawMode$5 = Raw.mode;
  9969. var COMMA$4 = TYPE$F.Comma;
  9970. // var( <ident> , <value>? )
  9971. var _var = function() {
  9972. var children = this.createList();
  9973. this.scanner.skipSC();
  9974. // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
  9975. children.push(this.Identifier());
  9976. this.scanner.skipSC();
  9977. if (this.scanner.tokenType === COMMA$4) {
  9978. children.push(this.Operator());
  9979. children.push(this.parseCustomProperty
  9980. ? this.Value(null)
  9981. : this.Raw(this.scanner.tokenIndex, rawMode$5.exclamationMarkOrSemicolon, false)
  9982. );
  9983. }
  9984. return children;
  9985. };
  9986. var value = {
  9987. getNode: _default,
  9988. '-moz-element': element,
  9989. 'element': element,
  9990. 'expression': expression,
  9991. 'var': _var
  9992. };
  9993. var scope = {
  9994. AtrulePrelude: atrulePrelude,
  9995. Selector: selector,
  9996. Value: value
  9997. };
  9998. var fontFace = {
  9999. parse: {
  10000. prelude: null,
  10001. block: function() {
  10002. return this.Block(true);
  10003. }
  10004. }
  10005. };
  10006. var TYPE$G = tokenizer.TYPE;
  10007. var STRING$3 = TYPE$G.String;
  10008. var IDENT$h = TYPE$G.Ident;
  10009. var URL$3 = TYPE$G.Url;
  10010. var FUNCTION$5 = TYPE$G.Function;
  10011. var LEFTPARENTHESIS$6 = TYPE$G.LeftParenthesis;
  10012. var _import = {
  10013. parse: {
  10014. prelude: function() {
  10015. var children = this.createList();
  10016. this.scanner.skipSC();
  10017. switch (this.scanner.tokenType) {
  10018. case STRING$3:
  10019. children.push(this.String());
  10020. break;
  10021. case URL$3:
  10022. case FUNCTION$5:
  10023. children.push(this.Url());
  10024. break;
  10025. default:
  10026. this.error('String or url() is expected');
  10027. }
  10028. if (this.lookupNonWSType(0) === IDENT$h ||
  10029. this.lookupNonWSType(0) === LEFTPARENTHESIS$6) {
  10030. children.push(this.WhiteSpace());
  10031. children.push(this.MediaQueryList());
  10032. }
  10033. return children;
  10034. },
  10035. block: null
  10036. }
  10037. };
  10038. var media = {
  10039. parse: {
  10040. prelude: function() {
  10041. return this.createSingleNodeList(
  10042. this.MediaQueryList()
  10043. );
  10044. },
  10045. block: function() {
  10046. return this.Block(false);
  10047. }
  10048. }
  10049. };
  10050. var page = {
  10051. parse: {
  10052. prelude: function() {
  10053. return this.createSingleNodeList(
  10054. this.SelectorList()
  10055. );
  10056. },
  10057. block: function() {
  10058. return this.Block(true);
  10059. }
  10060. }
  10061. };
  10062. var TYPE$H = tokenizer.TYPE;
  10063. var WHITESPACE$a = TYPE$H.WhiteSpace;
  10064. var COMMENT$9 = TYPE$H.Comment;
  10065. var IDENT$i = TYPE$H.Ident;
  10066. var FUNCTION$6 = TYPE$H.Function;
  10067. var COLON$6 = TYPE$H.Colon;
  10068. var LEFTPARENTHESIS$7 = TYPE$H.LeftParenthesis;
  10069. function consumeRaw$5() {
  10070. return this.createSingleNodeList(
  10071. this.Raw(this.scanner.tokenIndex, null, false)
  10072. );
  10073. }
  10074. function parentheses() {
  10075. this.scanner.skipSC();
  10076. if (this.scanner.tokenType === IDENT$i &&
  10077. this.lookupNonWSType(1) === COLON$6) {
  10078. return this.createSingleNodeList(
  10079. this.Declaration()
  10080. );
  10081. }
  10082. return readSequence.call(this);
  10083. }
  10084. function readSequence() {
  10085. var children = this.createList();
  10086. var space = null;
  10087. var child;
  10088. this.scanner.skipSC();
  10089. scan:
  10090. while (!this.scanner.eof) {
  10091. switch (this.scanner.tokenType) {
  10092. case WHITESPACE$a:
  10093. space = this.WhiteSpace();
  10094. continue;
  10095. case COMMENT$9:
  10096. this.scanner.next();
  10097. continue;
  10098. case FUNCTION$6:
  10099. child = this.Function(consumeRaw$5, this.scope.AtrulePrelude);
  10100. break;
  10101. case IDENT$i:
  10102. child = this.Identifier();
  10103. break;
  10104. case LEFTPARENTHESIS$7:
  10105. child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
  10106. break;
  10107. default:
  10108. break scan;
  10109. }
  10110. if (space !== null) {
  10111. children.push(space);
  10112. space = null;
  10113. }
  10114. children.push(child);
  10115. }
  10116. return children;
  10117. }
  10118. var supports = {
  10119. parse: {
  10120. prelude: function() {
  10121. var children = readSequence.call(this);
  10122. if (this.getFirstListNode(children) === null) {
  10123. this.error('Condition is expected');
  10124. }
  10125. return children;
  10126. },
  10127. block: function() {
  10128. return this.Block(false);
  10129. }
  10130. }
  10131. };
  10132. var atrule = {
  10133. 'font-face': fontFace,
  10134. 'import': _import,
  10135. 'media': media,
  10136. 'page': page,
  10137. 'supports': supports
  10138. };
  10139. var dir = {
  10140. parse: function() {
  10141. return this.createSingleNodeList(
  10142. this.Identifier()
  10143. );
  10144. }
  10145. };
  10146. var has$1 = {
  10147. parse: function() {
  10148. return this.createSingleNodeList(
  10149. this.SelectorList()
  10150. );
  10151. }
  10152. };
  10153. var lang = {
  10154. parse: function() {
  10155. return this.createSingleNodeList(
  10156. this.Identifier()
  10157. );
  10158. }
  10159. };
  10160. var selectorList = {
  10161. parse: function selectorList() {
  10162. return this.createSingleNodeList(
  10163. this.SelectorList()
  10164. );
  10165. }
  10166. };
  10167. var matches = selectorList;
  10168. var not = selectorList;
  10169. var ALLOW_OF_CLAUSE = true;
  10170. var nthWithOfClause = {
  10171. parse: function nthWithOfClause() {
  10172. return this.createSingleNodeList(
  10173. this.Nth(ALLOW_OF_CLAUSE)
  10174. );
  10175. }
  10176. };
  10177. var nthChild = nthWithOfClause;
  10178. var nthLastChild = nthWithOfClause;
  10179. var DISALLOW_OF_CLAUSE = false;
  10180. var nth = {
  10181. parse: function nth() {
  10182. return this.createSingleNodeList(
  10183. this.Nth(DISALLOW_OF_CLAUSE)
  10184. );
  10185. }
  10186. };
  10187. var nthLastOfType = nth;
  10188. var nthOfType = nth;
  10189. var slotted = {
  10190. parse: function compoundSelector() {
  10191. return this.createSingleNodeList(
  10192. this.Selector()
  10193. );
  10194. }
  10195. };
  10196. var pseudo = {
  10197. 'dir': dir,
  10198. 'has': has$1,
  10199. 'lang': lang,
  10200. 'matches': matches,
  10201. 'not': not,
  10202. 'nth-child': nthChild,
  10203. 'nth-last-child': nthLastChild,
  10204. 'nth-last-of-type': nthLastOfType,
  10205. 'nth-of-type': nthOfType,
  10206. 'slotted': slotted
  10207. };
  10208. var parser = {
  10209. parseContext: {
  10210. default: 'StyleSheet',
  10211. stylesheet: 'StyleSheet',
  10212. atrule: 'Atrule',
  10213. atrulePrelude: function(options) {
  10214. return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
  10215. },
  10216. mediaQueryList: 'MediaQueryList',
  10217. mediaQuery: 'MediaQuery',
  10218. rule: 'Rule',
  10219. selectorList: 'SelectorList',
  10220. selector: 'Selector',
  10221. block: function() {
  10222. return this.Block(true);
  10223. },
  10224. declarationList: 'DeclarationList',
  10225. declaration: 'Declaration',
  10226. value: 'Value'
  10227. },
  10228. scope: scope,
  10229. atrule: atrule,
  10230. pseudo: pseudo,
  10231. node: node
  10232. };
  10233. var walker = {
  10234. node: node
  10235. };
  10236. function merge() {
  10237. var dest = {};
  10238. for (var i = 0; i < arguments.length; i++) {
  10239. var src = arguments[i];
  10240. for (var key in src) {
  10241. dest[key] = src[key];
  10242. }
  10243. }
  10244. return dest;
  10245. }
  10246. var syntax = create$4.create(
  10247. merge(
  10248. lexer,
  10249. parser,
  10250. walker
  10251. )
  10252. );
  10253. var lib = syntax;
  10254. return lib;
  10255. }));