@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/README.md +59 -3
- package/dist/index-umd-web.js +253 -129
- package/dist/index.cjs +253 -129
- package/dist/index.d.ts +37 -3
- package/dist/lib/ast/minify.js +11 -0
- package/dist/lib/parser/declaration/map.js +47 -29
- package/dist/lib/parser/parse.js +17 -11
- package/dist/lib/parser/tokenize.js +40 -18
- package/dist/lib/parser/utils/syntax.js +15 -22
- package/dist/lib/parser/utils/type.js +4 -0
- package/dist/lib/renderer/render.js +108 -39
- package/dist/lib/renderer/utils/color.js +2 -2
- package/dist/node/index.js +7 -1
- package/dist/web/index.js +1 -0
- package/package.json +16 -16
- package/.gitattributes +0 -22
- package/dist/index.js +0 -10
package/dist/index-umd-web.js
CHANGED
|
@@ -165,37 +165,30 @@
|
|
|
165
165
|
return true;
|
|
166
166
|
}
|
|
167
167
|
function isDimension(name) {
|
|
168
|
-
let index =
|
|
169
|
-
while (index
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
if (index == 3) {
|
|
175
|
-
break;
|
|
168
|
+
let index = name.length;
|
|
169
|
+
while (index--) {
|
|
170
|
+
if (isLetter(name.charCodeAt(index))) {
|
|
171
|
+
continue;
|
|
176
172
|
}
|
|
173
|
+
index++;
|
|
174
|
+
break;
|
|
177
175
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
const number = name.slice(0, -index);
|
|
182
|
-
return number.length > 0 && isIdentStart(name.charCodeAt(name.length - index)) && isNumber(number);
|
|
176
|
+
const number = name.slice(0, index);
|
|
177
|
+
return number.length > 0 && isIdentStart(name.charCodeAt(index)) && isNumber(number);
|
|
183
178
|
}
|
|
184
179
|
function isPercentage(name) {
|
|
185
180
|
return name.endsWith('%') && isNumber(name.slice(0, -1));
|
|
186
181
|
}
|
|
187
182
|
function parseDimension(name) {
|
|
188
|
-
let index =
|
|
189
|
-
while (index
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
if (index == 3) {
|
|
195
|
-
break;
|
|
183
|
+
let index = name.length;
|
|
184
|
+
while (index--) {
|
|
185
|
+
if (isLetter(name.charCodeAt(index))) {
|
|
186
|
+
continue;
|
|
196
187
|
}
|
|
188
|
+
index++;
|
|
189
|
+
break;
|
|
197
190
|
}
|
|
198
|
-
const dimension = { typ: 'Dimension', val: name.slice(0,
|
|
191
|
+
const dimension = { typ: 'Dimension', val: name.slice(0, index), unit: name.slice(index) };
|
|
199
192
|
if (isAngle(dimension)) {
|
|
200
193
|
// @ts-ignore
|
|
201
194
|
dimension.typ = 'Angle';
|
|
@@ -1069,6 +1062,21 @@
|
|
|
1069
1062
|
|
|
1070
1063
|
const getConfig = () => config$1;
|
|
1071
1064
|
|
|
1065
|
+
const funcList = ['clamp', 'calc'];
|
|
1066
|
+
function matchType(val, properties) {
|
|
1067
|
+
if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
|
|
1068
|
+
(properties.types.includes(val.typ))) {
|
|
1069
|
+
return true;
|
|
1070
|
+
}
|
|
1071
|
+
if (val.typ == 'Number' && val.val == '0') {
|
|
1072
|
+
return properties.types.some(type => type == 'Length' || type == 'Angle');
|
|
1073
|
+
}
|
|
1074
|
+
if (val.typ == 'Func' && funcList.includes(val.val)) {
|
|
1075
|
+
return val.chi.every((t => ['Literal', 'Comma', 'Whitespace', 'Start-parens', 'End-parens'].includes(t.typ) || matchType(t, properties)));
|
|
1076
|
+
}
|
|
1077
|
+
return false;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1072
1080
|
// name to color
|
|
1073
1081
|
const COLORS_NAMES = Object.seal({
|
|
1074
1082
|
'aliceblue': '#f0f8ff',
|
|
@@ -1489,7 +1497,7 @@
|
|
|
1489
1497
|
return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
|
|
1490
1498
|
}
|
|
1491
1499
|
function getAngle(token) {
|
|
1492
|
-
if (token.typ == '
|
|
1500
|
+
if (token.typ == 'Angle') {
|
|
1493
1501
|
switch (token.unit) {
|
|
1494
1502
|
case 'deg':
|
|
1495
1503
|
// @ts-ignore
|
|
@@ -1562,6 +1570,23 @@
|
|
|
1562
1570
|
return values;
|
|
1563
1571
|
}
|
|
1564
1572
|
|
|
1573
|
+
function reduceNumber(val) {
|
|
1574
|
+
val = (+val).toString();
|
|
1575
|
+
if (val === '0') {
|
|
1576
|
+
return '0';
|
|
1577
|
+
}
|
|
1578
|
+
const chr = val.charAt(0);
|
|
1579
|
+
if (chr == '-') {
|
|
1580
|
+
const slice = val.slice(0, 2);
|
|
1581
|
+
if (slice == '-0') {
|
|
1582
|
+
return val.length == 2 ? '0' : '-' + val.slice(2);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
if (chr == '0') {
|
|
1586
|
+
return val.slice(1);
|
|
1587
|
+
}
|
|
1588
|
+
return val;
|
|
1589
|
+
}
|
|
1565
1590
|
function render(data, opt = {}) {
|
|
1566
1591
|
const startTime = performance.now();
|
|
1567
1592
|
const options = Object.assign(opt.minify ?? true ? {
|
|
@@ -1574,17 +1599,19 @@
|
|
|
1574
1599
|
compress: false,
|
|
1575
1600
|
removeComments: false,
|
|
1576
1601
|
}, { colorConvert: true, preserveLicense: false }, opt);
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
if (
|
|
1580
|
-
|
|
1602
|
+
return {
|
|
1603
|
+
code: doRender(data, options, function reducer(acc, curr) {
|
|
1604
|
+
if (curr.typ == 'Comment' && options.removeComments) {
|
|
1605
|
+
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1606
|
+
return acc;
|
|
1607
|
+
}
|
|
1608
|
+
return acc + curr.val;
|
|
1581
1609
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
}
|
|
1585
|
-
return { code: doRender(data, options, reducer, 0), stats: {
|
|
1610
|
+
return acc + renderToken(curr, options, reducer);
|
|
1611
|
+
}, 0), stats: {
|
|
1586
1612
|
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
1587
|
-
}
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1588
1615
|
}
|
|
1589
1616
|
// @ts-ignore
|
|
1590
1617
|
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
@@ -1597,8 +1624,10 @@
|
|
|
1597
1624
|
const indent = indents[level];
|
|
1598
1625
|
const indentSub = indents[level + 1];
|
|
1599
1626
|
switch (data.typ) {
|
|
1627
|
+
case 'Declaration':
|
|
1628
|
+
return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
|
|
1600
1629
|
case 'Comment':
|
|
1601
|
-
return options.removeComments
|
|
1630
|
+
return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
|
|
1602
1631
|
case 'StyleSheet':
|
|
1603
1632
|
return data.chi.reduce((css, node) => {
|
|
1604
1633
|
const str = doRender(node, options, reducer, level, indents);
|
|
@@ -1619,9 +1648,13 @@
|
|
|
1619
1648
|
let children = data.chi.reduce((css, node) => {
|
|
1620
1649
|
let str;
|
|
1621
1650
|
if (node.typ == 'Comment') {
|
|
1622
|
-
str = options.removeComments ? '' : node.val;
|
|
1651
|
+
str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
|
|
1623
1652
|
}
|
|
1624
1653
|
else if (node.typ == 'Declaration') {
|
|
1654
|
+
if (node.val.length == 0) {
|
|
1655
|
+
console.error(`invalid declaration`, node);
|
|
1656
|
+
return '';
|
|
1657
|
+
}
|
|
1625
1658
|
str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
|
|
1626
1659
|
}
|
|
1627
1660
|
else if (node.typ == 'AtRule' && !('chi' in node)) {
|
|
@@ -1648,7 +1681,18 @@
|
|
|
1648
1681
|
}
|
|
1649
1682
|
return '';
|
|
1650
1683
|
}
|
|
1651
|
-
function renderToken(token, options = {}) {
|
|
1684
|
+
function renderToken(token, options = {}, reducer) {
|
|
1685
|
+
if (reducer == null) {
|
|
1686
|
+
reducer = function (acc, curr) {
|
|
1687
|
+
if (curr.typ == 'Comment' && options.removeComments) {
|
|
1688
|
+
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1689
|
+
return acc;
|
|
1690
|
+
}
|
|
1691
|
+
return acc + curr.val;
|
|
1692
|
+
}
|
|
1693
|
+
return acc + renderToken(curr, options, reducer);
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1652
1696
|
switch (token.typ) {
|
|
1653
1697
|
case 'Color':
|
|
1654
1698
|
if (options.minify || options.colorConvert) {
|
|
@@ -1699,22 +1743,19 @@
|
|
|
1699
1743
|
case 'UrlFunc':
|
|
1700
1744
|
case 'Pseudo-class-func':
|
|
1701
1745
|
// @ts-ignore
|
|
1702
|
-
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(
|
|
1703
|
-
if (options.removeComments && curr.typ == 'Comment') {
|
|
1704
|
-
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1705
|
-
return acc;
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
return acc + renderToken(curr, options);
|
|
1709
|
-
}, '') + ')';
|
|
1746
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
|
|
1710
1747
|
case 'Includes':
|
|
1711
1748
|
return '~=';
|
|
1712
1749
|
case 'Dash-match':
|
|
1713
1750
|
return '|=';
|
|
1714
1751
|
case 'Lt':
|
|
1715
1752
|
return '<';
|
|
1753
|
+
case 'Lte':
|
|
1754
|
+
return '<=';
|
|
1716
1755
|
case 'Gt':
|
|
1717
1756
|
return '>';
|
|
1757
|
+
case 'Gte':
|
|
1758
|
+
return '>=';
|
|
1718
1759
|
case 'End-parens':
|
|
1719
1760
|
return ')';
|
|
1720
1761
|
case 'Attr-start':
|
|
@@ -1732,37 +1773,73 @@
|
|
|
1732
1773
|
case 'Important':
|
|
1733
1774
|
return '!important';
|
|
1734
1775
|
case 'Attr':
|
|
1735
|
-
return '[' + token.chi.reduce(
|
|
1776
|
+
return '[' + token.chi.reduce(reducer, '') + ']';
|
|
1736
1777
|
case 'Time':
|
|
1737
|
-
case 'Frequency':
|
|
1738
1778
|
case 'Angle':
|
|
1739
1779
|
case 'Length':
|
|
1740
1780
|
case 'Dimension':
|
|
1741
|
-
|
|
1781
|
+
case 'Frequency':
|
|
1782
|
+
case 'Resolution':
|
|
1783
|
+
let val = reduceNumber(token.val);
|
|
1784
|
+
let unit = token.unit;
|
|
1785
|
+
if (token.typ == 'Angle') {
|
|
1786
|
+
const angle = getAngle(token);
|
|
1787
|
+
let v;
|
|
1788
|
+
let value = val + unit;
|
|
1789
|
+
for (const u of ['turn', 'deg', 'rad', 'grad']) {
|
|
1790
|
+
if (token.unit == u) {
|
|
1791
|
+
continue;
|
|
1792
|
+
}
|
|
1793
|
+
switch (u) {
|
|
1794
|
+
case 'turn':
|
|
1795
|
+
v = reduceNumber(angle);
|
|
1796
|
+
if (v.length + 4 < value.length) {
|
|
1797
|
+
val = v;
|
|
1798
|
+
unit = u;
|
|
1799
|
+
value = v + u;
|
|
1800
|
+
}
|
|
1801
|
+
break;
|
|
1802
|
+
case 'deg':
|
|
1803
|
+
v = reduceNumber(angle * 360);
|
|
1804
|
+
if (v.length + 3 < value.length) {
|
|
1805
|
+
val = v;
|
|
1806
|
+
unit = u;
|
|
1807
|
+
value = v + u;
|
|
1808
|
+
}
|
|
1809
|
+
break;
|
|
1810
|
+
case 'rad':
|
|
1811
|
+
v = reduceNumber(angle * (2 * Math.PI));
|
|
1812
|
+
if (v.length + 3 < value.length) {
|
|
1813
|
+
val = v;
|
|
1814
|
+
unit = u;
|
|
1815
|
+
value = v + u;
|
|
1816
|
+
}
|
|
1817
|
+
break;
|
|
1818
|
+
case 'grad':
|
|
1819
|
+
v = reduceNumber(angle * 400);
|
|
1820
|
+
if (v.length + 4 < value.length) {
|
|
1821
|
+
val = v;
|
|
1822
|
+
unit = u;
|
|
1823
|
+
value = v + u;
|
|
1824
|
+
}
|
|
1825
|
+
break;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1742
1829
|
if (val === '0') {
|
|
1743
|
-
if (
|
|
1830
|
+
if (unit == 'Time') {
|
|
1744
1831
|
return '0s';
|
|
1745
1832
|
}
|
|
1746
|
-
if (
|
|
1833
|
+
if (unit == 'Frequency') {
|
|
1747
1834
|
return '0Hz';
|
|
1748
1835
|
}
|
|
1749
1836
|
// @ts-ignore
|
|
1750
|
-
if (
|
|
1837
|
+
if (unit == 'Resolution') {
|
|
1751
1838
|
return '0x';
|
|
1752
1839
|
}
|
|
1753
1840
|
return '0';
|
|
1754
1841
|
}
|
|
1755
|
-
|
|
1756
|
-
if (chr == '-') {
|
|
1757
|
-
const slice = val.slice(0, 2);
|
|
1758
|
-
if (slice == '-0') {
|
|
1759
|
-
return (val.length == 2 ? '0' : '-' + val.slice(2)) + token.unit;
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
else if (chr == '0') {
|
|
1763
|
-
return val.slice(1) + token.unit;
|
|
1764
|
-
}
|
|
1765
|
-
return val + token.unit;
|
|
1842
|
+
return val + unit;
|
|
1766
1843
|
case 'Perc':
|
|
1767
1844
|
return token.val + '%';
|
|
1768
1845
|
case 'Number':
|
|
@@ -1779,7 +1856,7 @@
|
|
|
1779
1856
|
}
|
|
1780
1857
|
return num;
|
|
1781
1858
|
case 'Comment':
|
|
1782
|
-
if (options.removeComments) {
|
|
1859
|
+
if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
|
|
1783
1860
|
return '';
|
|
1784
1861
|
}
|
|
1785
1862
|
case 'Url-token':
|
|
@@ -2000,17 +2077,6 @@
|
|
|
2000
2077
|
}
|
|
2001
2078
|
}
|
|
2002
2079
|
|
|
2003
|
-
function matchType(val, properties) {
|
|
2004
|
-
if (val.typ == 'Iden' && properties.keywords.includes(val.val) ||
|
|
2005
|
-
(properties.types.includes(val.typ))) {
|
|
2006
|
-
return true;
|
|
2007
|
-
}
|
|
2008
|
-
if (val.typ == 'Number' && val.val == '0') {
|
|
2009
|
-
return properties.types.some(type => type == 'Length' || type == 'Angle');
|
|
2010
|
-
}
|
|
2011
|
-
return false;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
2080
|
const propertiesConfig = getConfig();
|
|
2015
2081
|
class PropertyMap {
|
|
2016
2082
|
config;
|
|
@@ -2025,6 +2091,9 @@
|
|
|
2025
2091
|
this.pattern = config.pattern.split(/\s/);
|
|
2026
2092
|
}
|
|
2027
2093
|
add(declaration) {
|
|
2094
|
+
for (const val of declaration.val) {
|
|
2095
|
+
Object.defineProperty(val, 'propertyName', { enumerable: false, writable: true, value: declaration.nam });
|
|
2096
|
+
}
|
|
2028
2097
|
if (declaration.nam == this.config.shorthand) {
|
|
2029
2098
|
this.declarations = new Map;
|
|
2030
2099
|
this.declarations.set(declaration.nam, declaration);
|
|
@@ -2058,7 +2127,8 @@
|
|
|
2058
2127
|
i--;
|
|
2059
2128
|
continue;
|
|
2060
2129
|
}
|
|
2061
|
-
|
|
2130
|
+
// @ts-ignore
|
|
2131
|
+
if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
|
|
2062
2132
|
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
|
|
2063
2133
|
return acc;
|
|
2064
2134
|
}
|
|
@@ -2192,10 +2262,12 @@
|
|
|
2192
2262
|
}
|
|
2193
2263
|
else {
|
|
2194
2264
|
let count = 0;
|
|
2265
|
+
let match;
|
|
2195
2266
|
const separator = this.config.separator;
|
|
2196
2267
|
const tokens = {};
|
|
2197
2268
|
// @ts-ignore
|
|
2198
|
-
/* const valid: string[] =*/
|
|
2269
|
+
/* const valid: string[] =*/
|
|
2270
|
+
Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2199
2271
|
if (!this.declarations.has(curr[0])) {
|
|
2200
2272
|
if (curr[1].required) {
|
|
2201
2273
|
acc.push(curr[0]);
|
|
@@ -2204,33 +2276,40 @@
|
|
|
2204
2276
|
}
|
|
2205
2277
|
let current = 0;
|
|
2206
2278
|
const props = this.config.properties[curr[0]];
|
|
2207
|
-
const
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
tokens[curr[0]].
|
|
2279
|
+
const properties = this.declarations.get(curr[0]);
|
|
2280
|
+
for (const declaration of [(properties instanceof PropertySet ? [...properties][0] : properties)]) {
|
|
2281
|
+
// @ts-ignore
|
|
2282
|
+
for (const val of declaration.val) {
|
|
2283
|
+
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
|
|
2284
|
+
current++;
|
|
2285
|
+
if (tokens[curr[0]].length == current) {
|
|
2286
|
+
tokens[curr[0]].push([]);
|
|
2287
|
+
}
|
|
2288
|
+
continue;
|
|
2214
2289
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2290
|
+
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2291
|
+
continue;
|
|
2292
|
+
}
|
|
2293
|
+
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
|
|
2294
|
+
continue;
|
|
2295
|
+
}
|
|
2296
|
+
// @ts-ignore
|
|
2297
|
+
match = val.typ == 'Comment' || matchType(val, curr[1]);
|
|
2298
|
+
if (isShorthand) {
|
|
2299
|
+
isShorthand = match;
|
|
2300
|
+
}
|
|
2301
|
+
// @ts-ignore
|
|
2302
|
+
if (('propertyName' in val && val.propertyName == property) || match) {
|
|
2303
|
+
if (!(curr[0] in tokens)) {
|
|
2304
|
+
tokens[curr[0]] = [[]];
|
|
2305
|
+
}
|
|
2306
|
+
// is default value
|
|
2307
|
+
tokens[curr[0]][current].push(val);
|
|
2308
|
+
}
|
|
2309
|
+
else {
|
|
2310
|
+
acc.push(curr[0]);
|
|
2311
|
+
break;
|
|
2226
2312
|
}
|
|
2227
|
-
// is default value
|
|
2228
|
-
tokens[curr[0]][current].push(val);
|
|
2229
|
-
// continue;
|
|
2230
|
-
}
|
|
2231
|
-
else {
|
|
2232
|
-
acc.push(curr[0]);
|
|
2233
|
-
break;
|
|
2234
2313
|
}
|
|
2235
2314
|
}
|
|
2236
2315
|
if (count == 0) {
|
|
@@ -2239,7 +2318,12 @@
|
|
|
2239
2318
|
return acc;
|
|
2240
2319
|
}, []);
|
|
2241
2320
|
count++;
|
|
2242
|
-
if (!Object.
|
|
2321
|
+
if (!isShorthand || Object.entries(this.config.properties).some(entry => {
|
|
2322
|
+
// missing required property
|
|
2323
|
+
return entry[1].required && !(entry[0] in tokens);
|
|
2324
|
+
}) ||
|
|
2325
|
+
// @ts-ignore
|
|
2326
|
+
!Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
|
|
2243
2327
|
// @ts-ignore
|
|
2244
2328
|
iterable = this.declarations.values();
|
|
2245
2329
|
}
|
|
@@ -2792,6 +2876,17 @@
|
|
|
2792
2876
|
continue;
|
|
2793
2877
|
// }
|
|
2794
2878
|
}
|
|
2879
|
+
// @ts-ignore
|
|
2880
|
+
if (hasDeclaration(node)) {
|
|
2881
|
+
// @ts-ignore
|
|
2882
|
+
minifyRule(node);
|
|
2883
|
+
}
|
|
2884
|
+
else {
|
|
2885
|
+
minify(node, options, recursive);
|
|
2886
|
+
}
|
|
2887
|
+
previous = node;
|
|
2888
|
+
nodeIndex = i;
|
|
2889
|
+
continue;
|
|
2795
2890
|
}
|
|
2796
2891
|
// @ts-ignore
|
|
2797
2892
|
if (node.typ == 'Rule') {
|
|
@@ -3306,11 +3401,6 @@
|
|
|
3306
3401
|
}
|
|
3307
3402
|
buffer += quoteStr;
|
|
3308
3403
|
while (value = peek()) {
|
|
3309
|
-
// if (ind >= iterator.length) {
|
|
3310
|
-
//
|
|
3311
|
-
// yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
3312
|
-
// break;
|
|
3313
|
-
// }
|
|
3314
3404
|
if (value == '\\') {
|
|
3315
3405
|
const sequence = peek(6);
|
|
3316
3406
|
let escapeSequence = '';
|
|
@@ -3330,9 +3420,23 @@
|
|
|
3330
3420
|
}
|
|
3331
3421
|
break;
|
|
3332
3422
|
}
|
|
3423
|
+
// @ts-ignore
|
|
3424
|
+
if (isNewLine(codepoint)) {
|
|
3425
|
+
if (i == 1) {
|
|
3426
|
+
buffer += value + escapeSequence.slice(0, i);
|
|
3427
|
+
next(i + 1);
|
|
3428
|
+
continue;
|
|
3429
|
+
}
|
|
3430
|
+
// else {
|
|
3431
|
+
yield pushToken(buffer + value + escapeSequence.slice(0, i), 'Bad-string');
|
|
3432
|
+
buffer = '';
|
|
3433
|
+
// }
|
|
3434
|
+
next(i + 1);
|
|
3435
|
+
break;
|
|
3436
|
+
}
|
|
3333
3437
|
// not hex or new line
|
|
3334
3438
|
// @ts-ignore
|
|
3335
|
-
if (i == 1
|
|
3439
|
+
else if (i == 1) {
|
|
3336
3440
|
buffer += value + sequence[i];
|
|
3337
3441
|
next(2);
|
|
3338
3442
|
continue;
|
|
@@ -3352,13 +3456,6 @@
|
|
|
3352
3456
|
next(escapeSequence.length + 1);
|
|
3353
3457
|
continue;
|
|
3354
3458
|
}
|
|
3355
|
-
// buffer += value;
|
|
3356
|
-
// if (ind >= iterator.length) {
|
|
3357
|
-
//
|
|
3358
|
-
// // drop '\\' at the end
|
|
3359
|
-
// yield pushToken(buffer);
|
|
3360
|
-
// break;
|
|
3361
|
-
// }
|
|
3362
3459
|
buffer += next(2);
|
|
3363
3460
|
continue;
|
|
3364
3461
|
}
|
|
@@ -3368,20 +3465,28 @@
|
|
|
3368
3465
|
next();
|
|
3369
3466
|
// i += value.length;
|
|
3370
3467
|
buffer = '';
|
|
3371
|
-
|
|
3468
|
+
return;
|
|
3372
3469
|
}
|
|
3373
3470
|
if (isNewLine(value.charCodeAt(0))) {
|
|
3374
3471
|
hasNewLine = true;
|
|
3375
3472
|
}
|
|
3376
3473
|
if (hasNewLine && value == ';') {
|
|
3377
|
-
yield pushToken(buffer, 'Bad-string');
|
|
3474
|
+
yield pushToken(buffer + value, 'Bad-string');
|
|
3378
3475
|
buffer = '';
|
|
3476
|
+
next();
|
|
3379
3477
|
break;
|
|
3380
3478
|
}
|
|
3381
3479
|
buffer += value;
|
|
3382
|
-
// i += value.length;
|
|
3383
3480
|
next();
|
|
3384
3481
|
}
|
|
3482
|
+
if (hasNewLine) {
|
|
3483
|
+
yield pushToken(buffer, 'Bad-string');
|
|
3484
|
+
}
|
|
3485
|
+
else {
|
|
3486
|
+
// EOF - 'Unclosed-string' fixed
|
|
3487
|
+
yield pushToken(buffer + quote, 'String');
|
|
3488
|
+
}
|
|
3489
|
+
buffer = '';
|
|
3385
3490
|
}
|
|
3386
3491
|
function peek(count = 1) {
|
|
3387
3492
|
if (count == 1) {
|
|
@@ -3495,6 +3600,11 @@
|
|
|
3495
3600
|
yield pushToken(buffer);
|
|
3496
3601
|
buffer = '';
|
|
3497
3602
|
}
|
|
3603
|
+
if (peek() == '=') {
|
|
3604
|
+
yield pushToken('', 'Lte');
|
|
3605
|
+
next();
|
|
3606
|
+
break;
|
|
3607
|
+
}
|
|
3498
3608
|
buffer += value;
|
|
3499
3609
|
value = next();
|
|
3500
3610
|
if (ind >= iterator.length) {
|
|
@@ -3563,7 +3673,13 @@
|
|
|
3563
3673
|
yield pushToken(buffer);
|
|
3564
3674
|
buffer = '';
|
|
3565
3675
|
}
|
|
3566
|
-
|
|
3676
|
+
if (peek() == '=') {
|
|
3677
|
+
yield pushToken('', 'Gte');
|
|
3678
|
+
next();
|
|
3679
|
+
}
|
|
3680
|
+
else {
|
|
3681
|
+
yield pushToken('', 'Gt');
|
|
3682
|
+
}
|
|
3567
3683
|
consumeWhiteSpace();
|
|
3568
3684
|
break;
|
|
3569
3685
|
case '.':
|
|
@@ -3605,7 +3721,7 @@
|
|
|
3605
3721
|
break;
|
|
3606
3722
|
case '(':
|
|
3607
3723
|
if (buffer.length == 0) {
|
|
3608
|
-
yield pushToken(
|
|
3724
|
+
yield pushToken(value);
|
|
3609
3725
|
break;
|
|
3610
3726
|
}
|
|
3611
3727
|
buffer += value;
|
|
@@ -3719,9 +3835,11 @@
|
|
|
3719
3835
|
if (buffer.length > 0) {
|
|
3720
3836
|
yield pushToken(buffer);
|
|
3721
3837
|
}
|
|
3838
|
+
// yield pushToken('', 'EOF');
|
|
3722
3839
|
}
|
|
3723
3840
|
|
|
3724
3841
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
3842
|
+
const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
|
|
3725
3843
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
3726
3844
|
/**
|
|
3727
3845
|
*
|
|
@@ -3768,6 +3886,10 @@
|
|
|
3768
3886
|
let tokens = results.map(mapToken);
|
|
3769
3887
|
let i;
|
|
3770
3888
|
let loc;
|
|
3889
|
+
// if ((<Token>tokens.at(-1))?.typ == 'EOF') {
|
|
3890
|
+
//
|
|
3891
|
+
// tokens.pop();
|
|
3892
|
+
// }
|
|
3771
3893
|
for (i = 0; i < tokens.length; i++) {
|
|
3772
3894
|
if (tokens[i].typ == 'Comment') {
|
|
3773
3895
|
// @ts-ignore
|
|
@@ -3886,7 +4008,7 @@
|
|
|
3886
4008
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
3887
4009
|
// allowed nesting at-rules
|
|
3888
4010
|
// there must be a top level rule in the stack
|
|
3889
|
-
const raw = tokens.reduce((acc, curr) => {
|
|
4011
|
+
const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
|
|
3890
4012
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
3891
4013
|
return acc;
|
|
3892
4014
|
}, []);
|
|
@@ -3917,8 +4039,8 @@
|
|
|
3917
4039
|
const uniq = new Map;
|
|
3918
4040
|
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
3919
4041
|
if (curr.typ == 'Whitespace') {
|
|
3920
|
-
if (array[index - 1]?.typ
|
|
3921
|
-
array[index + 1]?.typ
|
|
4042
|
+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
4043
|
+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
3922
4044
|
combinators.includes(array[index - 1]?.val) ||
|
|
3923
4045
|
combinators.includes(array[index + 1]?.val)) {
|
|
3924
4046
|
return acc;
|
|
@@ -4106,13 +4228,13 @@
|
|
|
4106
4228
|
};
|
|
4107
4229
|
}
|
|
4108
4230
|
function parseString(src, options = { location: false }) {
|
|
4109
|
-
return [...tokenize(src)].map(t => {
|
|
4231
|
+
return parseTokens([...tokenize(src)].map(t => {
|
|
4110
4232
|
const token = getTokenType(t.token, t.hint);
|
|
4111
4233
|
if (options.location) {
|
|
4112
4234
|
Object.assign(token, { loc: t.position });
|
|
4113
4235
|
}
|
|
4114
4236
|
return token;
|
|
4115
|
-
});
|
|
4237
|
+
}));
|
|
4116
4238
|
}
|
|
4117
4239
|
function getTokenType(val, hint) {
|
|
4118
4240
|
if (val === '' && hint == null) {
|
|
@@ -4122,7 +4244,7 @@
|
|
|
4122
4244
|
return ([
|
|
4123
4245
|
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
4124
4246
|
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
4125
|
-
'Comma', 'Gt', 'Lt'
|
|
4247
|
+
'Comma', 'Gt', 'Lt', 'Gte', 'Lte', 'EOF'
|
|
4126
4248
|
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
4127
4249
|
}
|
|
4128
4250
|
if (val == ' ') {
|
|
@@ -4250,11 +4372,12 @@
|
|
|
4250
4372
|
const t = tokens[i];
|
|
4251
4373
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
4252
4374
|
i + 1 == tokens.length ||
|
|
4253
|
-
['Comma'].includes(tokens[i + 1].typ) ||
|
|
4375
|
+
['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
|
|
4254
4376
|
(i > 0 &&
|
|
4255
|
-
tokens[i + 1]?.typ != 'Literal'
|
|
4256
|
-
funcLike.includes(tokens[i - 1].typ) &&
|
|
4257
|
-
!['var', 'calc'].includes(tokens[i - 1].val))))
|
|
4377
|
+
// tokens[i + 1]?.typ != 'Literal' ||
|
|
4378
|
+
// funcLike.includes(tokens[i - 1].typ) &&
|
|
4379
|
+
// !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
|
|
4380
|
+
trimWhiteSpace.includes(tokens[i - 1].typ)))) {
|
|
4258
4381
|
tokens.splice(i--, 1);
|
|
4259
4382
|
continue;
|
|
4260
4383
|
}
|
|
@@ -4371,7 +4494,7 @@
|
|
|
4371
4494
|
let m = t.chi.length;
|
|
4372
4495
|
while (m-- > 0) {
|
|
4373
4496
|
// @ts-ignore
|
|
4374
|
-
if (t.chi[m].typ
|
|
4497
|
+
if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
|
|
4375
4498
|
// @ts-ignore
|
|
4376
4499
|
if (t.chi[m + 1]?.typ == 'Whitespace') {
|
|
4377
4500
|
// @ts-ignore
|
|
@@ -4623,6 +4746,7 @@
|
|
|
4623
4746
|
exports.isTime = isTime;
|
|
4624
4747
|
exports.isWhiteSpace = isWhiteSpace;
|
|
4625
4748
|
exports.load = load;
|
|
4749
|
+
exports.matchType = matchType;
|
|
4626
4750
|
exports.matchUrl = matchUrl;
|
|
4627
4751
|
exports.minify = minify;
|
|
4628
4752
|
exports.minifyRule = minifyRule;
|