@tbela99/css-parser 0.0.1-rc5 → 0.0.1-rc6

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.
package/dist/index.d.ts CHANGED
@@ -477,9 +477,9 @@ interface BorderRadius {
477
477
  interface ErrorDescription {
478
478
 
479
479
  // drop rule or declaration | fix rule or declaration
480
- action: 'drop';
480
+ action: 'drop' | 'ignore';
481
481
  message: string;
482
- location: {
482
+ location?: {
483
483
  src: string,
484
484
  lin: number,
485
485
  col: number;
@@ -505,6 +505,7 @@ interface ParserOptions {
505
505
  interface RenderOptions {
506
506
 
507
507
  minify?: boolean;
508
+ expandNestingRules?: boolean;
508
509
  preserveLicense?: boolean;
509
510
  indent?: string;
510
511
  newLine?: string;
@@ -529,6 +530,7 @@ interface ParseResult {
529
530
 
530
531
  interface RenderResult {
531
532
  code: string ;
533
+ errors: ErrorDescription[];
532
534
  stats: {
533
535
  total: string;
534
536
  }
@@ -577,7 +579,7 @@ interface Node {
577
579
 
578
580
  interface AstComment extends Node {
579
581
 
580
- typ: 'Comment',
582
+ typ: 'Comment' | 'CDOCOMM',
581
583
  val: string;
582
584
  }
583
585
  interface AstDeclaration extends Node {
@@ -630,6 +632,34 @@ type AstNode =
630
632
  | AstRule
631
633
  | AstDeclaration;
632
634
 
635
+ declare const combinators: string[];
636
+ declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean, errors?: ErrorDescription[]): AstNode;
637
+ declare function reduceSelector(selector: string[][]): {
638
+ match: boolean;
639
+ optimized: string[];
640
+ selector: string[][];
641
+ reducible: boolean;
642
+ } | null;
643
+ declare function hasDeclaration(node: AstRule): boolean;
644
+ declare function minifyRule(ast: AstRule | AstAtRule): AstRule | AstAtRule;
645
+ declare function splitRule(buffer: string): string[][];
646
+
647
+ declare function walk(node: AstNode): Generator<{
648
+ node: AstNode;
649
+ parent?: AstRuleList;
650
+ root?: AstRuleList;
651
+ }>;
652
+ declare function walkValues(values: Token[], parent?: Token): Generator<{
653
+ value: Token;
654
+ parent: Token | null;
655
+ }>;
656
+
657
+ declare function expand(ast: AstNode): AstNode;
658
+
659
+ declare const colorsFunc: string[];
660
+ declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
661
+ declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string, errors?: ErrorDescription[]): string;
662
+
633
663
  declare const urlTokenMatcher: RegExp;
634
664
  declare function parseString(src: string, options?: {
635
665
  location: boolean;
@@ -647,6 +677,7 @@ declare function isIdentStart(codepoint: number): boolean;
647
677
  declare function isDigit(codepoint: number): boolean;
648
678
  declare function isIdentCodepoint(codepoint: number): boolean;
649
679
  declare function isIdent(name: string): boolean;
680
+ declare function isNonPrintable(codepoint: number): boolean;
650
681
  declare function isPseudo(name: string): boolean;
651
682
  declare function isHash(name: string): boolean;
652
683
  declare function isNumber(name: string): boolean;
@@ -654,7 +685,6 @@ declare function isDimension(name: string): boolean;
654
685
  declare function isPercentage(name: string): boolean;
655
686
  declare function parseDimension(name: string): DimensionToken | LengthToken | AngleToken;
656
687
  declare function isHexColor(name: string): boolean;
657
- declare function isHexDigit(name: string): boolean;
658
688
  declare function isFunction(name: string): boolean;
659
689
  declare function isAtKeyword(name: string): boolean;
660
690
  declare function isNewLine(codepoint: number): boolean;
@@ -665,27 +695,6 @@ declare const getConfig: () => PropertiesConfig;
665
695
  declare const funcList: string[];
666
696
  declare function matchType(val: Token, properties: PropertyMapType): boolean;
667
697
 
668
- declare const colorsFunc: string[];
669
- declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
670
- declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string): string;
671
-
672
- declare const combinators: string[];
673
- declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean): AstNode;
674
- declare function reduceSelector(selector: string[][]): {
675
- match: boolean;
676
- optimized: string[];
677
- selector: string[][];
678
- reducible: boolean;
679
- } | null;
680
- declare function hasDeclaration(node: AstRule): boolean;
681
- declare function minifyRule(ast: AstRule | AstAtRule): AstRule | AstAtRule;
682
-
683
- declare function walk(node: AstNode): Generator<{
684
- node: AstNode;
685
- parent?: AstRuleList;
686
- root?: AstRuleList;
687
- }>;
688
-
689
698
  declare function load(url: string, currentFile: string): Promise<string>;
690
699
 
691
700
  declare const matchUrl: RegExp;
@@ -698,4 +707,4 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
698
707
  declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
699
708
  declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
700
709
 
701
- export { colorsFunc, combinators, dirname, funcList, getConfig, hasDeclaration, isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, load, matchType, matchUrl, minify, minifyRule, parse, parseDimension, parseString, reduceSelector, render, renderToken, resolve, tokenize, transform, urlTokenMatcher, walk };
710
+ export { colorsFunc, combinators, dirname, expand, funcList, getConfig, hasDeclaration, isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, load, matchType, matchUrl, minify, minifyRule, parse, parseDimension, parseString, reduceSelector, render, renderToken, resolve, splitRule, tokenize, transform, urlTokenMatcher, walk, walkValues };
@@ -0,0 +1,159 @@
1
+ import { splitRule, combinators } from './minify.js';
2
+ import { parseString } from '../parser/parse.js';
3
+ import { renderToken } from '../renderer/render.js';
4
+ import '../renderer/utils/color.js';
5
+ import { walkValues } from './walk.js';
6
+
7
+ function expand(ast) {
8
+ //
9
+ if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
10
+ return ast;
11
+ }
12
+ if ('Rule' == ast.typ) {
13
+ return {
14
+ typ: 'StyleSheet',
15
+ chi: expandRule(ast)
16
+ };
17
+ }
18
+ if (!('chi' in ast)) {
19
+ return { ...ast };
20
+ }
21
+ const result = { ...ast, chi: [] };
22
+ // @ts-ignore
23
+ for (let i = 0; i < ast.chi.length; i++) {
24
+ // @ts-ignore
25
+ const node = ast.chi[i];
26
+ if (node.typ == 'Rule') {
27
+ // @ts-ignore
28
+ result.chi.push(...expandRule(node));
29
+ // i += expanded.length - 1;
30
+ }
31
+ else if (node.typ == 'AtRule' && 'chi' in node) {
32
+ let hasRule = false;
33
+ let j = node.chi.length;
34
+ while (j--) {
35
+ if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
36
+ hasRule = true;
37
+ break;
38
+ }
39
+ }
40
+ // @ts-ignore
41
+ result.chi.push({ ...(hasRule ? expand(node) : node) });
42
+ }
43
+ else {
44
+ // @ts-ignore
45
+ result.chi.push(node);
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ function expandRule(node) {
51
+ const ast = { ...node, chi: node.chi.slice() };
52
+ const result = [];
53
+ if (ast.typ == 'Rule') {
54
+ let i = 0;
55
+ // @ts-ignore
56
+ delete ast.raw;
57
+ // @ts-ignore
58
+ delete ast.optimized;
59
+ for (; i < ast.chi.length; i++) {
60
+ if (ast.chi[i].typ == 'Rule') {
61
+ const rule = ast.chi[i];
62
+ if (!rule.sel.includes('&')) {
63
+ const selRule = splitRule(rule.sel);
64
+ selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
65
+ rule.sel = selRule.reduce((acc, curr) => {
66
+ acc.push(curr.join(''));
67
+ return acc;
68
+ }, []).join(',');
69
+ }
70
+ else {
71
+ rule.sel = replaceCompount(rule.sel, ast.sel);
72
+ }
73
+ delete rule.raw;
74
+ delete rule.optimized;
75
+ ast.chi.splice(i--, 1);
76
+ result.push(...expandRule(rule));
77
+ }
78
+ else if (ast.chi[i].typ == 'AtRule') {
79
+ let astAtRule = ast.chi[i];
80
+ const values = [];
81
+ if (astAtRule.nam == 'scope') {
82
+ if (astAtRule.val.includes('&')) {
83
+ astAtRule.val = replaceCompount(astAtRule.val, ast.sel);
84
+ }
85
+ // @ts-ignore
86
+ astAtRule = expand(astAtRule);
87
+ }
88
+ else {
89
+ // @ts-ignore
90
+ const clone = { ...ast, chi: astAtRule.chi.slice() };
91
+ // @ts-ignore
92
+ astAtRule.chi.length = 0;
93
+ for (const r of expandRule(clone)) {
94
+ if (r.typ == 'AtRule' && 'chi' in r) {
95
+ if (astAtRule.val !== '' && r.val !== '') {
96
+ if (astAtRule.nam == 'media' && r.nam == 'media') {
97
+ r.val = astAtRule.val + ' and ' + r.val;
98
+ }
99
+ else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
100
+ r.val = astAtRule.val + '.' + r.val;
101
+ }
102
+ }
103
+ // @ts-ignore
104
+ values.push(r);
105
+ }
106
+ else if (r.typ == 'Rule') {
107
+ // @ts-ignore
108
+ astAtRule.chi.push(...expandRule(r));
109
+ }
110
+ else {
111
+ // @ts-ignore
112
+ astAtRule.chi.push(r);
113
+ }
114
+ }
115
+ }
116
+ // @ts-ignore
117
+ result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
118
+ ast.chi.splice(i--, 1);
119
+ }
120
+ }
121
+ }
122
+ // @ts-ignore
123
+ return ast.chi.length > 0 ? [ast].concat(result) : result;
124
+ }
125
+ function replaceCompount(input, replace) {
126
+ const tokens = parseString(input);
127
+ for (const t of walkValues(tokens)) {
128
+ if (t.value.typ == 'Literal') {
129
+ if (t.value.val == '&') {
130
+ t.value.val = replace;
131
+ }
132
+ else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
133
+ t.value.val = replaceCompoundLiteral(t.value.val, replace);
134
+ }
135
+ }
136
+ }
137
+ return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
138
+ }
139
+ function replaceCompoundLiteral(selector, replace) {
140
+ const tokens = [''];
141
+ let i = 0;
142
+ for (; i < selector.length; i++) {
143
+ if (selector.charAt(i) == '&') {
144
+ tokens.push('&');
145
+ tokens.push('');
146
+ }
147
+ else {
148
+ tokens[tokens.length - 1] += selector.charAt(i);
149
+ }
150
+ }
151
+ return tokens.sort((a, b) => {
152
+ if (a == '&') {
153
+ return 1;
154
+ }
155
+ return b == '&' ? -1 : 0;
156
+ }).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
157
+ }
158
+
159
+ export { expand };
@@ -1,4 +1,4 @@
1
- import { isIdentStart, isIdent, isFunction, isWhiteSpace } from '../parser/utils/syntax.js';
1
+ import { isIdentStart, isWhiteSpace, isIdent, isFunction } from '../parser/utils/syntax.js';
2
2
  import { PropertyList } from '../parser/declaration/list.js';
3
3
  import { eq } from '../parser/utils/eq.js';
4
4
  import { render } from '../renderer/render.js';
@@ -6,7 +6,8 @@ import '../renderer/utils/color.js';
6
6
 
7
7
  const combinators = ['+', '>', '~'];
8
8
  const notEndingWith = ['(', '['].concat(combinators);
9
- function minify(ast, options = {}, recursive = false) {
9
+ const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
10
+ function minify(ast, options = {}, recursive = false, errors) {
10
11
  function wrapNodes(previous, node, match, ast, i, nodeIndex) {
11
12
  // @ts-ignore
12
13
  let pSel = match.selector1.reduce(reducer, []).join(',');
@@ -15,9 +16,7 @@ function minify(ast, options = {}, recursive = false) {
15
16
  // @ts-ignore
16
17
  const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
17
18
  // @ts-ignore
18
- Object.defineProperty(wrapper, 'raw', {
19
- enumerable: false,
20
- writable: true,
19
+ Object.defineProperty(wrapper, 'raw', { ...definedPropertySettings,
21
20
  // @ts-ignore
22
21
  value: match.match.map(t => t.slice())
23
22
  });
@@ -25,7 +24,7 @@ function minify(ast, options = {}, recursive = false) {
25
24
  // @ts-ignore
26
25
  wrapper.chi.push(...previous.chi);
27
26
  // @ts-ignore
28
- if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
27
+ if ((nSel == '&' || nSel === '')) {
29
28
  // @ts-ignore
30
29
  wrapper.chi.push(...node.chi);
31
30
  }
@@ -96,10 +95,10 @@ function minify(ast, options = {}, recursive = false) {
96
95
  node1 = { ...node1, chi: node1.chi.slice() };
97
96
  node2 = { ...node2, chi: node2.chi.slice() };
98
97
  if (raw1 != null) {
99
- Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
98
+ Object.defineProperty(node1, 'raw', { ...definedPropertySettings, value: raw1 });
100
99
  }
101
100
  if (raw2 != null) {
102
- Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
101
+ Object.defineProperty(node2, 'raw', { ...definedPropertySettings, value: raw2 });
103
102
  }
104
103
  const intersect = [];
105
104
  while (i--) {
@@ -199,8 +198,7 @@ function minify(ast, options = {}, recursive = false) {
199
198
  }
200
199
  }
201
200
  if (match.length > 1) {
202
- console.error(`unsupported multilevel matching`);
203
- console.error({ match, selector1, selector2 });
201
+ errors?.push({ action: 'ignore', message: `minify: unsupported multilevel matching\n${JSON.stringify({ match, selector1, selector2 }, null, 1)}` });
204
202
  return null;
205
203
  }
206
204
  for (const part of match) {
@@ -350,7 +348,7 @@ function minify(ast, options = {}, recursive = false) {
350
348
  minifyRule(node);
351
349
  }
352
350
  else {
353
- minify(node, options, recursive);
351
+ minify(node, options, recursive, errors);
354
352
  }
355
353
  previous = node;
356
354
  nodeIndex = i;
@@ -404,7 +402,7 @@ function minify(ast, options = {}, recursive = false) {
404
402
  nodeIndex = --i;
405
403
  // @ts-ignore
406
404
  previous = ast.chi[nodeIndex];
407
- minify(wrapper, options, recursive);
405
+ minify(wrapper, options, recursive, errors);
408
406
  continue;
409
407
  }
410
408
  // @ts-ignore
@@ -417,8 +415,7 @@ function minify(ast, options = {}, recursive = false) {
417
415
  wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
418
416
  // @ts-ignore
419
417
  Object.defineProperty(wrapper, 'raw', {
420
- enumerable: false,
421
- writable: true,
418
+ ...definedPropertySettings,
422
419
  // @ts-ignore
423
420
  value: [[node.optimized.optimized[0]]]
424
421
  });
@@ -474,82 +471,97 @@ function minify(ast, options = {}, recursive = false) {
474
471
  }
475
472
  }
476
473
  // @ts-ignore
477
- if (previous != null && 'chi' in previous && ('chi' in node)) {
474
+ if (previous != null) {
478
475
  // @ts-ignore
479
- if (previous.typ == node.typ) {
480
- let shouldMerge = true;
476
+ if ('chi' in previous && ('chi' in node)) {
481
477
  // @ts-ignore
482
- let k = previous.chi.length;
483
- while (k-- > 0) {
478
+ if (previous.typ == node.typ) {
479
+ let shouldMerge = true;
484
480
  // @ts-ignore
485
- if (previous.chi[k].typ == 'Comment') {
486
- continue;
487
- }
488
- // @ts-ignore
489
- shouldMerge = previous.chi[k].typ == 'Declaration';
490
- break;
491
- }
492
- if (shouldMerge) {
493
- // @ts-ignore
494
- if ((node.typ == 'Rule' && node.sel == previous.sel) ||
481
+ let k = previous.chi.length;
482
+ while (k-- > 0) {
495
483
  // @ts-ignore
496
- (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
497
- // @ts-ignore
498
- node.chi.unshift(...previous.chi);
484
+ if (previous.chi[k].typ == 'Comment') {
485
+ continue;
486
+ }
499
487
  // @ts-ignore
500
- ast.chi.splice(nodeIndex, 1);
488
+ shouldMerge = previous.chi[k].typ == 'Declaration';
489
+ break;
490
+ }
491
+ if (shouldMerge) {
501
492
  // @ts-ignore
502
- if (hasDeclaration(node)) {
493
+ if ((node.typ == 'Rule' && node.sel == previous.sel) ||
503
494
  // @ts-ignore
504
- minifyRule(node);
505
- }
506
- else {
507
- minify(node, options, recursive);
508
- }
509
- i--;
510
- previous = node;
511
- nodeIndex = i;
512
- continue;
513
- }
514
- else if (node.typ == 'Rule' && previous?.typ == 'Rule') {
515
- const intersect = diff(previous, node, options);
516
- if (intersect != null) {
517
- if (intersect.node1.chi.length == 0) {
518
- // @ts-ignore
519
- ast.chi.splice(i--, 1);
495
+ (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
496
+ // @ts-ignore
497
+ node.chi.unshift(...previous.chi);
498
+ // @ts-ignore
499
+ ast.chi.splice(nodeIndex, 1);
500
+ // @ts-ignore
501
+ if (hasDeclaration(node)) {
520
502
  // @ts-ignore
521
- node = ast.chi[i];
503
+ minifyRule(node);
522
504
  }
523
505
  else {
524
- // @ts-ignore
525
- ast.chi.splice(i, 1, intersect.node1);
526
- node = intersect.node1;
506
+ minify(node, options, recursive, errors);
527
507
  }
528
- if (intersect.node2.chi.length == 0) {
529
- // @ts-ignore
530
- ast.chi.splice(nodeIndex, 1, intersect.result);
531
- previous = intersect.result;
532
- }
533
- else {
534
- // @ts-ignore
535
- ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
536
- previous = intersect.result;
537
- // @ts-ignore
538
- i = nodeIndex;
508
+ i--;
509
+ previous = node;
510
+ nodeIndex = i;
511
+ continue;
512
+ }
513
+ else if (node.typ == 'Rule' && previous?.typ == 'Rule') {
514
+ const intersect = diff(previous, node, options);
515
+ if (intersect != null) {
516
+ if (intersect.node1.chi.length == 0) {
517
+ // @ts-ignore
518
+ ast.chi.splice(i--, 1);
519
+ // @ts-ignore
520
+ node = ast.chi[i];
521
+ }
522
+ else {
523
+ // @ts-ignore
524
+ ast.chi.splice(i, 1, intersect.node1);
525
+ node = intersect.node1;
526
+ }
527
+ if (intersect.node2.chi.length == 0) {
528
+ // @ts-ignore
529
+ ast.chi.splice(nodeIndex, 1, intersect.result);
530
+ previous = intersect.result;
531
+ }
532
+ else {
533
+ // @ts-ignore
534
+ ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
535
+ previous = intersect.result;
536
+ // @ts-ignore
537
+ i = nodeIndex;
538
+ }
539
539
  }
540
540
  }
541
541
  }
542
542
  }
543
- }
544
- // @ts-ignore
545
- if (recursive && previous != node) {
546
543
  // @ts-ignore
547
- if (hasDeclaration(previous)) {
544
+ if (recursive && previous != node) {
548
545
  // @ts-ignore
549
- minifyRule(previous);
546
+ if (hasDeclaration(previous)) {
547
+ // @ts-ignore
548
+ minifyRule(previous);
549
+ }
550
+ else {
551
+ minify(previous, options, recursive, errors);
552
+ }
550
553
  }
551
- else {
552
- minify(previous, options, recursive);
554
+ }
555
+ else {
556
+ if ('chi' in previous) {
557
+ // @ts-ignore
558
+ if (hasDeclaration(previous)) {
559
+ // @ts-ignore
560
+ minifyRule(previous);
561
+ }
562
+ else {
563
+ minify(previous, options, recursive, errors);
564
+ }
553
565
  }
554
566
  }
555
567
  }
@@ -565,7 +577,7 @@ function minify(ast, options = {}, recursive = false) {
565
577
  else {
566
578
  // @ts-ignore
567
579
  if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
568
- minify(node, options, recursive);
580
+ minify(node, options, recursive, errors);
569
581
  }
570
582
  }
571
583
  }
@@ -651,16 +663,6 @@ function reduceSelector(selector) {
651
663
  reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
652
664
  };
653
665
  }
654
- function hasOnlyDeclarations(node) {
655
- let k = node.chi.length;
656
- while (k--) {
657
- if (node.chi[k].typ == 'Comment') {
658
- continue;
659
- }
660
- return node.chi[k].typ == 'Declaration';
661
- }
662
- return true;
663
- }
664
666
  function hasDeclaration(node) {
665
667
  // @ts-ignore
666
668
  for (let i = 0; i < node.chi?.length; i++) {
@@ -786,7 +788,7 @@ function splitRule(buffer) {
786
788
  }
787
789
  function reduceRuleSelector(node) {
788
790
  if (node.raw == null) {
789
- Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: splitRule(node.sel) });
791
+ Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
790
792
  }
791
793
  // @ts-ignore
792
794
  // if (node.raw != null) {
@@ -796,7 +798,7 @@ function reduceRuleSelector(node) {
796
798
  return acc;
797
799
  }, []));
798
800
  if (optimized != null) {
799
- Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
801
+ Object.defineProperty(node, 'optimized', { ...definedPropertySettings, value: optimized });
800
802
  }
801
803
  if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
802
804
  const raw = [
@@ -814,10 +816,10 @@ function reduceRuleSelector(node) {
814
816
  if (sel.length < node.sel.length) {
815
817
  node.sel = sel;
816
818
  // node.raw = raw;
817
- Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
819
+ Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
818
820
  }
819
821
  }
820
822
  // }
821
823
  }
822
824
 
823
- export { combinators, hasDeclaration, minify, minifyRule, reduceSelector };
825
+ export { combinators, hasDeclaration, minify, minifyRule, reduceSelector, splitRule };
@@ -10,5 +10,14 @@ function* doWalk(node, parent, root) {
10
10
  }
11
11
  }
12
12
  }
13
+ function* walkValues(values, parent) {
14
+ for (const value of values) {
15
+ // @ts-ignore
16
+ yield { value, parent };
17
+ if ('chi' in value) {
18
+ yield* walkValues(value.chi, value);
19
+ }
20
+ }
21
+ }
13
22
 
14
- export { walk };
23
+ export { walk, walkValues };
@@ -1,8 +1,8 @@
1
1
  import { PropertySet } from './set.js';
2
2
  import '../../renderer/utils/color.js';
3
- import { getConfig } from '../utils/config.js';
4
3
  import { PropertyMap } from './map.js';
5
4
  import { parseString } from '../parse.js';
5
+ import { getConfig } from '../utils/config.js';
6
6
 
7
7
  const config = getConfig();
8
8
  class PropertyList {
@@ -340,6 +340,14 @@ class PropertyMap {
340
340
  acc.push(...curr);
341
341
  return acc;
342
342
  }, []);
343
+ if (this.config.mapping != null) {
344
+ const val = values.reduce((acc, curr) => acc + renderToken(curr, { removeComments: true }), '');
345
+ if (val in this.config.mapping) {
346
+ values.length = 0;
347
+ // @ts-ignore
348
+ values.push({ typ: ['"', "'"].includes(val.charAt(0)) ? 'String' : 'Iden', val: this.config.mapping[val] });
349
+ }
350
+ }
343
351
  iterable = [{
344
352
  typ: 'Declaration',
345
353
  nam: this.config.shorthand,