@tbela99/css-parser 0.0.1-rc2 → 0.0.1-rc4

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.cjs CHANGED
@@ -163,37 +163,30 @@ function isNumber(name) {
163
163
  return true;
164
164
  }
165
165
  function isDimension(name) {
166
- let index = 0;
167
- while (index++ < name.length) {
168
- if (isDigit(name.charCodeAt(name.length - index))) {
169
- index--;
170
- break;
171
- }
172
- if (index == 3) {
173
- break;
166
+ let index = name.length;
167
+ while (index--) {
168
+ if (isLetter(name.charCodeAt(index))) {
169
+ continue;
174
170
  }
171
+ index++;
172
+ break;
175
173
  }
176
- if (index == 0 || index > 3) {
177
- return false;
178
- }
179
- const number = name.slice(0, -index);
180
- return number.length > 0 && isIdentStart(name.charCodeAt(name.length - index)) && isNumber(number);
174
+ const number = name.slice(0, index);
175
+ return number.length > 0 && isIdentStart(name.charCodeAt(index)) && isNumber(number);
181
176
  }
182
177
  function isPercentage(name) {
183
178
  return name.endsWith('%') && isNumber(name.slice(0, -1));
184
179
  }
185
180
  function parseDimension(name) {
186
- let index = 0;
187
- while (index++ < name.length) {
188
- if (isDigit(name.charCodeAt(name.length - index))) {
189
- index--;
190
- break;
191
- }
192
- if (index == 3) {
193
- break;
181
+ let index = name.length;
182
+ while (index--) {
183
+ if (isLetter(name.charCodeAt(index))) {
184
+ continue;
194
185
  }
186
+ index++;
187
+ break;
195
188
  }
196
- const dimension = { typ: 'Dimension', val: name.slice(0, -index), unit: name.slice(-index) };
189
+ const dimension = { typ: 'Dimension', val: name.slice(0, index), unit: name.slice(index) };
197
190
  if (isAngle(dimension)) {
198
191
  // @ts-ignore
199
192
  dimension.typ = 'Angle';
@@ -1067,6 +1060,21 @@ var config$1 = {
1067
1060
 
1068
1061
  const getConfig = () => config$1;
1069
1062
 
1063
+ const funcList = ['clamp', 'calc'];
1064
+ function matchType(val, properties) {
1065
+ if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
1066
+ (properties.types.includes(val.typ))) {
1067
+ return true;
1068
+ }
1069
+ if (val.typ == 'Number' && val.val == '0') {
1070
+ return properties.types.some(type => type == 'Length' || type == 'Angle');
1071
+ }
1072
+ if (val.typ == 'Func' && funcList.includes(val.val)) {
1073
+ return val.chi.every((t => ['Literal', 'Comma', 'Whitespace', 'Start-parens', 'End-parens'].includes(t.typ) || matchType(t, properties)));
1074
+ }
1075
+ return false;
1076
+ }
1077
+
1070
1078
  // name to color
1071
1079
  const COLORS_NAMES = Object.seal({
1072
1080
  'aliceblue': '#f0f8ff',
@@ -1487,7 +1495,7 @@ function cmyk2hex(token) {
1487
1495
  return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
1488
1496
  }
1489
1497
  function getAngle(token) {
1490
- if (token.typ == 'Dimension') {
1498
+ if (token.typ == 'Angle') {
1491
1499
  switch (token.unit) {
1492
1500
  case 'deg':
1493
1501
  // @ts-ignore
@@ -1560,6 +1568,23 @@ function hsl2rgb(h, s, l, a = null) {
1560
1568
  return values;
1561
1569
  }
1562
1570
 
1571
+ function reduceNumber(val) {
1572
+ val = (+val).toString();
1573
+ if (val === '0') {
1574
+ return '0';
1575
+ }
1576
+ const chr = val.charAt(0);
1577
+ if (chr == '-') {
1578
+ const slice = val.slice(0, 2);
1579
+ if (slice == '-0') {
1580
+ return val.length == 2 ? '0' : '-' + val.slice(2);
1581
+ }
1582
+ }
1583
+ if (chr == '0') {
1584
+ return val.slice(1);
1585
+ }
1586
+ return val;
1587
+ }
1563
1588
  function render(data, opt = {}) {
1564
1589
  const startTime = performance.now();
1565
1590
  const options = Object.assign(opt.minify ?? true ? {
@@ -1572,17 +1597,19 @@ function render(data, opt = {}) {
1572
1597
  compress: false,
1573
1598
  removeComments: false,
1574
1599
  }, { colorConvert: true, preserveLicense: false }, opt);
1575
- function reducer(acc, curr, index, original) {
1576
- if (curr.typ == 'Comment' && options.removeComments) {
1577
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1578
- return acc;
1600
+ return {
1601
+ code: doRender(data, options, function reducer(acc, curr) {
1602
+ if (curr.typ == 'Comment' && options.removeComments) {
1603
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1604
+ return acc;
1605
+ }
1606
+ return acc + curr.val;
1579
1607
  }
1580
- }
1581
- return acc + renderToken(curr, options);
1582
- }
1583
- return { code: doRender(data, options, reducer, 0), stats: {
1608
+ return acc + renderToken(curr, options, reducer);
1609
+ }, 0), stats: {
1584
1610
  total: `${(performance.now() - startTime).toFixed(2)}ms`
1585
- } };
1611
+ }
1612
+ };
1586
1613
  }
1587
1614
  // @ts-ignore
1588
1615
  function doRender(data, options, reducer, level = 0, indents = []) {
@@ -1595,8 +1622,10 @@ function doRender(data, options, reducer, level = 0, indents = []) {
1595
1622
  const indent = indents[level];
1596
1623
  const indentSub = indents[level + 1];
1597
1624
  switch (data.typ) {
1625
+ case 'Declaration':
1626
+ return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
1598
1627
  case 'Comment':
1599
- return options.removeComments ? '' : data.val;
1628
+ return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
1600
1629
  case 'StyleSheet':
1601
1630
  return data.chi.reduce((css, node) => {
1602
1631
  const str = doRender(node, options, reducer, level, indents);
@@ -1617,9 +1646,13 @@ function doRender(data, options, reducer, level = 0, indents = []) {
1617
1646
  let children = data.chi.reduce((css, node) => {
1618
1647
  let str;
1619
1648
  if (node.typ == 'Comment') {
1620
- str = options.removeComments ? '' : node.val;
1649
+ str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
1621
1650
  }
1622
1651
  else if (node.typ == 'Declaration') {
1652
+ if (node.val.length == 0) {
1653
+ console.error(`invalid declaration`, node);
1654
+ return '';
1655
+ }
1623
1656
  str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
1624
1657
  }
1625
1658
  else if (node.typ == 'AtRule' && !('chi' in node)) {
@@ -1646,7 +1679,18 @@ function doRender(data, options, reducer, level = 0, indents = []) {
1646
1679
  }
1647
1680
  return '';
1648
1681
  }
1649
- function renderToken(token, options = {}) {
1682
+ function renderToken(token, options = {}, reducer) {
1683
+ if (reducer == null) {
1684
+ reducer = function (acc, curr) {
1685
+ if (curr.typ == 'Comment' && options.removeComments) {
1686
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1687
+ return acc;
1688
+ }
1689
+ return acc + curr.val;
1690
+ }
1691
+ return acc + renderToken(curr, options, reducer);
1692
+ };
1693
+ }
1650
1694
  switch (token.typ) {
1651
1695
  case 'Color':
1652
1696
  if (options.minify || options.colorConvert) {
@@ -1697,22 +1741,19 @@ function renderToken(token, options = {}) {
1697
1741
  case 'UrlFunc':
1698
1742
  case 'Pseudo-class-func':
1699
1743
  // @ts-ignore
1700
- return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
1701
- if (options.removeComments && curr.typ == 'Comment') {
1702
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1703
- return acc;
1704
- }
1705
- }
1706
- return acc + renderToken(curr, options);
1707
- }, '') + ')';
1744
+ return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
1708
1745
  case 'Includes':
1709
1746
  return '~=';
1710
1747
  case 'Dash-match':
1711
1748
  return '|=';
1712
1749
  case 'Lt':
1713
1750
  return '<';
1751
+ case 'Lte':
1752
+ return '<=';
1714
1753
  case 'Gt':
1715
1754
  return '>';
1755
+ case 'Gte':
1756
+ return '>=';
1716
1757
  case 'End-parens':
1717
1758
  return ')';
1718
1759
  case 'Attr-start':
@@ -1730,37 +1771,73 @@ function renderToken(token, options = {}) {
1730
1771
  case 'Important':
1731
1772
  return '!important';
1732
1773
  case 'Attr':
1733
- return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options), '') + ']';
1774
+ return '[' + token.chi.reduce(reducer, '') + ']';
1734
1775
  case 'Time':
1735
- case 'Frequency':
1736
1776
  case 'Angle':
1737
1777
  case 'Length':
1738
1778
  case 'Dimension':
1739
- const val = (+token.val).toString();
1779
+ case 'Frequency':
1780
+ case 'Resolution':
1781
+ let val = reduceNumber(token.val);
1782
+ let unit = token.unit;
1783
+ if (token.typ == 'Angle') {
1784
+ const angle = getAngle(token);
1785
+ let v;
1786
+ let value = val + unit;
1787
+ for (const u of ['turn', 'deg', 'rad', 'grad']) {
1788
+ if (token.unit == u) {
1789
+ continue;
1790
+ }
1791
+ switch (u) {
1792
+ case 'turn':
1793
+ v = reduceNumber(angle);
1794
+ if (v.length + 4 < value.length) {
1795
+ val = v;
1796
+ unit = u;
1797
+ value = v + u;
1798
+ }
1799
+ break;
1800
+ case 'deg':
1801
+ v = reduceNumber(angle * 360);
1802
+ if (v.length + 3 < value.length) {
1803
+ val = v;
1804
+ unit = u;
1805
+ value = v + u;
1806
+ }
1807
+ break;
1808
+ case 'rad':
1809
+ v = reduceNumber(angle * (2 * Math.PI));
1810
+ if (v.length + 3 < value.length) {
1811
+ val = v;
1812
+ unit = u;
1813
+ value = v + u;
1814
+ }
1815
+ break;
1816
+ case 'grad':
1817
+ v = reduceNumber(angle * 400);
1818
+ if (v.length + 4 < value.length) {
1819
+ val = v;
1820
+ unit = u;
1821
+ value = v + u;
1822
+ }
1823
+ break;
1824
+ }
1825
+ }
1826
+ }
1740
1827
  if (val === '0') {
1741
- if (token.typ == 'Time') {
1828
+ if (unit == 'Time') {
1742
1829
  return '0s';
1743
1830
  }
1744
- if (token.typ == 'Frequency') {
1831
+ if (unit == 'Frequency') {
1745
1832
  return '0Hz';
1746
1833
  }
1747
1834
  // @ts-ignore
1748
- if (token.typ == 'Resolution') {
1835
+ if (unit == 'Resolution') {
1749
1836
  return '0x';
1750
1837
  }
1751
1838
  return '0';
1752
1839
  }
1753
- const chr = val.charAt(0);
1754
- if (chr == '-') {
1755
- const slice = val.slice(0, 2);
1756
- if (slice == '-0') {
1757
- return (val.length == 2 ? '0' : '-' + val.slice(2)) + token.unit;
1758
- }
1759
- }
1760
- else if (chr == '0') {
1761
- return val.slice(1) + token.unit;
1762
- }
1763
- return val + token.unit;
1840
+ return val + unit;
1764
1841
  case 'Perc':
1765
1842
  return token.val + '%';
1766
1843
  case 'Number':
@@ -1777,7 +1854,7 @@ function renderToken(token, options = {}) {
1777
1854
  }
1778
1855
  return num;
1779
1856
  case 'Comment':
1780
- if (options.removeComments) {
1857
+ if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
1781
1858
  return '';
1782
1859
  }
1783
1860
  case 'Url-token':
@@ -1998,17 +2075,6 @@ class PropertySet {
1998
2075
  }
1999
2076
  }
2000
2077
 
2001
- function matchType(val, properties) {
2002
- if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
2003
- (properties.types.includes(val.typ))) {
2004
- return true;
2005
- }
2006
- if (val.typ == 'Number' && val.val == '0') {
2007
- return properties.types.some(type => type == 'Length' || type == 'Angle');
2008
- }
2009
- return false;
2010
- }
2011
-
2012
2078
  const propertiesConfig = getConfig();
2013
2079
  class PropertyMap {
2014
2080
  config;
@@ -2023,6 +2089,9 @@ class PropertyMap {
2023
2089
  this.pattern = config.pattern.split(/\s/);
2024
2090
  }
2025
2091
  add(declaration) {
2092
+ for (const val of declaration.val) {
2093
+ Object.defineProperty(val, 'propertyName', { enumerable: false, writable: true, value: declaration.nam });
2094
+ }
2026
2095
  if (declaration.nam == this.config.shorthand) {
2027
2096
  this.declarations = new Map;
2028
2097
  this.declarations.set(declaration.nam, declaration);
@@ -2056,7 +2125,8 @@ class PropertyMap {
2056
2125
  i--;
2057
2126
  continue;
2058
2127
  }
2059
- if (matchType(acc[i], props)) {
2128
+ // @ts-ignore
2129
+ if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
2060
2130
  if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
2061
2131
  return acc;
2062
2132
  }
@@ -2190,10 +2260,12 @@ class PropertyMap {
2190
2260
  }
2191
2261
  else {
2192
2262
  let count = 0;
2263
+ let match;
2193
2264
  const separator = this.config.separator;
2194
2265
  const tokens = {};
2195
2266
  // @ts-ignore
2196
- /* const valid: string[] =*/ Object.entries(this.config.properties).reduce((acc, curr) => {
2267
+ /* const valid: string[] =*/
2268
+ Object.entries(this.config.properties).reduce((acc, curr) => {
2197
2269
  if (!this.declarations.has(curr[0])) {
2198
2270
  if (curr[1].required) {
2199
2271
  acc.push(curr[0]);
@@ -2202,33 +2274,40 @@ class PropertyMap {
2202
2274
  }
2203
2275
  let current = 0;
2204
2276
  const props = this.config.properties[curr[0]];
2205
- const declaration = this.declarations.get(curr[0]);
2206
- // @ts-ignore
2207
- for (const val of (declaration instanceof PropertySet ? [...declaration][0] : declaration).val) {
2208
- if (separator != null && separator.typ == val.typ && eq(separator, val)) {
2209
- current++;
2210
- if (tokens[curr[0]].length == current) {
2211
- tokens[curr[0]].push([]);
2277
+ const properties = this.declarations.get(curr[0]);
2278
+ for (const declaration of [(properties instanceof PropertySet ? [...properties][0] : properties)]) {
2279
+ // @ts-ignore
2280
+ for (const val of declaration.val) {
2281
+ if (separator != null && separator.typ == val.typ && eq(separator, val)) {
2282
+ current++;
2283
+ if (tokens[curr[0]].length == current) {
2284
+ tokens[curr[0]].push([]);
2285
+ }
2286
+ continue;
2212
2287
  }
2213
- continue;
2214
- }
2215
- if (val.typ == 'Whitespace' || val.typ == 'Comment') {
2216
- continue;
2217
- }
2218
- if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
2219
- continue;
2220
- }
2221
- if (matchType(val, curr[1])) {
2222
- if (!(curr[0] in tokens)) {
2223
- tokens[curr[0]] = [[]];
2288
+ if (val.typ == 'Whitespace' || val.typ == 'Comment') {
2289
+ continue;
2290
+ }
2291
+ if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
2292
+ continue;
2293
+ }
2294
+ // @ts-ignore
2295
+ match = val.typ == 'Comment' || matchType(val, curr[1]);
2296
+ if (isShorthand) {
2297
+ isShorthand = match;
2298
+ }
2299
+ // @ts-ignore
2300
+ if (('propertyName' in val && val.propertyName == property) || match) {
2301
+ if (!(curr[0] in tokens)) {
2302
+ tokens[curr[0]] = [[]];
2303
+ }
2304
+ // is default value
2305
+ tokens[curr[0]][current].push(val);
2306
+ }
2307
+ else {
2308
+ acc.push(curr[0]);
2309
+ break;
2224
2310
  }
2225
- // is default value
2226
- tokens[curr[0]][current].push(val);
2227
- // continue;
2228
- }
2229
- else {
2230
- acc.push(curr[0]);
2231
- break;
2232
2311
  }
2233
2312
  }
2234
2313
  if (count == 0) {
@@ -2237,7 +2316,12 @@ class PropertyMap {
2237
2316
  return acc;
2238
2317
  }, []);
2239
2318
  count++;
2240
- if (!Object.values(tokens).every(v => v.length == count)) {
2319
+ if (!isShorthand || Object.entries(this.config.properties).some(entry => {
2320
+ // missing required property
2321
+ return entry[1].required && !(entry[0] in tokens);
2322
+ }) ||
2323
+ // @ts-ignore
2324
+ !Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
2241
2325
  // @ts-ignore
2242
2326
  iterable = this.declarations.values();
2243
2327
  }
@@ -2790,6 +2874,17 @@ function minify(ast, options = {}, recursive = false) {
2790
2874
  continue;
2791
2875
  // }
2792
2876
  }
2877
+ // @ts-ignore
2878
+ if (hasDeclaration(node)) {
2879
+ // @ts-ignore
2880
+ minifyRule(node);
2881
+ }
2882
+ else {
2883
+ minify(node, options, recursive);
2884
+ }
2885
+ previous = node;
2886
+ nodeIndex = i;
2887
+ continue;
2793
2888
  }
2794
2889
  // @ts-ignore
2795
2890
  if (node.typ == 'Rule') {
@@ -3304,11 +3399,6 @@ function* tokenize(iterator) {
3304
3399
  }
3305
3400
  buffer += quoteStr;
3306
3401
  while (value = peek()) {
3307
- // if (ind >= iterator.length) {
3308
- //
3309
- // yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
3310
- // break;
3311
- // }
3312
3402
  if (value == '\\') {
3313
3403
  const sequence = peek(6);
3314
3404
  let escapeSequence = '';
@@ -3328,9 +3418,23 @@ function* tokenize(iterator) {
3328
3418
  }
3329
3419
  break;
3330
3420
  }
3421
+ // @ts-ignore
3422
+ if (isNewLine(codepoint)) {
3423
+ if (i == 1) {
3424
+ buffer += value + escapeSequence.slice(0, i);
3425
+ next(i + 1);
3426
+ continue;
3427
+ }
3428
+ // else {
3429
+ yield pushToken(buffer + value + escapeSequence.slice(0, i), 'Bad-string');
3430
+ buffer = '';
3431
+ // }
3432
+ next(i + 1);
3433
+ break;
3434
+ }
3331
3435
  // not hex or new line
3332
3436
  // @ts-ignore
3333
- if (i == 1 && !isNewLine(codepoint)) {
3437
+ else if (i == 1) {
3334
3438
  buffer += value + sequence[i];
3335
3439
  next(2);
3336
3440
  continue;
@@ -3350,13 +3454,6 @@ function* tokenize(iterator) {
3350
3454
  next(escapeSequence.length + 1);
3351
3455
  continue;
3352
3456
  }
3353
- // buffer += value;
3354
- // if (ind >= iterator.length) {
3355
- //
3356
- // // drop '\\' at the end
3357
- // yield pushToken(buffer);
3358
- // break;
3359
- // }
3360
3457
  buffer += next(2);
3361
3458
  continue;
3362
3459
  }
@@ -3366,20 +3463,28 @@ function* tokenize(iterator) {
3366
3463
  next();
3367
3464
  // i += value.length;
3368
3465
  buffer = '';
3369
- break;
3466
+ return;
3370
3467
  }
3371
3468
  if (isNewLine(value.charCodeAt(0))) {
3372
3469
  hasNewLine = true;
3373
3470
  }
3374
3471
  if (hasNewLine && value == ';') {
3375
- yield pushToken(buffer, 'Bad-string');
3472
+ yield pushToken(buffer + value, 'Bad-string');
3376
3473
  buffer = '';
3474
+ next();
3377
3475
  break;
3378
3476
  }
3379
3477
  buffer += value;
3380
- // i += value.length;
3381
3478
  next();
3382
3479
  }
3480
+ if (hasNewLine) {
3481
+ yield pushToken(buffer, 'Bad-string');
3482
+ }
3483
+ else {
3484
+ // EOF - 'Unclosed-string' fixed
3485
+ yield pushToken(buffer + quote, 'String');
3486
+ }
3487
+ buffer = '';
3383
3488
  }
3384
3489
  function peek(count = 1) {
3385
3490
  if (count == 1) {
@@ -3493,6 +3598,11 @@ function* tokenize(iterator) {
3493
3598
  yield pushToken(buffer);
3494
3599
  buffer = '';
3495
3600
  }
3601
+ if (peek() == '=') {
3602
+ yield pushToken('', 'Lte');
3603
+ next();
3604
+ break;
3605
+ }
3496
3606
  buffer += value;
3497
3607
  value = next();
3498
3608
  if (ind >= iterator.length) {
@@ -3561,7 +3671,13 @@ function* tokenize(iterator) {
3561
3671
  yield pushToken(buffer);
3562
3672
  buffer = '';
3563
3673
  }
3564
- yield pushToken('', 'Gt');
3674
+ if (peek() == '=') {
3675
+ yield pushToken('', 'Gte');
3676
+ next();
3677
+ }
3678
+ else {
3679
+ yield pushToken('', 'Gt');
3680
+ }
3565
3681
  consumeWhiteSpace();
3566
3682
  break;
3567
3683
  case '.':
@@ -3603,7 +3719,7 @@ function* tokenize(iterator) {
3603
3719
  break;
3604
3720
  case '(':
3605
3721
  if (buffer.length == 0) {
3606
- yield pushToken('', 'Start-parens');
3722
+ yield pushToken(value);
3607
3723
  break;
3608
3724
  }
3609
3725
  buffer += value;
@@ -3717,9 +3833,11 @@ function* tokenize(iterator) {
3717
3833
  if (buffer.length > 0) {
3718
3834
  yield pushToken(buffer);
3719
3835
  }
3836
+ // yield pushToken('', 'EOF');
3720
3837
  }
3721
3838
 
3722
3839
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
3840
+ const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
3723
3841
  const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
3724
3842
  /**
3725
3843
  *
@@ -3766,6 +3884,10 @@ async function parse$1(iterator, opt = {}) {
3766
3884
  let tokens = results.map(mapToken);
3767
3885
  let i;
3768
3886
  let loc;
3887
+ // if ((<Token>tokens.at(-1))?.typ == 'EOF') {
3888
+ //
3889
+ // tokens.pop();
3890
+ // }
3769
3891
  for (i = 0; i < tokens.length; i++) {
3770
3892
  if (tokens[i].typ == 'Comment') {
3771
3893
  // @ts-ignore
@@ -3884,7 +4006,7 @@ async function parse$1(iterator, opt = {}) {
3884
4006
  // https://www.w3.org/TR/css-nesting-1/#conditionals
3885
4007
  // allowed nesting at-rules
3886
4008
  // there must be a top level rule in the stack
3887
- const raw = tokens.reduce((acc, curr) => {
4009
+ const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
3888
4010
  acc.push(renderToken(curr, { removeComments: true }));
3889
4011
  return acc;
3890
4012
  }, []);
@@ -3915,8 +4037,8 @@ async function parse$1(iterator, opt = {}) {
3915
4037
  const uniq = new Map;
3916
4038
  parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
3917
4039
  if (curr.typ == 'Whitespace') {
3918
- if (array[index - 1]?.typ == 'Gt' ||
3919
- array[index + 1]?.typ == 'Gt' ||
4040
+ if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
4041
+ trimWhiteSpace.includes(array[index + 1]?.typ) ||
3920
4042
  combinators.includes(array[index - 1]?.val) ||
3921
4043
  combinators.includes(array[index + 1]?.val)) {
3922
4044
  return acc;
@@ -4104,13 +4226,13 @@ async function parse$1(iterator, opt = {}) {
4104
4226
  };
4105
4227
  }
4106
4228
  function parseString(src, options = { location: false }) {
4107
- return [...tokenize(src)].map(t => {
4229
+ return parseTokens([...tokenize(src)].map(t => {
4108
4230
  const token = getTokenType(t.token, t.hint);
4109
4231
  if (options.location) {
4110
4232
  Object.assign(token, { loc: t.position });
4111
4233
  }
4112
4234
  return token;
4113
- });
4235
+ }));
4114
4236
  }
4115
4237
  function getTokenType(val, hint) {
4116
4238
  if (val === '' && hint == null) {
@@ -4120,7 +4242,7 @@ function getTokenType(val, hint) {
4120
4242
  return ([
4121
4243
  'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
4122
4244
  'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
4123
- 'Comma', 'Gt', 'Lt'
4245
+ 'Comma', 'Gt', 'Lt', 'Gte', 'Lte', 'EOF'
4124
4246
  ].includes(hint) ? { typ: hint } : { typ: hint, val });
4125
4247
  }
4126
4248
  if (val == ' ') {
@@ -4248,11 +4370,12 @@ function parseTokens(tokens, options = {}) {
4248
4370
  const t = tokens[i];
4249
4371
  if (t.typ == 'Whitespace' && ((i == 0 ||
4250
4372
  i + 1 == tokens.length ||
4251
- ['Comma'].includes(tokens[i + 1].typ) ||
4373
+ ['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
4252
4374
  (i > 0 &&
4253
- tokens[i + 1]?.typ != 'Literal' &&
4254
- funcLike.includes(tokens[i - 1].typ) &&
4255
- !['var', 'calc'].includes(tokens[i - 1].val))))) {
4375
+ // tokens[i + 1]?.typ != 'Literal' ||
4376
+ // funcLike.includes(tokens[i - 1].typ) &&
4377
+ // !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
4378
+ trimWhiteSpace.includes(tokens[i - 1].typ)))) {
4256
4379
  tokens.splice(i--, 1);
4257
4380
  continue;
4258
4381
  }
@@ -4369,7 +4492,7 @@ function parseTokens(tokens, options = {}) {
4369
4492
  let m = t.chi.length;
4370
4493
  while (m-- > 0) {
4371
4494
  // @ts-ignore
4372
- if (t.chi[m].typ == 'Literal') {
4495
+ if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
4373
4496
  // @ts-ignore
4374
4497
  if (t.chi[m + 1]?.typ == 'Whitespace') {
4375
4498
  // @ts-ignore
@@ -4607,6 +4730,7 @@ exports.isResolution = isResolution;
4607
4730
  exports.isTime = isTime;
4608
4731
  exports.isWhiteSpace = isWhiteSpace;
4609
4732
  exports.load = load;
4733
+ exports.matchType = matchType;
4610
4734
  exports.matchUrl = matchUrl;
4611
4735
  exports.minify = minify;
4612
4736
  exports.minifyRule = minifyRule;