feature-range.cjs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. 'use strict';
  2. const types = require('../../../tokenizer/types.cjs');
  3. const LESSTHANSIGN = 60; // <
  4. const EQUALSIGN = 61; // =
  5. const GREATERTHANSIGN = 62; // >
  6. const structure = {
  7. left: ['Identifier', 'Number', 'Dimension', 'Ratio'],
  8. leftComparison: String,
  9. middle: ['Identifier', 'Number', 'Dimension', 'Ratio'],
  10. rightComparison: [String, null],
  11. right: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
  12. };
  13. function readTerm() {
  14. this.skipSC();
  15. switch (this.tokenType) {
  16. case types.Number:
  17. if (this.lookupNonWSType(1) === types.Delim) {
  18. return this.Ratio();
  19. } else {
  20. return this.Number();
  21. }
  22. case types.Dimension:
  23. return this.Dimension();
  24. case types.Ident:
  25. return this.Identifier();
  26. default:
  27. this.error('Number, dimension, ratio or identifier is expected');
  28. }
  29. }
  30. function readComparison(expectColon) {
  31. this.skipSC();
  32. if (this.isDelim(LESSTHANSIGN) ||
  33. this.isDelim(GREATERTHANSIGN)) {
  34. const value = this.source[this.tokenStart];
  35. this.next();
  36. if (this.isDelim(EQUALSIGN)) {
  37. this.next();
  38. return value + '=';
  39. }
  40. return value;
  41. }
  42. if (this.isDelim(EQUALSIGN)) {
  43. return '=';
  44. }
  45. this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`);
  46. }
  47. function createParse(type) {
  48. return function parse() {
  49. const start = this.tokenStart;
  50. this.skipSC();
  51. this.eat(types.LeftParenthesis);
  52. const left = readTerm.call(this);
  53. const leftComparison = readComparison.call(this, left.type === 'Identifier');
  54. const middle = readTerm.call(this);
  55. let rightComparison = null;
  56. let right = null;
  57. if (this.lookupNonWSType(0) !== types.RightParenthesis) {
  58. rightComparison = readComparison.call(this);
  59. right = readTerm.call(this);
  60. }
  61. this.skipSC();
  62. this.eat(types.RightParenthesis);
  63. return {
  64. type,
  65. loc: this.getLocation(start, this.tokenStart),
  66. left,
  67. leftComparison,
  68. middle,
  69. rightComparison,
  70. right
  71. };
  72. };
  73. }
  74. function generate(node) {
  75. this.token(types.LeftParenthesis, '(');
  76. this.node(node.left);
  77. this.tokenize(node.leftComparison);
  78. this.node(node.middle);
  79. if (node.right) {
  80. this.tokenize(node.rightComparison);
  81. this.node(node.right);
  82. }
  83. this.token(types.RightParenthesis, ')');
  84. }
  85. exports.createParse = createParse;
  86. exports.generate = generate;
  87. exports.structure = structure;