Ratio.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import {
  2. Delim,
  3. Number as NumberToken,
  4. Function as FunctionToken
  5. } from '../../tokenizer/index.js';
  6. const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
  7. // Media Queries Level 3 defines terms of <ratio> as a positive (not zero or negative)
  8. // integers (see https://drafts.csswg.org/mediaqueries-3/#values)
  9. // However, Media Queries Level 4 removes any definition of values
  10. // (see https://drafts.csswg.org/mediaqueries-4/#values) and refers to
  11. // CSS Values and Units for detail. In CSS Values and Units Level 4 a <ratio>
  12. // definition was added (see https://drafts.csswg.org/css-values-4/#ratios) which
  13. // defines ratio as "<number [0,∞]> [ / <number [0,∞]> ]?" and based on it
  14. // any constrains on terms were removed. Parser also doesn't test numbers
  15. // in any way to make possible for linting and fixing them by the tools using CSSTree.
  16. // An additional syntax examination may be applied by a lexer.
  17. function consumeTerm() {
  18. this.skipSC();
  19. switch (this.tokenType) {
  20. case NumberToken:
  21. return this.Number();
  22. case FunctionToken:
  23. return this.Function(this.readSequence, this.scope.Value);
  24. default:
  25. this.error('Number of function is expected');
  26. }
  27. }
  28. export const name = 'Ratio';
  29. export const structure = {
  30. left: ['Number', 'Function'],
  31. right: ['Number', 'Function', null]
  32. };
  33. // <number [0,∞]> [ / <number [0,∞]> ]?
  34. export function parse() {
  35. const start = this.tokenStart;
  36. const left = consumeTerm.call(this);
  37. let right = null;
  38. this.skipSC();
  39. if (this.isDelim(SOLIDUS)) {
  40. this.eatDelim(SOLIDUS);
  41. right = consumeTerm.call(this);
  42. }
  43. return {
  44. type: 'Ratio',
  45. loc: this.getLocation(start, this.tokenStart),
  46. left,
  47. right
  48. };
  49. }
  50. export function generate(node) {
  51. this.node(node.left);
  52. this.token(Delim, '/');
  53. if (node.right) {
  54. this.node(node.right);
  55. } else {
  56. this.node(NumberToken, 1);
  57. }
  58. }