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

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,35 @@ 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[], nestingContent?: boolean): 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, parent?: AstRuleList, root?: AstRuleList): 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
+ declare function replaceCompound(input: string, replace: string): string;
659
+
660
+ declare const colorsFunc: string[];
661
+ declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
662
+ declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string, errors?: ErrorDescription[]): string;
663
+
633
664
  declare const urlTokenMatcher: RegExp;
634
665
  declare function parseString(src: string, options?: {
635
666
  location: boolean;
@@ -647,6 +678,7 @@ declare function isIdentStart(codepoint: number): boolean;
647
678
  declare function isDigit(codepoint: number): boolean;
648
679
  declare function isIdentCodepoint(codepoint: number): boolean;
649
680
  declare function isIdent(name: string): boolean;
681
+ declare function isNonPrintable(codepoint: number): boolean;
650
682
  declare function isPseudo(name: string): boolean;
651
683
  declare function isHash(name: string): boolean;
652
684
  declare function isNumber(name: string): boolean;
@@ -654,7 +686,6 @@ declare function isDimension(name: string): boolean;
654
686
  declare function isPercentage(name: string): boolean;
655
687
  declare function parseDimension(name: string): DimensionToken | LengthToken | AngleToken;
656
688
  declare function isHexColor(name: string): boolean;
657
- declare function isHexDigit(name: string): boolean;
658
689
  declare function isFunction(name: string): boolean;
659
690
  declare function isAtKeyword(name: string): boolean;
660
691
  declare function isNewLine(codepoint: number): boolean;
@@ -665,27 +696,6 @@ declare const getConfig: () => PropertiesConfig;
665
696
  declare const funcList: string[];
666
697
  declare function matchType(val: Token, properties: PropertyMapType): boolean;
667
698
 
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
699
  declare function load(url: string, currentFile: string): Promise<string>;
690
700
 
691
701
  declare const matchUrl: RegExp;
@@ -698,4 +708,4 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
698
708
  declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
699
709
  declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
700
710
 
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 };
711
+ 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, replaceCompound, 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 = replaceCompound(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 = replaceCompound(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 replaceCompound(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, replaceCompound };
@@ -1,12 +1,15 @@
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
- import { render } from '../renderer/render.js';
5
- import '../renderer/utils/color.js';
4
+ import { render, renderToken } from '../renderer/render.js';
5
+ import { parseString } from '../parser/parse.js';
6
+ import { replaceCompound } from './expand.js';
7
+ import { walkValues } from './walk.js';
6
8
 
7
9
  const combinators = ['+', '>', '~'];
8
10
  const notEndingWith = ['(', '['].concat(combinators);
9
- function minify(ast, options = {}, recursive = false) {
11
+ const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
12
+ function minify(ast, options = {}, recursive = false, errors, nestingContent) {
10
13
  function wrapNodes(previous, node, match, ast, i, nodeIndex) {
11
14
  // @ts-ignore
12
15
  let pSel = match.selector1.reduce(reducer, []).join(',');
@@ -15,9 +18,7 @@ function minify(ast, options = {}, recursive = false) {
15
18
  // @ts-ignore
16
19
  const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
17
20
  // @ts-ignore
18
- Object.defineProperty(wrapper, 'raw', {
19
- enumerable: false,
20
- writable: true,
21
+ Object.defineProperty(wrapper, 'raw', { ...definedPropertySettings,
21
22
  // @ts-ignore
22
23
  value: match.match.map(t => t.slice())
23
24
  });
@@ -25,7 +26,7 @@ function minify(ast, options = {}, recursive = false) {
25
26
  // @ts-ignore
26
27
  wrapper.chi.push(...previous.chi);
27
28
  // @ts-ignore
28
- if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
29
+ if ((nSel == '&' || nSel === '')) {
29
30
  // @ts-ignore
30
31
  wrapper.chi.push(...node.chi);
31
32
  }
@@ -96,10 +97,10 @@ function minify(ast, options = {}, recursive = false) {
96
97
  node1 = { ...node1, chi: node1.chi.slice() };
97
98
  node2 = { ...node2, chi: node2.chi.slice() };
98
99
  if (raw1 != null) {
99
- Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
100
+ Object.defineProperty(node1, 'raw', { ...definedPropertySettings, value: raw1 });
100
101
  }
101
102
  if (raw2 != null) {
102
- Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
103
+ Object.defineProperty(node2, 'raw', { ...definedPropertySettings, value: raw2 });
103
104
  }
104
105
  const intersect = [];
105
106
  while (i--) {
@@ -199,8 +200,7 @@ function minify(ast, options = {}, recursive = false) {
199
200
  }
200
201
  }
201
202
  if (match.length > 1) {
202
- console.error(`unsupported multilevel matching`);
203
- console.error({ match, selector1, selector2 });
203
+ errors?.push({ action: 'ignore', message: `minify: unsupported multilevel matching\n${JSON.stringify({ match, selector1, selector2 }, null, 1)}` });
204
204
  return null;
205
205
  }
206
206
  for (const part of match) {
@@ -298,8 +298,28 @@ function minify(ast, options = {}, recursive = false) {
298
298
  selector2
299
299
  };
300
300
  }
301
+ function fixSelector(node) {
302
+ // @ts-ignore
303
+ if (node.sel.includes('&')) {
304
+ const attributes = parseString(node.sel);
305
+ for (const attr of walkValues(attributes)) {
306
+ if (attr.value.typ == 'Pseudo-class-func' && attr.value.val == ':is') {
307
+ let i = attr.value.chi.length;
308
+ while (i--) {
309
+ if (attr.value.chi[i].typ == 'Literal' && attr.value.chi[i].val == '&') {
310
+ attr.value.chi.splice(i, 1);
311
+ }
312
+ }
313
+ }
314
+ }
315
+ node.sel = attributes.reduce((acc, curr) => acc + renderToken(curr), '');
316
+ }
317
+ }
301
318
  // @ts-ignore
302
319
  if (('chi' in ast) && ast.chi?.length > 0) {
320
+ if (!nestingContent) {
321
+ nestingContent = options.nestingRules && ast.typ == 'Rule';
322
+ }
303
323
  let i = 0;
304
324
  let previous;
305
325
  let node;
@@ -314,7 +334,6 @@ function minify(ast, options = {}, recursive = false) {
314
334
  node = ast.chi[i];
315
335
  // @ts-ignore
316
336
  if (previous == node) {
317
- // console.error('idem!');
318
337
  // @ts-ignore
319
338
  ast.chi.splice(i, 1);
320
339
  i--;
@@ -330,7 +349,6 @@ function minify(ast, options = {}, recursive = false) {
330
349
  i--;
331
350
  continue;
332
351
  }
333
- // console.debug({previous, node});
334
352
  // @ts-ignore
335
353
  if (previous?.typ == 'AtRule' &&
336
354
  previous.nam == node.nam &&
@@ -350,7 +368,7 @@ function minify(ast, options = {}, recursive = false) {
350
368
  minifyRule(node);
351
369
  }
352
370
  else {
353
- minify(node, options, recursive);
371
+ minify(node, options, recursive, errors, nestingContent);
354
372
  }
355
373
  previous = node;
356
374
  nodeIndex = i;
@@ -404,7 +422,7 @@ function minify(ast, options = {}, recursive = false) {
404
422
  nodeIndex = --i;
405
423
  // @ts-ignore
406
424
  previous = ast.chi[nodeIndex];
407
- minify(wrapper, options, recursive);
425
+ minify(wrapper, options, recursive, errors, nestingContent);
408
426
  continue;
409
427
  }
410
428
  // @ts-ignore
@@ -417,8 +435,7 @@ function minify(ast, options = {}, recursive = false) {
417
435
  wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
418
436
  // @ts-ignore
419
437
  Object.defineProperty(wrapper, 'raw', {
420
- enumerable: false,
421
- writable: true,
438
+ ...definedPropertySettings,
422
439
  // @ts-ignore
423
440
  value: [[node.optimized.optimized[0]]]
424
441
  });
@@ -438,7 +455,7 @@ function minify(ast, options = {}, recursive = false) {
438
455
  let wrap = true;
439
456
  // @ts-ignore
440
457
  const selector = node.optimized.selector.reduce((acc, curr) => {
441
- if (curr[0] == '&') {
458
+ if (curr[0] == '&' && curr.length > 1) {
442
459
  if (curr[1] == ' ') {
443
460
  curr.splice(0, 2);
444
461
  }
@@ -462,7 +479,7 @@ function minify(ast, options = {}, recursive = false) {
462
479
  if (!wrap) {
463
480
  wrap = selector.some(s => s[0] != '&');
464
481
  }
465
- const rule = selector.map(s => {
482
+ let rule = selector.map(s => {
466
483
  if (s[0] == '&') {
467
484
  // @ts-ignore
468
485
  s[0] = node.optimized.optimized[0];
@@ -470,89 +487,119 @@ function minify(ast, options = {}, recursive = false) {
470
487
  return s.join('');
471
488
  }).join(',');
472
489
  // @ts-ignore
473
- node.sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
490
+ let sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
491
+ if (rule.includes('&')) {
492
+ // @ts-ignore
493
+ rule = replaceCompound(rule, node.optimized.optimized[0]);
494
+ }
495
+ if (sel.length < node.sel.length) {
496
+ node.sel = sel;
497
+ }
474
498
  }
475
499
  }
476
500
  // @ts-ignore
477
- if (previous != null && 'chi' in previous && ('chi' in node)) {
501
+ if (previous != null) {
478
502
  // @ts-ignore
479
- if (previous.typ == node.typ) {
480
- let shouldMerge = true;
503
+ if ('chi' in previous && ('chi' in node)) {
481
504
  // @ts-ignore
482
- let k = previous.chi.length;
483
- while (k-- > 0) {
505
+ if (previous.typ == node.typ) {
506
+ let shouldMerge = true;
484
507
  // @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) ||
508
+ let k = previous.chi.length;
509
+ while (k-- > 0) {
495
510
  // @ts-ignore
496
- (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
497
- // @ts-ignore
498
- node.chi.unshift(...previous.chi);
511
+ if (previous.chi[k].typ == 'Comment') {
512
+ continue;
513
+ }
499
514
  // @ts-ignore
500
- ast.chi.splice(nodeIndex, 1);
515
+ shouldMerge = previous.chi[k].typ == 'Declaration';
516
+ break;
517
+ }
518
+ if (shouldMerge) {
501
519
  // @ts-ignore
502
- if (hasDeclaration(node)) {
520
+ if ((node.typ == 'Rule' && node.sel == previous.sel) ||
503
521
  // @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);
522
+ (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
523
+ // @ts-ignore
524
+ node.chi.unshift(...previous.chi);
525
+ // @ts-ignore
526
+ ast.chi.splice(nodeIndex, 1);
527
+ // @ts-ignore
528
+ if (hasDeclaration(node)) {
520
529
  // @ts-ignore
521
- node = ast.chi[i];
530
+ minifyRule(node);
522
531
  }
523
532
  else {
524
- // @ts-ignore
525
- ast.chi.splice(i, 1, intersect.node1);
526
- node = intersect.node1;
527
- }
528
- if (intersect.node2.chi.length == 0) {
529
- // @ts-ignore
530
- ast.chi.splice(nodeIndex, 1, intersect.result);
531
- previous = intersect.result;
533
+ minify(node, options, recursive, errors, nestingContent);
532
534
  }
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;
535
+ i--;
536
+ previous = node;
537
+ nodeIndex = i;
538
+ continue;
539
+ }
540
+ else if (node.typ == 'Rule' && previous?.typ == 'Rule') {
541
+ const intersect = diff(previous, node, options);
542
+ if (intersect != null) {
543
+ if (intersect.node1.chi.length == 0) {
544
+ // @ts-ignore
545
+ ast.chi.splice(i--, 1);
546
+ // @ts-ignore
547
+ node = ast.chi[i];
548
+ }
549
+ else {
550
+ // @ts-ignore
551
+ ast.chi.splice(i, 1, intersect.node1);
552
+ node = intersect.node1;
553
+ }
554
+ if (intersect.node2.chi.length == 0) {
555
+ // @ts-ignore
556
+ ast.chi.splice(nodeIndex, 1, intersect.result);
557
+ previous = intersect.result;
558
+ }
559
+ else {
560
+ // @ts-ignore
561
+ ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
562
+ previous = intersect.result;
563
+ // @ts-ignore
564
+ i = nodeIndex;
565
+ }
539
566
  }
540
567
  }
541
568
  }
542
569
  }
543
- }
544
- // @ts-ignore
545
- if (recursive && previous != node) {
546
570
  // @ts-ignore
547
- if (hasDeclaration(previous)) {
571
+ if (recursive && previous != node) {
548
572
  // @ts-ignore
549
- minifyRule(previous);
573
+ if (hasDeclaration(previous)) {
574
+ // @ts-ignore
575
+ minifyRule(previous);
576
+ }
577
+ else {
578
+ minify(previous, options, recursive, errors, nestingContent);
579
+ }
550
580
  }
551
- else {
552
- minify(previous, options, recursive);
581
+ }
582
+ else {
583
+ if ('chi' in previous) {
584
+ // @ts-ignore
585
+ if (hasDeclaration(previous)) {
586
+ // @ts-ignore
587
+ minifyRule(previous);
588
+ }
589
+ else {
590
+ minify(previous, options, recursive, errors, nestingContent);
591
+ }
553
592
  }
554
593
  }
555
594
  }
595
+ if (!nestingContent &&
596
+ // @ts-ignore
597
+ previous != null &&
598
+ // previous.optimized != null &&
599
+ previous.typ == 'Rule' &&
600
+ previous.sel.includes('&')) {
601
+ fixSelector(previous);
602
+ }
556
603
  previous = node;
557
604
  nodeIndex = i;
558
605
  }
@@ -565,10 +612,18 @@ function minify(ast, options = {}, recursive = false) {
565
612
  else {
566
613
  // @ts-ignore
567
614
  if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
568
- minify(node, options, recursive);
615
+ minify(node, options, recursive, errors, nestingContent);
569
616
  }
570
617
  }
571
618
  }
619
+ if (!nestingContent &&
620
+ // @ts-ignore
621
+ node != null &&
622
+ // previous.optimized != null &&
623
+ node.typ == 'Rule' &&
624
+ node.sel.includes('&')) {
625
+ fixSelector(node);
626
+ }
572
627
  }
573
628
  return ast;
574
629
  }
@@ -651,16 +706,6 @@ function reduceSelector(selector) {
651
706
  reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
652
707
  };
653
708
  }
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
709
  function hasDeclaration(node) {
665
710
  // @ts-ignore
666
711
  for (let i = 0; i < node.chi?.length; i++) {
@@ -786,7 +831,7 @@ function splitRule(buffer) {
786
831
  }
787
832
  function reduceRuleSelector(node) {
788
833
  if (node.raw == null) {
789
- Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: splitRule(node.sel) });
834
+ Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
790
835
  }
791
836
  // @ts-ignore
792
837
  // if (node.raw != null) {
@@ -796,7 +841,7 @@ function reduceRuleSelector(node) {
796
841
  return acc;
797
842
  }, []));
798
843
  if (optimized != null) {
799
- Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
844
+ Object.defineProperty(node, 'optimized', { ...definedPropertySettings, value: optimized });
800
845
  }
801
846
  if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
802
847
  const raw = [
@@ -814,10 +859,9 @@ function reduceRuleSelector(node) {
814
859
  if (sel.length < node.sel.length) {
815
860
  node.sel = sel;
816
861
  // node.raw = raw;
817
- Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
862
+ Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
818
863
  }
819
864
  }
820
- // }
821
865
  }
822
866
 
823
- export { combinators, hasDeclaration, minify, minifyRule, reduceSelector };
867
+ export { combinators, hasDeclaration, minify, minifyRule, reduceSelector, splitRule };