@eslint/css-tree 3.5.3 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,91 @@ const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs');
7
7
  const types = require('../tokenizer/types.cjs');
8
8
  const utils = require('../tokenizer/utils.cjs');
9
9
 
10
- const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
10
+ // CSS mathematical functions categorized by return type behavior
11
+ // See: https://www.w3.org/TR/css-values-4/#math
12
+
13
+ // Calculation functions that return different types depending on input
14
+ const calcFunctionNames = [
15
+ 'calc(',
16
+ '-moz-calc(',
17
+ '-webkit-calc('
18
+ ];
19
+
20
+ // Comparison functions that return different types depending on input
21
+ const comparisonFunctionNames = [
22
+ 'min(',
23
+ 'max(',
24
+ 'clamp('
25
+ ];
26
+
27
+ // Functions that return a stepped value, i.e. a value that is rounded to the nearest step
28
+ const steppedValueFunctionNames = [
29
+ 'round(',
30
+ 'mod(',
31
+ 'rem('
32
+ ];
33
+
34
+ // Trigonometrical functions that return a <number>
35
+ const trigNumberFunctionNames = [
36
+ 'sin(',
37
+ 'cos(',
38
+ 'tan('
39
+ ];
40
+
41
+ // Trigonometrical functions that return a <angle>
42
+ const trigAngleFunctionNames = [
43
+ 'asin(',
44
+ 'acos(',
45
+ 'atan(',
46
+ 'atan2('
47
+ ];
48
+
49
+ // Other functions that return a <number>
50
+ const otherNumberFunctionNames = [
51
+ 'pow(',
52
+ 'sqrt(',
53
+ 'log(',
54
+ 'exp(',
55
+ 'sign('
56
+ ];
57
+
58
+ // Exponential functions that return a <number> or <dimension> or <percentage>
59
+ const expNumberDimensionPercentageFunctionNames = [
60
+ 'hypot('
61
+ ];
62
+
63
+ // Return the same type as the input
64
+ const signFunctionNames = [
65
+ 'abs('
66
+ ];
67
+
68
+ const numberFunctionNames = [
69
+ ...calcFunctionNames,
70
+ ...comparisonFunctionNames,
71
+ ...steppedValueFunctionNames,
72
+ ...trigNumberFunctionNames,
73
+ ...otherNumberFunctionNames,
74
+ ...expNumberDimensionPercentageFunctionNames,
75
+ ...signFunctionNames
76
+ ];
77
+
78
+ const percentageFunctionNames = [
79
+ ...calcFunctionNames,
80
+ ...comparisonFunctionNames,
81
+ ...steppedValueFunctionNames,
82
+ ...expNumberDimensionPercentageFunctionNames,
83
+ ...signFunctionNames
84
+ ];
85
+
86
+ const dimensionFunctionNames = [
87
+ ...calcFunctionNames,
88
+ ...comparisonFunctionNames,
89
+ ...steppedValueFunctionNames,
90
+ ...trigAngleFunctionNames,
91
+ ...expNumberDimensionPercentageFunctionNames,
92
+ ...signFunctionNames
93
+ ];
94
+
11
95
  const balancePair = new Map([
12
96
  [types.Function, types.RightParenthesis],
13
97
  [types.LeftParenthesis, types.RightParenthesis],
@@ -114,16 +198,17 @@ function consumeFunction(token, getNextToken) {
114
198
  return length;
115
199
  }
116
200
 
201
+
117
202
  // TODO: implement
118
203
  // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
119
204
  // https://drafts.csswg.org/css-values/#calc-notation
120
- function calc(next) {
205
+ function math(next, functionNames) {
121
206
  return function(token, getNextToken, opts) {
122
207
  if (token === null) {
123
208
  return 0;
124
209
  }
125
210
 
126
- if (token.type === types.Function && eqStrAny(token.value, calcFunctionNames)) {
211
+ if (token.type === types.Function && eqStrAny(token.value, functionNames)) {
127
212
  return consumeFunction(token, getNextToken);
128
213
  }
129
214
 
@@ -530,12 +615,12 @@ const productionTypes = {
530
615
  'ident': tokenType(types.Ident),
531
616
 
532
617
  // percentage
533
- 'percentage': calc(percentage),
618
+ 'percentage': math(percentage, percentageFunctionNames),
534
619
 
535
620
  // numeric
536
621
  'zero': zero(),
537
- 'number': calc(number),
538
- 'integer': calc(integer),
622
+ 'number': math(number, numberFunctionNames),
623
+ 'integer': math(integer, numberFunctionNames),
539
624
 
540
625
  // complex types
541
626
  'custom-ident': customIdent,
@@ -563,15 +648,15 @@ function createDemensionTypes(units) {
563
648
  } = units || {};
564
649
 
565
650
  return {
566
- 'dimension': calc(dimension(null)),
567
- 'angle': calc(dimension(angle)),
568
- 'decibel': calc(dimension(decibel)),
569
- 'frequency': calc(dimension(frequency)),
570
- 'flex': calc(dimension(flex)),
571
- 'length': calc(zero(dimension(length))),
572
- 'resolution': calc(dimension(resolution)),
573
- 'semitones': calc(dimension(semitones)),
574
- 'time': calc(dimension(time))
651
+ 'dimension': math(dimension(null), dimensionFunctionNames),
652
+ 'angle': math(dimension(angle), dimensionFunctionNames),
653
+ 'decibel': math(dimension(decibel), dimensionFunctionNames),
654
+ 'frequency': math(dimension(frequency), dimensionFunctionNames),
655
+ 'flex': math(dimension(flex), dimensionFunctionNames),
656
+ 'length': math(zero(dimension(length)), dimensionFunctionNames),
657
+ 'resolution': math(dimension(resolution), dimensionFunctionNames),
658
+ 'semitones': math(dimension(semitones), dimensionFunctionNames),
659
+ 'time': math(dimension(time), dimensionFunctionNames)
575
660
  };
576
661
  }
577
662
 
@@ -35,10 +35,24 @@ function consumeDeclaration() {
35
35
  return node;
36
36
  }
37
37
 
38
+ function isElementSelectorStart() {
39
+ if (this.tokenType !== types.Ident) {
40
+ return false;
41
+ }
42
+
43
+ const nextTokenType = this.lookupTypeNonSC(1);
44
+
45
+ if (nextTokenType !== types.Colon && nextTokenType !== types.Semicolon && nextTokenType !== types.RightCurlyBracket) {
46
+ return true;
47
+ }
48
+
49
+ return false;
50
+ }
51
+
38
52
  function isSelectorStart() {
39
53
  return this.tokenType === types.Delim && selectorStarts.has(this.source.charCodeAt(this.tokenStart)) ||
40
54
  this.tokenType === types.Hash || this.tokenType === types.LeftSquareBracket ||
41
- this.tokenType === types.Colon;
55
+ this.tokenType === types.Colon || isElementSelectorStart.call(this);
42
56
  }
43
57
 
44
58
  const name = 'Block';
@@ -51,8 +65,7 @@ const structure = {
51
65
  ]]
52
66
  };
53
67
 
54
- function parse(isStyleBlock) {
55
- const consumer = isStyleBlock ? consumeDeclaration : consumeRule;
68
+ function parse(isStyleBlock, { allowNestedRules = false } = {}) {
56
69
  const start = this.tokenStart;
57
70
  let children = this.createList();
58
71
 
@@ -74,10 +87,16 @@ function parse(isStyleBlock) {
74
87
  break;
75
88
 
76
89
  default:
77
- if (isStyleBlock && isSelectorStart.call(this)) {
78
- children.push(consumeRule.call(this));
90
+ if (isStyleBlock) {
91
+
92
+ if (allowNestedRules && isSelectorStart.call(this)) {
93
+ children.push(consumeRule.call(this));
94
+ } else {
95
+ children.push(consumeDeclaration.call(this));
96
+ }
97
+
79
98
  } else {
80
- children.push(consumer.call(this));
99
+ children.push(consumeRule.call(this));
81
100
  }
82
101
  }
83
102
  }
@@ -37,7 +37,7 @@ function parse() {
37
37
  prelude = consumeRaw.call(this, startToken);
38
38
  }
39
39
 
40
- block = this.Block(true);
40
+ block = this.Block(true, { allowNestedRules: true });
41
41
 
42
42
  return {
43
43
  type: 'Rule',
package/data/patch.json CHANGED
@@ -815,10 +815,6 @@
815
815
  "system-family-name": {
816
816
  "syntax": "caption | icon | menu | message-box | small-caption | status-bar",
817
817
  "comment": "new definition on font-4, https://drafts.csswg.org/css-fonts-4/#system-family-name-value"
818
- },
819
- "parentheses-block": {
820
- "comment": "missed in mdn-data",
821
- "syntax": "( <any-value>* )"
822
818
  }
823
819
  }
824
820
  }