@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.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';
|
|
@@ -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 == '
|
|
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
|
-
|
|
1576
|
-
|
|
1577
|
-
if (
|
|
1578
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 (
|
|
1828
|
+
if (unit == 'Time') {
|
|
1742
1829
|
return '0s';
|
|
1743
1830
|
}
|
|
1744
|
-
if (
|
|
1831
|
+
if (unit == 'Frequency') {
|
|
1745
1832
|
return '0Hz';
|
|
1746
1833
|
}
|
|
1747
1834
|
// @ts-ignore
|
|
1748
|
-
if (
|
|
1835
|
+
if (unit == 'Resolution') {
|
|
1749
1836
|
return '0x';
|
|
1750
1837
|
}
|
|
1751
1838
|
return '0';
|
|
1752
1839
|
}
|
|
1753
|
-
|
|
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
|
-
|
|
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[] =*/
|
|
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
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
tokens[curr[0]].
|
|
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
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
3919
|
-
array[index + 1]?.typ
|
|
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
|
|
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;
|