@tbela99/css-parser 0.0.1-rc3 → 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-umd-web.js +191 -92
- package/dist/index.cjs +191 -92
- package/dist/index.d.ts +10 -2
- package/dist/lib/ast/minify.js +11 -0
- package/dist/lib/parser/declaration/map.js +7 -3
- package/dist/lib/parser/parse.js +15 -9
- package/dist/lib/parser/tokenize.js +40 -18
- package/dist/lib/parser/utils/syntax.js +15 -22
- package/dist/lib/renderer/render.js +103 -40
- package/dist/lib/renderer/utils/color.js +2 -2
- package/dist/node/index.js +7 -1
- package/package.json +8 -7
- package/dist/index.js +0 -11
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 =
|
|
167
|
-
while (index
|
|
168
|
-
if (
|
|
169
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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 =
|
|
187
|
-
while (index
|
|
188
|
-
if (
|
|
189
|
-
|
|
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,
|
|
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';
|
|
@@ -1502,7 +1495,7 @@ function cmyk2hex(token) {
|
|
|
1502
1495
|
return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
|
|
1503
1496
|
}
|
|
1504
1497
|
function getAngle(token) {
|
|
1505
|
-
if (token.typ == '
|
|
1498
|
+
if (token.typ == 'Angle') {
|
|
1506
1499
|
switch (token.unit) {
|
|
1507
1500
|
case 'deg':
|
|
1508
1501
|
// @ts-ignore
|
|
@@ -1575,6 +1568,23 @@ function hsl2rgb(h, s, l, a = null) {
|
|
|
1575
1568
|
return values;
|
|
1576
1569
|
}
|
|
1577
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
|
+
}
|
|
1578
1588
|
function render(data, opt = {}) {
|
|
1579
1589
|
const startTime = performance.now();
|
|
1580
1590
|
const options = Object.assign(opt.minify ?? true ? {
|
|
@@ -1587,17 +1597,19 @@ function render(data, opt = {}) {
|
|
|
1587
1597
|
compress: false,
|
|
1588
1598
|
removeComments: false,
|
|
1589
1599
|
}, { colorConvert: true, preserveLicense: false }, opt);
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
if (
|
|
1593
|
-
|
|
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;
|
|
1594
1607
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
}
|
|
1598
|
-
return { code: doRender(data, options, reducer, 0), stats: {
|
|
1608
|
+
return acc + renderToken(curr, options, reducer);
|
|
1609
|
+
}, 0), stats: {
|
|
1599
1610
|
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
1600
|
-
}
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1601
1613
|
}
|
|
1602
1614
|
// @ts-ignore
|
|
1603
1615
|
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
@@ -1611,9 +1623,9 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1611
1623
|
const indentSub = indents[level + 1];
|
|
1612
1624
|
switch (data.typ) {
|
|
1613
1625
|
case 'Declaration':
|
|
1614
|
-
return `${data.nam}:${options.indent}${data.val.reduce(
|
|
1626
|
+
return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
|
|
1615
1627
|
case 'Comment':
|
|
1616
|
-
return options.removeComments
|
|
1628
|
+
return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
|
|
1617
1629
|
case 'StyleSheet':
|
|
1618
1630
|
return data.chi.reduce((css, node) => {
|
|
1619
1631
|
const str = doRender(node, options, reducer, level, indents);
|
|
@@ -1634,7 +1646,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1634
1646
|
let children = data.chi.reduce((css, node) => {
|
|
1635
1647
|
let str;
|
|
1636
1648
|
if (node.typ == 'Comment') {
|
|
1637
|
-
str = options.removeComments ? '' : node.val;
|
|
1649
|
+
str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
|
|
1638
1650
|
}
|
|
1639
1651
|
else if (node.typ == 'Declaration') {
|
|
1640
1652
|
if (node.val.length == 0) {
|
|
@@ -1667,7 +1679,18 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1667
1679
|
}
|
|
1668
1680
|
return '';
|
|
1669
1681
|
}
|
|
1670
|
-
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
|
+
}
|
|
1671
1694
|
switch (token.typ) {
|
|
1672
1695
|
case 'Color':
|
|
1673
1696
|
if (options.minify || options.colorConvert) {
|
|
@@ -1718,22 +1741,19 @@ function renderToken(token, options = {}) {
|
|
|
1718
1741
|
case 'UrlFunc':
|
|
1719
1742
|
case 'Pseudo-class-func':
|
|
1720
1743
|
// @ts-ignore
|
|
1721
|
-
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(
|
|
1722
|
-
if (options.removeComments && curr.typ == 'Comment') {
|
|
1723
|
-
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1724
|
-
return acc;
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
return acc + renderToken(curr, options);
|
|
1728
|
-
}, '') + ')';
|
|
1744
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
|
|
1729
1745
|
case 'Includes':
|
|
1730
1746
|
return '~=';
|
|
1731
1747
|
case 'Dash-match':
|
|
1732
1748
|
return '|=';
|
|
1733
1749
|
case 'Lt':
|
|
1734
1750
|
return '<';
|
|
1751
|
+
case 'Lte':
|
|
1752
|
+
return '<=';
|
|
1735
1753
|
case 'Gt':
|
|
1736
1754
|
return '>';
|
|
1755
|
+
case 'Gte':
|
|
1756
|
+
return '>=';
|
|
1737
1757
|
case 'End-parens':
|
|
1738
1758
|
return ')';
|
|
1739
1759
|
case 'Attr-start':
|
|
@@ -1751,37 +1771,73 @@ function renderToken(token, options = {}) {
|
|
|
1751
1771
|
case 'Important':
|
|
1752
1772
|
return '!important';
|
|
1753
1773
|
case 'Attr':
|
|
1754
|
-
return '[' + token.chi.reduce(
|
|
1774
|
+
return '[' + token.chi.reduce(reducer, '') + ']';
|
|
1755
1775
|
case 'Time':
|
|
1756
|
-
case 'Frequency':
|
|
1757
1776
|
case 'Angle':
|
|
1758
1777
|
case 'Length':
|
|
1759
1778
|
case 'Dimension':
|
|
1760
|
-
|
|
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
|
+
}
|
|
1761
1827
|
if (val === '0') {
|
|
1762
|
-
if (
|
|
1828
|
+
if (unit == 'Time') {
|
|
1763
1829
|
return '0s';
|
|
1764
1830
|
}
|
|
1765
|
-
if (
|
|
1831
|
+
if (unit == 'Frequency') {
|
|
1766
1832
|
return '0Hz';
|
|
1767
1833
|
}
|
|
1768
1834
|
// @ts-ignore
|
|
1769
|
-
if (
|
|
1835
|
+
if (unit == 'Resolution') {
|
|
1770
1836
|
return '0x';
|
|
1771
1837
|
}
|
|
1772
1838
|
return '0';
|
|
1773
1839
|
}
|
|
1774
|
-
|
|
1775
|
-
if (chr == '-') {
|
|
1776
|
-
const slice = val.slice(0, 2);
|
|
1777
|
-
if (slice == '-0') {
|
|
1778
|
-
return (val.length == 2 ? '0' : '-' + val.slice(2)) + token.unit;
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
else if (chr == '0') {
|
|
1782
|
-
return val.slice(1) + token.unit;
|
|
1783
|
-
}
|
|
1784
|
-
return val + token.unit;
|
|
1840
|
+
return val + unit;
|
|
1785
1841
|
case 'Perc':
|
|
1786
1842
|
return token.val + '%';
|
|
1787
1843
|
case 'Number':
|
|
@@ -1798,7 +1854,7 @@ function renderToken(token, options = {}) {
|
|
|
1798
1854
|
}
|
|
1799
1855
|
return num;
|
|
1800
1856
|
case 'Comment':
|
|
1801
|
-
if (options.removeComments) {
|
|
1857
|
+
if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
|
|
1802
1858
|
return '';
|
|
1803
1859
|
}
|
|
1804
1860
|
case 'Url-token':
|
|
@@ -2069,6 +2125,7 @@ class PropertyMap {
|
|
|
2069
2125
|
i--;
|
|
2070
2126
|
continue;
|
|
2071
2127
|
}
|
|
2128
|
+
// @ts-ignore
|
|
2072
2129
|
if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
|
|
2073
2130
|
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
|
|
2074
2131
|
return acc;
|
|
@@ -2234,17 +2291,18 @@ class PropertyMap {
|
|
|
2234
2291
|
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
|
|
2235
2292
|
continue;
|
|
2236
2293
|
}
|
|
2237
|
-
|
|
2294
|
+
// @ts-ignore
|
|
2295
|
+
match = val.typ == 'Comment' || matchType(val, curr[1]);
|
|
2238
2296
|
if (isShorthand) {
|
|
2239
2297
|
isShorthand = match;
|
|
2240
2298
|
}
|
|
2299
|
+
// @ts-ignore
|
|
2241
2300
|
if (('propertyName' in val && val.propertyName == property) || match) {
|
|
2242
2301
|
if (!(curr[0] in tokens)) {
|
|
2243
2302
|
tokens[curr[0]] = [[]];
|
|
2244
2303
|
}
|
|
2245
2304
|
// is default value
|
|
2246
2305
|
tokens[curr[0]][current].push(val);
|
|
2247
|
-
// continue;
|
|
2248
2306
|
}
|
|
2249
2307
|
else {
|
|
2250
2308
|
acc.push(curr[0]);
|
|
@@ -2261,7 +2319,9 @@ class PropertyMap {
|
|
|
2261
2319
|
if (!isShorthand || Object.entries(this.config.properties).some(entry => {
|
|
2262
2320
|
// missing required property
|
|
2263
2321
|
return entry[1].required && !(entry[0] in tokens);
|
|
2264
|
-
}) ||
|
|
2322
|
+
}) ||
|
|
2323
|
+
// @ts-ignore
|
|
2324
|
+
!Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
|
|
2265
2325
|
// @ts-ignore
|
|
2266
2326
|
iterable = this.declarations.values();
|
|
2267
2327
|
}
|
|
@@ -2814,6 +2874,17 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
2814
2874
|
continue;
|
|
2815
2875
|
// }
|
|
2816
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;
|
|
2817
2888
|
}
|
|
2818
2889
|
// @ts-ignore
|
|
2819
2890
|
if (node.typ == 'Rule') {
|
|
@@ -3328,11 +3399,6 @@ function* tokenize(iterator) {
|
|
|
3328
3399
|
}
|
|
3329
3400
|
buffer += quoteStr;
|
|
3330
3401
|
while (value = peek()) {
|
|
3331
|
-
// if (ind >= iterator.length) {
|
|
3332
|
-
//
|
|
3333
|
-
// yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
3334
|
-
// break;
|
|
3335
|
-
// }
|
|
3336
3402
|
if (value == '\\') {
|
|
3337
3403
|
const sequence = peek(6);
|
|
3338
3404
|
let escapeSequence = '';
|
|
@@ -3352,9 +3418,23 @@ function* tokenize(iterator) {
|
|
|
3352
3418
|
}
|
|
3353
3419
|
break;
|
|
3354
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
|
+
}
|
|
3355
3435
|
// not hex or new line
|
|
3356
3436
|
// @ts-ignore
|
|
3357
|
-
if (i == 1
|
|
3437
|
+
else if (i == 1) {
|
|
3358
3438
|
buffer += value + sequence[i];
|
|
3359
3439
|
next(2);
|
|
3360
3440
|
continue;
|
|
@@ -3374,13 +3454,6 @@ function* tokenize(iterator) {
|
|
|
3374
3454
|
next(escapeSequence.length + 1);
|
|
3375
3455
|
continue;
|
|
3376
3456
|
}
|
|
3377
|
-
// buffer += value;
|
|
3378
|
-
// if (ind >= iterator.length) {
|
|
3379
|
-
//
|
|
3380
|
-
// // drop '\\' at the end
|
|
3381
|
-
// yield pushToken(buffer);
|
|
3382
|
-
// break;
|
|
3383
|
-
// }
|
|
3384
3457
|
buffer += next(2);
|
|
3385
3458
|
continue;
|
|
3386
3459
|
}
|
|
@@ -3390,20 +3463,28 @@ function* tokenize(iterator) {
|
|
|
3390
3463
|
next();
|
|
3391
3464
|
// i += value.length;
|
|
3392
3465
|
buffer = '';
|
|
3393
|
-
|
|
3466
|
+
return;
|
|
3394
3467
|
}
|
|
3395
3468
|
if (isNewLine(value.charCodeAt(0))) {
|
|
3396
3469
|
hasNewLine = true;
|
|
3397
3470
|
}
|
|
3398
3471
|
if (hasNewLine && value == ';') {
|
|
3399
|
-
yield pushToken(buffer, 'Bad-string');
|
|
3472
|
+
yield pushToken(buffer + value, 'Bad-string');
|
|
3400
3473
|
buffer = '';
|
|
3474
|
+
next();
|
|
3401
3475
|
break;
|
|
3402
3476
|
}
|
|
3403
3477
|
buffer += value;
|
|
3404
|
-
// i += value.length;
|
|
3405
3478
|
next();
|
|
3406
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 = '';
|
|
3407
3488
|
}
|
|
3408
3489
|
function peek(count = 1) {
|
|
3409
3490
|
if (count == 1) {
|
|
@@ -3517,6 +3598,11 @@ function* tokenize(iterator) {
|
|
|
3517
3598
|
yield pushToken(buffer);
|
|
3518
3599
|
buffer = '';
|
|
3519
3600
|
}
|
|
3601
|
+
if (peek() == '=') {
|
|
3602
|
+
yield pushToken('', 'Lte');
|
|
3603
|
+
next();
|
|
3604
|
+
break;
|
|
3605
|
+
}
|
|
3520
3606
|
buffer += value;
|
|
3521
3607
|
value = next();
|
|
3522
3608
|
if (ind >= iterator.length) {
|
|
@@ -3585,7 +3671,13 @@ function* tokenize(iterator) {
|
|
|
3585
3671
|
yield pushToken(buffer);
|
|
3586
3672
|
buffer = '';
|
|
3587
3673
|
}
|
|
3588
|
-
|
|
3674
|
+
if (peek() == '=') {
|
|
3675
|
+
yield pushToken('', 'Gte');
|
|
3676
|
+
next();
|
|
3677
|
+
}
|
|
3678
|
+
else {
|
|
3679
|
+
yield pushToken('', 'Gt');
|
|
3680
|
+
}
|
|
3589
3681
|
consumeWhiteSpace();
|
|
3590
3682
|
break;
|
|
3591
3683
|
case '.':
|
|
@@ -3627,7 +3719,7 @@ function* tokenize(iterator) {
|
|
|
3627
3719
|
break;
|
|
3628
3720
|
case '(':
|
|
3629
3721
|
if (buffer.length == 0) {
|
|
3630
|
-
yield pushToken(
|
|
3722
|
+
yield pushToken(value);
|
|
3631
3723
|
break;
|
|
3632
3724
|
}
|
|
3633
3725
|
buffer += value;
|
|
@@ -3741,9 +3833,11 @@ function* tokenize(iterator) {
|
|
|
3741
3833
|
if (buffer.length > 0) {
|
|
3742
3834
|
yield pushToken(buffer);
|
|
3743
3835
|
}
|
|
3836
|
+
// yield pushToken('', 'EOF');
|
|
3744
3837
|
}
|
|
3745
3838
|
|
|
3746
3839
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
3840
|
+
const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
|
|
3747
3841
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
3748
3842
|
/**
|
|
3749
3843
|
*
|
|
@@ -3790,6 +3884,10 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3790
3884
|
let tokens = results.map(mapToken);
|
|
3791
3885
|
let i;
|
|
3792
3886
|
let loc;
|
|
3887
|
+
// if ((<Token>tokens.at(-1))?.typ == 'EOF') {
|
|
3888
|
+
//
|
|
3889
|
+
// tokens.pop();
|
|
3890
|
+
// }
|
|
3793
3891
|
for (i = 0; i < tokens.length; i++) {
|
|
3794
3892
|
if (tokens[i].typ == 'Comment') {
|
|
3795
3893
|
// @ts-ignore
|
|
@@ -3908,7 +4006,7 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3908
4006
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
3909
4007
|
// allowed nesting at-rules
|
|
3910
4008
|
// there must be a top level rule in the stack
|
|
3911
|
-
const raw = tokens.reduce((acc, curr) => {
|
|
4009
|
+
const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
|
|
3912
4010
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
3913
4011
|
return acc;
|
|
3914
4012
|
}, []);
|
|
@@ -3939,8 +4037,8 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3939
4037
|
const uniq = new Map;
|
|
3940
4038
|
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
3941
4039
|
if (curr.typ == 'Whitespace') {
|
|
3942
|
-
if (array[index - 1]?.typ
|
|
3943
|
-
array[index + 1]?.typ
|
|
4040
|
+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
4041
|
+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
3944
4042
|
combinators.includes(array[index - 1]?.val) ||
|
|
3945
4043
|
combinators.includes(array[index + 1]?.val)) {
|
|
3946
4044
|
return acc;
|
|
@@ -4144,7 +4242,7 @@ function getTokenType(val, hint) {
|
|
|
4144
4242
|
return ([
|
|
4145
4243
|
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
4146
4244
|
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
4147
|
-
'Comma', 'Gt', 'Lt'
|
|
4245
|
+
'Comma', 'Gt', 'Lt', 'Gte', 'Lte', 'EOF'
|
|
4148
4246
|
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
4149
4247
|
}
|
|
4150
4248
|
if (val == ' ') {
|
|
@@ -4272,11 +4370,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
4272
4370
|
const t = tokens[i];
|
|
4273
4371
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
4274
4372
|
i + 1 == tokens.length ||
|
|
4275
|
-
['Comma'].includes(tokens[i + 1].typ) ||
|
|
4373
|
+
['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
|
|
4276
4374
|
(i > 0 &&
|
|
4277
|
-
tokens[i + 1]?.typ != 'Literal'
|
|
4278
|
-
funcLike.includes(tokens[i - 1].typ) &&
|
|
4279
|
-
!['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)))) {
|
|
4280
4379
|
tokens.splice(i--, 1);
|
|
4281
4380
|
continue;
|
|
4282
4381
|
}
|
|
@@ -4393,7 +4492,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
4393
4492
|
let m = t.chi.length;
|
|
4394
4493
|
while (m-- > 0) {
|
|
4395
4494
|
// @ts-ignore
|
|
4396
|
-
if (t.chi[m].typ
|
|
4495
|
+
if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
|
|
4397
4496
|
// @ts-ignore
|
|
4398
4497
|
if (t.chi[m + 1]?.typ == 'Whitespace') {
|
|
4399
4498
|
// @ts-ignore
|
package/dist/index.d.ts
CHANGED
|
@@ -91,12 +91,14 @@ interface BlockEndToken {
|
|
|
91
91
|
}
|
|
92
92
|
interface AttrStartToken {
|
|
93
93
|
typ: 'Attr-start';
|
|
94
|
+
chi?: Token[];
|
|
94
95
|
}
|
|
95
96
|
interface AttrEndToken {
|
|
96
97
|
typ: 'Attr-end';
|
|
97
98
|
}
|
|
98
99
|
interface ParensStartToken {
|
|
99
100
|
typ: 'Start-parens';
|
|
101
|
+
chi?: Token[];
|
|
100
102
|
}
|
|
101
103
|
interface ParensEndToken {
|
|
102
104
|
typ: 'End-parens';
|
|
@@ -131,9 +133,15 @@ interface DashMatchToken {
|
|
|
131
133
|
interface LessThanToken {
|
|
132
134
|
typ: 'Lt';
|
|
133
135
|
}
|
|
136
|
+
interface LessThanOrEqualToken {
|
|
137
|
+
typ: 'Lte';
|
|
138
|
+
}
|
|
134
139
|
interface GreaterThanToken {
|
|
135
140
|
typ: 'Gt';
|
|
136
141
|
}
|
|
142
|
+
interface GreaterThanOrEqualToken {
|
|
143
|
+
typ: 'Gte';
|
|
144
|
+
}
|
|
137
145
|
interface PseudoClassToken {
|
|
138
146
|
typ: 'Pseudo-class';
|
|
139
147
|
val: string;
|
|
@@ -171,7 +179,7 @@ interface AttrToken {
|
|
|
171
179
|
typ: 'Attr';
|
|
172
180
|
chi: Token[];
|
|
173
181
|
}
|
|
174
|
-
declare type Token = LiteralToken | IdentToken | CommaToken | ColonToken | SemiColonToken | NumberToken | AtRuleToken | PercentageToken | FunctionURLToken | FunctionToken | DimensionToken | LengthToken | AngleToken | StringToken | TimeToken | FrequencyToken | ResolutionToken | UnclosedStringToken | HashToken | BadStringToken | BlockStartToken | BlockEndToken | AttrStartToken | AttrEndToken | ParensStartToken | ParensEndToken | CDOCommentToken | BadCDOCommentToken | CommentToken | BadCommentToken | WhitespaceToken | IncludesToken | DashMatchToken | LessThanToken | GreaterThanToken | PseudoClassToken | PseudoClassFunctionToken | DelimToken | BadUrlToken | UrlToken | ImportantToken | ColorToken | AttrToken | EOFToken;
|
|
182
|
+
declare type Token = LiteralToken | IdentToken | CommaToken | ColonToken | SemiColonToken | NumberToken | AtRuleToken | PercentageToken | FunctionURLToken | FunctionToken | DimensionToken | LengthToken | AngleToken | StringToken | TimeToken | FrequencyToken | ResolutionToken | UnclosedStringToken | HashToken | BadStringToken | BlockStartToken | BlockEndToken | AttrStartToken | AttrEndToken | ParensStartToken | ParensEndToken | CDOCommentToken | BadCDOCommentToken | CommentToken | BadCommentToken | WhitespaceToken | IncludesToken | DashMatchToken | LessThanToken | LessThanOrEqualToken | GreaterThanToken | GreaterThanOrEqualToken | PseudoClassToken | PseudoClassFunctionToken | DelimToken | BadUrlToken | UrlToken | ImportantToken | ColorToken | AttrToken | EOFToken;
|
|
175
183
|
|
|
176
184
|
interface PropertyMapType {
|
|
177
185
|
default: string[];
|
|
@@ -656,7 +664,7 @@ declare const getConfig: () => PropertiesConfig;
|
|
|
656
664
|
declare function matchType(val: Token, properties: PropertyMapType): boolean;
|
|
657
665
|
|
|
658
666
|
declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
|
|
659
|
-
declare function renderToken(token: Token, options?: RenderOptions): string;
|
|
667
|
+
declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string): string;
|
|
660
668
|
|
|
661
669
|
declare const combinators: string[];
|
|
662
670
|
declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean): AstNode;
|
package/dist/lib/ast/minify.js
CHANGED
|
@@ -344,6 +344,17 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
344
344
|
continue;
|
|
345
345
|
// }
|
|
346
346
|
}
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
if (hasDeclaration(node)) {
|
|
349
|
+
// @ts-ignore
|
|
350
|
+
minifyRule(node);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
minify(node, options, recursive);
|
|
354
|
+
}
|
|
355
|
+
previous = node;
|
|
356
|
+
nodeIndex = i;
|
|
357
|
+
continue;
|
|
347
358
|
}
|
|
348
359
|
// @ts-ignore
|
|
349
360
|
if (node.typ == 'Rule') {
|
|
@@ -55,6 +55,7 @@ class PropertyMap {
|
|
|
55
55
|
i--;
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
+
// @ts-ignore
|
|
58
59
|
if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
|
|
59
60
|
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
|
|
60
61
|
return acc;
|
|
@@ -220,17 +221,18 @@ class PropertyMap {
|
|
|
220
221
|
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
|
|
221
222
|
continue;
|
|
222
223
|
}
|
|
223
|
-
|
|
224
|
+
// @ts-ignore
|
|
225
|
+
match = val.typ == 'Comment' || matchType(val, curr[1]);
|
|
224
226
|
if (isShorthand) {
|
|
225
227
|
isShorthand = match;
|
|
226
228
|
}
|
|
229
|
+
// @ts-ignore
|
|
227
230
|
if (('propertyName' in val && val.propertyName == property) || match) {
|
|
228
231
|
if (!(curr[0] in tokens)) {
|
|
229
232
|
tokens[curr[0]] = [[]];
|
|
230
233
|
}
|
|
231
234
|
// is default value
|
|
232
235
|
tokens[curr[0]][current].push(val);
|
|
233
|
-
// continue;
|
|
234
236
|
}
|
|
235
237
|
else {
|
|
236
238
|
acc.push(curr[0]);
|
|
@@ -247,7 +249,9 @@ class PropertyMap {
|
|
|
247
249
|
if (!isShorthand || Object.entries(this.config.properties).some(entry => {
|
|
248
250
|
// missing required property
|
|
249
251
|
return entry[1].required && !(entry[0] in tokens);
|
|
250
|
-
}) ||
|
|
252
|
+
}) ||
|
|
253
|
+
// @ts-ignore
|
|
254
|
+
!Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
|
|
251
255
|
// @ts-ignore
|
|
252
256
|
iterable = this.declarations.values();
|
|
253
257
|
}
|