Feature.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import {
  2. Ident,
  3. Number,
  4. Dimension,
  5. Function as FunctionToken,
  6. LeftParenthesis,
  7. RightParenthesis,
  8. Colon,
  9. Delim
  10. } from '../../tokenizer/index.js';
  11. const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
  12. export const name = 'Feature';
  13. export const structure = {
  14. kind: String,
  15. name: String,
  16. value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null]
  17. };
  18. export function parse(kind) {
  19. const start = this.tokenStart;
  20. let name;
  21. let value = null;
  22. this.eat(LeftParenthesis);
  23. this.skipSC();
  24. name = this.consume(Ident);
  25. this.skipSC();
  26. if (this.tokenType !== RightParenthesis) {
  27. this.eat(Colon);
  28. this.skipSC();
  29. switch (this.tokenType) {
  30. case Number:
  31. if (this.lookupNonWSType(1) === Delim) {
  32. value = this.Ratio();
  33. } else {
  34. value = this.Number();
  35. }
  36. break;
  37. case Dimension:
  38. value = this.Dimension();
  39. break;
  40. case Ident:
  41. value = this.Identifier();
  42. break;
  43. case FunctionToken:
  44. value = this.parseWithFallback(
  45. () => {
  46. const res = this.Function(this.readSequence, this.scope.Value);
  47. this.skipSC();
  48. if (this.isDelim(SOLIDUS)) {
  49. this.error();
  50. }
  51. return res;
  52. },
  53. () => {
  54. return this.Ratio();
  55. }
  56. );
  57. break;
  58. default:
  59. this.error('Number, dimension, ratio or identifier is expected');
  60. }
  61. this.skipSC();
  62. }
  63. if (!this.eof) {
  64. this.eat(RightParenthesis);
  65. }
  66. return {
  67. type: 'Feature',
  68. loc: this.getLocation(start, this.tokenStart),
  69. kind,
  70. name,
  71. value
  72. };
  73. }
  74. export function generate(node) {
  75. this.token(LeftParenthesis, '(');
  76. this.token(Ident, node.name);
  77. if (node.value !== null) {
  78. this.token(Colon, ':');
  79. this.node(node.value);
  80. }
  81. this.token(RightParenthesis, ')');
  82. }