@tbela99/css-parser 1.0.0 → 1.1.1-alpha4

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 (87) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +16 -11
  3. package/dist/index-umd-web.js +3805 -1894
  4. package/dist/index.cjs +3806 -1895
  5. package/dist/index.d.ts +184 -57
  6. package/dist/lib/ast/expand.js +2 -1
  7. package/dist/lib/ast/features/calc.js +12 -1
  8. package/dist/lib/ast/features/inlinecssvariables.js +47 -24
  9. package/dist/lib/ast/features/prefix.js +117 -86
  10. package/dist/lib/ast/features/shorthand.js +29 -6
  11. package/dist/lib/ast/features/transform.js +10 -3
  12. package/dist/lib/ast/features/type.js +7 -0
  13. package/dist/lib/ast/math/expression.js +7 -1
  14. package/dist/lib/ast/math/math.js +6 -0
  15. package/dist/lib/ast/minify.js +165 -77
  16. package/dist/lib/ast/transform/compute.js +1 -0
  17. package/dist/lib/ast/transform/matrix.js +1 -0
  18. package/dist/lib/ast/types.js +26 -15
  19. package/dist/lib/ast/utils/utils.js +104 -0
  20. package/dist/lib/ast/walk.js +33 -7
  21. package/dist/lib/fs/resolve.js +10 -0
  22. package/dist/lib/parser/declaration/list.js +48 -45
  23. package/dist/lib/parser/declaration/map.js +1 -0
  24. package/dist/lib/parser/declaration/set.js +2 -1
  25. package/dist/lib/parser/parse.js +350 -279
  26. package/dist/lib/parser/tokenize.js +147 -72
  27. package/dist/lib/parser/utils/declaration.js +4 -3
  28. package/dist/lib/parser/utils/type.js +2 -1
  29. package/dist/lib/renderer/color/a98rgb.js +2 -1
  30. package/dist/lib/renderer/color/color-mix.js +10 -7
  31. package/dist/lib/renderer/color/color.js +171 -153
  32. package/dist/lib/renderer/color/hex.js +2 -1
  33. package/dist/lib/renderer/color/hsl.js +2 -1
  34. package/dist/lib/renderer/color/hwb.js +2 -1
  35. package/dist/lib/renderer/color/lab.js +2 -1
  36. package/dist/lib/renderer/color/lch.js +2 -1
  37. package/dist/lib/renderer/color/oklab.js +2 -1
  38. package/dist/lib/renderer/color/oklch.js +2 -1
  39. package/dist/lib/renderer/color/p3.js +2 -1
  40. package/dist/lib/renderer/color/rec2020.js +2 -1
  41. package/dist/lib/renderer/color/relativecolor.js +17 -11
  42. package/dist/lib/renderer/color/rgb.js +4 -3
  43. package/dist/lib/renderer/color/srgb.js +18 -17
  44. package/dist/lib/renderer/color/utils/components.js +6 -5
  45. package/dist/lib/renderer/color/utils/constants.js +47 -3
  46. package/dist/lib/renderer/color/xyz.js +2 -1
  47. package/dist/lib/renderer/color/xyzd50.js +2 -1
  48. package/dist/lib/renderer/render.js +48 -20
  49. package/dist/lib/syntax/syntax.js +257 -140
  50. package/dist/lib/validation/at-rules/container.js +75 -97
  51. package/dist/lib/validation/at-rules/counter-style.js +9 -8
  52. package/dist/lib/validation/at-rules/custom-media.js +13 -15
  53. package/dist/lib/validation/at-rules/document.js +22 -27
  54. package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
  55. package/dist/lib/validation/at-rules/import.js +30 -81
  56. package/dist/lib/validation/at-rules/keyframes.js +18 -22
  57. package/dist/lib/validation/at-rules/layer.js +5 -5
  58. package/dist/lib/validation/at-rules/media.js +42 -52
  59. package/dist/lib/validation/at-rules/namespace.js +19 -23
  60. package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
  61. package/dist/lib/validation/at-rules/page.js +8 -7
  62. package/dist/lib/validation/at-rules/supports.js +73 -82
  63. package/dist/lib/validation/at-rules/when.js +32 -36
  64. package/dist/lib/validation/atrule.js +15 -14
  65. package/dist/lib/validation/config.js +24 -1
  66. package/dist/lib/validation/config.json.js +611 -111
  67. package/dist/lib/validation/parser/parse.js +206 -212
  68. package/dist/lib/validation/parser/types.js +1 -1
  69. package/dist/lib/validation/selector.js +3 -3
  70. package/dist/lib/validation/syntax.js +984 -0
  71. package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
  72. package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
  73. package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
  74. package/dist/lib/validation/syntaxes/family-name.js +9 -8
  75. package/dist/lib/validation/syntaxes/keyframe-block-list.js +4 -3
  76. package/dist/lib/validation/syntaxes/keyframe-selector.js +15 -18
  77. package/dist/lib/validation/syntaxes/layer-name.js +6 -5
  78. package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
  79. package/dist/lib/validation/syntaxes/relative-selector.js +2 -1
  80. package/dist/lib/validation/syntaxes/url.js +18 -22
  81. package/dist/lib/validation/utils/list.js +2 -1
  82. package/dist/lib/validation/utils/whitespace.js +2 -1
  83. package/dist/node/index.js +4 -2
  84. package/dist/node/load.js +5 -0
  85. package/dist/web/index.js +4 -2
  86. package/dist/web/load.js +5 -0
  87. package/package.json +14 -13
@@ -1,12 +1,15 @@
1
1
  import { parseString } from '../parser/parse.js';
2
+ import '../parser/tokenize.js';
3
+ import '../parser/utils/config.js';
2
4
  import { EnumToken } from './types.js';
3
5
  import { walkValues } from './walk.js';
4
6
  import { replaceCompound } from './expand.js';
5
- import { isIdent, isFunction, isWhiteSpace, isIdentStart } from '../syntax/syntax.js';
6
- import '../parser/utils/config.js';
7
+ import { isWhiteSpace, isIdent, isFunction, isIdentStart } from '../syntax/syntax.js';
7
8
  import { eq } from '../parser/utils/eq.js';
8
9
  import { doRender, renderToken } from '../renderer/render.js';
10
+ import '../renderer/color/utils/constants.js';
9
11
  import * as index from './features/index.js';
12
+ import { FeatureWalkMode } from './features/type.js';
10
13
 
11
14
  const combinators = ['+', '>', '~', '||', '|'];
12
15
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
@@ -23,13 +26,9 @@ const features = Object.values(index).sort((a, b) => a.ordering - b.ordering);
23
26
  * @param context
24
27
  */
25
28
  function minify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
26
- if (!('nodes' in context)) {
27
- context.nodes = new Set;
28
- }
29
- if (context.nodes.has(ast)) {
30
- return ast;
31
- }
32
- context.nodes.add(ast);
29
+ let preprocess = false;
30
+ let postprocess = false;
31
+ let parents;
33
32
  if (!('features' in options)) {
34
33
  // @ts-ignore
35
34
  options = {
@@ -43,28 +42,118 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
43
42
  for (const feature of features) {
44
43
  feature.register(options);
45
44
  }
45
+ options.features.sort((a, b) => a.ordering - b.ordering);
46
+ }
47
+ for (const feature of options.features) {
48
+ if (feature.preProcess) {
49
+ preprocess = true;
50
+ }
51
+ if (feature.postProcess) {
52
+ postprocess = true;
53
+ }
54
+ }
55
+ if (preprocess) {
56
+ parents = [ast];
57
+ for (const parent of parents) {
58
+ if (parent.typ == EnumToken.CommentTokenType ||
59
+ parent.typ == EnumToken.CDOCOMMTokenType) {
60
+ Object.defineProperty(parent, 'parent', {
61
+ ...definedPropertySettings,
62
+ value: parent
63
+ });
64
+ continue;
65
+ }
66
+ for (const feature of options.features) {
67
+ if (!feature.preProcess) {
68
+ continue;
69
+ }
70
+ feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Pre);
71
+ }
72
+ if (('chi' in parent)) {
73
+ // @ts-ignore
74
+ for (const node of parent.chi) {
75
+ parents.push(Object.defineProperty(node, 'parent', {
76
+ ...definedPropertySettings,
77
+ value: parent
78
+ }));
79
+ }
80
+ }
81
+ }
82
+ for (const feature of options.features) {
83
+ if (feature.preProcess && 'cleanup' in feature) {
84
+ // @ts-ignore
85
+ feature.cleanup(ast, options, context, FeatureWalkMode.Pre);
86
+ }
87
+ }
46
88
  }
47
- function reducer(acc, curr, index, array) {
48
- // trim :is()
49
- if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
50
- curr = curr.slice(1, -1);
89
+ doMinify(ast, options, recursive, errors, nestingContent, context);
90
+ parents = [ast];
91
+ for (const parent of parents) {
92
+ // parent = parents.shift() as AstNode;
93
+ if (parent.typ == EnumToken.CommentTokenType ||
94
+ parent.typ == EnumToken.CDOCOMMTokenType) {
95
+ continue;
51
96
  }
52
- if (curr[0] == '&') {
53
- if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
54
- curr.splice(0, 2);
97
+ if (postprocess) {
98
+ for (const feature of options.features) {
99
+ if (!feature.postProcess) {
100
+ continue;
101
+ }
102
+ feature.run(parent, options, parent.parent ?? ast, context, FeatureWalkMode.Post);
55
103
  }
56
- else if (combinators.includes(curr[1])) {
57
- curr.shift();
104
+ }
105
+ if (('chi' in parent)) {
106
+ // @ts-ignore
107
+ for (const node of parent.chi) {
108
+ parents.push(Object.defineProperty(node, 'parent', {
109
+ ...definedPropertySettings,
110
+ value: parent
111
+ }));
58
112
  }
59
113
  }
60
- else if (ast.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
114
+ }
115
+ if (postprocess) {
116
+ for (const feature of options.features) {
117
+ if (feature.postProcess && 'cleanup' in feature) {
118
+ // @ts-ignore
119
+ feature.cleanup(ast, options, context, FeatureWalkMode.Post);
120
+ }
121
+ }
122
+ }
123
+ return ast;
124
+ }
125
+ function reduce(acc, curr, index, array) {
126
+ // trim :is()
127
+ if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
128
+ curr = curr.slice(1, -1);
129
+ }
130
+ if (curr[0] == '&') {
131
+ if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
132
+ curr.splice(0, 2);
133
+ }
134
+ else if (combinators.includes(curr[1])) {
135
+ curr.shift();
136
+ }
137
+ }
138
+ else { // @ts-ignore
139
+ if (this.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
61
140
  curr.unshift('&', ' ');
62
141
  }
63
- acc.push(curr.join(''));
64
- return acc;
65
142
  }
143
+ acc.push(curr.join(''));
144
+ return acc;
145
+ }
146
+ function doMinify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
147
+ if (!('nodes' in context)) {
148
+ context.nodes = new Set;
149
+ }
150
+ if (context.nodes.has(ast)) {
151
+ return ast;
152
+ }
153
+ context.nodes.add(ast);
66
154
  // @ts-ignore
67
155
  if ('chi' in ast && ast.chi.length > 0) {
156
+ const reducer = reduce.bind(ast);
68
157
  if (!nestingContent) {
69
158
  nestingContent = options.nestingRules && ast.typ == EnumToken.RuleNodeType;
70
159
  }
@@ -99,7 +188,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
99
188
  continue;
100
189
  }
101
190
  if (node.chi.length > 0) {
102
- minify(node, options, true, errors, nestingContent, context);
191
+ doMinify(node, options, true, errors, nestingContent, context);
103
192
  }
104
193
  }
105
194
  if (node.typ == EnumToken.KeyFrameRuleNodeType) {
@@ -148,7 +237,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
148
237
  }
149
238
  // @ts-ignore
150
239
  if (!hasDeclaration(node)) {
151
- minify(node, options, recursive, errors, nestingContent, context);
240
+ doMinify(node, options, recursive, errors, nestingContent, context);
152
241
  }
153
242
  previous = node;
154
243
  nodeIndex = i;
@@ -199,7 +288,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
199
288
  nodeIndex = --i;
200
289
  // @ts-ignore
201
290
  previous = ast.chi[nodeIndex];
202
- minify(wrapper, options, recursive, errors, nestingContent, context);
291
+ doMinify(wrapper, options, recursive, errors, nestingContent, context);
203
292
  continue;
204
293
  }
205
294
  // @ts-ignore
@@ -306,7 +395,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
306
395
  // @ts-ignore
307
396
  // minifyRule(node, <MinifyOptions>options, ast, context);
308
397
  // } else {
309
- minify(node, options, recursive, errors, nestingContent, context);
398
+ doMinify(node, options, recursive, errors, nestingContent, context);
310
399
  }
311
400
  i--;
312
401
  previous = node;
@@ -361,7 +450,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
361
450
  // @ts-ignore
362
451
  // minifyRule(previous, <MinifyOptions>options, ast, context);
363
452
  // } else {
364
- minify(previous, options, recursive, errors, nestingContent, context);
453
+ doMinify(previous, options, recursive, errors, nestingContent, context);
365
454
  }
366
455
  }
367
456
  }
@@ -372,14 +461,14 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
372
461
  // @ts-ignore
373
462
  // minifyRule(previous, <MinifyOptions>options, ast, context);
374
463
  // } else {
375
- minify(previous, options, recursive, errors, nestingContent, context);
464
+ doMinify(previous, options, recursive, errors, nestingContent, context);
376
465
  }
377
466
  }
378
467
  }
379
468
  }
380
469
  // else if ('chi' in node) {
381
470
  //
382
- // minify(node, options, recursive, errors, nestingContent, context);
471
+ // doMinify(node, options, recursive, errors, nestingContent, context);
383
472
  // }
384
473
  if (!nestingContent &&
385
474
  // @ts-ignore
@@ -398,7 +487,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
398
487
  if (node.typ == EnumToken.KeyframeAtRuleNodeType || !node.chi.some(n => n.typ == EnumToken.DeclarationNodeType)) {
399
488
  // @ts-ignore
400
489
  if (!(node.typ == EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
401
- minify(node, options, recursive, errors, nestingContent, context);
490
+ doMinify(node, options, recursive, errors, nestingContent, context);
402
491
  }
403
492
  }
404
493
  }
@@ -411,41 +500,6 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
411
500
  fixSelector(node);
412
501
  }
413
502
  }
414
- if (ast.typ == EnumToken.StyleSheetNodeType) {
415
- let parent;
416
- let parents = [ast];
417
- while (parents.length > 0) {
418
- parent = parents.shift();
419
- // @ts-ignore
420
- for (let k = 0; k < parent.chi.length; k++) {
421
- // @ts-ignore
422
- const node = parent.chi[k];
423
- if (!('chi' in node) || node.typ == EnumToken.StyleSheetNodeType || (node.typ == EnumToken.AtRuleNodeType && node.nam == 'font-face')) {
424
- continue;
425
- }
426
- // @ts-ignore
427
- if (node.chi.length > 0) {
428
- parents.push(node);
429
- Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: parent });
430
- for (const feature of options.features) {
431
- feature.run(node, options, parent, context);
432
- }
433
- }
434
- // @ts-ignore
435
- if (options.removeEmpty && node.chi.length == 0) {
436
- // @ts-ignore
437
- parent.chi.splice(k, 1);
438
- k--;
439
- }
440
- }
441
- }
442
- for (const feature of options.features) {
443
- if ('cleanup' in feature) {
444
- // @ts-ignore
445
- feature.cleanup(ast, options, context);
446
- }
447
- }
448
- }
449
503
  return ast;
450
504
  }
451
505
  function hasDeclaration(node) {
@@ -600,6 +654,28 @@ function splitRule(buffer) {
600
654
  result.push([]);
601
655
  continue;
602
656
  }
657
+ if (chr == '.') {
658
+ if (str !== '') {
659
+ // @ts-ignore
660
+ result.at(-1).push(str);
661
+ str = '';
662
+ }
663
+ str += chr;
664
+ continue;
665
+ }
666
+ if (combinators.includes(chr)) {
667
+ if (str !== '') {
668
+ // @ts-ignore
669
+ result.at(-1).push(str);
670
+ str = '';
671
+ }
672
+ if (chr == '|' && buffer.charAt(i + 1) == '|') {
673
+ chr += buffer.charAt(++i);
674
+ }
675
+ // @ts-ignore
676
+ result.at(-1).push(chr);
677
+ continue;
678
+ }
603
679
  if (chr == ':') {
604
680
  if (str !== '') {
605
681
  // @ts-ignore
@@ -816,7 +892,6 @@ function matchSelectors(selector1, selector2, parentType, errors) {
816
892
  }, []);
817
893
  }
818
894
  }
819
- // @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
820
895
  acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
821
896
  return acc;
822
897
  }
@@ -894,6 +969,9 @@ function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
894
969
  return wrapper;
895
970
  }
896
971
  function diff(n1, n2, reducer, options = {}) {
972
+ if (!('cache' in options)) {
973
+ options.cache = new WeakMap();
974
+ }
897
975
  let node1 = n1;
898
976
  let node2 = n2;
899
977
  let exchanged = false;
@@ -906,12 +984,9 @@ function diff(n1, n2, reducer, options = {}) {
906
984
  let i = node1.chi.length;
907
985
  let j = node2.chi.length;
908
986
  if (i == 0 || j == 0) {
909
- // @ts-ignore
910
987
  return null;
911
988
  }
912
- // @ts-ignore
913
989
  const raw1 = node1.raw;
914
- // @ts-ignore
915
990
  const raw2 = node2.raw;
916
991
  if (raw1 != null && raw2 != null) {
917
992
  const prefixes1 = new Set;
@@ -959,9 +1034,16 @@ function diff(n1, n2, reducer, options = {}) {
959
1034
  }
960
1035
  }
961
1036
  }
962
- // @ts-ignore
1037
+ const css1 = options.cache.get(node1);
1038
+ const css2 = options.cache.get(node2);
963
1039
  node1 = { ...node1, chi: node1.chi.slice() };
964
1040
  node2 = { ...node2, chi: node2.chi.slice() };
1041
+ if (css1 != null) {
1042
+ options.cache.set(node1, css1);
1043
+ }
1044
+ if (css2 != null) {
1045
+ options.cache.set(node2, css2);
1046
+ }
965
1047
  if (raw1 != null) {
966
1048
  Object.defineProperty(node1, 'raw', { ...definedPropertySettings, value: raw1 });
967
1049
  }
@@ -982,24 +1064,34 @@ function diff(n1, n2, reducer, options = {}) {
982
1064
  continue;
983
1065
  }
984
1066
  if (node1.chi[i].nam == node2.chi[j].nam) {
985
- if (eq(node1.chi[i], node2.chi[j])) {
1067
+ if (node1.chi[i].typ == node2.chi[j].typ && eq(node1.chi[i], node2.chi[j])) {
986
1068
  intersect.push(node1.chi[i]);
987
1069
  node1.chi.splice(i, 1);
988
1070
  node2.chi.splice(j, 1);
1071
+ options.cache.delete(node1);
1072
+ options.cache.delete(node2);
989
1073
  break;
990
1074
  }
991
1075
  }
992
1076
  }
993
1077
  }
994
- // @ts-ignore
995
1078
  const result = (intersect.length == 0 ? null : {
996
1079
  ...node1,
997
1080
  // @ts-ignore
998
1081
  sel: [...new Set([...(n1?.raw?.reduce(reducer, []) ?? splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) ?? splitRule(n2.sel))])].join(','),
999
1082
  chi: intersect.reverse()
1000
1083
  });
1001
- if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0)) {
1002
- // @ts-ignore
1084
+ if (result == null || [n1, n2].reduce((acc, curr) => {
1085
+ let css = options.cache.get(curr);
1086
+ if (css == null) {
1087
+ css = doRender(curr, options).code;
1088
+ options.cache.set(curr, css);
1089
+ }
1090
+ return curr.chi.length == 0 ? acc : acc + css.length;
1091
+ }, 0) <= [node1, node2, result].reduce((acc, curr) => {
1092
+ const css = doRender(curr, options).code;
1093
+ return curr.chi.length == 0 ? acc : acc + css.length;
1094
+ }, 0)) {
1003
1095
  return null;
1004
1096
  }
1005
1097
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node1 : node2 };
@@ -1008,9 +1100,6 @@ function reduceRuleSelector(node) {
1008
1100
  if (node.raw == null) {
1009
1101
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
1010
1102
  }
1011
- // @ts-ignore
1012
- // if (node.raw != null) {
1013
- // @ts-ignore
1014
1103
  let optimized = reduceSelector(node.raw.reduce((acc, curr) => {
1015
1104
  acc.push(curr.slice());
1016
1105
  return acc;
@@ -1044,7 +1133,6 @@ function reduceRuleSelector(node) {
1044
1133
  const sel = raw[0].join('');
1045
1134
  if (sel.length < node.sel.length) {
1046
1135
  node.sel = sel;
1047
- // node.raw = raw;
1048
1136
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
1049
1137
  }
1050
1138
  }
@@ -5,6 +5,7 @@ import { transformFunctions } from '../../syntax/syntax.js';
5
5
  import '../minify.js';
6
6
  import '../walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
8
9
  import '../../parser/utils/config.js';
9
10
  import { getNumber, getAngle } from '../../renderer/color/color.js';
10
11
  import '../../renderer/color/utils/constants.js';
@@ -7,6 +7,7 @@ import '../../renderer/color/utils/constants.js';
7
7
  import '../minify.js';
8
8
  import '../walk.js';
9
9
  import '../../parser/parse.js';
10
+ import '../../parser/tokenize.js';
10
11
  import '../../parser/utils/config.js';
11
12
 
12
13
  function parseMatrix(mat) {
@@ -1,9 +1,30 @@
1
+ var SyntaxValidationResult;
2
+ (function (SyntaxValidationResult) {
3
+ SyntaxValidationResult[SyntaxValidationResult["Valid"] = 0] = "Valid";
4
+ SyntaxValidationResult[SyntaxValidationResult["Drop"] = 1] = "Drop";
5
+ SyntaxValidationResult[SyntaxValidationResult["Lenient"] = 2] = "Lenient"; /* preserve unknown at-rules, declarations and pseudo-classes */
6
+ })(SyntaxValidationResult || (SyntaxValidationResult = {}));
7
+ /**
8
+ * validation level enum
9
+ */
1
10
  var ValidationLevel;
2
11
  (function (ValidationLevel) {
3
- ValidationLevel[ValidationLevel["Valid"] = 0] = "Valid";
4
- ValidationLevel[ValidationLevel["Drop"] = 1] = "Drop";
5
- ValidationLevel[ValidationLevel["Lenient"] = 2] = "Lenient"; /* preserve unknown at-rules, declarations and pseudo-classes */
12
+ /**
13
+ * disable validation
14
+ */
15
+ ValidationLevel[ValidationLevel["None"] = 0] = "None";
16
+ /**
17
+ * validate selectors and at-rules
18
+ */
19
+ ValidationLevel[ValidationLevel["Default"] = 1] = "Default";
20
+ /**
21
+ * validate selectors, at-rules and declarations
22
+ */
23
+ ValidationLevel[ValidationLevel["All"] = 2] = "All"; // selectors + at-rules + declarations
6
24
  })(ValidationLevel || (ValidationLevel = {}));
25
+ /**
26
+ * token types enum
27
+ */
7
28
  var EnumToken;
8
29
  (function (EnumToken) {
9
30
  EnumToken[EnumToken["CommentTokenType"] = 0] = "CommentTokenType";
@@ -103,6 +124,7 @@ var EnumToken;
103
124
  EnumToken[EnumToken["PseudoPageTokenType"] = 91] = "PseudoPageTokenType";
104
125
  EnumToken[EnumToken["PseudoElementTokenType"] = 92] = "PseudoElementTokenType";
105
126
  EnumToken[EnumToken["KeyframeAtRuleNodeType"] = 93] = "KeyframeAtRuleNodeType";
127
+ EnumToken[EnumToken["InvalidDeclarationNodeType"] = 94] = "InvalidDeclarationNodeType";
106
128
  /* aliases */
107
129
  EnumToken[EnumToken["Time"] = 25] = "Time";
108
130
  EnumToken[EnumToken["Iden"] = 7] = "Iden";
@@ -132,16 +154,5 @@ var EnumToken;
132
154
  EnumToken[EnumToken["TimingFunction"] = 17] = "TimingFunction";
133
155
  EnumToken[EnumToken["TimelineFunction"] = 16] = "TimelineFunction";
134
156
  })(EnumToken || (EnumToken = {}));
135
- const funcLike = [
136
- EnumToken.ParensTokenType,
137
- EnumToken.FunctionTokenType,
138
- EnumToken.UrlFunctionTokenType,
139
- EnumToken.StartParensTokenType,
140
- EnumToken.ImageFunctionTokenType,
141
- EnumToken.TimingFunctionTokenType,
142
- EnumToken.TimingFunctionTokenType,
143
- EnumToken.PseudoClassFuncTokenType,
144
- EnumToken.GridTemplateFuncTokenType
145
- ];
146
157
 
147
- export { EnumToken, ValidationLevel, funcLike };
158
+ export { EnumToken, SyntaxValidationResult, ValidationLevel };
@@ -0,0 +1,104 @@
1
+ import { funcLike, ColorKind } from '../../renderer/color/utils/constants.js';
2
+ import { EnumToken } from '../types.js';
3
+ import '../minify.js';
4
+ import '../walk.js';
5
+ import '../../parser/parse.js';
6
+ import '../../parser/tokenize.js';
7
+ import '../../parser/utils/config.js';
8
+ import '../../renderer/sourcemap/lib/encode.js';
9
+ import { minmax } from '../../renderer/color/color.js';
10
+
11
+ function reduceNumber(val) {
12
+ val = String(+val);
13
+ if (val === '0') {
14
+ return '0';
15
+ }
16
+ const chr = val.charAt(0);
17
+ if (chr == '-') {
18
+ const slice = val.slice(0, 2);
19
+ if (slice == '-0') {
20
+ return val.length == 2 ? '0' : '-' + val.slice(2);
21
+ }
22
+ }
23
+ if (chr == '0') {
24
+ return val.slice(1);
25
+ }
26
+ return val;
27
+ }
28
+ /**
29
+ * clamp color values
30
+ * @param token
31
+ */
32
+ function clamp(token) {
33
+ if (token.kin == ColorKind.RGB || token.kin == ColorKind.RGBA) {
34
+ token.chi.filter((token) => ![EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType].includes(token.typ)).forEach((token, index) => {
35
+ if (index <= 2) {
36
+ if (token.typ == EnumToken.NumberTokenType) {
37
+ token.val = String(minmax(+token.val, 0, 255));
38
+ }
39
+ else if (token.typ == EnumToken.PercentageTokenType) {
40
+ token.val = String(minmax(+token.val, 0, 100));
41
+ }
42
+ }
43
+ else {
44
+ if (token.typ == EnumToken.NumberTokenType) {
45
+ token.val = String(minmax(+token.val, 0, 1));
46
+ }
47
+ else if (token.typ == EnumToken.PercentageTokenType) {
48
+ token.val = String(minmax(+token.val, 0, 100));
49
+ }
50
+ }
51
+ });
52
+ }
53
+ return token;
54
+ }
55
+ function getNumber(token) {
56
+ if (token.typ == EnumToken.IdenTokenType && token.val == 'none') {
57
+ return 0;
58
+ }
59
+ // @ts-ignore
60
+ return token.typ == EnumToken.PercentageTokenType ? token.val / 100 : +token.val;
61
+ }
62
+ /**
63
+ * convert angle to turn
64
+ * @param token
65
+ */
66
+ function getAngle(token) {
67
+ if (token.typ == EnumToken.IdenTokenType) {
68
+ if (token.val == 'none') {
69
+ return 0;
70
+ }
71
+ }
72
+ if (token.typ == EnumToken.AngleTokenType) {
73
+ switch (token.unit) {
74
+ case 'deg':
75
+ // @ts-ignore
76
+ return token.val / 360;
77
+ case 'rad':
78
+ // @ts-ignore
79
+ return token.val / (2 * Math.PI);
80
+ case 'grad':
81
+ // @ts-ignore
82
+ return token.val / 400;
83
+ case 'turn':
84
+ // @ts-ignore
85
+ return +token.val;
86
+ }
87
+ }
88
+ // @ts-ignore
89
+ return token.val / 360;
90
+ }
91
+ function filterValues(values) {
92
+ let i = 0;
93
+ for (; i < values.length; i++) {
94
+ if (values[i].typ == EnumToken.ImportantTokenType && values[i - 1]?.typ == EnumToken.WhitespaceTokenType) {
95
+ values.splice(i - 1, 1);
96
+ }
97
+ else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == EnumToken.WhitespaceTokenType) {
98
+ values.splice(i + 1, 1);
99
+ }
100
+ }
101
+ return values;
102
+ }
103
+
104
+ export { clamp, filterValues, getAngle, getNumber, reduceNumber };
@@ -1,5 +1,3 @@
1
- import { EnumToken } from './types.js';
2
-
3
1
  var WalkerOptionEnum;
4
2
  (function (WalkerOptionEnum) {
5
3
  WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 0] = "Ignore";
@@ -46,7 +44,7 @@ function* walk(node, filter) {
46
44
  }
47
45
  }
48
46
  /**
49
- * walk ast values
47
+ * walk ast node value tokens
50
48
  * @param values
51
49
  * @param root
52
50
  * @param filter
@@ -113,10 +111,38 @@ function* walkValues(values, root = null, filter, reverse) {
113
111
  stack.unshift(...sliced);
114
112
  }
115
113
  }
116
- else if (value.typ == EnumToken.BinaryExpressionTokenType) {
117
- map.set(value.l, value);
118
- map.set(value.r, value);
119
- stack.unshift(value.l, value.r);
114
+ else {
115
+ const values = [];
116
+ if ('l' in value && value.l != null) {
117
+ // @ts-ignore
118
+ values.push(value.l);
119
+ // @ts-ignore
120
+ map.set(value.l, value);
121
+ }
122
+ if ('op' in value && typeof value.op == 'object') {
123
+ values.push(value.op);
124
+ // @ts-ignore
125
+ map.set(value.op, value);
126
+ }
127
+ if ('r' in value && value.r != null) {
128
+ if (Array.isArray(value.r)) {
129
+ for (const r of value.r) {
130
+ // @ts-ignore
131
+ values.push(r);
132
+ // @ts-ignore
133
+ map.set(r, value);
134
+ }
135
+ }
136
+ else {
137
+ // @ts-ignore
138
+ values.push(value.r);
139
+ // @ts-ignore
140
+ map.set(value.r, value);
141
+ }
142
+ }
143
+ if (values.length > 0) {
144
+ stack.unshift(...values);
145
+ }
120
146
  }
121
147
  if (eventType == WalkerValueEvent.Leave && filter.fn != null) {
122
148
  const isValid = filter.type == null || value.typ == filter.type ||
@@ -1,4 +1,8 @@
1
1
  const matchUrl = /^(https?:)?\/\//;
2
+ /**
3
+ * return the directory name of a path
4
+ * @param path
5
+ */
2
6
  function dirname(path) {
3
7
  if (path == '/' || path === '') {
4
8
  return path;
@@ -47,6 +51,12 @@ function splitPath(result) {
47
51
  }
48
52
  return { parts, i };
49
53
  }
54
+ /**
55
+ * resolve path
56
+ * @param url
57
+ * @param currentDirectory
58
+ * @param cwd
59
+ */
50
60
  function resolve(url, currentDirectory, cwd) {
51
61
  if (matchUrl.test(url)) {
52
62
  return {