@tbela99/css-parser 0.2.0 → 0.4.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.
Files changed (57) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +250 -77
  3. package/dist/config.json.js +245 -1
  4. package/dist/index-umd-web.js +4241 -1583
  5. package/dist/index.cjs +4242 -1584
  6. package/dist/index.d.ts +71 -23
  7. package/dist/lib/ast/expand.js +1 -1
  8. package/dist/lib/ast/features/calc.js +31 -192
  9. package/dist/lib/ast/features/index.js +3 -3
  10. package/dist/lib/ast/features/inlinecssvariables.js +6 -6
  11. package/dist/lib/ast/features/shorthand.js +5 -6
  12. package/dist/lib/ast/math/expression.js +220 -0
  13. package/dist/lib/ast/{features/utils → math}/math.js +4 -4
  14. package/dist/lib/ast/minify.js +0 -1
  15. package/dist/lib/ast/types.js +31 -13
  16. package/dist/lib/ast/utils/minifyfeature.js +4 -3
  17. package/dist/lib/ast/walk.js +24 -4
  18. package/dist/lib/fs/resolve.js +4 -3
  19. package/dist/lib/parser/declaration/list.js +6 -2
  20. package/dist/lib/parser/declaration/map.js +158 -24
  21. package/dist/lib/parser/declaration/set.js +42 -22
  22. package/dist/lib/parser/parse.js +345 -349
  23. package/dist/lib/parser/tokenize.js +220 -223
  24. package/dist/lib/parser/utils/declaration.js +67 -0
  25. package/dist/lib/parser/utils/syntax.js +172 -6
  26. package/dist/lib/parser/utils/type.js +2 -2
  27. package/dist/lib/renderer/color/a98rgb.js +64 -0
  28. package/dist/lib/renderer/color/color.js +521 -0
  29. package/dist/lib/renderer/color/colormix.js +337 -0
  30. package/dist/lib/renderer/color/hex.js +92 -0
  31. package/dist/lib/renderer/color/hsl.js +118 -0
  32. package/dist/lib/renderer/color/hsv.js +20 -0
  33. package/dist/lib/renderer/color/hwb.js +101 -0
  34. package/dist/lib/renderer/color/lab.js +136 -0
  35. package/dist/lib/renderer/color/lch.js +79 -0
  36. package/dist/lib/renderer/color/oklab.js +121 -0
  37. package/dist/lib/renderer/color/oklch.js +65 -0
  38. package/dist/lib/renderer/color/p3.js +57 -0
  39. package/dist/lib/renderer/color/prophotorgb.js +56 -0
  40. package/dist/lib/renderer/color/rec2020.js +70 -0
  41. package/dist/lib/renderer/color/relativecolor.js +152 -0
  42. package/dist/lib/renderer/color/rgb.js +44 -0
  43. package/dist/lib/renderer/color/srgb.js +261 -0
  44. package/dist/lib/renderer/color/utils/components.js +20 -0
  45. package/dist/lib/renderer/color/utils/constants.js +191 -0
  46. package/dist/lib/renderer/color/utils/matrix.js +35 -0
  47. package/dist/lib/renderer/color/xyz.js +64 -0
  48. package/dist/lib/renderer/color/xyzd50.js +33 -0
  49. package/dist/lib/renderer/render.js +128 -30
  50. package/dist/node/index.js +1 -1
  51. package/dist/node/load.js +1 -1
  52. package/dist/web/index.js +1 -1
  53. package/package.json +19 -18
  54. package/quickjs.sh +1 -0
  55. package/dist/lib/iterable/weakmap.js +0 -53
  56. package/dist/lib/renderer/utils/color.js +0 -499
  57. /package/dist/lib/iterable/{set.js → weakset.js} +0 -0
@@ -0,0 +1,220 @@
1
+ import { EnumToken } from '../types.js';
2
+ import { compute } from './math.js';
3
+ import { reduceNumber } from '../../renderer/render.js';
4
+
5
+ /**
6
+ * evaluate an array of tokens
7
+ * @param tokens
8
+ */
9
+ function evaluate(tokens) {
10
+ const nodes = inlineExpression(evaluateExpression(buildExpression(tokens)));
11
+ if (nodes.length <= 1) {
12
+ return nodes;
13
+ }
14
+ const map = new Map;
15
+ let token;
16
+ let i;
17
+ for (i = 0; i < nodes.length; i++) {
18
+ token = nodes[i];
19
+ if (token.typ == EnumToken.Add) {
20
+ continue;
21
+ }
22
+ if (token.typ == EnumToken.Sub) {
23
+ if (!isScalarToken(nodes[i + 1])) {
24
+ token = { typ: EnumToken.ListToken, chi: [nodes[i], nodes[i + 1]] };
25
+ }
26
+ else {
27
+ token = doEvaluate(nodes[i + 1], { typ: EnumToken.NumberTokenType, val: '-1' }, EnumToken.Mul);
28
+ }
29
+ i++;
30
+ }
31
+ if (!map.has(token.typ)) {
32
+ map.set(token.typ, [token]);
33
+ }
34
+ else {
35
+ map.get(token.typ).push(token);
36
+ }
37
+ }
38
+ return [...map].reduce((acc, curr) => {
39
+ const token = curr[1].reduce((acc, curr) => doEvaluate(acc, curr, EnumToken.Add));
40
+ if (token.typ != EnumToken.BinaryExpressionTokenType) {
41
+ if ('val' in token && +token.val < 0) {
42
+ acc.push({ typ: EnumToken.Sub }, { ...token, val: String(-token.val) });
43
+ return acc;
44
+ }
45
+ }
46
+ if (acc.length > 0 && curr[0] != EnumToken.ListToken) {
47
+ acc.push({ typ: EnumToken.Add });
48
+ }
49
+ acc.push(token);
50
+ return acc;
51
+ }, []);
52
+ }
53
+ /**
54
+ * evaluate arithmetic operation
55
+ * @param l
56
+ * @param r
57
+ * @param op
58
+ */
59
+ function doEvaluate(l, r, op) {
60
+ const defaultReturn = {
61
+ typ: EnumToken.BinaryExpressionTokenType,
62
+ op,
63
+ l,
64
+ r
65
+ };
66
+ if (!isScalarToken(l) || !isScalarToken(r)) {
67
+ return defaultReturn;
68
+ }
69
+ if ((op == EnumToken.Add || op == EnumToken.Sub)) {
70
+ // @ts-ignore
71
+ if (l.typ != r.typ) {
72
+ return defaultReturn;
73
+ }
74
+ }
75
+ else if (op == EnumToken.Mul &&
76
+ ![EnumToken.NumberTokenType, EnumToken.PercentageTokenType].includes(l.typ) &&
77
+ ![EnumToken.NumberTokenType, EnumToken.PercentageTokenType].includes(r.typ)) {
78
+ return defaultReturn;
79
+ }
80
+ const typ = l.typ == EnumToken.NumberTokenType ? r.typ : (r.typ == EnumToken.NumberTokenType ? l.typ : (l.typ == EnumToken.PercentageTokenType ? r.typ : l.typ));
81
+ // @ts-ignore
82
+ let v1 = typeof l.val == 'string' ? +l.val : l.val;
83
+ // @ts-ignore
84
+ let v2 = typeof r.val == 'string' ? +r.val : r.val;
85
+ if (op == EnumToken.Mul) {
86
+ if (l.typ != EnumToken.NumberTokenType && r.typ != EnumToken.NumberTokenType) {
87
+ if (typeof v1 == 'number' && l.typ == EnumToken.PercentageTokenType) {
88
+ v1 = {
89
+ typ: EnumToken.FractionTokenType,
90
+ l: { typ: EnumToken.NumberTokenType, val: String(v1) },
91
+ r: { typ: EnumToken.NumberTokenType, val: '100' }
92
+ };
93
+ }
94
+ else if (typeof v2 == 'number' && r.typ == EnumToken.PercentageTokenType) {
95
+ v2 = {
96
+ typ: EnumToken.FractionTokenType,
97
+ l: { typ: EnumToken.NumberTokenType, val: String(v2) },
98
+ r: { typ: EnumToken.NumberTokenType, val: '100' }
99
+ };
100
+ }
101
+ }
102
+ }
103
+ // @ts-ignore
104
+ const val = compute(v1, v2, op);
105
+ return {
106
+ ...(l.typ == EnumToken.NumberTokenType ? r : l),
107
+ typ,
108
+ val: typeof val == 'number' ? reduceNumber(val) : val
109
+ };
110
+ }
111
+ /**
112
+ * convert BinaryExpression into an array
113
+ * @param token
114
+ */
115
+ function inlineExpression(token) {
116
+ const result = [];
117
+ if (token.typ == EnumToken.ParensTokenType && token.chi.length == 1) {
118
+ result.push(token.chi[0]);
119
+ }
120
+ else if (token.typ == EnumToken.BinaryExpressionTokenType) {
121
+ if ([EnumToken.Mul, EnumToken.Div].includes(token.op)) {
122
+ result.push(token);
123
+ }
124
+ else {
125
+ result.push(...inlineExpression(token.l), { typ: token.op }, ...inlineExpression(token.r));
126
+ }
127
+ }
128
+ else {
129
+ result.push(token);
130
+ }
131
+ return result;
132
+ }
133
+ /**
134
+ * evaluate expression
135
+ * @param token
136
+ */
137
+ function evaluateExpression(token) {
138
+ if (token.typ != EnumToken.BinaryExpressionTokenType) {
139
+ return token;
140
+ }
141
+ if (token.r.typ == EnumToken.BinaryExpressionTokenType) {
142
+ token.r = evaluateExpression(token.r);
143
+ }
144
+ if (token.l.typ == EnumToken.BinaryExpressionTokenType) {
145
+ token.l = evaluateExpression(token.l);
146
+ }
147
+ return doEvaluate(token.l, token.r, token.op);
148
+ }
149
+ function isScalarToken(token) {
150
+ return 'unit' in token || [EnumToken.NumberTokenType, EnumToken.FractionTokenType, EnumToken.PercentageTokenType].includes(token.typ);
151
+ }
152
+ /**
153
+ *
154
+ * generate binary expression tree
155
+ * @param tokens
156
+ */
157
+ function buildExpression(tokens) {
158
+ return factor(factor(tokens.filter(t => t.typ != EnumToken.WhitespaceTokenType), ['/', '*']), ['+', '-'])[0];
159
+ }
160
+ function getArithmeticOperation(op) {
161
+ if (op == '+') {
162
+ return EnumToken.Add;
163
+ }
164
+ if (op == '-') {
165
+ return EnumToken.Sub;
166
+ }
167
+ if (op == '/') {
168
+ return EnumToken.Div;
169
+ }
170
+ return EnumToken.Mul;
171
+ }
172
+ /**
173
+ *
174
+ * generate binary expression tree
175
+ * @param token
176
+ */
177
+ function factorToken(token) {
178
+ if (token.typ == EnumToken.ParensTokenType || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc')) {
179
+ if (token.typ == EnumToken.FunctionTokenType && token.val == 'calc') {
180
+ token = { ...token, typ: EnumToken.ParensTokenType };
181
+ // @ts-ignore
182
+ delete token.val;
183
+ }
184
+ return buildExpression(token.chi);
185
+ }
186
+ return token;
187
+ }
188
+ /**
189
+ * generate binary expression tree
190
+ * @param tokens
191
+ * @param ops
192
+ */
193
+ function factor(tokens, ops) {
194
+ let isOp;
195
+ const opList = ops.map(x => getArithmeticOperation(x));
196
+ if (tokens.length == 1) {
197
+ return [factorToken(tokens[0])];
198
+ }
199
+ for (let i = 0; i < tokens.length; i++) {
200
+ if (tokens[i].typ == EnumToken.ListToken) {
201
+ // @ts-ignore
202
+ tokens.splice(i, 1, ...tokens[i].chi);
203
+ }
204
+ isOp = opList.includes(tokens[i].typ);
205
+ if (isOp ||
206
+ // @ts-ignore
207
+ (tokens[i].typ == EnumToken.LiteralTokenType && ops.includes(tokens[i].val))) {
208
+ tokens.splice(i - 1, 3, {
209
+ typ: EnumToken.BinaryExpressionTokenType,
210
+ op: isOp ? tokens[i].typ : getArithmeticOperation(tokens[i].val),
211
+ l: factorToken(tokens[i - 1]),
212
+ r: factorToken(tokens[i + 1])
213
+ });
214
+ i--;
215
+ }
216
+ }
217
+ return tokens;
218
+ }
219
+
220
+ export { evaluate };
@@ -1,7 +1,7 @@
1
- import { EnumToken } from '../../types.js';
2
- import { reduceNumber } from '../../../renderer/render.js';
1
+ import { EnumToken } from '../types.js';
2
+ import { reduceNumber } from '../../renderer/render.js';
3
3
 
4
- const gcd = (x, y) => {
4
+ function gcd(x, y) {
5
5
  x = Math.abs(x);
6
6
  y = Math.abs(y);
7
7
  let t;
@@ -14,7 +14,7 @@ const gcd = (x, y) => {
14
14
  x = t;
15
15
  }
16
16
  return x;
17
- };
17
+ }
18
18
  function compute(a, b, op) {
19
19
  if (typeof a == 'number' && typeof b == 'number') {
20
20
  switch (op) {
@@ -17,7 +17,6 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
17
17
  context.nodes = new WeakSet;
18
18
  }
19
19
  if (context.nodes.has(ast)) {
20
- // console.error('skipped', ast.typ);
21
20
  return ast;
22
21
  }
23
22
  context.nodes.add(ast);
@@ -57,25 +57,30 @@ var EnumToken;
57
57
  EnumToken[EnumToken["BadStringTokenType"] = 54] = "BadStringTokenType";
58
58
  EnumToken[EnumToken["BinaryExpressionTokenType"] = 55] = "BinaryExpressionTokenType";
59
59
  EnumToken[EnumToken["UnaryExpressionTokenType"] = 56] = "UnaryExpressionTokenType";
60
+ EnumToken[EnumToken["FlexTokenType"] = 57] = "FlexTokenType";
60
61
  /* catch all */
61
- EnumToken[EnumToken["ListToken"] = 57] = "ListToken";
62
+ EnumToken[EnumToken["ListToken"] = 58] = "ListToken";
62
63
  /* arithmetic tokens */
63
- EnumToken[EnumToken["Add"] = 58] = "Add";
64
- EnumToken[EnumToken["Mul"] = 59] = "Mul";
65
- EnumToken[EnumToken["Div"] = 60] = "Div";
66
- EnumToken[EnumToken["Sub"] = 61] = "Sub";
64
+ EnumToken[EnumToken["Add"] = 59] = "Add";
65
+ EnumToken[EnumToken["Mul"] = 60] = "Mul";
66
+ EnumToken[EnumToken["Div"] = 61] = "Div";
67
+ EnumToken[EnumToken["Sub"] = 62] = "Sub";
67
68
  /* new tokens */
68
- EnumToken[EnumToken["ColumnCombinatorTokenType"] = 62] = "ColumnCombinatorTokenType";
69
- EnumToken[EnumToken["ContainMatchTokenType"] = 63] = "ContainMatchTokenType";
70
- EnumToken[EnumToken["StartMatchTokenType"] = 64] = "StartMatchTokenType";
71
- EnumToken[EnumToken["EndMatchTokenType"] = 65] = "EndMatchTokenType";
72
- EnumToken[EnumToken["MatchExpressionTokenType"] = 66] = "MatchExpressionTokenType";
73
- EnumToken[EnumToken["NameSpaceAttributeTokenType"] = 67] = "NameSpaceAttributeTokenType";
74
- EnumToken[EnumToken["FractionTokenType"] = 68] = "FractionTokenType";
69
+ EnumToken[EnumToken["ColumnCombinatorTokenType"] = 63] = "ColumnCombinatorTokenType";
70
+ EnumToken[EnumToken["ContainMatchTokenType"] = 64] = "ContainMatchTokenType";
71
+ EnumToken[EnumToken["StartMatchTokenType"] = 65] = "StartMatchTokenType";
72
+ EnumToken[EnumToken["EndMatchTokenType"] = 66] = "EndMatchTokenType";
73
+ EnumToken[EnumToken["MatchExpressionTokenType"] = 67] = "MatchExpressionTokenType";
74
+ EnumToken[EnumToken["NameSpaceAttributeTokenType"] = 68] = "NameSpaceAttributeTokenType";
75
+ EnumToken[EnumToken["FractionTokenType"] = 69] = "FractionTokenType";
76
+ EnumToken[EnumToken["IdenListTokenType"] = 70] = "IdenListTokenType";
77
+ EnumToken[EnumToken["GridTemplateFuncTokenType"] = 71] = "GridTemplateFuncTokenType";
75
78
  /* aliases */
76
79
  EnumToken[EnumToken["Time"] = 25] = "Time";
77
80
  EnumToken[EnumToken["Iden"] = 7] = "Iden";
81
+ EnumToken[EnumToken["EOF"] = 47] = "EOF";
78
82
  EnumToken[EnumToken["Hash"] = 28] = "Hash";
83
+ EnumToken[EnumToken["Flex"] = 57] = "Flex";
79
84
  EnumToken[EnumToken["Angle"] = 24] = "Angle";
80
85
  EnumToken[EnumToken["Color"] = 49] = "Color";
81
86
  EnumToken[EnumToken["Comma"] = 9] = "Comma";
@@ -90,12 +95,25 @@ var EnumToken;
90
95
  EnumToken[EnumToken["Frequency"] = 26] = "Frequency";
91
96
  EnumToken[EnumToken["Resolution"] = 27] = "Resolution";
92
97
  EnumToken[EnumToken["Whitespace"] = 36] = "Whitespace";
98
+ EnumToken[EnumToken["IdenList"] = 70] = "IdenList";
93
99
  EnumToken[EnumToken["DashedIden"] = 8] = "DashedIden";
100
+ EnumToken[EnumToken["GridTemplateFunc"] = 71] = "GridTemplateFunc";
94
101
  EnumToken[EnumToken["ImageFunc"] = 19] = "ImageFunc";
95
102
  EnumToken[EnumToken["CommentNodeType"] = 0] = "CommentNodeType";
96
103
  EnumToken[EnumToken["CDOCOMMNodeType"] = 1] = "CDOCOMMNodeType";
97
104
  EnumToken[EnumToken["TimingFunction"] = 17] = "TimingFunction";
98
105
  EnumToken[EnumToken["TimelineFunction"] = 16] = "TimelineFunction";
99
106
  })(EnumToken || (EnumToken = {}));
107
+ const funcLike = [
108
+ EnumToken.ParensTokenType,
109
+ EnumToken.FunctionTokenType,
110
+ EnumToken.UrlFunctionTokenType,
111
+ EnumToken.StartParensTokenType,
112
+ EnumToken.ImageFunctionTokenType,
113
+ EnumToken.TimingFunctionTokenType,
114
+ EnumToken.TimingFunctionTokenType,
115
+ EnumToken.PseudoClassFuncTokenType,
116
+ EnumToken.GridTemplateFuncTokenType
117
+ ];
100
118
 
101
- export { EnumToken };
119
+ export { EnumToken, funcLike };
@@ -1,7 +1,8 @@
1
1
  class MinifyFeature {
2
- static get ordering() { return 10000; }
3
- register(options) { }
4
- run(ast, options = {}, parent, context) {
2
+ static get ordering() {
3
+ return 10000;
4
+ }
5
+ register(options) {
5
6
  }
6
7
  }
7
8
 
@@ -1,3 +1,5 @@
1
+ import { EnumToken } from './types.js';
2
+
1
3
  function* walk(node, filter) {
2
4
  const parents = [node];
3
5
  const root = node;
@@ -27,20 +29,38 @@ function* walk(node, filter) {
27
29
  }
28
30
  }
29
31
  }
30
- function* walkValues(values) {
32
+ function* walkValues(values, root = null, filter) {
31
33
  const stack = values.slice();
32
34
  const weakMap = new WeakMap;
33
35
  let value;
34
36
  while (stack.length > 0) {
35
37
  value = stack.shift();
38
+ let option = null;
39
+ if (filter != null) {
40
+ option = filter(value);
41
+ if (option === 'ignore') {
42
+ continue;
43
+ }
44
+ if (option === 'stop') {
45
+ break;
46
+ }
47
+ }
36
48
  // @ts-ignore
37
- yield { value, parent: weakMap.get(value) };
38
- if ('chi' in value) {
39
- for (const child of value.chi) {
49
+ if (option !== 'children') {
50
+ // @ts-ignore
51
+ yield { value, parent: weakMap.get(value), root };
52
+ }
53
+ if (option !== 'ignore-children' && 'chi' in value) {
54
+ for (const child of value.chi.slice()) {
40
55
  weakMap.set(child, value);
41
56
  }
42
57
  stack.unshift(...value.chi);
43
58
  }
59
+ else if (value.typ == EnumToken.BinaryExpressionTokenType) {
60
+ weakMap.set(value.l, value);
61
+ weakMap.set(value.r, value);
62
+ stack.unshift(value.l, value.r);
63
+ }
44
64
  }
45
65
  }
46
66
 
@@ -35,13 +35,14 @@ function splitPath(result) {
35
35
  parts[parts.length - 1] += chr;
36
36
  }
37
37
  }
38
- let k = parts.length;
39
- while (k--) {
38
+ let k = -1;
39
+ while (++k < parts.length) {
40
40
  if (parts[k] == '.') {
41
- parts.splice(k, 1);
41
+ parts.splice(k--, 1);
42
42
  }
43
43
  else if (parts[k] == '..') {
44
44
  parts.splice(k - 1, 2);
45
+ k -= 2;
45
46
  }
46
47
  }
47
48
  return { parts, i };
@@ -1,8 +1,8 @@
1
1
  import { PropertySet } from './set.js';
2
- import '../../renderer/utils/color.js';
3
2
  import { EnumToken } from '../../ast/types.js';
4
3
  import '../../ast/minify.js';
5
4
  import { parseString } from '../parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
6
  import '../../renderer/sourcemap/lib/encode.js';
7
7
  import { getConfig } from '../utils/config.js';
8
8
  import { PropertyMap } from './map.js';
@@ -21,7 +21,11 @@ class PropertyList {
21
21
  this.declarations = new Map;
22
22
  }
23
23
  set(nam, value) {
24
- return this.add({ typ: EnumToken.DeclarationNodeType, nam, val: Array.isArray(value) ? value : parseString(String(value)) });
24
+ return this.add({
25
+ typ: EnumToken.DeclarationNodeType,
26
+ nam,
27
+ val: Array.isArray(value) ? value : parseString(String(value))
28
+ });
25
29
  }
26
30
  add(declaration) {
27
31
  if (declaration.typ != EnumToken.DeclarationNodeType || !this.options.removeDuplicateDeclarations) {