@tbela99/css-parser 0.3.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 (61) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +191 -80
  3. package/dist/config.json.js +20 -1
  4. package/dist/index-umd-web.js +3210 -1352
  5. package/dist/index.cjs +3211 -1353
  6. package/dist/index.d.ts +910 -0
  7. package/dist/lib/ast/expand.js +1 -1
  8. package/dist/lib/ast/features/calc.js +1 -2
  9. package/dist/lib/ast/features/inlinecssvariables.js +1 -1
  10. package/dist/lib/ast/features/shorthand.js +1 -1
  11. package/dist/lib/ast/math/expression.js +38 -3
  12. package/dist/lib/ast/math/math.js +2 -2
  13. package/dist/lib/ast/minify.js +0 -1
  14. package/dist/lib/ast/types.js +1 -0
  15. package/dist/lib/ast/utils/minifyfeature.js +4 -3
  16. package/dist/lib/parser/declaration/list.js +1 -1
  17. package/dist/lib/parser/declaration/map.js +129 -26
  18. package/dist/lib/parser/declaration/set.js +1 -1
  19. package/dist/lib/parser/parse.js +325 -303
  20. package/dist/lib/parser/tokenize.js +220 -223
  21. package/dist/lib/parser/utils/declaration.js +1 -1
  22. package/dist/lib/parser/utils/syntax.js +159 -23
  23. package/dist/lib/parser/utils/type.js +2 -2
  24. package/dist/lib/renderer/color/a98rgb.js +64 -0
  25. package/dist/lib/renderer/color/color.js +521 -0
  26. package/dist/lib/renderer/color/colormix.js +337 -0
  27. package/dist/lib/renderer/color/hex.js +92 -0
  28. package/dist/lib/renderer/color/hsl.js +118 -0
  29. package/dist/lib/renderer/color/hsv.js +20 -0
  30. package/dist/lib/renderer/color/hwb.js +101 -0
  31. package/dist/lib/renderer/color/lab.js +136 -0
  32. package/dist/lib/renderer/color/lch.js +79 -0
  33. package/dist/lib/renderer/color/oklab.js +121 -0
  34. package/dist/lib/renderer/color/oklch.js +65 -0
  35. package/dist/lib/renderer/color/p3.js +57 -0
  36. package/dist/lib/renderer/color/prophotorgb.js +56 -0
  37. package/dist/lib/renderer/color/rec2020.js +70 -0
  38. package/dist/lib/renderer/color/relativecolor.js +152 -0
  39. package/dist/lib/renderer/color/rgb.js +44 -0
  40. package/dist/lib/renderer/color/srgb.js +261 -0
  41. package/dist/lib/renderer/color/utils/components.js +20 -0
  42. package/dist/lib/renderer/color/utils/constants.js +191 -0
  43. package/dist/lib/renderer/color/utils/matrix.js +35 -0
  44. package/dist/lib/renderer/color/xyz.js +64 -0
  45. package/dist/lib/renderer/color/xyzd50.js +33 -0
  46. package/dist/lib/renderer/render.js +61 -32
  47. package/dist/node/index.js +1 -1
  48. package/dist/node/load.js +1 -1
  49. package/dist/web/index.js +1 -1
  50. package/package.json +15 -14
  51. package/quickjs.sh +1 -0
  52. package/dist/lib/ast/features/utils/math.js +0 -95
  53. package/dist/lib/iterable/set.js +0 -48
  54. package/dist/lib/iterable/weakmap.js +0 -53
  55. package/dist/lib/renderer/utils/calccolor.js +0 -238
  56. package/dist/lib/renderer/utils/color.js +0 -371
  57. package/dist/lib/renderer/utils/hex.js +0 -124
  58. package/dist/lib/renderer/utils/hsl.js +0 -49
  59. package/dist/lib/renderer/utils/hsv.js +0 -15
  60. package/dist/lib/renderer/utils/hwb.js +0 -50
  61. package/dist/lib/renderer/utils/rgb.js +0 -66
@@ -1,9 +1,9 @@
1
1
  import { splitRule, combinators } from './minify.js';
2
2
  import { parseString } from '../parser/parse.js';
3
3
  import { renderToken } from '../renderer/render.js';
4
- import '../renderer/utils/color.js';
5
4
  import { EnumToken } from './types.js';
6
5
  import { walkValues } from './walk.js';
6
+ import '../renderer/color/utils/constants.js';
7
7
 
8
8
  function expand(ast) {
9
9
  //
@@ -21,7 +21,7 @@ class ComputeCalcExpressionFeature extends MinifyFeature {
21
21
  }
22
22
  run(ast) {
23
23
  if (!('chi' in ast)) {
24
- return ast;
24
+ return;
25
25
  }
26
26
  // @ts-ignore
27
27
  for (const node of ast.chi) {
@@ -58,7 +58,6 @@ class ComputeCalcExpressionFeature extends MinifyFeature {
58
58
  }
59
59
  }
60
60
  }
61
- return ast;
62
61
  }
63
62
  }
64
63
 
@@ -45,7 +45,7 @@ class InlineCssVariablesFeature extends MinifyFeature {
45
45
  if (!('variableScope' in context)) {
46
46
  context.variableScope = new Map;
47
47
  }
48
- const isRoot = parent.typ == EnumToken.StyleSheetNodeType && ast.typ == EnumToken.RuleNodeType && ast.sel == ':root';
48
+ const isRoot = parent.typ == EnumToken.StyleSheetNodeType && ast.typ == EnumToken.RuleNodeType && [':root', 'html'].includes(ast.sel);
49
49
  const variableScope = context.variableScope;
50
50
  // @ts-ignore
51
51
  for (const node of ast.chi) {
@@ -1,8 +1,8 @@
1
1
  import { PropertyList } from '../../parser/declaration/list.js';
2
- import '../../renderer/utils/color.js';
3
2
  import { EnumToken } from '../types.js';
4
3
  import '../minify.js';
5
4
  import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
6
  import '../../renderer/sourcemap/lib/encode.js';
7
7
  import { MinifyFeature } from '../utils/minifyfeature.js';
8
8
 
@@ -72,10 +72,41 @@ function doEvaluate(l, r, op) {
72
72
  return defaultReturn;
73
73
  }
74
74
  }
75
- const typ = l.typ == EnumToken.NumberTokenType ? r.typ : l.typ;
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;
76
83
  // @ts-ignore
77
- const val = compute(typeof l.val == 'string' ? +l.val : l.val, typeof r.val == 'string' ? +r.val : r.val, op);
78
- return { ...(l.typ == EnumToken.NumberTokenType ? r : l), typ, val: typeof val == 'number' ? reduceNumber(val) : val };
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
+ };
79
110
  }
80
111
  /**
81
112
  * convert BinaryExpression into an array
@@ -166,6 +197,10 @@ function factor(tokens, ops) {
166
197
  return [factorToken(tokens[0])];
167
198
  }
168
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
+ }
169
204
  isOp = opList.includes(tokens[i].typ);
170
205
  if (isOp ||
171
206
  // @ts-ignore
@@ -1,7 +1,7 @@
1
1
  import { EnumToken } from '../types.js';
2
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);
@@ -78,6 +78,7 @@ var EnumToken;
78
78
  /* aliases */
79
79
  EnumToken[EnumToken["Time"] = 25] = "Time";
80
80
  EnumToken[EnumToken["Iden"] = 7] = "Iden";
81
+ EnumToken[EnumToken["EOF"] = 47] = "EOF";
81
82
  EnumToken[EnumToken["Hash"] = 28] = "Hash";
82
83
  EnumToken[EnumToken["Flex"] = 57] = "Flex";
83
84
  EnumToken[EnumToken["Angle"] = 24] = "Angle";
@@ -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,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';
@@ -1,9 +1,9 @@
1
1
  import { eq } from '../utils/eq.js';
2
2
  import { renderToken } from '../../renderer/render.js';
3
- import '../../renderer/utils/color.js';
4
3
  import { EnumToken } from '../../ast/types.js';
5
4
  import '../../ast/minify.js';
6
5
  import { parseString } from '../parse.js';
6
+ import '../../renderer/color/utils/constants.js';
7
7
  import { getConfig } from '../utils/config.js';
8
8
  import { matchType } from '../utils/type.js';
9
9
  import { PropertySet } from './set.js';
@@ -22,12 +22,10 @@ class PropertyMap {
22
22
  this.pattern = config.pattern.split(/\s/);
23
23
  }
24
24
  add(declaration) {
25
- for (const val of declaration.val) {
26
- Object.defineProperty(val, 'propertyName', { enumerable: false, writable: true, value: declaration.nam });
27
- }
28
25
  if (declaration.nam == this.config.shorthand) {
29
26
  this.declarations = new Map;
30
27
  this.declarations.set(declaration.nam, declaration);
28
+ this.matchTypes(declaration);
31
29
  }
32
30
  else {
33
31
  const separator = this.config.separator != null ? {
@@ -165,6 +163,55 @@ class PropertyMap {
165
163
  }
166
164
  return this;
167
165
  }
166
+ matchTypes(declaration) {
167
+ const patterns = this.pattern.slice();
168
+ const values = [...declaration.val];
169
+ let i;
170
+ let j;
171
+ const map = new Map;
172
+ for (i = 0; i < patterns.length; i++) {
173
+ for (j = 0; j < values.length; j++) {
174
+ if (!map.has(patterns[i])) {
175
+ // @ts-ignore
176
+ map.set(patterns[i], this.config.properties?.[patterns[i]]?.constraints?.mapping?.max ?? 1);
177
+ }
178
+ let count = map.get(patterns[i]);
179
+ if (count > 0 && matchType(values[j], this.config.properties[patterns[i]])) {
180
+ Object.defineProperty(values[j], 'propertyName', {
181
+ enumerable: false,
182
+ writable: true,
183
+ value: patterns[i]
184
+ });
185
+ map.set(patterns[i], --count);
186
+ values.splice(j--, 1);
187
+ }
188
+ }
189
+ }
190
+ if (this.config.set != null) {
191
+ for (const [key, val] of Object.entries(this.config.set)) {
192
+ if (map.has(key)) {
193
+ for (const v of val) {
194
+ // missing
195
+ if (map.get(v) == 1) {
196
+ let i = declaration.val.length;
197
+ while (i--) {
198
+ // @ts-ignore
199
+ if (declaration.val[i].propertyName == key) {
200
+ const val = { ...declaration.val[i] };
201
+ Object.defineProperty(val, 'propertyName', {
202
+ enumerable: false,
203
+ writable: true,
204
+ value: v
205
+ });
206
+ declaration.val.splice(i, 0, val, { typ: EnumToken.WhitespaceTokenType });
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
168
215
  [Symbol.iterator]() {
169
216
  let iterable;
170
217
  let requiredCount = 0;
@@ -195,34 +242,60 @@ class PropertyMap {
195
242
  if (isShorthand && this.declarations.has(this.config.shorthand)) {
196
243
  const cache = new Map();
197
244
  const removeDefaults = (declaration) => {
198
- let config = this.config.shorthand == declaration.nam ? this.config : this.config.properties[declaration.nam];
199
- if (config == null && declaration.nam in propertiesConfig.properties) {
200
- // @ts-ignore
201
- const shorthand = propertiesConfig.properties[declaration.nam].shorthand;
202
- // @ts-ignore
203
- config = propertiesConfig.properties[shorthand];
204
- }
205
- declaration.val = declaration.val.map((t) => {
245
+ let i;
246
+ let t;
247
+ let map = new Map();
248
+ let value = [];
249
+ let values = [];
250
+ // @ts-ignore
251
+ let typ = (EnumToken[this.config.separator?.typ] ?? EnumToken.CommaTokenType);
252
+ let separator = this.config.separator ? renderToken(this.config.separator) : ',';
253
+ this.matchTypes(declaration);
254
+ values.push(value);
255
+ for (i = 0; i < declaration.val.length; i++) {
256
+ t = declaration.val[i];
206
257
  if (!cache.has(t)) {
207
258
  cache.set(t, renderToken(t, { minify: true }));
208
259
  }
209
- const value = cache.get(t);
260
+ if (t.typ == typ && separator == cache.get(t)) {
261
+ this.removeDefaults(map, value);
262
+ value = [];
263
+ values.push(value);
264
+ map.clear();
265
+ continue;
266
+ }
267
+ value.push(t);
210
268
  // @ts-ignore
211
- if (config?.mapping?.[value] != null) {
269
+ if ('propertyName' in t) {
212
270
  // @ts-ignore
213
- t = parseString(config.mapping[value])[0];
214
- cache.set(t, renderToken(t, { minify: true }));
271
+ if (!map.has(t.propertyName)) {
272
+ // @ts-ignore
273
+ map.set(t.propertyName, { t: [t], value: [cache.get(t)] });
274
+ }
275
+ else {
276
+ // @ts-ignore
277
+ const v = map.get(t.propertyName);
278
+ v.t.push(t);
279
+ v.value.push(cache.get(t));
280
+ }
281
+ }
282
+ }
283
+ this.removeDefaults(map, value);
284
+ declaration.val = values.reduce((acc, curr) => {
285
+ for (const cr of curr) {
286
+ if (cr.typ == EnumToken.WhitespaceTokenType && acc.at(-1)?.typ == cr.typ) {
287
+ continue;
288
+ }
289
+ acc.push(cr);
215
290
  }
216
- return t;
217
- }).filter((val) => {
218
- return !config?.default?.includes(cache.get(val));
219
- })
220
- .filter((val, index, array) => !(index > 0 &&
221
- val.typ == EnumToken.WhitespaceTokenType &&
222
- array[index - 1].typ == EnumToken.WhitespaceTokenType));
223
- if (declaration.val.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
291
+ return acc;
292
+ }, []);
293
+ while (declaration.val.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
224
294
  declaration.val.pop();
225
295
  }
296
+ while (declaration.val.at(0)?.typ == EnumToken.WhitespaceTokenType) {
297
+ declaration.val.shift();
298
+ }
226
299
  return declaration;
227
300
  };
228
301
  const values = [...this.declarations.values()].reduce((acc, curr) => {
@@ -322,12 +395,12 @@ class PropertyMap {
322
395
  return acc;
323
396
  }, []);
324
397
  count++;
325
- if (!isShorthand || Object.entries(this.config.properties).some(entry => {
398
+ if (!isShorthand || Object.entries(this.config.properties).some((entry) => {
326
399
  // missing required property
327
400
  return entry[1].required && !(entry[0] in tokens);
328
401
  }) ||
329
402
  // @ts-ignore
330
- !Object.values(tokens).every(v => v.filter(t => t.typ != EnumToken.CommentTokenType).length == count)) {
403
+ !Object.values(tokens).every((v) => v.filter((t) => t.typ != EnumToken.CommentTokenType).length == count)) {
331
404
  // @ts-ignore
332
405
  iterable = this.declarations.values();
333
406
  }
@@ -482,6 +555,36 @@ class PropertyMap {
482
555
  }
483
556
  };
484
557
  }
558
+ removeDefaults(map, value) {
559
+ for (const [key, val] of map) {
560
+ const config = this.config.properties[key];
561
+ if (config == null) {
562
+ continue;
563
+ }
564
+ const v = val.value.join(' ');
565
+ if (config.default.includes(v) || (value.length == 1 && this.config.default.includes(v))) {
566
+ for (const token of value) {
567
+ if (val.t.includes(token)) {
568
+ let index = value.indexOf(token);
569
+ value.splice(index, 1);
570
+ if (config.prefix != null) {
571
+ while (index-- > 0) {
572
+ if (value[index].typ == EnumToken.WhitespaceTokenType) {
573
+ continue;
574
+ }
575
+ if (value[index].typ == EnumToken[config.prefix.typ] &&
576
+ // @ts-ignore
577
+ value[index].val == config.prefix.val) {
578
+ value.splice(index, 1);
579
+ break;
580
+ }
581
+ }
582
+ }
583
+ }
584
+ }
585
+ }
586
+ }
587
+ }
485
588
  }
486
589
 
487
590
  export { PropertyMap };
@@ -3,7 +3,7 @@ import { isLength } from '../utils/syntax.js';
3
3
  import { EnumToken } from '../../ast/types.js';
4
4
  import '../../ast/minify.js';
5
5
  import '../parse.js';
6
- import '../../renderer/utils/color.js';
6
+ import '../../renderer/color/utils/constants.js';
7
7
  import '../../renderer/sourcemap/lib/encode.js';
8
8
 
9
9
  function dedup(values) {