@tbela99/css-parser 0.6.0 → 0.7.1

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 (51) hide show
  1. package/README.md +114 -4
  2. package/dist/config.json.js +3 -1
  3. package/dist/index-umd-web.js +53942 -40
  4. package/dist/index.cjs +53946 -40
  5. package/dist/index.d.ts +127 -18
  6. package/dist/lib/ast/expand.js +69 -3
  7. package/dist/lib/ast/features/index.js +1 -0
  8. package/dist/lib/ast/features/prefix.js +118 -0
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/minify.js +44 -10
  11. package/dist/lib/ast/types.js +16 -1
  12. package/dist/lib/ast/walk.js +3 -1
  13. package/dist/lib/parser/declaration/list.js +1 -1
  14. package/dist/lib/parser/declaration/map.js +9 -4
  15. package/dist/lib/parser/declaration/set.js +2 -1
  16. package/dist/lib/parser/parse.js +239 -11
  17. package/dist/lib/parser/tokenize.js +26 -5
  18. package/dist/lib/parser/utils/config.js +1 -0
  19. package/dist/lib/parser/utils/declaration.js +2 -1
  20. package/dist/lib/parser/utils/syntax.js +1 -0
  21. package/dist/lib/parser/utils/type.js +1 -0
  22. package/dist/lib/renderer/color/a98rgb.js +1 -0
  23. package/dist/lib/renderer/color/color.js +1 -0
  24. package/dist/lib/renderer/color/colormix.js +3 -2
  25. package/dist/lib/renderer/color/hex.js +1 -0
  26. package/dist/lib/renderer/color/hsl.js +1 -0
  27. package/dist/lib/renderer/color/hwb.js +1 -0
  28. package/dist/lib/renderer/color/lab.js +1 -0
  29. package/dist/lib/renderer/color/lch.js +1 -0
  30. package/dist/lib/renderer/color/oklab.js +1 -0
  31. package/dist/lib/renderer/color/oklch.js +1 -0
  32. package/dist/lib/renderer/color/p3.js +1 -0
  33. package/dist/lib/renderer/color/rec2020.js +1 -0
  34. package/dist/lib/renderer/color/relativecolor.js +1 -0
  35. package/dist/lib/renderer/color/rgb.js +1 -0
  36. package/dist/lib/renderer/color/srgb.js +1 -0
  37. package/dist/lib/renderer/color/utils/components.js +1 -0
  38. package/dist/lib/renderer/color/utils/constants.js +1 -0
  39. package/dist/lib/renderer/color/xyz.js +1 -0
  40. package/dist/lib/renderer/color/xyzd50.js +1 -0
  41. package/dist/lib/renderer/render.js +25 -5
  42. package/dist/lib/syntax/syntax.js +456 -0
  43. package/dist/lib/validation/config.js +9 -0
  44. package/dist/lib/validation/config.json.js +52883 -0
  45. package/dist/lib/validation/parser/parse.js +16 -0
  46. package/dist/lib/validation/parser/types.js +39 -0
  47. package/dist/lib/validation/selector.js +459 -0
  48. package/dist/node/index.js +14 -0
  49. package/dist/web/index.js +10 -0
  50. package/package.json +13 -13
  51. package/jsr.json +0 -29
@@ -32,6 +32,7 @@ function* walkValues(values, root = null, filter) {
32
32
  const stack = values.slice();
33
33
  const map = new Map;
34
34
  let value;
35
+ let previous = null;
35
36
  while ((value = stack.shift())) {
36
37
  let option = null;
37
38
  if (filter != null) {
@@ -46,7 +47,7 @@ function* walkValues(values, root = null, filter) {
46
47
  // @ts-ignore
47
48
  if (option !== 'children') {
48
49
  // @ts-ignore
49
- yield { value, parent: map.get(value), root };
50
+ yield { value, parent: map.get(value), previousValue: previous, nextValue: stack[0] ?? null, root };
50
51
  }
51
52
  if (option !== 'ignore-children' && 'chi' in value) {
52
53
  for (const child of value.chi.slice()) {
@@ -59,6 +60,7 @@ function* walkValues(values, root = null, filter) {
59
60
  map.set(value.r, value);
60
61
  stack.unshift(value.l, value.r);
61
62
  }
63
+ previous = value;
62
64
  }
63
65
  }
64
66
 
@@ -1,10 +1,10 @@
1
1
  import { PropertySet } from './set.js';
2
+ import { getConfig } from '../utils/config.js';
2
3
  import { EnumToken } from '../../ast/types.js';
3
4
  import '../../ast/minify.js';
4
5
  import { parseString } from '../parse.js';
5
6
  import '../../renderer/color/utils/constants.js';
6
7
  import '../../renderer/sourcemap/lib/encode.js';
7
- import { getConfig } from '../utils/config.js';
8
8
  import { PropertyMap } from './map.js';
9
9
 
10
10
  const config = getConfig();
@@ -1,11 +1,11 @@
1
1
  import { eq } from '../utils/eq.js';
2
- import { renderToken } from '../../renderer/render.js';
2
+ import { getConfig } from '../utils/config.js';
3
+ import { matchType } from '../utils/type.js';
3
4
  import { EnumToken } from '../../ast/types.js';
4
5
  import '../../ast/minify.js';
5
6
  import { parseString } from '../parse.js';
7
+ import { renderToken } from '../../renderer/render.js';
6
8
  import '../../renderer/color/utils/constants.js';
7
- import { getConfig } from '../utils/config.js';
8
- import { matchType } from '../utils/type.js';
9
9
  import { PropertySet } from './set.js';
10
10
 
11
11
  const propertiesConfig = getConfig();
@@ -248,7 +248,9 @@ class PropertyMap {
248
248
  // @ts-ignore
249
249
  let typ = (EnumToken[this.config.separator?.typ] ?? EnumToken.CommaTokenType);
250
250
  // @ts-ignore
251
- let separator = this.config.separator ? renderToken(this.config.separator) : ',';
251
+ const sep = this.config.separator == null ? null : { ...this.config.separator, typ: EnumToken[this.config.separator.typ] };
252
+ // @ts-ignore
253
+ const separator = this.config.separator ? renderToken({ ...this.config.separator, typ: EnumToken[this.config.separator.typ] }) : ',';
252
254
  this.matchTypes(declaration);
253
255
  values.push(value);
254
256
  for (i = 0; i < declaration.val.length; i++) {
@@ -281,6 +283,9 @@ class PropertyMap {
281
283
  }
282
284
  this.removeDefaults(map, value);
283
285
  declaration.val = values.reduce((acc, curr) => {
286
+ if (sep != null && acc.length > 0) {
287
+ acc.push({ ...sep });
288
+ }
284
289
  for (const cr of curr) {
285
290
  if (cr.typ == EnumToken.WhitespaceTokenType && acc.at(-1)?.typ == cr.typ) {
286
291
  continue;
@@ -1,8 +1,9 @@
1
1
  import { eq } from '../utils/eq.js';
2
- import { isLength } from '../utils/syntax.js';
3
2
  import { EnumToken } from '../../ast/types.js';
4
3
  import '../../ast/minify.js';
5
4
  import '../parse.js';
5
+ import { isLength } from '../../syntax/syntax.js';
6
+ import '../utils/config.js';
6
7
  import '../../renderer/color/utils/constants.js';
7
8
  import '../../renderer/sourcemap/lib/encode.js';
8
9
 
@@ -1,5 +1,6 @@
1
- import { isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isIdent, isHexColor, isHash, isIdentStart, isColor } from './utils/syntax.js';
2
- import { EnumToken, funcLike } from '../ast/types.js';
1
+ import { isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isIdent, isHexColor, isHash, isIdentStart, isColor } from '../syntax/syntax.js';
2
+ import './utils/config.js';
3
+ import { EnumToken, funcLike, ValidationLevel } from '../ast/types.js';
3
4
  import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
4
5
  import { walkValues, walk } from '../ast/walk.js';
5
6
  import { expand } from '../ast/expand.js';
@@ -7,6 +8,7 @@ import { parseDeclaration } from './utils/declaration.js';
7
8
  import { renderToken } from '../renderer/render.js';
8
9
  import { COLORS_NAMES, systemColors, deprecatedSystemColors } from '../renderer/color/utils/constants.js';
9
10
  import { tokenize } from './tokenize.js';
11
+ import { validateSelector } from '../validation/selector.js';
10
12
 
11
13
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
12
14
  const trimWhiteSpace = [EnumToken.CommentTokenType, EnumToken.GtTokenType, EnumToken.GteTokenType, EnumToken.LtTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType];
@@ -24,13 +26,51 @@ const enumTokenHints = new Set([
24
26
  EnumToken.EOFTokenType
25
27
  ]);
26
28
  const webkitPseudoAliasMap = {
27
- '-webkit-autofill': 'autofill'
29
+ '-webkit-autofill': 'autofill',
30
+ '-webkit-any': 'is',
31
+ '-moz-any': 'is',
32
+ '-webkit-border-after': 'border-block-end',
33
+ '-webkit-border-after-color': 'border-block-end-color',
34
+ '-webkit-border-after-style': 'border-block-end-style',
35
+ '-webkit-border-after-width': 'border-block-end-width',
36
+ '-webkit-border-before': 'border-block-start',
37
+ '-webkit-border-before-color': 'border-block-start-color',
38
+ '-webkit-border-before-style': 'border-block-start-style',
39
+ '-webkit-border-before-width': 'border-block-start-width',
40
+ '-webkit-border-end': 'border-inline-end',
41
+ '-webkit-border-end-color': 'border-inline-end-color',
42
+ '-webkit-border-end-style': 'border-inline-end-style',
43
+ '-webkit-border-end-width': 'border-inline-end-width',
44
+ '-webkit-border-start': 'border-inline-start',
45
+ '-webkit-border-start-color': 'border-inline-start-color',
46
+ '-webkit-border-start-style': 'border-inline-start-style',
47
+ '-webkit-border-start-width': 'border-inline-start-width',
48
+ '-webkit-box-align': 'align-items',
49
+ '-webkit-box-direction': 'flex-direction',
50
+ '-webkit-box-flex': 'flex-grow',
51
+ '-webkit-box-lines': 'flex-flow',
52
+ '-webkit-box-ordinal-group': 'order',
53
+ '-webkit-box-orient': 'flex-direction',
54
+ '-webkit-box-pack': 'justify-content',
55
+ '-webkit-column-break-after': 'break-after',
56
+ '-webkit-column-break-before': 'break-before',
57
+ '-webkit-column-break-inside': 'break-inside',
58
+ '-webkit-font-feature-settings': 'font-feature-settings',
59
+ '-webkit-hyphenate-character': 'hyphenate-character',
60
+ '-webkit-initial-letter': 'initial-letter',
61
+ '-webkit-margin-end': 'margin-block-end',
62
+ '-webkit-margin-start': 'margin-block-start',
63
+ '-webkit-padding-after': 'padding-block-end',
64
+ '-webkit-padding-before': 'padding-block-start',
65
+ '-webkit-padding-end': 'padding-inline-end',
66
+ '-webkit-padding-start': 'padding-inline-start',
67
+ '-webkit-min-device-pixel-ratio': 'min-resolution',
68
+ '-webkit-max-device-pixel-ratio': 'max-resolution'
28
69
  };
29
70
  function reject(reason) {
30
71
  throw new Error(reason ?? 'Parsing aborted');
31
72
  }
32
73
  async function doParse(iterator, options = {}) {
33
- // return new Promise(async (resolve, reject) => {
34
74
  if (options.signal != null) {
35
75
  options.signal.addEventListener('abort', reject);
36
76
  }
@@ -49,6 +89,8 @@ async function doParse(iterator, options = {}) {
49
89
  computeCalcExpression: true,
50
90
  inlineCssVariables: false,
51
91
  setParent: true,
92
+ removePrefix: false,
93
+ validation: false,
52
94
  ...options
53
95
  };
54
96
  if (options.expandNestingRules) {
@@ -129,7 +171,13 @@ async function doParse(iterator, options = {}) {
129
171
  await parseNode(tokens, context, stats, options, errors, src, map);
130
172
  const previousNode = stack.pop();
131
173
  // @ts-ignore
132
- context = stack[stack.length - 1] || ast;
174
+ context = stack[stack.length - 1] ?? ast;
175
+ if (previousNode != null && previousNode.typ == EnumToken.InvalidRuleTokenType) {
176
+ const index = context.chi.findIndex(node => node == previousNode);
177
+ if (index > -1) {
178
+ context.chi.splice(index, 1);
179
+ }
180
+ }
133
181
  // @ts-ignore
134
182
  if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
135
183
  context.chi.pop();
@@ -140,6 +188,12 @@ async function doParse(iterator, options = {}) {
140
188
  }
141
189
  if (tokens.length > 0) {
142
190
  await parseNode(tokens, context, stats, options, errors, src, map);
191
+ if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
192
+ const index = context.chi.findIndex(node => node == context);
193
+ if (index > -1) {
194
+ context.chi.splice(index, 1);
195
+ }
196
+ }
143
197
  }
144
198
  while (stack.length > 0 && context != ast) {
145
199
  const previousNode = stack.pop();
@@ -420,6 +474,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
420
474
  if (delim.typ == EnumToken.BlockStartTokenType) {
421
475
  const position = map.get(tokens[0]);
422
476
  const uniq = new Map;
477
+ // const uniqTokens: Token[][] = [[]];
423
478
  parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
424
479
  if (curr.typ == EnumToken.CommentTokenType) {
425
480
  return acc;
@@ -435,18 +490,49 @@ async function parseNode(results, context, stats, options, errors, src, map) {
435
490
  let t = renderToken(curr, { minify: false });
436
491
  if (t == ',') {
437
492
  acc.push([]);
493
+ // uniqTokens.push([]);
438
494
  }
439
495
  else {
440
496
  acc[acc.length - 1].push(t);
497
+ // uniqTokens[uniqTokens.length - 1].push(curr);
441
498
  }
442
499
  return acc;
443
500
  }, [[]]).reduce((acc, curr) => {
501
+ let i = 0;
502
+ for (; i < curr.length; i++) {
503
+ if (i + 1 < curr.length && curr[i] == '*') {
504
+ if (curr[i] == '*') {
505
+ let index = curr[i + 1] == ' ' ? 2 : 1;
506
+ if (!['>', '~', '+'].includes(curr[index])) {
507
+ curr.splice(i, index);
508
+ }
509
+ }
510
+ }
511
+ }
444
512
  acc.set(curr.join(''), curr);
445
513
  return acc;
446
514
  }, uniq);
515
+ const ruleType = context.typ == EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
516
+ if (ruleType == EnumToken.RuleNodeType) {
517
+ const valid = validateSelector(parseSelector(tokens), options, context);
518
+ if (valid.valid != ValidationLevel.Valid) {
519
+ const node = {
520
+ typ: EnumToken.InvalidRuleTokenType,
521
+ // @ts-ignore
522
+ sel: tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), ''),
523
+ chi: []
524
+ };
525
+ errors.push({
526
+ action: 'drop',
527
+ message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
528
+ location: { src, ...(map.get(valid.node) ?? position) }
529
+ });
530
+ context.chi.push(node);
531
+ return node;
532
+ }
533
+ }
447
534
  const node = {
448
- typ: context.typ == EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType,
449
- // @ts-ignore
535
+ typ: ruleType,
450
536
  sel: [...uniq.keys()].join(','),
451
537
  chi: []
452
538
  };
@@ -529,6 +615,145 @@ async function parseNode(results, context, stats, options, errors, src, map) {
529
615
  }
530
616
  }
531
617
  }
618
+ function parseSelector(tokens) {
619
+ for (const { value, previousValue, nextValue, parent } of walkValues(tokens)) {
620
+ if (value.typ == EnumToken.CommentTokenType ||
621
+ value.typ == EnumToken.WhitespaceTokenType ||
622
+ value.typ == EnumToken.CommaTokenType ||
623
+ value.typ == EnumToken.IdenTokenType ||
624
+ value.typ == EnumToken.HashTokenType) {
625
+ continue;
626
+ }
627
+ if (parent == null) {
628
+ if (value.typ == EnumToken.GtTokenType) {
629
+ // @ts-ignore
630
+ value.typ = EnumToken.ChildCombinatorTokenType;
631
+ }
632
+ // @ts-ignore
633
+ else if (value.typ == EnumToken.WhitespaceTokenType) {
634
+ if (nextValue != null && nextValue.typ == EnumToken.LiteralTokenType) {
635
+ if (['>', '+', '~'].includes(nextValue.val)) {
636
+ switch (value.val) {
637
+ case '>':
638
+ // @ts-ignore
639
+ nextValue.typ = EnumToken.ChildCombinatorTokenType;
640
+ break;
641
+ case '+':
642
+ // @ts-ignore
643
+ nextValue.typ = EnumToken.NextSiblingCombinatorTokenType;
644
+ break;
645
+ case '~':
646
+ // @ts-ignore
647
+ nextValue.typ = EnumToken.SubsequentSiblingCombinatorTokenType;
648
+ break;
649
+ }
650
+ // @ts-ignore
651
+ delete nextValue.val;
652
+ continue;
653
+ }
654
+ }
655
+ if (previousValue != null && [
656
+ EnumToken.ChildCombinatorTokenType,
657
+ EnumToken.DescendantCombinatorTokenType,
658
+ EnumToken.NextSiblingCombinatorTokenType,
659
+ EnumToken.SubsequentSiblingCombinatorTokenType,
660
+ EnumToken.ColumnCombinatorTokenType,
661
+ EnumToken.NameSpaceAttributeTokenType,
662
+ EnumToken.CommaTokenType
663
+ ].includes(previousValue.typ)) {
664
+ continue;
665
+ }
666
+ // @ts-ignore
667
+ value.typ = EnumToken.DescendantCombinatorTokenType;
668
+ }
669
+ else if (value.typ == EnumToken.LiteralTokenType) {
670
+ if (value.val.charAt(0) == '&') {
671
+ // @ts-ignore
672
+ value.typ = EnumToken.NestingSelectorTokenType;
673
+ // @ts-ignore
674
+ delete value.val;
675
+ }
676
+ else if (value.val.charAt(0) == '.') {
677
+ if (!isIdent(value.val.slice(1))) {
678
+ // @ts-ignore
679
+ value.typ = EnumToken.InvalidClassSelectorTokenType;
680
+ }
681
+ else {
682
+ // @ts-ignore
683
+ value.typ = EnumToken.ClassSelectorTokenType;
684
+ }
685
+ }
686
+ // @ts-ignore
687
+ if (value.typ == EnumToken.DelimTokenType) {
688
+ // @ts-ignore
689
+ value.typ = EnumToken.NextSiblingCombinatorTokenType;
690
+ }
691
+ else if (['*', '>', '+', '~'].includes(value.val)) {
692
+ switch (value.val) {
693
+ case '*':
694
+ // @ts-ignore
695
+ value.typ = EnumToken.UniversalSelectorTokenType;
696
+ break;
697
+ case '>':
698
+ // @ts-ignore
699
+ value.typ = EnumToken.ChildCombinatorTokenType;
700
+ break;
701
+ case '+':
702
+ // @ts-ignore
703
+ value.typ = EnumToken.NextSiblingCombinatorTokenType;
704
+ break;
705
+ case '~':
706
+ // @ts-ignore
707
+ value.typ = EnumToken.SubsequentSiblingCombinatorTokenType;
708
+ break;
709
+ }
710
+ // @ts-ignore
711
+ // @ts-ignore
712
+ delete value.val;
713
+ }
714
+ }
715
+ else if (value.typ == EnumToken.ColorTokenType) {
716
+ if (value.kin == 'lit' || value.kin == 'hex' || value.kin == 'sys' || value.kin == 'dpsys') {
717
+ if (value.kin == 'hex') {
718
+ if (!isIdent(value.val.slice(1))) {
719
+ continue;
720
+ }
721
+ // @ts-ignore
722
+ value.typ = EnumToken.HashTokenType;
723
+ }
724
+ else {
725
+ // @ts-ignore
726
+ value.typ = EnumToken.IdenTokenType;
727
+ }
728
+ // @ts-ignore
729
+ delete value.kin;
730
+ }
731
+ }
732
+ }
733
+ }
734
+ let i = 0;
735
+ const combinators = [
736
+ EnumToken.ChildCombinatorTokenType,
737
+ EnumToken.NextSiblingCombinatorTokenType,
738
+ EnumToken.SubsequentSiblingCombinatorTokenType
739
+ ];
740
+ for (; i < tokens.length; i++) {
741
+ if (combinators.includes(tokens[i].typ)) {
742
+ if (i + 1 < tokens.length && [EnumToken.WhitespaceTokenType, EnumToken.DescendantCombinatorTokenType].includes(tokens[i + 1].typ)) {
743
+ tokens.splice(i + 1, 1);
744
+ }
745
+ if (i > 0 && [EnumToken.WhitespaceTokenType, EnumToken.DescendantCombinatorTokenType].includes(tokens[i - 1].typ)) {
746
+ tokens.splice(i - 1, 1);
747
+ i--;
748
+ continue;
749
+ }
750
+ }
751
+ if (tokens[i].typ == EnumToken.WhitespaceTokenType) {
752
+ tokens[i].typ = EnumToken.DescendantCombinatorTokenType;
753
+ }
754
+ }
755
+ return tokens;
756
+ }
532
757
  function parseString(src, options = { location: false }) {
533
758
  return parseTokens([...tokenize(src)].map(t => {
534
759
  const token = getTokenType(t.token, t.hint);
@@ -573,7 +798,7 @@ function getTokenType(val, hint) {
573
798
  return { typ: EnumToken.StartParensTokenType };
574
799
  }
575
800
  if (val == '=') {
576
- return { typ: EnumToken.DelimTokenType, val };
801
+ return { typ: EnumToken.DelimTokenType };
577
802
  }
578
803
  if (val == ';') {
579
804
  return { typ: EnumToken.SemiColonTokenType };
@@ -731,7 +956,7 @@ function parseTokens(tokens, options = {}) {
731
956
  const typ = tokens[i + 1]?.typ;
732
957
  if (typ != null) {
733
958
  if (typ == EnumToken.FunctionTokenType) {
734
- tokens[i + 1].val = ':' + tokens[i + 1].val;
959
+ tokens[i + 1].val = ':' + (tokens[i + 1].val in webkitPseudoAliasMap ? webkitPseudoAliasMap[tokens[i + 1].val] : tokens[i + 1].val);
735
960
  tokens[i + 1].typ = EnumToken.PseudoClassFuncTokenType;
736
961
  }
737
962
  else if (typ == EnumToken.IdenTokenType) {
@@ -762,7 +987,10 @@ function parseTokens(tokens, options = {}) {
762
987
  break;
763
988
  }
764
989
  }
765
- Object.assign(t, { typ: EnumToken.AttrTokenType, chi: tokens.splice(i + 1, k - i) });
990
+ Object.assign(t, {
991
+ typ: inAttr == 0 ? EnumToken.AttrTokenType : EnumToken.InvalidAttrTokenType,
992
+ chi: tokens.splice(i + 1, k - i)
993
+ });
766
994
  // @ts-ignore
767
995
  if (t.chi.at(-1).typ == EnumToken.AttrEndTokenType) {
768
996
  // @ts-ignore
@@ -1033,4 +1261,4 @@ function parseTokens(tokens, options = {}) {
1033
1261
  return tokens;
1034
1262
  }
1035
1263
 
1036
- export { doParse, parseString, parseTokens, urlTokenMatcher };
1264
+ export { doParse, parseSelector, parseString, parseTokens, urlTokenMatcher };
@@ -1,7 +1,8 @@
1
- import { isWhiteSpace, isNewLine, isDigit, isNonPrintable } from './utils/syntax.js';
2
1
  import { EnumToken } from '../ast/types.js';
3
2
  import '../ast/minify.js';
4
3
  import './parse.js';
4
+ import { isWhiteSpace, isNewLine, isDigit, isNonPrintable } from '../syntax/syntax.js';
5
+ import './utils/config.js';
5
6
  import '../renderer/color/utils/constants.js';
6
7
  import '../renderer/sourcemap/lib/encode.js';
7
8
 
@@ -55,7 +56,7 @@ function* consumeString(quoteStr, buffer, parseInfo) {
55
56
  continue;
56
57
  }
57
58
  if (escapeSequence.trimEnd().length > 0) {
58
- const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
59
+ const codepoint = parseInt(escapeSequence, 16);
59
60
  if (codepoint == 0 ||
60
61
  // leading surrogate
61
62
  (0xD800 <= codepoint && codepoint <= 0xDBFF) ||
@@ -186,6 +187,13 @@ function* tokenize(stream) {
186
187
  buffer = '';
187
188
  }
188
189
  break;
190
+ case '&':
191
+ if (buffer.length > 0) {
192
+ yield pushToken(buffer, parseInfo);
193
+ buffer = '';
194
+ }
195
+ yield pushToken(value, parseInfo);
196
+ break;
189
197
  case '<':
190
198
  if (buffer.length > 0) {
191
199
  yield pushToken(buffer, parseInfo);
@@ -235,9 +243,22 @@ function* tokenize(stream) {
235
243
  case '~':
236
244
  case '|':
237
245
  case '$':
238
- if (value == '|' && peek(parseInfo) == '|') {
239
- next(parseInfo);
240
- yield pushToken('', parseInfo, EnumToken.ColumnCombinatorTokenType);
246
+ if (buffer.length > 0) {
247
+ yield pushToken(buffer, parseInfo);
248
+ buffer = '';
249
+ }
250
+ if (value == '|') {
251
+ if (peek(parseInfo) == '|') {
252
+ next(parseInfo);
253
+ yield pushToken('', parseInfo, EnumToken.ColumnCombinatorTokenType);
254
+ }
255
+ else if (peek(parseInfo) == '=') {
256
+ buffer += next(parseInfo);
257
+ yield pushToken(buffer, parseInfo);
258
+ }
259
+ else {
260
+ yield pushToken('|', parseInfo);
261
+ }
241
262
  buffer = '';
242
263
  break;
243
264
  }
@@ -1,5 +1,6 @@
1
1
  import config from '../../../config.json.js';
2
2
 
3
+ Object.freeze(config);
3
4
  const getConfig = () => config;
4
5
 
5
6
  export { getConfig };
@@ -2,7 +2,8 @@ import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
3
  import { walkValues } from '../../ast/walk.js';
4
4
  import '../parse.js';
5
- import { isWhiteSpace } from './syntax.js';
5
+ import { isWhiteSpace } from '../../syntax/syntax.js';
6
+ import './config.js';
6
7
  import '../../renderer/color/utils/constants.js';
7
8
  import '../../renderer/sourcemap/lib/encode.js';
8
9
 
@@ -2,6 +2,7 @@ import { colorsFunc } from '../../renderer/render.js';
2
2
  import { EnumToken } from '../../ast/types.js';
3
3
  import '../../ast/minify.js';
4
4
  import '../parse.js';
5
+ import './config.js';
5
6
  import { COLORS_NAMES } from '../../renderer/color/utils/constants.js';
6
7
 
7
8
  // https://www.w3.org/TR/CSS21/syndata.html#syntax
@@ -3,6 +3,7 @@ import '../../ast/minify.js';
3
3
  import '../parse.js';
4
4
  import '../../renderer/color/utils/constants.js';
5
5
  import '../../renderer/sourcemap/lib/encode.js';
6
+ import './config.js';
6
7
 
7
8
  // https://www.w3.org/TR/css-values-4/#math-function
8
9
  const funcList = ['clamp', 'calc'];
@@ -6,6 +6,7 @@ import '../../ast/minify.js';
6
6
  import '../../parser/parse.js';
7
7
  import { srgb2xyz } from './xyz.js';
8
8
  import '../sourcemap/lib/encode.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function a98rgb2srgbvalues(r, g, b, a = null) {
11
12
  // @ts-ignore
@@ -18,6 +18,7 @@ import { xyzd502srgb, srgb2xyz } from './xyz.js';
18
18
  import { p32srgbvalues, srgb2p3values } from './p3.js';
19
19
  import { XYZ_D65_to_D50 } from './xyzd50.js';
20
20
  import '../sourcemap/lib/encode.js';
21
+ import '../../parser/utils/config.js';
21
22
 
22
23
  function convert(token, to) {
23
24
  if (token.kin == to) {
@@ -1,7 +1,8 @@
1
- import '../../parser/parse.js';
2
- import { isRectangularOrthogonalColorspace, isPolarColorspace } from '../../parser/utils/syntax.js';
3
1
  import { EnumToken } from '../../ast/types.js';
4
2
  import '../../ast/minify.js';
3
+ import '../../parser/parse.js';
4
+ import { isRectangularOrthogonalColorspace, isPolarColorspace } from '../../syntax/syntax.js';
5
+ import '../../parser/utils/config.js';
5
6
  import { getNumber } from './color.js';
6
7
  import { srgb2rgb } from './rgb.js';
7
8
  import './utils/constants.js';
@@ -6,6 +6,7 @@ import { hsl2rgb, hwb2rgb, cmyk2rgb, oklab2rgb, oklch2rgb, lab2rgb, lch2rgb } fr
6
6
  import { NAMES_COLORS } from './utils/constants.js';
7
7
  import { getComponents } from './utils/components.js';
8
8
  import '../sourcemap/lib/encode.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function toHexString(acc, value) {
11
12
  return acc + value.toString(16).padStart(2, '0');
@@ -8,6 +8,7 @@ import '../../ast/minify.js';
8
8
  import '../../parser/parse.js';
9
9
  import { hslvalues } from './srgb.js';
10
10
  import '../sourcemap/lib/encode.js';
11
+ import '../../parser/utils/config.js';
11
12
 
12
13
  function hex2hsl(token) {
13
14
  // @ts-ignore
@@ -7,6 +7,7 @@ import '../../ast/minify.js';
7
7
  import '../../parser/parse.js';
8
8
  import { lab2srgb, lch2srgb, oklab2srgb, oklch2srgb } from './srgb.js';
9
9
  import '../sourcemap/lib/encode.js';
10
+ import '../../parser/utils/config.js';
10
11
 
11
12
  function rgb2hwb(token) {
12
13
  // @ts-ignore
@@ -9,6 +9,7 @@ import { EnumToken } from '../../ast/types.js';
9
9
  import '../../ast/minify.js';
10
10
  import '../../parser/parse.js';
11
11
  import '../sourcemap/lib/encode.js';
12
+ import '../../parser/utils/config.js';
12
13
 
13
14
  // L: 0% = 0.0, 100% = 100.0
14
15
  // for a and b: -100% = -125, 100% = 125
@@ -6,6 +6,7 @@ import '../../ast/minify.js';
6
6
  import '../../parser/parse.js';
7
7
  import { srgb2lab, xyz2lab, hex2lab, rgb2lab, hsl2lab, hwb2lab, getLABComponents, oklab2lab, oklch2lab } from './lab.js';
8
8
  import '../sourcemap/lib/encode.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function hex2lch(token) {
11
12
  // @ts-ignore
@@ -9,6 +9,7 @@ import '../../parser/parse.js';
9
9
  import { lch2labvalues } from './lab.js';
10
10
  import { getOKLCHComponents } from './oklch.js';
11
11
  import '../sourcemap/lib/encode.js';
12
+ import '../../parser/utils/config.js';
12
13
 
13
14
  function hex2oklab(token) {
14
15
  // @ts-ignore
@@ -7,6 +7,7 @@ import '../../parser/parse.js';
7
7
  import { lab2lchvalues } from './lch.js';
8
8
  import { srgb2oklab, hex2oklab, rgb2oklab, hsl2oklab, hwb2oklab, lab2oklab, lch2oklab, getOKLABComponents } from './oklab.js';
9
9
  import '../sourcemap/lib/encode.js';
10
+ import '../../parser/utils/config.js';
10
11
 
11
12
  function hex2oklch(token) {
12
13
  // @ts-ignore
@@ -6,6 +6,7 @@ import '../../ast/minify.js';
6
6
  import '../../parser/parse.js';
7
7
  import { srgb2xyz } from './xyz.js';
8
8
  import '../sourcemap/lib/encode.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function p32srgbvalues(r, g, b, alpha) {
11
12
  // @ts-ignore
@@ -6,6 +6,7 @@ import '../../ast/minify.js';
6
6
  import '../../parser/parse.js';
7
7
  import { srgb2xyz } from './xyz.js';
8
8
  import '../sourcemap/lib/encode.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function rec20202srgb(r, g, b, a) {
11
12
  // @ts-ignore
@@ -6,6 +6,7 @@ import '../../parser/parse.js';
6
6
  import { reduceNumber } from '../render.js';
7
7
  import { colorRange } from './utils/constants.js';
8
8
  import { evaluate } from '../../ast/math/expression.js';
9
+ import '../../parser/utils/config.js';
9
10
 
10
11
  function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
11
12
  let r;