@tbela99/css-parser 0.0.1-alpha3 → 0.0.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.
@@ -55,7 +55,7 @@
55
55
  // -
56
56
  if (codepoint == 0x2d) {
57
57
  const nextCodepoint = name.charCodeAt(1);
58
- if (nextCodepoint == null) {
58
+ if (Number.isNaN(nextCodepoint)) {
59
59
  return false;
60
60
  }
61
61
  // -
@@ -104,6 +104,9 @@
104
104
  let codepoint = name.charCodeAt(0);
105
105
  let i = 0;
106
106
  const j = name.length;
107
+ if (j == 1 && !isDigit(codepoint)) {
108
+ return false;
109
+ }
107
110
  // '+' '-'
108
111
  if ([0x2b, 0x2d].includes(codepoint)) {
109
112
  i++;
@@ -247,7 +250,9 @@
247
250
  return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
248
251
  }
249
252
  function isWhiteSpace(codepoint) {
250
- return codepoint == 0x9 || codepoint == 0x20 || isNewLine(codepoint);
253
+ return codepoint == 0x9 || codepoint == 0x20 ||
254
+ // isNewLine
255
+ codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
251
256
  }
252
257
 
253
258
  var properties = {
@@ -1470,18 +1475,21 @@
1470
1475
  return acc;
1471
1476
  }
1472
1477
  }
1473
- if (options.compress && curr.typ == 'Whitespace') {
1474
- if (original[index + 1]?.typ == 'Start-parens' ||
1475
- (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
1476
- original[index - 1].typ == 'End-parens' ||
1477
- original[index - 1].typ == 'UrlFunc' ||
1478
- original[index - 1].typ == 'Func' ||
1479
- (original[index - 1].typ == 'Color' &&
1480
- original[index - 1].kin != 'hex' &&
1481
- original[index - 1].kin != 'lit')))) {
1482
- return acc;
1483
- }
1484
- }
1478
+ // if (options.compress && curr.typ == 'Whitespace') {
1479
+ //
1480
+ // if (original[index + 1]?.typ == 'Start-parens' ||
1481
+ // (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
1482
+ // original[index - 1].typ == 'End-parens' ||
1483
+ // original[index - 1].typ == 'UrlFunc' ||
1484
+ // original[index - 1].typ == 'Func' ||
1485
+ // (
1486
+ // original[index - 1].typ == 'Color' &&
1487
+ // (<ColorToken>original[index - 1]).kin != 'hex' &&
1488
+ // (<ColorToken>original[index - 1]).kin != 'lit')))) {
1489
+ //
1490
+ // return acc;
1491
+ // }
1492
+ // }
1485
1493
  return acc + renderToken(curr, options);
1486
1494
  }
1487
1495
  return { code: doRender(data, options, reducer) };
@@ -1589,11 +1597,15 @@
1589
1597
  if (token.kin == 'hex' || token.kin == 'lit') {
1590
1598
  return token.val;
1591
1599
  }
1600
+ case 'Start-parens':
1601
+ if (!('chi' in token)) {
1602
+ return '(';
1603
+ }
1592
1604
  case 'Func':
1593
1605
  case 'UrlFunc':
1594
1606
  case 'Pseudo-class-func':
1595
1607
  // @ts-ignore
1596
- return (options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) : token.val) + '(' + token.chi.reduce((acc, curr) => {
1608
+ return ( /* options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
1597
1609
  if (options.removeComments && curr.typ == 'Comment') {
1598
1610
  if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1599
1611
  return acc;
@@ -1609,8 +1621,6 @@
1609
1621
  return '<';
1610
1622
  case 'Gt':
1611
1623
  return '>';
1612
- case 'Start-parens':
1613
- return '(';
1614
1624
  case 'End-parens':
1615
1625
  return ')';
1616
1626
  case 'Attr-start':
@@ -1686,7 +1696,7 @@
1686
1696
  case 'String':
1687
1697
  case 'Iden':
1688
1698
  case 'Delim':
1689
- return options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : token.val;
1699
+ return /* options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
1690
1700
  }
1691
1701
  throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
1692
1702
  }
@@ -2272,6 +2282,125 @@
2272
2282
  continue;
2273
2283
  }
2274
2284
  // @ts-ignore
2285
+ if (node.typ == 'Rule') {
2286
+ reduceRuleSelector(node);
2287
+ // @ts-ignore
2288
+ if (options.nestingRules && node.raw != null && previous?.raw != null && node.raw.length == 1 && previous.raw.length == 1) {
2289
+ const match = [];
2290
+ // @ts-ignore
2291
+ while (node.raw[0].length > 0 && previous.raw[0].length > 0) {
2292
+ // @ts-ignore
2293
+ if (node.raw[0][0] != previous.raw[0][0]) {
2294
+ break;
2295
+ }
2296
+ // @ts-ignore
2297
+ match.push(node.raw[0].shift());
2298
+ // @ts-ignore
2299
+ previous.raw[0].shift();
2300
+ }
2301
+ if (match.length > 0) {
2302
+ // @ts-ignore
2303
+ const wrapper = { ...previous, chi: [] };
2304
+ // @ts-ignore
2305
+ if (previous.raw[0].length == 0) {
2306
+ // @ts-ignore
2307
+ wrapper.chi.push(...previous.chi);
2308
+ }
2309
+ else {
2310
+ // @ts-ignore
2311
+ previous.sel = previous.raw.reduce((acc, curr) => {
2312
+ acc.push(curr.join(''));
2313
+ return acc;
2314
+ }, []).join(',');
2315
+ // @ts-ignore
2316
+ wrapper.chi.push(previous);
2317
+ }
2318
+ // @ts-ignore
2319
+ if (node.raw[0].length == 0) {
2320
+ // @ts-ignore
2321
+ if (previous.raw.length == 0) {
2322
+ // @ts-ignore
2323
+ wrapper.chi.push(...node.chi);
2324
+ }
2325
+ else {
2326
+ if (hasOnlyDeclarations(wrapper)) {
2327
+ wrapper.chi.push(...node.chi);
2328
+ }
2329
+ else {
2330
+ // @ts-ignore
2331
+ node.raw[0].push('&');
2332
+ // @ts-ignore
2333
+ node.sel = node.raw.reduce((acc, curr) => {
2334
+ acc.push(curr.join(''));
2335
+ return acc;
2336
+ }, []).join(',');
2337
+ // @ts-ignore
2338
+ wrapper.chi.push(node);
2339
+ }
2340
+ }
2341
+ }
2342
+ else {
2343
+ // @ts-ignore
2344
+ node.sel = node.raw.reduce((acc, curr) => {
2345
+ acc.push(curr.join(''));
2346
+ return acc;
2347
+ }, []).join(',');
2348
+ // @ts-ignore
2349
+ wrapper.chi.push(node);
2350
+ }
2351
+ Object.defineProperty(wrapper, 'raw', { enumerable: false, writable: true, value: [match] });
2352
+ // @ts-ignore
2353
+ ast.chi.splice(i, 1, wrapper);
2354
+ // @ts-ignore
2355
+ ast.chi.splice(nodeIndex, 1);
2356
+ // @ts-ignore
2357
+ while (i < ast.chi.length) {
2358
+ // @ts-ignore
2359
+ const nextNode = ast.chi[i];
2360
+ // @ts-ignore
2361
+ if (nextNode.typ != 'Rule' || nextNode.raw == null) {
2362
+ break;
2363
+ }
2364
+ reduceRuleSelector(nextNode);
2365
+ // @ts-ignore
2366
+ if (nextNode.raw.length != 1 || !eq(wrapper.raw[0], nextNode.raw[0].slice(0, wrapper.raw[0].length))) {
2367
+ break;
2368
+ }
2369
+ // @ts-ignore
2370
+ nextNode.raw[0].splice(0, wrapper.raw[0].length);
2371
+ // @ts-ignore
2372
+ if (nextNode.raw[0].length == 0 ||
2373
+ // @ts-ignore
2374
+ (nextNode.raw.length == 1 && nextNode.raw[0] == '&')) {
2375
+ if (hasOnlyDeclarations(wrapper)) {
2376
+ wrapper.chi.push(...nextNode.chi);
2377
+ // @ts-ignore
2378
+ ast.chi.splice(i, 1);
2379
+ continue;
2380
+ }
2381
+ else {
2382
+ // @ts-ignore
2383
+ nextNode.raw[0].push('&');
2384
+ }
2385
+ }
2386
+ // @ts-ignore
2387
+ nextNode.sel = nextNode.raw.reduce((acc, curr) => {
2388
+ acc.push(curr.join(''));
2389
+ return acc;
2390
+ }, []).join(',');
2391
+ wrapper.chi.push(nextNode);
2392
+ // @ts-ignore
2393
+ ast.chi.splice(i, 1);
2394
+ }
2395
+ deduplicateRule(wrapper);
2396
+ nodeIndex = --i;
2397
+ // @ts-ignore
2398
+ previous = ast.chi[i];
2399
+ continue;
2400
+ }
2401
+ }
2402
+ }
2403
+ // @ts-ignore
2275
2404
  if (previous != null && 'chi' in previous && ('chi' in node)) {
2276
2405
  // @ts-ignore
2277
2406
  if (previous.typ == node.typ) {
@@ -2291,7 +2420,7 @@
2291
2420
  // @ts-ignore
2292
2421
  if ((node.typ == 'Rule' && node.sel == previous.sel) ||
2293
2422
  // @ts-ignore
2294
- (node.typ == 'AtRule') && node.val == previous.val) {
2423
+ (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
2295
2424
  // @ts-ignore
2296
2425
  node.chi.unshift(...previous.chi);
2297
2426
  // @ts-ignore
@@ -2313,19 +2442,26 @@
2313
2442
  if (intersect != null) {
2314
2443
  if (intersect.node1.chi.length == 0) {
2315
2444
  // @ts-ignore
2316
- ast.chi.splice(i, 1);
2445
+ ast.chi.splice(i--, 1);
2446
+ // @ts-ignore
2447
+ node = ast.chi[i];
2317
2448
  }
2318
2449
  else {
2319
2450
  // @ts-ignore
2320
2451
  ast.chi.splice(i, 1, intersect.node1);
2452
+ node = intersect.node1;
2321
2453
  }
2322
2454
  if (intersect.node2.chi.length == 0) {
2323
2455
  // @ts-ignore
2324
2456
  ast.chi.splice(nodeIndex, 1, intersect.result);
2457
+ previous = intersect.result;
2325
2458
  }
2326
2459
  else {
2327
2460
  // @ts-ignore
2328
2461
  ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
2462
+ previous = intersect.result;
2463
+ // @ts-ignore
2464
+ i = nodeIndex;
2329
2465
  }
2330
2466
  }
2331
2467
  }
@@ -2352,12 +2488,24 @@
2352
2488
  deduplicateRule(node);
2353
2489
  }
2354
2490
  else {
2355
- deduplicate(node, options, recursive);
2491
+ if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
2492
+ deduplicate(node, options, recursive);
2493
+ }
2356
2494
  }
2357
2495
  }
2358
2496
  }
2359
2497
  return ast;
2360
2498
  }
2499
+ function hasOnlyDeclarations(node) {
2500
+ let k = node.chi.length;
2501
+ while (k--) {
2502
+ if (node.chi[k].typ == 'Comment') {
2503
+ continue;
2504
+ }
2505
+ return node.chi[k].typ == 'Declaration';
2506
+ }
2507
+ return true;
2508
+ }
2361
2509
  function hasDeclaration(node) {
2362
2510
  // @ts-ignore
2363
2511
  for (let i = 0; i < node.chi?.length; i++) {
@@ -2417,30 +2565,6 @@
2417
2565
  }
2418
2566
  // @ts-ignore
2419
2567
  ast.chi = children.concat(ast.chi?.slice(k));
2420
- /*
2421
- // @ts-ignore
2422
-
2423
- const properties: PropertyList = new PropertyList();
2424
-
2425
- for (; k < j; k++) {
2426
-
2427
- // @ts-ignore
2428
- if ('Comment' == ast.chi[k].typ || 'Declaration' == ast.chi[k].typ) {
2429
-
2430
- // @ts-ignore
2431
- properties.add(ast.chi[k]);
2432
- continue;
2433
- }
2434
-
2435
- break;
2436
- }
2437
-
2438
- // @ts-ignore
2439
- ast.chi = [...properties].concat(ast.chi.slice(k));
2440
- */
2441
- //
2442
- // @ts-ignore
2443
- // ast.chi.splice(0, k - 1, ...properties);
2444
2568
  return ast;
2445
2569
  }
2446
2570
  function splitRule(buffer) {
@@ -2499,7 +2623,6 @@
2499
2623
  }
2500
2624
  }
2501
2625
  i = k;
2502
- continue;
2503
2626
  }
2504
2627
  }
2505
2628
  if (str !== '') {
@@ -2507,6 +2630,35 @@
2507
2630
  }
2508
2631
  return result;
2509
2632
  }
2633
+ function reduceRuleSelector(node) {
2634
+ // @ts-ignore
2635
+ if (node.raw != null) {
2636
+ // @ts-ignore
2637
+ let optimized = reduceSelector(node.raw);
2638
+ if (optimized != null) {
2639
+ Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
2640
+ }
2641
+ if (optimized != null && optimized.match && optimized.reducible) {
2642
+ const raw = [
2643
+ [
2644
+ optimized.optimized[0], ':is('
2645
+ ].concat(optimized.selector.reduce((acc, curr) => {
2646
+ if (acc.length > 0) {
2647
+ acc.push(',');
2648
+ }
2649
+ acc.push(...curr);
2650
+ return acc;
2651
+ }, [])).concat(')')
2652
+ ];
2653
+ const sel = raw[0].join('');
2654
+ if (sel.length < node.sel.length) {
2655
+ node.sel = sel;
2656
+ // node.raw = raw;
2657
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
2658
+ }
2659
+ }
2660
+ }
2661
+ }
2510
2662
  function diff(n1, n2, options = {}) {
2511
2663
  let node1 = n1;
2512
2664
  let node2 = n2;
@@ -2523,8 +2675,28 @@
2523
2675
  // @ts-ignore
2524
2676
  return null;
2525
2677
  }
2678
+ // @ts-ignore
2679
+ const raw1 = node1.raw;
2680
+ // @ts-ignore
2681
+ const optimized1 = node1.optimized;
2682
+ // @ts-ignore
2683
+ const raw2 = node2.raw;
2684
+ // @ts-ignore
2685
+ const optimized2 = node2.optimized;
2526
2686
  node1 = { ...node1, chi: node1.chi.slice() };
2527
2687
  node2 = { ...node2, chi: node2.chi.slice() };
2688
+ if (raw1 != null) {
2689
+ Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
2690
+ }
2691
+ if (optimized1 != null) {
2692
+ Object.defineProperty(node1, 'optimized', { enumerable: false, writable: true, value: optimized1 });
2693
+ }
2694
+ if (raw2 != null) {
2695
+ Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
2696
+ }
2697
+ if (optimized2 != null) {
2698
+ Object.defineProperty(node2, 'optimized', { enumerable: false, writable: true, value: optimized2 });
2699
+ }
2528
2700
  const intersect = [];
2529
2701
  while (i--) {
2530
2702
  if (node1.chi[i].typ == 'Comment') {
@@ -2552,7 +2724,7 @@
2552
2724
  const result = (intersect.length == 0 ? null : {
2553
2725
  ...node1,
2554
2726
  // @ts-ignore
2555
- sel: [...new Set([...(n1.raw || splitRule(n1.sel)).concat(n2.raw || splitRule(n2.sel))])].join(),
2727
+ sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(),
2556
2728
  chi: intersect.reverse()
2557
2729
  });
2558
2730
  if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
@@ -2561,6 +2733,63 @@
2561
2733
  }
2562
2734
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
2563
2735
  }
2736
+ function reduceSelector(selector) {
2737
+ if (selector.length < 2) {
2738
+ return null;
2739
+ }
2740
+ const optimized = [];
2741
+ const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
2742
+ let i = 0;
2743
+ let j;
2744
+ let match;
2745
+ for (; i < k; i++) {
2746
+ const item = selector[0][i];
2747
+ match = true;
2748
+ for (j = 1; j < selector.length; j++) {
2749
+ if (item != selector[j][i]) {
2750
+ match = false;
2751
+ break;
2752
+ }
2753
+ }
2754
+ if (!match) {
2755
+ break;
2756
+ }
2757
+ optimized.push(item);
2758
+ }
2759
+ if (optimized.at(-1) == ' ') {
2760
+ optimized.pop();
2761
+ }
2762
+ let reducible = optimized.length == 1;
2763
+ if (optimized.length == 0) {
2764
+ return { match: false, optimized, selector, reducible };
2765
+ }
2766
+ return {
2767
+ match: true,
2768
+ optimized,
2769
+ selector: selector.reduce((acc, curr) => {
2770
+ const slice = curr.slice(optimized.length);
2771
+ // @ts-ignore
2772
+ if (slice.length > 0 && slice[0] == ' ') {
2773
+ slice.shift();
2774
+ }
2775
+ if (slice.length == 0) {
2776
+ slice.push('&');
2777
+ }
2778
+ if (reducible) {
2779
+ const chr = slice[0].charAt(0);
2780
+ // @ts-ignore
2781
+ reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
2782
+ }
2783
+ acc.push(slice);
2784
+ return acc;
2785
+ }, []),
2786
+ reducible
2787
+ };
2788
+ }
2789
+ function reducer(acc, curr) {
2790
+ acc.push(curr.join(''));
2791
+ return acc;
2792
+ }
2564
2793
 
2565
2794
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
2566
2795
  const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
@@ -2570,6 +2799,7 @@
2570
2799
  src: '',
2571
2800
  sourcemap: false,
2572
2801
  compress: false,
2802
+ nestingRules: false,
2573
2803
  resolveImport: false,
2574
2804
  resolveUrls: false,
2575
2805
  removeEmpty: true,
@@ -2840,11 +3070,16 @@
2840
3070
  try {
2841
3071
  // @ts-ignore
2842
3072
  const root = await options.load(url, options.src).then((src) => {
2843
- bytesIn += src.length;
2844
- // @ts-ignore
2845
- return parse$1(src, Object.assign({}, options, { src: options.resolve(url, options.src).absolute }));
3073
+ return parse$1(src, Object.assign({}, options, {
3074
+ compress: false,
3075
+ // @ts-ignore
3076
+ src: options.resolve(url, options.src).absolute
3077
+ }));
2846
3078
  });
2847
- context.chi.push(...root.ast.chi);
3079
+ bytesIn += root.bytesIn;
3080
+ if (root.ast.chi.length > 0) {
3081
+ context.chi.push(...root.ast.chi);
3082
+ }
2848
3083
  if (root.errors.length > 0) {
2849
3084
  errors.push(...root.errors);
2850
3085
  }
@@ -2859,20 +3094,16 @@
2859
3094
  // https://www.w3.org/TR/css-nesting-1/#conditionals
2860
3095
  // allowed nesting at-rules
2861
3096
  // there must be a top level rule in the stack
3097
+ const raw = tokens.reduce((acc, curr, index, array) => {
3098
+ acc.push(renderToken(curr, { removeComments: true }));
3099
+ return acc;
3100
+ }, []);
2862
3101
  const node = {
2863
3102
  typ: 'AtRule',
2864
3103
  nam: renderToken(atRule, { removeComments: true }),
2865
- val: tokens.reduce((acc, curr, index, array) => {
2866
- if (curr.typ == 'Whitespace') {
2867
- if (array[index + 1]?.typ == 'Start-parens' ||
2868
- array[index - 1]?.typ == 'End-parens' ||
2869
- array[index - 1]?.typ == 'Func') {
2870
- return acc;
2871
- }
2872
- }
2873
- return acc + renderToken(curr, { removeComments: true });
2874
- }, '')
3104
+ val: raw.join('')
2875
3105
  };
3106
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: false, value: raw });
2876
3107
  if (delim.typ == 'Block-start') {
2877
3108
  node.chi = [];
2878
3109
  }
@@ -2897,23 +3128,28 @@
2897
3128
  return null;
2898
3129
  }
2899
3130
  }
2900
- const sel = parseTokens(tokens, { compress: options.compress }).map(curr => renderToken(curr, { compress: true }));
2901
- const raw = [...new Set(sel.reduce((acc, curr) => {
2902
- if (curr == ',') {
2903
- acc.push('');
2904
- }
2905
- else {
2906
- acc[acc.length - 1] += curr;
2907
- }
2908
- return acc;
2909
- }, ['']))];
3131
+ const uniq = new Map;
3132
+ parseTokens(tokens, { compress: options.compress }).reduce((acc, curr) => {
3133
+ let t = renderToken(curr, { compress: true });
3134
+ if (t == ',') {
3135
+ acc.push([]);
3136
+ }
3137
+ else {
3138
+ acc[acc.length - 1].push(t);
3139
+ }
3140
+ return acc;
3141
+ }, [[]]).reduce((acc, curr) => {
3142
+ acc.set(curr.join(''), curr);
3143
+ return acc;
3144
+ }, uniq);
2910
3145
  const node = {
2911
3146
  typ: 'Rule',
2912
3147
  // @ts-ignore
2913
- sel: raw.join(','),
3148
+ sel: [...uniq.keys()].join(','),
2914
3149
  chi: []
2915
3150
  };
2916
- Object.defineProperty(node, 'raw', { enumerable: false, get: () => raw });
3151
+ let raw = [...uniq.values()];
3152
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
2917
3153
  loc = {
2918
3154
  sta: position,
2919
3155
  src
@@ -2937,7 +3173,13 @@
2937
3173
  }
2938
3174
  if (tokens[i].typ == 'Colon') {
2939
3175
  name = tokens.slice(0, i);
2940
- value = parseTokens(tokens.slice(i + 1), { parseColor: true, src: options.src, resolveUrls: options.resolveUrls, resolve: options.resolve, cwd: options.cwd });
3176
+ value = parseTokens(tokens.slice(i + 1), {
3177
+ parseColor: true,
3178
+ src: options.src,
3179
+ resolveUrls: options.resolveUrls,
3180
+ resolve: options.resolve,
3181
+ cwd: options.cwd
3182
+ });
2941
3183
  }
2942
3184
  }
2943
3185
  if (name == null) {
@@ -2956,11 +3198,6 @@
2956
3198
  }
2957
3199
  }
2958
3200
  }
2959
- // if (name.length == 0) {
2960
- //
2961
- // errors.push({action: 'drop', message: 'invalid declaration', location: {src, ...position}});
2962
- // return null;
2963
- // }
2964
3201
  if (value == null) {
2965
3202
  errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
2966
3203
  return null;
@@ -2983,16 +3220,6 @@
2983
3220
  errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
2984
3221
  return null;
2985
3222
  }
2986
- // // location not needed for declaration
2987
- // loc = <Location>{
2988
- // sta: position,
2989
- // src
2990
- // };
2991
- //
2992
- // if (options.sourcemap) {
2993
- //
2994
- // node.loc = loc
2995
- // }
2996
3223
  // @ts-ignore
2997
3224
  context.chi.push(node);
2998
3225
  return null;
@@ -3217,11 +3444,6 @@
3217
3444
  }
3218
3445
  }
3219
3446
  }
3220
- // else {
3221
- //
3222
- // pushToken(getType(buffer));
3223
- // buffer = '';
3224
- // }
3225
3447
  break;
3226
3448
  case '<':
3227
3449
  if (buffer.length > 0) {
@@ -3299,6 +3521,10 @@
3299
3521
  if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
3300
3522
  tokens.pop();
3301
3523
  }
3524
+ if (buffer !== '') {
3525
+ pushToken(getType(buffer));
3526
+ buffer = '';
3527
+ }
3302
3528
  pushToken({ typ: 'Gt' });
3303
3529
  consumeWhiteSpace();
3304
3530
  break;
@@ -3313,10 +3539,6 @@
3313
3539
  buffer += value + next();
3314
3540
  break;
3315
3541
  }
3316
- // if (value == ',' && tokens[tokens.length - 1]?.typ == 'Whitespace') {
3317
- //
3318
- // tokens.pop();
3319
- // }
3320
3542
  pushToken(getType(value));
3321
3543
  buffer = '';
3322
3544
  while (isWhiteSpace(peek().charCodeAt(0))) {
@@ -3339,7 +3561,7 @@
3339
3561
  pushToken(getType(buffer));
3340
3562
  buffer = '';
3341
3563
  const token = tokens[tokens.length - 1];
3342
- if (token.typ == 'UrlFunc' /* && token.chi == 'url' */) {
3564
+ if (token.typ == 'UrlFunc') {
3343
3565
  // consume either string or url token
3344
3566
  let whitespace = '';
3345
3567
  value = peek();
@@ -3456,15 +3678,6 @@
3456
3678
  if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
3457
3679
  context.chi.pop();
3458
3680
  }
3459
- else if (previousNode != null && previousNode != ast && options.compress) {
3460
- // @ts-ignore
3461
- if (hasDeclaration(previousNode)) {
3462
- deduplicateRule(previousNode);
3463
- }
3464
- else {
3465
- deduplicate(previousNode, options);
3466
- }
3467
- }
3468
3681
  tokens.length = 0;
3469
3682
  map.clear();
3470
3683
  buffer = '';
@@ -3499,17 +3712,8 @@
3499
3712
  await parseNode(tokens);
3500
3713
  }
3501
3714
  if (options.compress) {
3502
- while (stack.length > 0) {
3503
- const node = stack.pop();
3504
- if (hasDeclaration(node)) {
3505
- deduplicateRule(node, options);
3506
- }
3507
- else {
3508
- deduplicate(node, options);
3509
- }
3510
- }
3511
3715
  if (ast.chi.length > 0) {
3512
- deduplicate(ast, options);
3716
+ deduplicate(ast, options, true);
3513
3717
  }
3514
3718
  }
3515
3719
  return { ast, errors, bytesIn };
@@ -3519,8 +3723,10 @@
3519
3723
  const t = tokens[i];
3520
3724
  if (t.typ == 'Whitespace' && ((i == 0 ||
3521
3725
  i + 1 == tokens.length ||
3522
- ['Comma', 'Start-parens'].includes(tokens[i + 1].typ) ||
3523
- (i > 0 && funcLike.includes(tokens[i - 1].typ))))) {
3726
+ ['Comma'].includes(tokens[i + 1].typ) ||
3727
+ (i > 0 &&
3728
+ funcLike.includes(tokens[i - 1].typ) &&
3729
+ !['var', 'calc'].includes(tokens[i - 1].val))))) {
3524
3730
  tokens.splice(i--, 1);
3525
3731
  continue;
3526
3732
  }
@@ -3618,9 +3824,9 @@
3618
3824
  // @ts-ignore
3619
3825
  t.chi.pop();
3620
3826
  }
3827
+ let isColor = true;
3621
3828
  // @ts-ignore
3622
3829
  if (options.parseColor && ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'].includes(t.val)) {
3623
- let isColor = true;
3624
3830
  // @ts-ignore
3625
3831
  for (const v of t.chi) {
3626
3832
  if (v.typ == 'Func' && v.val == 'var') {
@@ -3628,37 +3834,38 @@
3628
3834
  break;
3629
3835
  }
3630
3836
  }
3631
- if (!isColor) {
3632
- continue;
3633
- }
3634
- // @ts-ignore
3635
- t.typ = 'Color';
3636
- // @ts-ignore
3637
- t.kin = t.val;
3638
- // @ts-ignore
3639
- let m = t.chi.length;
3640
- while (m-- > 0) {
3837
+ if (isColor) {
3838
+ // @ts-ignore
3839
+ t.typ = 'Color';
3641
3840
  // @ts-ignore
3642
- if (t.chi[m].typ == 'Literal') {
3841
+ t.kin = t.val;
3842
+ // @ts-ignore
3843
+ let m = t.chi.length;
3844
+ while (m-- > 0) {
3643
3845
  // @ts-ignore
3644
- if (t.chi[m + 1]?.typ == 'Whitespace') {
3846
+ if (t.chi[m].typ == 'Literal') {
3645
3847
  // @ts-ignore
3646
- t.chi.splice(m + 1, 1);
3647
- }
3648
- // @ts-ignore
3649
- if (t.chi[m - 1]?.typ == 'Whitespace') {
3848
+ if (t.chi[m + 1]?.typ == 'Whitespace') {
3849
+ // @ts-ignore
3850
+ t.chi.splice(m + 1, 1);
3851
+ }
3650
3852
  // @ts-ignore
3651
- t.chi.splice(m - 1, 1);
3652
- m--;
3853
+ if (t.chi[m - 1]?.typ == 'Whitespace') {
3854
+ // @ts-ignore
3855
+ t.chi.splice(m - 1, 1);
3856
+ m--;
3857
+ }
3653
3858
  }
3654
3859
  }
3860
+ continue;
3655
3861
  }
3656
3862
  }
3657
- else if (t.typ == 'UrlFunc') {
3863
+ if (t.typ == 'UrlFunc') {
3658
3864
  // @ts-ignore
3659
3865
  if (t.chi[0]?.typ == 'String') {
3660
3866
  // @ts-ignore
3661
3867
  const value = t.chi[0].val.slice(1, -1);
3868
+ // @ts-ignore
3662
3869
  if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
3663
3870
  // @ts-ignore
3664
3871
  t.chi[0].typ = 'Url-token';
@@ -3882,20 +4089,18 @@
3882
4089
  }
3883
4090
 
3884
4091
  function parse(iterator, opt = {}) {
3885
- Object.assign(opt, {
4092
+ return parse$1(iterator, Object.assign(opt, {
3886
4093
  load,
3887
4094
  resolve,
3888
4095
  cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
3889
- });
3890
- return parse$1(iterator, opt);
4096
+ }));
3891
4097
  }
3892
4098
  function transform(css, options = {}) {
3893
- Object.assign(options, {
4099
+ return transform$1(css, Object.assign(options, {
3894
4100
  load,
3895
4101
  resolve,
3896
4102
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
3897
- });
3898
- return transform$1(css, options);
4103
+ }));
3899
4104
  }
3900
4105
 
3901
4106
  exports.deduplicate = deduplicate;
@@ -3905,6 +4110,7 @@
3905
4110
  exports.load = load;
3906
4111
  exports.matchUrl = matchUrl;
3907
4112
  exports.parse = parse;
4113
+ exports.reduceSelector = reduceSelector;
3908
4114
  exports.render = render;
3909
4115
  exports.renderToken = renderToken;
3910
4116
  exports.resolve = resolve;