@tbela99/css-parser 0.0.1-alpha5 → 0.0.1-rc1
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/.gitattributes +1 -0
- package/README.md +18 -6
- package/dist/config.json.js +95 -4
- package/dist/index-umd-web.js +1609 -1391
- package/dist/index.cjs +1609 -1391
- package/dist/index.d.ts +317 -9
- package/dist/index.js +6 -2
- package/dist/lib/{parser/deduplicate.js → ast/minify.js} +393 -414
- package/dist/lib/parser/declaration/list.js +38 -9
- package/dist/lib/parser/declaration/map.js +203 -145
- package/dist/lib/parser/declaration/set.js +26 -34
- package/dist/lib/parser/parse.js +237 -683
- package/dist/lib/parser/tokenize.js +452 -0
- package/dist/lib/parser/utils/eq.js +29 -5
- package/dist/lib/parser/utils/syntax.js +24 -7
- package/dist/lib/renderer/render.js +9 -6
- package/dist/lib/transform.js +1 -1
- package/dist/node/index.js +1 -0
- package/dist/web/index.js +6 -2
- package/package.json +11 -5
- /package/dist/lib/{walker → ast}/walk.js +0 -0
package/dist/index-umd-web.js
CHANGED
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
9
9
|
// '\\'
|
|
10
10
|
const REVERSE_SOLIDUS = 0x5c;
|
|
11
|
+
const dimensionUnits = [
|
|
12
|
+
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
13
|
+
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
14
|
+
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
15
|
+
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
16
|
+
];
|
|
11
17
|
function isLength(dimension) {
|
|
12
|
-
return 'unit' in dimension &&
|
|
13
|
-
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
14
|
-
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
15
|
-
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
16
|
-
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
17
|
-
].includes(dimension.unit.toLowerCase());
|
|
18
|
+
return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
|
|
18
19
|
}
|
|
19
20
|
function isResolution(dimension) {
|
|
20
21
|
return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
|
|
@@ -239,6 +240,22 @@
|
|
|
239
240
|
}
|
|
240
241
|
return true;
|
|
241
242
|
}
|
|
243
|
+
function isHexDigit(name) {
|
|
244
|
+
if (name.length || name.length > 6) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
for (let chr of name) {
|
|
248
|
+
let codepoint = chr.charCodeAt(0);
|
|
249
|
+
if (!isDigit(codepoint) &&
|
|
250
|
+
// A F
|
|
251
|
+
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
252
|
+
// a f
|
|
253
|
+
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
242
259
|
function isFunction(name) {
|
|
243
260
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
244
261
|
}
|
|
@@ -374,6 +391,7 @@
|
|
|
374
391
|
},
|
|
375
392
|
"border-width": {
|
|
376
393
|
shorthand: "border-width",
|
|
394
|
+
map: "border",
|
|
377
395
|
properties: [
|
|
378
396
|
"border-top-width",
|
|
379
397
|
"border-right-width",
|
|
@@ -384,6 +402,9 @@
|
|
|
384
402
|
"Length",
|
|
385
403
|
"Perc"
|
|
386
404
|
],
|
|
405
|
+
"default": [
|
|
406
|
+
"medium"
|
|
407
|
+
],
|
|
387
408
|
keywords: [
|
|
388
409
|
"thin",
|
|
389
410
|
"medium",
|
|
@@ -391,19 +412,24 @@
|
|
|
391
412
|
]
|
|
392
413
|
},
|
|
393
414
|
"border-top-width": {
|
|
415
|
+
map: "border",
|
|
394
416
|
shorthand: "border-width"
|
|
395
417
|
},
|
|
396
418
|
"border-right-width": {
|
|
419
|
+
map: "border",
|
|
397
420
|
shorthand: "border-width"
|
|
398
421
|
},
|
|
399
422
|
"border-bottom-width": {
|
|
423
|
+
map: "border",
|
|
400
424
|
shorthand: "border-width"
|
|
401
425
|
},
|
|
402
426
|
"border-left-width": {
|
|
427
|
+
map: "border",
|
|
403
428
|
shorthand: "border-width"
|
|
404
429
|
},
|
|
405
430
|
"border-style": {
|
|
406
431
|
shorthand: "border-style",
|
|
432
|
+
map: "border",
|
|
407
433
|
properties: [
|
|
408
434
|
"border-top-style",
|
|
409
435
|
"border-right-style",
|
|
@@ -412,6 +438,9 @@
|
|
|
412
438
|
],
|
|
413
439
|
types: [
|
|
414
440
|
],
|
|
441
|
+
"default": [
|
|
442
|
+
"none"
|
|
443
|
+
],
|
|
415
444
|
keywords: [
|
|
416
445
|
"none",
|
|
417
446
|
"hidden",
|
|
@@ -426,19 +455,24 @@
|
|
|
426
455
|
]
|
|
427
456
|
},
|
|
428
457
|
"border-top-style": {
|
|
458
|
+
map: "border",
|
|
429
459
|
shorthand: "border-style"
|
|
430
460
|
},
|
|
431
461
|
"border-right-style": {
|
|
462
|
+
map: "border",
|
|
432
463
|
shorthand: "border-style"
|
|
433
464
|
},
|
|
434
465
|
"border-bottom-style": {
|
|
466
|
+
map: "border",
|
|
435
467
|
shorthand: "border-style"
|
|
436
468
|
},
|
|
437
469
|
"border-left-style": {
|
|
470
|
+
map: "border",
|
|
438
471
|
shorthand: "border-style"
|
|
439
472
|
},
|
|
440
473
|
"border-color": {
|
|
441
474
|
shorthand: "border-color",
|
|
475
|
+
map: "border",
|
|
442
476
|
properties: [
|
|
443
477
|
"border-top-color",
|
|
444
478
|
"border-right-color",
|
|
@@ -448,23 +482,95 @@
|
|
|
448
482
|
types: [
|
|
449
483
|
"Color"
|
|
450
484
|
],
|
|
485
|
+
"default": [
|
|
486
|
+
"currentcolor"
|
|
487
|
+
],
|
|
451
488
|
keywords: [
|
|
452
489
|
]
|
|
453
490
|
},
|
|
454
491
|
"border-top-color": {
|
|
492
|
+
map: "border",
|
|
455
493
|
shorthand: "border-color"
|
|
456
494
|
},
|
|
457
495
|
"border-right-color": {
|
|
496
|
+
map: "border",
|
|
458
497
|
shorthand: "border-color"
|
|
459
498
|
},
|
|
460
499
|
"border-bottom-color": {
|
|
500
|
+
map: "border",
|
|
461
501
|
shorthand: "border-color"
|
|
462
502
|
},
|
|
463
503
|
"border-left-color": {
|
|
504
|
+
map: "border",
|
|
464
505
|
shorthand: "border-color"
|
|
465
506
|
}
|
|
466
507
|
};
|
|
467
508
|
var map = {
|
|
509
|
+
border: {
|
|
510
|
+
shorthand: "border",
|
|
511
|
+
pattern: "border-color border-style border-width",
|
|
512
|
+
keywords: [
|
|
513
|
+
"none"
|
|
514
|
+
],
|
|
515
|
+
"default": [
|
|
516
|
+
"0",
|
|
517
|
+
"none"
|
|
518
|
+
],
|
|
519
|
+
properties: {
|
|
520
|
+
"border-color": {
|
|
521
|
+
types: [
|
|
522
|
+
"Color"
|
|
523
|
+
],
|
|
524
|
+
"default": [
|
|
525
|
+
"currentcolor"
|
|
526
|
+
],
|
|
527
|
+
keywords: [
|
|
528
|
+
]
|
|
529
|
+
},
|
|
530
|
+
"border-style": {
|
|
531
|
+
types: [
|
|
532
|
+
],
|
|
533
|
+
"default": [
|
|
534
|
+
"none"
|
|
535
|
+
],
|
|
536
|
+
keywords: [
|
|
537
|
+
"none",
|
|
538
|
+
"hidden",
|
|
539
|
+
"dotted",
|
|
540
|
+
"dashed",
|
|
541
|
+
"solid",
|
|
542
|
+
"double",
|
|
543
|
+
"groove",
|
|
544
|
+
"ridge",
|
|
545
|
+
"inset",
|
|
546
|
+
"outset"
|
|
547
|
+
]
|
|
548
|
+
},
|
|
549
|
+
"border-width": {
|
|
550
|
+
types: [
|
|
551
|
+
"Length",
|
|
552
|
+
"Perc"
|
|
553
|
+
],
|
|
554
|
+
"default": [
|
|
555
|
+
"medium"
|
|
556
|
+
],
|
|
557
|
+
keywords: [
|
|
558
|
+
"thin",
|
|
559
|
+
"medium",
|
|
560
|
+
"thick"
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
"border-color": {
|
|
566
|
+
shorthand: "border"
|
|
567
|
+
},
|
|
568
|
+
"border-style": {
|
|
569
|
+
shorthand: "border"
|
|
570
|
+
},
|
|
571
|
+
"border-width": {
|
|
572
|
+
shorthand: "border"
|
|
573
|
+
},
|
|
468
574
|
outline: {
|
|
469
575
|
shorthand: "outline",
|
|
470
576
|
pattern: "outline-color outline-style outline-width",
|
|
@@ -481,12 +587,10 @@
|
|
|
481
587
|
"Color"
|
|
482
588
|
],
|
|
483
589
|
"default": [
|
|
484
|
-
"currentColor"
|
|
485
|
-
"invert"
|
|
590
|
+
"currentColor"
|
|
486
591
|
],
|
|
487
592
|
keywords: [
|
|
488
|
-
"currentColor"
|
|
489
|
-
"invert"
|
|
593
|
+
"currentColor"
|
|
490
594
|
]
|
|
491
595
|
},
|
|
492
596
|
"outline-style": {
|
|
@@ -824,6 +928,7 @@
|
|
|
824
928
|
"default": [
|
|
825
929
|
"transparent"
|
|
826
930
|
],
|
|
931
|
+
multiple: true,
|
|
827
932
|
keywords: [
|
|
828
933
|
]
|
|
829
934
|
},
|
|
@@ -844,6 +949,7 @@
|
|
|
844
949
|
"default": [
|
|
845
950
|
"scroll"
|
|
846
951
|
],
|
|
952
|
+
multiple: true,
|
|
847
953
|
keywords: [
|
|
848
954
|
"scroll",
|
|
849
955
|
"fixed",
|
|
@@ -856,6 +962,7 @@
|
|
|
856
962
|
"default": [
|
|
857
963
|
"border-box"
|
|
858
964
|
],
|
|
965
|
+
multiple: true,
|
|
859
966
|
keywords: [
|
|
860
967
|
"border-box",
|
|
861
968
|
"padding-box",
|
|
@@ -869,6 +976,7 @@
|
|
|
869
976
|
"default": [
|
|
870
977
|
"padding-box"
|
|
871
978
|
],
|
|
979
|
+
multiple: true,
|
|
872
980
|
keywords: [
|
|
873
981
|
"border-box",
|
|
874
982
|
"padding-box",
|
|
@@ -1458,7 +1566,7 @@
|
|
|
1458
1566
|
}
|
|
1459
1567
|
|
|
1460
1568
|
function render(data, opt = {}) {
|
|
1461
|
-
const options = Object.assign(opt.
|
|
1569
|
+
const options = Object.assign(opt.minify ?? true ? {
|
|
1462
1570
|
indent: '',
|
|
1463
1571
|
newLine: '',
|
|
1464
1572
|
removeComments: true
|
|
@@ -1543,8 +1651,11 @@
|
|
|
1543
1651
|
function renderToken(token, options = {}) {
|
|
1544
1652
|
switch (token.typ) {
|
|
1545
1653
|
case 'Color':
|
|
1546
|
-
if (options.
|
|
1547
|
-
|
|
1654
|
+
if (options.minify || options.colorConvert) {
|
|
1655
|
+
if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
|
|
1656
|
+
return 'currentcolor';
|
|
1657
|
+
}
|
|
1658
|
+
let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
|
|
1548
1659
|
if (token.val == 'rgb' || token.val == 'rgba') {
|
|
1549
1660
|
value = rgb2Hex(token);
|
|
1550
1661
|
}
|
|
@@ -1588,7 +1699,7 @@
|
|
|
1588
1699
|
case 'UrlFunc':
|
|
1589
1700
|
case 'Pseudo-class-func':
|
|
1590
1701
|
// @ts-ignore
|
|
1591
|
-
return ( /* options.
|
|
1702
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
|
|
1592
1703
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
1593
1704
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1594
1705
|
return acc;
|
|
@@ -1679,21 +1790,45 @@
|
|
|
1679
1790
|
case 'String':
|
|
1680
1791
|
case 'Iden':
|
|
1681
1792
|
case 'Delim':
|
|
1682
|
-
return /* options.
|
|
1793
|
+
return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
1683
1794
|
}
|
|
1684
1795
|
throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
1685
1796
|
}
|
|
1686
1797
|
|
|
1687
1798
|
function eq(a, b) {
|
|
1688
|
-
if (
|
|
1799
|
+
if (a == null || b == null) {
|
|
1800
|
+
return a == b;
|
|
1801
|
+
}
|
|
1802
|
+
if (typeof a != 'object' || typeof b != 'object') {
|
|
1689
1803
|
return a === b;
|
|
1690
1804
|
}
|
|
1805
|
+
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) {
|
|
1806
|
+
return false;
|
|
1807
|
+
}
|
|
1808
|
+
if (Array.isArray(a)) {
|
|
1809
|
+
if (a.length != b.length) {
|
|
1810
|
+
return false;
|
|
1811
|
+
}
|
|
1812
|
+
let i = 0;
|
|
1813
|
+
for (; i < a.length; i++) {
|
|
1814
|
+
if (!eq(a[i], b[i])) {
|
|
1815
|
+
return false;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
return true;
|
|
1819
|
+
}
|
|
1691
1820
|
const k1 = Object.keys(a);
|
|
1692
1821
|
const k2 = Object.keys(b);
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1822
|
+
if (k1.length != k2.length) {
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
let key;
|
|
1826
|
+
for (key of k1) {
|
|
1827
|
+
if (!eq(a[key], b[key])) {
|
|
1828
|
+
return false;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return true;
|
|
1697
1832
|
}
|
|
1698
1833
|
|
|
1699
1834
|
class PropertySet {
|
|
@@ -1705,8 +1840,7 @@
|
|
|
1705
1840
|
}
|
|
1706
1841
|
add(declaration) {
|
|
1707
1842
|
if (declaration.nam == this.config.shorthand) {
|
|
1708
|
-
this.declarations
|
|
1709
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1843
|
+
this.declarations = new Map;
|
|
1710
1844
|
}
|
|
1711
1845
|
else {
|
|
1712
1846
|
// expand shorthand
|
|
@@ -1729,6 +1863,10 @@
|
|
|
1729
1863
|
}
|
|
1730
1864
|
if (token.typ != 'Whitespace' && token.typ != 'Comment') {
|
|
1731
1865
|
if (token.typ == 'Iden' && this.config.keywords.includes(token.val)) {
|
|
1866
|
+
if (tokens.length == 0) {
|
|
1867
|
+
tokens.push([]);
|
|
1868
|
+
current++;
|
|
1869
|
+
}
|
|
1732
1870
|
tokens[current].push(token);
|
|
1733
1871
|
}
|
|
1734
1872
|
if (token.typ == 'Literal' && token.val == this.config.separator) {
|
|
@@ -1744,10 +1882,6 @@
|
|
|
1744
1882
|
this.declarations.delete(this.config.shorthand);
|
|
1745
1883
|
for (const values of tokens) {
|
|
1746
1884
|
this.config.properties.forEach((property, index) => {
|
|
1747
|
-
// if (property == declaration.nam) {
|
|
1748
|
-
//
|
|
1749
|
-
// return;
|
|
1750
|
-
// }
|
|
1751
1885
|
if (!this.declarations.has(property)) {
|
|
1752
1886
|
this.declarations.set(property, {
|
|
1753
1887
|
typ: 'Declaration',
|
|
@@ -1776,30 +1910,20 @@
|
|
|
1776
1910
|
this.declarations.set(declaration.nam, declaration);
|
|
1777
1911
|
return this;
|
|
1778
1912
|
}
|
|
1779
|
-
// declaration.chi = declaration.chi.reduce((acc: Token[], token: Token) => {
|
|
1780
|
-
//
|
|
1781
|
-
// if (this.config.types.includes(token.typ) || ('0' == (<DimensionToken>token).chi && (
|
|
1782
|
-
// this.config.types.includes('Length') ||
|
|
1783
|
-
// this.config.types.includes('Angle') ||
|
|
1784
|
-
// this.config.types.includes('Dimension'))) || (token.typ == 'Iden' && this.config.keywords.includes(token.chi))) {
|
|
1785
|
-
//
|
|
1786
|
-
// acc.push(token);
|
|
1787
|
-
// }
|
|
1788
|
-
//
|
|
1789
|
-
// return acc;
|
|
1790
|
-
// }, <Token[]>[]);
|
|
1791
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1792
1913
|
}
|
|
1914
|
+
this.declarations.set(declaration.nam, declaration);
|
|
1793
1915
|
return this;
|
|
1794
1916
|
}
|
|
1917
|
+
isShortHand() {
|
|
1918
|
+
if (this.declarations.has(this.config.shorthand)) {
|
|
1919
|
+
return this.declarations.size == 1;
|
|
1920
|
+
}
|
|
1921
|
+
return this.config.properties.length == this.declarations.size;
|
|
1922
|
+
}
|
|
1795
1923
|
[Symbol.iterator]() {
|
|
1796
1924
|
let iterator;
|
|
1797
1925
|
const declarations = this.declarations;
|
|
1798
|
-
if (declarations.size < this.config.properties.length
|
|
1799
|
-
return !declarations.has(property) || (index > 0 &&
|
|
1800
|
-
// @ts-ignore
|
|
1801
|
-
declarations.get(property).val.length != declarations.get(this.config.properties[Math.floor(index / 2)]).val.length);
|
|
1802
|
-
})) {
|
|
1926
|
+
if (declarations.size < this.config.properties.length) {
|
|
1803
1927
|
iterator = declarations.values();
|
|
1804
1928
|
}
|
|
1805
1929
|
else {
|
|
@@ -1857,17 +1981,20 @@
|
|
|
1857
1981
|
return acc;
|
|
1858
1982
|
}, [])
|
|
1859
1983
|
}][Symbol.iterator]();
|
|
1860
|
-
return {
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
}
|
|
1984
|
+
// return {
|
|
1985
|
+
// next() {
|
|
1986
|
+
//
|
|
1987
|
+
// return iterator.next();
|
|
1988
|
+
// }
|
|
1989
|
+
// }
|
|
1865
1990
|
}
|
|
1866
|
-
return
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1991
|
+
return iterator;
|
|
1992
|
+
// return {
|
|
1993
|
+
// next() {
|
|
1994
|
+
//
|
|
1995
|
+
// return iterator.next();
|
|
1996
|
+
// }
|
|
1997
|
+
// }
|
|
1871
1998
|
}
|
|
1872
1999
|
}
|
|
1873
2000
|
|
|
@@ -1882,34 +2009,7 @@
|
|
|
1882
2009
|
return false;
|
|
1883
2010
|
}
|
|
1884
2011
|
|
|
1885
|
-
|
|
1886
|
-
if (val == 'transparent' || val == 'currentcolor') {
|
|
1887
|
-
return {
|
|
1888
|
-
typ: 'Color',
|
|
1889
|
-
val,
|
|
1890
|
-
kin: 'lit'
|
|
1891
|
-
};
|
|
1892
|
-
}
|
|
1893
|
-
if (val.endsWith('%')) {
|
|
1894
|
-
return {
|
|
1895
|
-
typ: 'Perc',
|
|
1896
|
-
val: val.slice(0, -1)
|
|
1897
|
-
};
|
|
1898
|
-
}
|
|
1899
|
-
return {
|
|
1900
|
-
typ: isNumber(val) ? 'Number' : 'Iden',
|
|
1901
|
-
val
|
|
1902
|
-
};
|
|
1903
|
-
}
|
|
1904
|
-
function parseString(val) {
|
|
1905
|
-
return val.split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
1906
|
-
if (acc.length > 0) {
|
|
1907
|
-
acc.push({ typ: 'Whitespace' });
|
|
1908
|
-
}
|
|
1909
|
-
acc.push(curr);
|
|
1910
|
-
return acc;
|
|
1911
|
-
}, []);
|
|
1912
|
-
}
|
|
2012
|
+
const propertiesConfig = getConfig();
|
|
1913
2013
|
class PropertyMap {
|
|
1914
2014
|
config;
|
|
1915
2015
|
declarations;
|
|
@@ -1924,7 +2024,7 @@
|
|
|
1924
2024
|
}
|
|
1925
2025
|
add(declaration) {
|
|
1926
2026
|
if (declaration.nam == this.config.shorthand) {
|
|
1927
|
-
this.declarations
|
|
2027
|
+
this.declarations = new Map;
|
|
1928
2028
|
this.declarations.set(declaration.nam, declaration);
|
|
1929
2029
|
}
|
|
1930
2030
|
else {
|
|
@@ -2001,8 +2101,7 @@
|
|
|
2001
2101
|
const defaults = parseString(props.default[0]);
|
|
2002
2102
|
if (!(property in tokens)) {
|
|
2003
2103
|
tokens[property] = [
|
|
2004
|
-
[...defaults
|
|
2005
|
-
]
|
|
2104
|
+
[...defaults]
|
|
2006
2105
|
];
|
|
2007
2106
|
}
|
|
2008
2107
|
else {
|
|
@@ -2036,145 +2135,229 @@
|
|
|
2036
2135
|
}, new Map);
|
|
2037
2136
|
}
|
|
2038
2137
|
}
|
|
2039
|
-
|
|
2138
|
+
// @ts-ignore
|
|
2139
|
+
const config = propertiesConfig.properties[declaration.nam];
|
|
2140
|
+
let property = declaration.nam;
|
|
2141
|
+
if (config != null) {
|
|
2142
|
+
property = config.shorthand;
|
|
2143
|
+
let value = this.declarations.get(property);
|
|
2144
|
+
if (!(value instanceof PropertySet)) {
|
|
2145
|
+
// @ts-ignore
|
|
2146
|
+
this.declarations.set(property, new PropertySet(propertiesConfig.properties[config.shorthand]));
|
|
2147
|
+
// Token[]
|
|
2148
|
+
if (value != null) {
|
|
2149
|
+
// @ts-ignore
|
|
2150
|
+
this.declarations.get(property).add(value);
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
this.declarations.get(property).add(declaration);
|
|
2154
|
+
}
|
|
2155
|
+
else {
|
|
2156
|
+
this.declarations.set(declaration.nam, declaration);
|
|
2157
|
+
}
|
|
2040
2158
|
}
|
|
2041
2159
|
return this;
|
|
2042
2160
|
}
|
|
2043
2161
|
[Symbol.iterator]() {
|
|
2044
|
-
let
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
return this.declarations.values();
|
|
2054
|
-
}
|
|
2055
|
-
let count = 0;
|
|
2056
|
-
const separator = this.config.separator;
|
|
2057
|
-
const tokens = {};
|
|
2058
|
-
// @ts-ignore
|
|
2059
|
-
const valid = Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2060
|
-
if (!this.declarations.has(curr[0])) {
|
|
2061
|
-
if (curr[1].required) {
|
|
2062
|
-
acc.push(curr[0]);
|
|
2162
|
+
let iterable;
|
|
2163
|
+
let requiredCount = 0;
|
|
2164
|
+
let property;
|
|
2165
|
+
let isShorthand = true;
|
|
2166
|
+
for (property of Object.keys(this.config.properties)) {
|
|
2167
|
+
if (this.config.properties[property].required) {
|
|
2168
|
+
if (!this.declarations.has(property)) {
|
|
2169
|
+
isShorthand = false;
|
|
2170
|
+
break;
|
|
2063
2171
|
}
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
for (const val of this.declarations.get(curr[0]).val) {
|
|
2070
|
-
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
|
|
2071
|
-
current++;
|
|
2072
|
-
if (tokens[curr[0]].length == current) {
|
|
2073
|
-
tokens[curr[0]].push([]);
|
|
2172
|
+
else {
|
|
2173
|
+
const val = this.declarations.get(property);
|
|
2174
|
+
if (val instanceof PropertySet && !val.isShortHand()) {
|
|
2175
|
+
isShorthand = false;
|
|
2176
|
+
break;
|
|
2074
2177
|
}
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2078
|
-
continue;
|
|
2079
|
-
}
|
|
2080
|
-
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(val, props.separator)) {
|
|
2081
|
-
continue;
|
|
2082
|
-
}
|
|
2083
|
-
if (matchType(val, curr[1])) {
|
|
2084
|
-
if (!(curr[0] in tokens)) {
|
|
2085
|
-
tokens[curr[0]] = [[]];
|
|
2178
|
+
else {
|
|
2179
|
+
requiredCount++;
|
|
2086
2180
|
}
|
|
2087
|
-
// is default value
|
|
2088
|
-
tokens[curr[0]][current].push(val);
|
|
2089
|
-
continue;
|
|
2090
2181
|
}
|
|
2091
|
-
acc.push(curr[0]);
|
|
2092
|
-
break;
|
|
2093
2182
|
}
|
|
2094
|
-
if (count == 0) {
|
|
2095
|
-
count = current;
|
|
2096
|
-
}
|
|
2097
|
-
return acc;
|
|
2098
|
-
}, []);
|
|
2099
|
-
if (valid.length > 0 || Object.values(tokens).every(v => v.every(v => v.length == count))) {
|
|
2100
|
-
return this.declarations.values();
|
|
2101
2183
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2184
|
+
if (requiredCount == 0) {
|
|
2185
|
+
requiredCount = this.declarations.size;
|
|
2186
|
+
}
|
|
2187
|
+
if (!isShorthand || requiredCount < this.requiredCount) {
|
|
2188
|
+
// @ts-ignore
|
|
2189
|
+
iterable = this.declarations.values();
|
|
2190
|
+
}
|
|
2191
|
+
else {
|
|
2192
|
+
let count = 0;
|
|
2193
|
+
const separator = this.config.separator;
|
|
2194
|
+
const tokens = {};
|
|
2195
|
+
// @ts-ignore
|
|
2196
|
+
/* const valid: string[] =*/ Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2197
|
+
if (!this.declarations.has(curr[0])) {
|
|
2198
|
+
if (curr[1].required) {
|
|
2199
|
+
acc.push(curr[0]);
|
|
2111
2200
|
}
|
|
2112
|
-
acc.push(curr);
|
|
2113
2201
|
return acc;
|
|
2114
|
-
}, []);
|
|
2115
|
-
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
|
|
2116
|
-
continue;
|
|
2117
2202
|
}
|
|
2118
|
-
|
|
2203
|
+
let current = 0;
|
|
2204
|
+
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([]);
|
|
2212
|
+
}
|
|
2213
|
+
continue;
|
|
2214
|
+
}
|
|
2119
2215
|
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2120
|
-
|
|
2216
|
+
continue;
|
|
2121
2217
|
}
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
if (
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
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]] = [[]];
|
|
2224
|
+
}
|
|
2225
|
+
// is default value
|
|
2226
|
+
tokens[curr[0]][current].push(val);
|
|
2227
|
+
// continue;
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
acc.push(curr[0]);
|
|
2231
|
+
break;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
if (count == 0) {
|
|
2235
|
+
count = current;
|
|
2236
|
+
}
|
|
2237
|
+
return acc;
|
|
2238
|
+
}, []);
|
|
2239
|
+
count++;
|
|
2240
|
+
if (!Object.values(tokens).every(v => v.length == count)) {
|
|
2241
|
+
// @ts-ignore
|
|
2242
|
+
iterable = this.declarations.values();
|
|
2243
|
+
}
|
|
2244
|
+
else {
|
|
2245
|
+
const values = Object.entries(tokens).reduce((acc, curr) => {
|
|
2246
|
+
const props = this.config.properties[curr[0]];
|
|
2247
|
+
for (let i = 0; i < curr[1].length; i++) {
|
|
2248
|
+
if (acc.length == i) {
|
|
2249
|
+
acc.push([]);
|
|
2250
|
+
}
|
|
2251
|
+
let values = curr[1][i].reduce((acc, curr) => {
|
|
2252
|
+
if (acc.length > 0) {
|
|
2253
|
+
acc.push({ typ: 'Whitespace' });
|
|
2254
|
+
}
|
|
2255
|
+
acc.push(curr);
|
|
2256
|
+
return acc;
|
|
2257
|
+
}, []);
|
|
2258
|
+
// @todo remove renderToken call
|
|
2259
|
+
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
|
|
2260
|
+
continue;
|
|
2261
|
+
}
|
|
2262
|
+
let doFilterDefault = true;
|
|
2263
|
+
if (curr[0] in propertiesConfig.properties) {
|
|
2264
|
+
for (let v of values) {
|
|
2265
|
+
if (!['Whitespace', 'Comment', 'Iden'].includes(v.typ)
|
|
2266
|
+
|| (v.typ == 'Iden' && !this.config.properties[curr[0]].default.includes(v.val))) {
|
|
2267
|
+
doFilterDefault = false;
|
|
2268
|
+
break;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
// remove default values
|
|
2273
|
+
values = values.filter((val) => {
|
|
2274
|
+
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2275
|
+
return false;
|
|
2276
|
+
}
|
|
2277
|
+
return !doFilterDefault || !(val.typ == 'Iden' && props.default.includes(val.val));
|
|
2278
|
+
});
|
|
2279
|
+
if (values.length > 0) {
|
|
2280
|
+
if ('mapping' in props) {
|
|
2130
2281
|
// @ts-ignore
|
|
2131
|
-
if (
|
|
2132
|
-
|
|
2133
|
-
|
|
2282
|
+
if (!('constraints' in props) || !('max' in props.constraints) || values.length <= props.constraints.mapping.max) {
|
|
2283
|
+
let i = values.length;
|
|
2284
|
+
while (i--) {
|
|
2285
|
+
// @ts-ignore
|
|
2286
|
+
if (values[i].typ == 'Iden' && values[i].val in props.mapping) {
|
|
2287
|
+
// @ts-ignore
|
|
2288
|
+
values.splice(i, 1, ...parseString(props.mapping[values[i].val]));
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2134
2291
|
}
|
|
2135
2292
|
}
|
|
2293
|
+
if ('prefix' in props) {
|
|
2294
|
+
// @ts-ignore
|
|
2295
|
+
acc[i].push({ ...props.prefix });
|
|
2296
|
+
}
|
|
2297
|
+
else if (acc[i].length > 0) {
|
|
2298
|
+
acc[i].push({ typ: 'Whitespace' });
|
|
2299
|
+
}
|
|
2300
|
+
acc[i].push(...values.reduce((acc, curr) => {
|
|
2301
|
+
if (acc.length > 0) {
|
|
2302
|
+
// @ts-ignore
|
|
2303
|
+
acc.push({ ...(props.separator ?? { typ: 'Whitespace' }) });
|
|
2304
|
+
}
|
|
2305
|
+
// @ts-ignore
|
|
2306
|
+
acc.push(curr);
|
|
2307
|
+
return acc;
|
|
2308
|
+
}, []));
|
|
2136
2309
|
}
|
|
2137
2310
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2311
|
+
return acc;
|
|
2312
|
+
}, []).reduce((acc, curr) => {
|
|
2313
|
+
if (acc.length > 0) {
|
|
2314
|
+
acc.push({ ...separator });
|
|
2141
2315
|
}
|
|
2142
|
-
|
|
2143
|
-
|
|
2316
|
+
if (curr.length == 0 && this.config.default.length > 0) {
|
|
2317
|
+
curr.push(...parseString(this.config.default[0]).reduce((acc, curr) => {
|
|
2318
|
+
if (acc.length > 0) {
|
|
2319
|
+
acc.push({ typ: 'Whitespace' });
|
|
2320
|
+
}
|
|
2321
|
+
acc.push(curr);
|
|
2322
|
+
return acc;
|
|
2323
|
+
}, []));
|
|
2144
2324
|
}
|
|
2145
|
-
acc
|
|
2146
|
-
|
|
2325
|
+
acc.push(...curr);
|
|
2326
|
+
return acc;
|
|
2327
|
+
}, []);
|
|
2328
|
+
iterable = [{
|
|
2329
|
+
typ: 'Declaration',
|
|
2330
|
+
nam: this.config.shorthand,
|
|
2331
|
+
val: values
|
|
2332
|
+
}][Symbol.iterator]();
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
const iterators = [];
|
|
2336
|
+
return {
|
|
2337
|
+
// @ts-ignore
|
|
2338
|
+
next() {
|
|
2339
|
+
let v = iterable.next();
|
|
2340
|
+
while (v.done || v.value instanceof PropertySet) {
|
|
2341
|
+
if (v.value instanceof PropertySet) {
|
|
2342
|
+
// @ts-ignore
|
|
2343
|
+
iterators.push(iterable);
|
|
2344
|
+
iterable = v.value[Symbol.iterator]();
|
|
2345
|
+
v = iterable.next();
|
|
2346
|
+
}
|
|
2347
|
+
if (v.done) {
|
|
2348
|
+
if (iterators.length > 0) {
|
|
2147
2349
|
// @ts-ignore
|
|
2148
|
-
|
|
2350
|
+
iterable = iterators.pop();
|
|
2351
|
+
v = iterable.next();
|
|
2352
|
+
}
|
|
2353
|
+
if (v.done && iterators.length == 0) {
|
|
2354
|
+
break;
|
|
2149
2355
|
}
|
|
2150
|
-
// @ts-ignore
|
|
2151
|
-
acc.push(curr);
|
|
2152
|
-
return acc;
|
|
2153
|
-
}, []));
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
return acc;
|
|
2157
|
-
}, []).reduce((acc, curr) => {
|
|
2158
|
-
if (acc.length > 0) {
|
|
2159
|
-
acc.push({ ...separator });
|
|
2160
|
-
}
|
|
2161
|
-
if (curr.length == 0) {
|
|
2162
|
-
curr.push(...this.config.default[0].split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
2163
|
-
if (acc.length > 0) {
|
|
2164
|
-
acc.push({ typ: 'Whitespace' });
|
|
2165
2356
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
}, []));
|
|
2357
|
+
}
|
|
2358
|
+
return v;
|
|
2169
2359
|
}
|
|
2170
|
-
|
|
2171
|
-
return acc;
|
|
2172
|
-
}, []);
|
|
2173
|
-
return [{
|
|
2174
|
-
typ: 'Declaration',
|
|
2175
|
-
nam: this.config.shorthand,
|
|
2176
|
-
val: values
|
|
2177
|
-
}][Symbol.iterator]();
|
|
2360
|
+
};
|
|
2178
2361
|
}
|
|
2179
2362
|
}
|
|
2180
2363
|
|
|
@@ -2184,33 +2367,61 @@
|
|
|
2184
2367
|
constructor() {
|
|
2185
2368
|
this.declarations = new Map;
|
|
2186
2369
|
}
|
|
2370
|
+
set(nam, value) {
|
|
2371
|
+
return this.add({ typ: 'Declaration', nam, val: Array.isArray(value) ? value : parseString(String(value)) });
|
|
2372
|
+
}
|
|
2187
2373
|
add(declaration) {
|
|
2188
2374
|
if (declaration.typ != 'Declaration') {
|
|
2189
2375
|
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
|
|
2190
2376
|
return this;
|
|
2191
2377
|
}
|
|
2192
|
-
|
|
2378
|
+
let propertyName = declaration.nam;
|
|
2379
|
+
let shortHandType;
|
|
2380
|
+
let shorthand;
|
|
2193
2381
|
if (propertyName in config.properties) {
|
|
2194
2382
|
// @ts-ignore
|
|
2195
|
-
|
|
2196
|
-
|
|
2383
|
+
if ('map' in config.properties[propertyName]) {
|
|
2384
|
+
shortHandType = 'map';
|
|
2197
2385
|
// @ts-ignore
|
|
2198
|
-
|
|
2386
|
+
shorthand = config.properties[propertyName].map;
|
|
2199
2387
|
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2388
|
+
else {
|
|
2389
|
+
shortHandType = 'set';
|
|
2390
|
+
// @ts-ignore
|
|
2391
|
+
shorthand = config.properties[propertyName].shorthand;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
else if (propertyName in config.map) {
|
|
2395
|
+
shortHandType = 'map';
|
|
2396
|
+
// @ts-ignore
|
|
2397
|
+
shorthand = config.map[propertyName].shorthand;
|
|
2202
2398
|
}
|
|
2203
|
-
|
|
2399
|
+
// @ts-ignore
|
|
2400
|
+
if (shortHandType == 'map') {
|
|
2204
2401
|
// @ts-ignore
|
|
2205
|
-
const shorthand = config.map[propertyName].shorthand;
|
|
2206
2402
|
if (!this.declarations.has(shorthand)) {
|
|
2207
2403
|
// @ts-ignore
|
|
2208
2404
|
this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
|
|
2209
2405
|
}
|
|
2406
|
+
// @ts-ignore
|
|
2210
2407
|
this.declarations.get(shorthand).add(declaration);
|
|
2211
|
-
return this;
|
|
2408
|
+
// return this;
|
|
2409
|
+
}
|
|
2410
|
+
// @ts-ignore
|
|
2411
|
+
else if (shortHandType == 'set') {
|
|
2412
|
+
// @ts-ignore
|
|
2413
|
+
// const shorthand: string = <string>config.properties[propertyName].shorthand;
|
|
2414
|
+
if (!this.declarations.has(shorthand)) {
|
|
2415
|
+
// @ts-ignore
|
|
2416
|
+
this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
|
|
2417
|
+
}
|
|
2418
|
+
// @ts-ignore
|
|
2419
|
+
this.declarations.get(shorthand).add(declaration);
|
|
2420
|
+
// return this;
|
|
2421
|
+
}
|
|
2422
|
+
else {
|
|
2423
|
+
this.declarations.set(propertyName, declaration);
|
|
2212
2424
|
}
|
|
2213
|
-
this.declarations.set(propertyName, declaration);
|
|
2214
2425
|
return this;
|
|
2215
2426
|
}
|
|
2216
2427
|
[Symbol.iterator]() {
|
|
@@ -2239,56 +2450,300 @@
|
|
|
2239
2450
|
}
|
|
2240
2451
|
}
|
|
2241
2452
|
|
|
2242
|
-
const configuration = getConfig();
|
|
2243
2453
|
const combinators = ['+', '>', '~'];
|
|
2244
2454
|
const notEndingWith = ['(', '['].concat(combinators);
|
|
2245
|
-
function
|
|
2246
|
-
|
|
2247
|
-
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
2248
|
-
// @ts-ignore
|
|
2249
|
-
let nSel = match.selector2.reduce(reducer, []).join(',');
|
|
2250
|
-
// @ts-ignore
|
|
2251
|
-
const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
|
|
2252
|
-
// @ts-ignore
|
|
2253
|
-
Object.defineProperty(wrapper, 'raw', {
|
|
2254
|
-
enumerable: false,
|
|
2255
|
-
writable: true,
|
|
2455
|
+
function minify(ast, options = {}, recursive = false) {
|
|
2456
|
+
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
2256
2457
|
// @ts-ignore
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2458
|
+
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
2459
|
+
// @ts-ignore
|
|
2460
|
+
let nSel = match.selector2.reduce(reducer, []).join(',');
|
|
2260
2461
|
// @ts-ignore
|
|
2261
|
-
wrapper
|
|
2462
|
+
const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
|
|
2262
2463
|
// @ts-ignore
|
|
2263
|
-
|
|
2464
|
+
Object.defineProperty(wrapper, 'raw', {
|
|
2465
|
+
enumerable: false,
|
|
2466
|
+
writable: true,
|
|
2264
2467
|
// @ts-ignore
|
|
2265
|
-
|
|
2468
|
+
value: match.match.map(t => t.slice())
|
|
2469
|
+
});
|
|
2470
|
+
if (pSel == '&' || pSel === '') {
|
|
2471
|
+
// @ts-ignore
|
|
2472
|
+
wrapper.chi.push(...previous.chi);
|
|
2473
|
+
// @ts-ignore
|
|
2474
|
+
if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
|
|
2475
|
+
// @ts-ignore
|
|
2476
|
+
wrapper.chi.push(...node.chi);
|
|
2477
|
+
}
|
|
2478
|
+
else {
|
|
2479
|
+
// @ts-ignore
|
|
2480
|
+
wrapper.chi.push(node);
|
|
2481
|
+
}
|
|
2266
2482
|
}
|
|
2267
2483
|
else {
|
|
2268
2484
|
// @ts-ignore
|
|
2269
|
-
wrapper.chi.push(node);
|
|
2485
|
+
wrapper.chi.push(previous, node);
|
|
2270
2486
|
}
|
|
2487
|
+
// @ts-ignore
|
|
2488
|
+
ast.chi.splice(i, 1, wrapper);
|
|
2489
|
+
// @ts-ignore
|
|
2490
|
+
ast.chi.splice(nodeIndex, 1);
|
|
2491
|
+
// @ts-ignore
|
|
2492
|
+
previous.sel = pSel;
|
|
2493
|
+
// @ts-ignore
|
|
2494
|
+
previous.raw = match.selector1;
|
|
2495
|
+
// @ts-ignore
|
|
2496
|
+
node.sel = nSel;
|
|
2497
|
+
// @ts-ignore
|
|
2498
|
+
node.raw = match.selector2;
|
|
2499
|
+
reduceRuleSelector(wrapper);
|
|
2500
|
+
return wrapper;
|
|
2271
2501
|
}
|
|
2272
|
-
|
|
2502
|
+
function reducer(acc, curr, index, array) {
|
|
2503
|
+
// trim :is()
|
|
2504
|
+
if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
|
|
2505
|
+
curr = curr.slice(1, -1);
|
|
2506
|
+
}
|
|
2507
|
+
if (curr[0] == '&') {
|
|
2508
|
+
if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
|
|
2509
|
+
curr.splice(0, 2);
|
|
2510
|
+
}
|
|
2511
|
+
else if (combinators.includes(curr[1])) {
|
|
2512
|
+
curr.splice(0, 1);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
else if (ast.typ == 'Rule' && (isIdent(curr[0]) || isFunction(curr[0]))) {
|
|
2516
|
+
curr.unshift('&', ' ');
|
|
2517
|
+
}
|
|
2518
|
+
acc.push(curr.join(''));
|
|
2519
|
+
return acc;
|
|
2520
|
+
}
|
|
2521
|
+
function diff(n1, n2, options = {}) {
|
|
2522
|
+
let node1 = n1;
|
|
2523
|
+
let node2 = n2;
|
|
2524
|
+
let exchanged = false;
|
|
2525
|
+
if (node1.chi.length > node2.chi.length) {
|
|
2526
|
+
const t = node1;
|
|
2527
|
+
node1 = node2;
|
|
2528
|
+
node2 = t;
|
|
2529
|
+
exchanged = true;
|
|
2530
|
+
}
|
|
2531
|
+
let i = node1.chi.length;
|
|
2532
|
+
let j = node2.chi.length;
|
|
2533
|
+
if (i == 0 || j == 0) {
|
|
2534
|
+
// @ts-ignore
|
|
2535
|
+
return null;
|
|
2536
|
+
}
|
|
2537
|
+
// @ts-ignore
|
|
2538
|
+
const raw1 = node1.raw;
|
|
2539
|
+
// @ts-ignore
|
|
2540
|
+
const raw2 = node2.raw;
|
|
2541
|
+
// @ts-ignore
|
|
2542
|
+
node1 = { ...node1, chi: node1.chi.slice() };
|
|
2543
|
+
node2 = { ...node2, chi: node2.chi.slice() };
|
|
2544
|
+
if (raw1 != null) {
|
|
2545
|
+
Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
|
|
2546
|
+
}
|
|
2547
|
+
if (raw2 != null) {
|
|
2548
|
+
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2549
|
+
}
|
|
2550
|
+
const intersect = [];
|
|
2551
|
+
while (i--) {
|
|
2552
|
+
if (node1.chi[i].typ == 'Comment') {
|
|
2553
|
+
continue;
|
|
2554
|
+
}
|
|
2555
|
+
j = node2.chi.length;
|
|
2556
|
+
if (j == 0) {
|
|
2557
|
+
break;
|
|
2558
|
+
}
|
|
2559
|
+
while (j--) {
|
|
2560
|
+
if (node2.chi[j].typ == 'Comment') {
|
|
2561
|
+
continue;
|
|
2562
|
+
}
|
|
2563
|
+
if (node1.chi[i].nam == node2.chi[j].nam) {
|
|
2564
|
+
if (eq(node1.chi[i], node2.chi[j])) {
|
|
2565
|
+
intersect.push(node1.chi[i]);
|
|
2566
|
+
node1.chi.splice(i, 1);
|
|
2567
|
+
node2.chi.splice(j, 1);
|
|
2568
|
+
break;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2273
2573
|
// @ts-ignore
|
|
2274
|
-
|
|
2574
|
+
const result = (intersect.length == 0 ? null : {
|
|
2575
|
+
...node1,
|
|
2576
|
+
// @ts-ignore
|
|
2577
|
+
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(','),
|
|
2578
|
+
chi: intersect.reverse()
|
|
2579
|
+
});
|
|
2580
|
+
if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
|
|
2581
|
+
// @ts-ignore
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
|
|
2585
|
+
}
|
|
2586
|
+
function matchSelectors(selector1, selector2, parentType) {
|
|
2587
|
+
let match = [[]];
|
|
2588
|
+
const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
|
|
2589
|
+
let i = 0;
|
|
2590
|
+
let k;
|
|
2591
|
+
let l;
|
|
2592
|
+
let token;
|
|
2593
|
+
let matching = true;
|
|
2594
|
+
let matchFunction = 0;
|
|
2595
|
+
let inAttr = 0;
|
|
2596
|
+
for (; i < j; i++) {
|
|
2597
|
+
k = 0;
|
|
2598
|
+
token = selector1[0][i];
|
|
2599
|
+
for (; k < selector1.length; k++) {
|
|
2600
|
+
if (selector1[k][i] != token) {
|
|
2601
|
+
matching = false;
|
|
2602
|
+
break;
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
if (matching) {
|
|
2606
|
+
l = 0;
|
|
2607
|
+
for (; l < selector2.length; l++) {
|
|
2608
|
+
if (selector2[l][i] != token) {
|
|
2609
|
+
matching = false;
|
|
2610
|
+
break;
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
if (!matching) {
|
|
2615
|
+
break;
|
|
2616
|
+
}
|
|
2617
|
+
if (token == ',') {
|
|
2618
|
+
match.push([]);
|
|
2619
|
+
}
|
|
2620
|
+
else {
|
|
2621
|
+
if (token.endsWith('(')) {
|
|
2622
|
+
matchFunction++;
|
|
2623
|
+
}
|
|
2624
|
+
if (token.endsWith('[')) {
|
|
2625
|
+
inAttr++;
|
|
2626
|
+
}
|
|
2627
|
+
else if (token == ')') {
|
|
2628
|
+
matchFunction--;
|
|
2629
|
+
}
|
|
2630
|
+
else if (token == ']') {
|
|
2631
|
+
inAttr--;
|
|
2632
|
+
}
|
|
2633
|
+
match.at(-1).push(token);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
// invalid function
|
|
2637
|
+
if (matchFunction != 0 || inAttr != 0) {
|
|
2638
|
+
return null;
|
|
2639
|
+
}
|
|
2640
|
+
if (parentType != 'Rule') {
|
|
2641
|
+
for (const part of match) {
|
|
2642
|
+
if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
|
|
2643
|
+
return null;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
if (match.length > 1) {
|
|
2648
|
+
console.error(`unsupported multilevel matching`);
|
|
2649
|
+
console.error({ match, selector1, selector2 });
|
|
2650
|
+
return null;
|
|
2651
|
+
}
|
|
2652
|
+
for (const part of match) {
|
|
2653
|
+
while (part.length > 0) {
|
|
2654
|
+
const token = part.at(-1);
|
|
2655
|
+
if (token == ' ' || combinators.includes(token) || notEndingWith.includes(token.at(-1))) {
|
|
2656
|
+
part.pop();
|
|
2657
|
+
continue;
|
|
2658
|
+
}
|
|
2659
|
+
break;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
if (match.every(t => t.length == 0)) {
|
|
2663
|
+
return null;
|
|
2664
|
+
}
|
|
2665
|
+
if (eq([['&']], match)) {
|
|
2666
|
+
return null;
|
|
2667
|
+
}
|
|
2668
|
+
function reduce(acc, curr) {
|
|
2669
|
+
if (acc === null) {
|
|
2670
|
+
return null;
|
|
2671
|
+
}
|
|
2672
|
+
let hasCompoundSelector = true;
|
|
2673
|
+
curr = curr.slice(match[0].length);
|
|
2674
|
+
while (curr.length > 0) {
|
|
2675
|
+
if (curr[0] == ' ') {
|
|
2676
|
+
hasCompoundSelector = false;
|
|
2677
|
+
curr.unshift('&');
|
|
2678
|
+
continue;
|
|
2679
|
+
}
|
|
2680
|
+
break;
|
|
2681
|
+
}
|
|
2682
|
+
// invalid function match
|
|
2683
|
+
if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
|
|
2684
|
+
return null;
|
|
2685
|
+
}
|
|
2686
|
+
if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
|
|
2687
|
+
return null;
|
|
2688
|
+
}
|
|
2689
|
+
if (hasCompoundSelector && curr.length > 0) {
|
|
2690
|
+
hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
2691
|
+
}
|
|
2692
|
+
if (curr[0] == ':is(') {
|
|
2693
|
+
let inFunction = 0;
|
|
2694
|
+
let canReduce = true;
|
|
2695
|
+
const isCompound = curr.reduce((acc, token, index) => {
|
|
2696
|
+
if (index == 0) {
|
|
2697
|
+
inFunction++;
|
|
2698
|
+
canReduce = curr[1] == '&';
|
|
2699
|
+
}
|
|
2700
|
+
else if (token.endsWith('(')) {
|
|
2701
|
+
if (inFunction == 0) {
|
|
2702
|
+
canReduce = false;
|
|
2703
|
+
}
|
|
2704
|
+
inFunction++;
|
|
2705
|
+
}
|
|
2706
|
+
else if (token == ')') {
|
|
2707
|
+
inFunction--;
|
|
2708
|
+
}
|
|
2709
|
+
else if (token == ',') {
|
|
2710
|
+
if (!canReduce) {
|
|
2711
|
+
canReduce = curr[index + 1] == '&';
|
|
2712
|
+
}
|
|
2713
|
+
acc.push([]);
|
|
2714
|
+
}
|
|
2715
|
+
else
|
|
2716
|
+
acc.at(-1)?.push(token);
|
|
2717
|
+
return acc;
|
|
2718
|
+
}, [[]]);
|
|
2719
|
+
if (inFunction > 0) {
|
|
2720
|
+
canReduce = false;
|
|
2721
|
+
}
|
|
2722
|
+
if (canReduce) {
|
|
2723
|
+
curr = isCompound.reduce((acc, curr) => {
|
|
2724
|
+
if (acc.length > 0) {
|
|
2725
|
+
acc.push(',');
|
|
2726
|
+
}
|
|
2727
|
+
acc.push(...curr);
|
|
2728
|
+
return acc;
|
|
2729
|
+
}, []);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
// @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
|
|
2733
|
+
acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
|
|
2734
|
+
return acc;
|
|
2735
|
+
}
|
|
2736
|
+
// @ts-ignore
|
|
2737
|
+
selector1 = selector1.reduce(reduce, []);
|
|
2738
|
+
// @ts-ignore
|
|
2739
|
+
selector2 = selector2.reduce(reduce, []);
|
|
2740
|
+
return selector1 == null || selector2 == null ? null : {
|
|
2741
|
+
eq: eq(selector1, selector2),
|
|
2742
|
+
match,
|
|
2743
|
+
selector1,
|
|
2744
|
+
selector2
|
|
2745
|
+
};
|
|
2275
2746
|
}
|
|
2276
|
-
// @ts-ignore
|
|
2277
|
-
ast.chi.splice(i, 1, wrapper);
|
|
2278
|
-
// @ts-ignore
|
|
2279
|
-
ast.chi.splice(nodeIndex, 1);
|
|
2280
|
-
// @ts-ignore
|
|
2281
|
-
previous.sel = pSel;
|
|
2282
|
-
// @ts-ignore
|
|
2283
|
-
previous.raw = match.selector1;
|
|
2284
|
-
// @ts-ignore
|
|
2285
|
-
node.sel = nSel;
|
|
2286
|
-
// @ts-ignore
|
|
2287
|
-
node.raw = match.selector2;
|
|
2288
|
-
reduceRuleSelector(wrapper);
|
|
2289
|
-
return wrapper;
|
|
2290
|
-
}
|
|
2291
|
-
function deduplicate(ast, options = {}, recursive = false) {
|
|
2292
2747
|
// @ts-ignore
|
|
2293
2748
|
if (('chi' in ast) && ast.chi?.length > 0) {
|
|
2294
2749
|
let i = 0;
|
|
@@ -2328,7 +2783,8 @@
|
|
|
2328
2783
|
// @ts-ignore
|
|
2329
2784
|
if (options.nestingRules) {
|
|
2330
2785
|
// @ts-ignore
|
|
2331
|
-
if (previous
|
|
2786
|
+
if (previous?.typ == 'Rule') {
|
|
2787
|
+
// @ts-ignore
|
|
2332
2788
|
reduceRuleSelector(previous);
|
|
2333
2789
|
// @ts-ignore
|
|
2334
2790
|
match = matchSelectors(previous.raw, node.raw, ast.typ);
|
|
@@ -2367,7 +2823,7 @@
|
|
|
2367
2823
|
nodeIndex = --i;
|
|
2368
2824
|
// @ts-ignore
|
|
2369
2825
|
previous = ast.chi[nodeIndex];
|
|
2370
|
-
|
|
2826
|
+
minify(wrapper, options, recursive);
|
|
2371
2827
|
continue;
|
|
2372
2828
|
}
|
|
2373
2829
|
// @ts-ignore
|
|
@@ -2416,13 +2872,24 @@
|
|
|
2416
2872
|
}
|
|
2417
2873
|
else if (combinators.includes(curr[0])) {
|
|
2418
2874
|
curr.unshift('&');
|
|
2875
|
+
wrap = false;
|
|
2419
2876
|
}
|
|
2420
2877
|
// @ts-ignore
|
|
2421
|
-
acc.push(curr
|
|
2878
|
+
acc.push(curr);
|
|
2422
2879
|
return acc;
|
|
2423
2880
|
}, []);
|
|
2881
|
+
if (!wrap) {
|
|
2882
|
+
wrap = selector.some(s => s[0] != '&');
|
|
2883
|
+
}
|
|
2884
|
+
const rule = selector.map(s => {
|
|
2885
|
+
if (s[0] == '&') {
|
|
2886
|
+
// @ts-ignore
|
|
2887
|
+
s[0] = node.optimized.optimized[0];
|
|
2888
|
+
}
|
|
2889
|
+
return s.join('');
|
|
2890
|
+
}).join(',');
|
|
2424
2891
|
// @ts-ignore
|
|
2425
|
-
node.sel =
|
|
2892
|
+
node.sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
|
|
2426
2893
|
}
|
|
2427
2894
|
}
|
|
2428
2895
|
// @ts-ignore
|
|
@@ -2453,10 +2920,10 @@
|
|
|
2453
2920
|
// @ts-ignore
|
|
2454
2921
|
if (hasDeclaration(node)) {
|
|
2455
2922
|
// @ts-ignore
|
|
2456
|
-
|
|
2923
|
+
minifyRule(node);
|
|
2457
2924
|
}
|
|
2458
2925
|
else {
|
|
2459
|
-
|
|
2926
|
+
minify(node, options, recursive);
|
|
2460
2927
|
}
|
|
2461
2928
|
i--;
|
|
2462
2929
|
previous = node;
|
|
@@ -2498,10 +2965,10 @@
|
|
|
2498
2965
|
// @ts-ignore
|
|
2499
2966
|
if (hasDeclaration(previous)) {
|
|
2500
2967
|
// @ts-ignore
|
|
2501
|
-
|
|
2968
|
+
minifyRule(previous);
|
|
2502
2969
|
}
|
|
2503
2970
|
else {
|
|
2504
|
-
|
|
2971
|
+
minify(previous, options, recursive);
|
|
2505
2972
|
}
|
|
2506
2973
|
}
|
|
2507
2974
|
}
|
|
@@ -2512,18 +2979,97 @@
|
|
|
2512
2979
|
if (recursive && node != null && ('chi' in node)) {
|
|
2513
2980
|
// @ts-ignore
|
|
2514
2981
|
if (node.chi.some(n => n.typ == 'Declaration')) {
|
|
2515
|
-
|
|
2982
|
+
minifyRule(node);
|
|
2516
2983
|
}
|
|
2517
2984
|
else {
|
|
2518
2985
|
// @ts-ignore
|
|
2519
2986
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
2520
|
-
|
|
2987
|
+
minify(node, options, recursive);
|
|
2521
2988
|
}
|
|
2522
2989
|
}
|
|
2523
2990
|
}
|
|
2524
2991
|
}
|
|
2525
2992
|
return ast;
|
|
2526
2993
|
}
|
|
2994
|
+
function reduceSelector(selector) {
|
|
2995
|
+
if (selector.length == 0) {
|
|
2996
|
+
return null;
|
|
2997
|
+
}
|
|
2998
|
+
const optimized = [];
|
|
2999
|
+
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
3000
|
+
let i = 0;
|
|
3001
|
+
let j;
|
|
3002
|
+
let match;
|
|
3003
|
+
for (; i < k; i++) {
|
|
3004
|
+
const item = selector[0][i];
|
|
3005
|
+
match = true;
|
|
3006
|
+
for (j = 1; j < selector.length; j++) {
|
|
3007
|
+
if (item != selector[j][i]) {
|
|
3008
|
+
match = false;
|
|
3009
|
+
break;
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
if (!match) {
|
|
3013
|
+
break;
|
|
3014
|
+
}
|
|
3015
|
+
optimized.push(item);
|
|
3016
|
+
}
|
|
3017
|
+
while (optimized.length > 0) {
|
|
3018
|
+
const last = optimized.at(-1);
|
|
3019
|
+
if ((last == ' ' || combinators.includes(last))) {
|
|
3020
|
+
optimized.pop();
|
|
3021
|
+
continue;
|
|
3022
|
+
}
|
|
3023
|
+
break;
|
|
3024
|
+
}
|
|
3025
|
+
selector.forEach((selector) => selector.splice(0, optimized.length));
|
|
3026
|
+
// combinator
|
|
3027
|
+
if (combinators.includes(optimized.at(-1))) {
|
|
3028
|
+
const combinator = optimized.pop();
|
|
3029
|
+
selector.forEach(selector => selector.unshift(combinator));
|
|
3030
|
+
}
|
|
3031
|
+
let reducible = optimized.length == 1;
|
|
3032
|
+
if (optimized[0] == '&' && optimized[1] == ' ') {
|
|
3033
|
+
optimized.splice(0, 2);
|
|
3034
|
+
}
|
|
3035
|
+
if (optimized.length == 0 ||
|
|
3036
|
+
(optimized[0].charAt(0) == '&' ||
|
|
3037
|
+
selector.length == 1)) {
|
|
3038
|
+
return {
|
|
3039
|
+
match: false,
|
|
3040
|
+
optimized,
|
|
3041
|
+
selector: selector.map(selector => selector[0] == '&' && selector[1] == ' ' ? selector.slice(2) : selector),
|
|
3042
|
+
reducible: selector.length > 1 && selector.every((selector) => !combinators.includes(selector[0]))
|
|
3043
|
+
};
|
|
3044
|
+
}
|
|
3045
|
+
return {
|
|
3046
|
+
match: true,
|
|
3047
|
+
optimized,
|
|
3048
|
+
selector: selector.reduce((acc, curr) => {
|
|
3049
|
+
let hasCompound = true;
|
|
3050
|
+
if (hasCompound && curr.length > 0) {
|
|
3051
|
+
hasCompound = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
3052
|
+
}
|
|
3053
|
+
// @ts-ignore
|
|
3054
|
+
if (hasCompound && curr[0] == ' ') {
|
|
3055
|
+
hasCompound = false;
|
|
3056
|
+
curr.unshift('&');
|
|
3057
|
+
}
|
|
3058
|
+
if (curr.length == 0) {
|
|
3059
|
+
curr.push('&');
|
|
3060
|
+
hasCompound = false;
|
|
3061
|
+
}
|
|
3062
|
+
if (reducible) {
|
|
3063
|
+
const chr = curr[0].charAt(0);
|
|
3064
|
+
// @ts-ignore
|
|
3065
|
+
reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
|
|
3066
|
+
}
|
|
3067
|
+
acc.push(hasCompound ? ['&'].concat(curr) : curr);
|
|
3068
|
+
return acc;
|
|
3069
|
+
}, []),
|
|
3070
|
+
reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
2527
3073
|
function hasOnlyDeclarations(node) {
|
|
2528
3074
|
let k = node.chi.length;
|
|
2529
3075
|
while (k--) {
|
|
@@ -2546,7 +3092,7 @@
|
|
|
2546
3092
|
}
|
|
2547
3093
|
return true;
|
|
2548
3094
|
}
|
|
2549
|
-
function
|
|
3095
|
+
function minifyRule(ast) {
|
|
2550
3096
|
// @ts-ignore
|
|
2551
3097
|
if (!('chi' in ast) || ast.chi?.length <= 1) {
|
|
2552
3098
|
return ast;
|
|
@@ -2554,45 +3100,19 @@
|
|
|
2554
3100
|
// @ts-ignore
|
|
2555
3101
|
const j = ast.chi.length;
|
|
2556
3102
|
let k = 0;
|
|
2557
|
-
let
|
|
3103
|
+
let properties = new PropertyList();
|
|
2558
3104
|
// @ts-ignore
|
|
2559
3105
|
for (; k < j; k++) {
|
|
2560
3106
|
// @ts-ignore
|
|
2561
3107
|
const node = ast.chi[k];
|
|
2562
|
-
if (node.typ == 'Comment') {
|
|
2563
|
-
|
|
2564
|
-
map.set(node, node);
|
|
3108
|
+
if (node.typ == 'Comment' || node.typ == 'Declaration') {
|
|
3109
|
+
properties.add(node);
|
|
2565
3110
|
continue;
|
|
2566
3111
|
}
|
|
2567
|
-
|
|
2568
|
-
break;
|
|
2569
|
-
}
|
|
2570
|
-
if (node.nam in configuration.map ||
|
|
2571
|
-
node.nam in configuration.properties) {
|
|
2572
|
-
// @ts-ignore
|
|
2573
|
-
const shorthand = node.nam in configuration.map ? configuration.map[node.nam].shorthand : configuration.properties[node.nam].shorthand;
|
|
2574
|
-
if (!map.has(shorthand)) {
|
|
2575
|
-
map.set(shorthand, new PropertyList());
|
|
2576
|
-
}
|
|
2577
|
-
map.get(shorthand).add(node);
|
|
2578
|
-
}
|
|
2579
|
-
else {
|
|
2580
|
-
map.set(node.nam, node);
|
|
2581
|
-
}
|
|
2582
|
-
}
|
|
2583
|
-
const children = [];
|
|
2584
|
-
for (let child of map.values()) {
|
|
2585
|
-
if (child instanceof PropertyList) {
|
|
2586
|
-
// @ts-ignore
|
|
2587
|
-
children.push(...child);
|
|
2588
|
-
}
|
|
2589
|
-
else {
|
|
2590
|
-
// @ts-ignore
|
|
2591
|
-
children.push(child);
|
|
2592
|
-
}
|
|
3112
|
+
break;
|
|
2593
3113
|
}
|
|
2594
3114
|
// @ts-ignore
|
|
2595
|
-
ast.chi =
|
|
3115
|
+
ast.chi = [...properties].concat(ast.chi.slice(k));
|
|
2596
3116
|
return ast;
|
|
2597
3117
|
}
|
|
2598
3118
|
function splitRule(buffer) {
|
|
@@ -2718,345 +3238,482 @@
|
|
|
2718
3238
|
}
|
|
2719
3239
|
// }
|
|
2720
3240
|
}
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
let node2 = n2;
|
|
2724
|
-
let exchanged = false;
|
|
2725
|
-
if (node1.chi.length > node2.chi.length) {
|
|
2726
|
-
const t = node1;
|
|
2727
|
-
node1 = node2;
|
|
2728
|
-
node2 = t;
|
|
2729
|
-
exchanged = true;
|
|
2730
|
-
}
|
|
2731
|
-
let i = node1.chi.length;
|
|
2732
|
-
let j = node2.chi.length;
|
|
2733
|
-
if (i == 0 || j == 0) {
|
|
2734
|
-
// @ts-ignore
|
|
2735
|
-
return null;
|
|
2736
|
-
}
|
|
2737
|
-
// @ts-ignore
|
|
2738
|
-
const raw1 = node1.raw;
|
|
2739
|
-
// @ts-ignore
|
|
2740
|
-
// const optimized1 = node1.optimized;
|
|
2741
|
-
// @ts-ignore
|
|
2742
|
-
const raw2 = node2.raw;
|
|
3241
|
+
|
|
3242
|
+
function* walk(node) {
|
|
2743
3243
|
// @ts-ignore
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
// Object.defineProperty(node1, 'optimized', {enumerable: false, writable: true, value: optimized1});
|
|
2752
|
-
// }
|
|
2753
|
-
if (raw2 != null) {
|
|
2754
|
-
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2755
|
-
}
|
|
2756
|
-
// if (optimized2 != null) {
|
|
2757
|
-
// Object.defineProperty(node2, 'optimized', {enumerable: false, writable: true, value: optimized2});
|
|
2758
|
-
// }
|
|
2759
|
-
const intersect = [];
|
|
2760
|
-
while (i--) {
|
|
2761
|
-
if (node1.chi[i].typ == 'Comment') {
|
|
2762
|
-
continue;
|
|
2763
|
-
}
|
|
2764
|
-
j = node2.chi.length;
|
|
2765
|
-
if (j == 0) {
|
|
2766
|
-
break;
|
|
3244
|
+
yield* doWalk(node, null, null);
|
|
3245
|
+
}
|
|
3246
|
+
function* doWalk(node, parent, root) {
|
|
3247
|
+
yield { node, parent, root };
|
|
3248
|
+
if ('chi' in node) {
|
|
3249
|
+
for (const child of node.chi) {
|
|
3250
|
+
yield* doWalk(child, node, (root ?? node));
|
|
2767
3251
|
}
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
function* tokenize(iterator) {
|
|
3256
|
+
let ind = -1;
|
|
3257
|
+
let lin = 1;
|
|
3258
|
+
let col = 0;
|
|
3259
|
+
const position = {
|
|
3260
|
+
ind: Math.max(ind, 0),
|
|
3261
|
+
lin: lin,
|
|
3262
|
+
col: Math.max(col, 1)
|
|
3263
|
+
};
|
|
3264
|
+
let value;
|
|
3265
|
+
let buffer = '';
|
|
3266
|
+
function consumeWhiteSpace() {
|
|
3267
|
+
let count = 0;
|
|
3268
|
+
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3269
|
+
count++;
|
|
2780
3270
|
}
|
|
3271
|
+
next(count);
|
|
3272
|
+
return count;
|
|
2781
3273
|
}
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
});
|
|
2789
|
-
if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
|
|
2790
|
-
// @ts-ignore
|
|
2791
|
-
return null;
|
|
3274
|
+
function pushToken(token, hint) {
|
|
3275
|
+
const result = { token, hint, position: { ...position }, bytesIn: ind };
|
|
3276
|
+
position.ind = ind;
|
|
3277
|
+
position.lin = lin;
|
|
3278
|
+
position.col = col == 0 ? 1 : col;
|
|
3279
|
+
return result;
|
|
2792
3280
|
}
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
for (; i < j; i++) {
|
|
2806
|
-
k = 0;
|
|
2807
|
-
token = selector1[0][i];
|
|
2808
|
-
for (; k < selector1.length; k++) {
|
|
2809
|
-
if (selector1[k][i] != token) {
|
|
2810
|
-
matching = false;
|
|
3281
|
+
function* consumeString(quoteStr) {
|
|
3282
|
+
const quote = quoteStr;
|
|
3283
|
+
let value;
|
|
3284
|
+
let hasNewLine = false;
|
|
3285
|
+
if (buffer.length > 0) {
|
|
3286
|
+
yield pushToken(buffer);
|
|
3287
|
+
buffer = '';
|
|
3288
|
+
}
|
|
3289
|
+
buffer += quoteStr;
|
|
3290
|
+
while (value = peek()) {
|
|
3291
|
+
if (ind >= iterator.length) {
|
|
3292
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
2811
3293
|
break;
|
|
2812
3294
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
3295
|
+
if (value == '\\') {
|
|
3296
|
+
const sequence = peek(6);
|
|
3297
|
+
let escapeSequence = '';
|
|
3298
|
+
let codepoint;
|
|
3299
|
+
let i;
|
|
3300
|
+
for (i = 1; i < sequence.length; i++) {
|
|
3301
|
+
codepoint = sequence.charCodeAt(i);
|
|
3302
|
+
if (codepoint == 0x20 ||
|
|
3303
|
+
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
3304
|
+
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3305
|
+
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3306
|
+
escapeSequence += sequence[i];
|
|
3307
|
+
if (codepoint == 0x20) {
|
|
3308
|
+
break;
|
|
3309
|
+
}
|
|
3310
|
+
continue;
|
|
3311
|
+
}
|
|
2819
3312
|
break;
|
|
2820
3313
|
}
|
|
3314
|
+
// not hex or new line
|
|
3315
|
+
// @ts-ignore
|
|
3316
|
+
if (i == 1 && !isNewLine(codepoint)) {
|
|
3317
|
+
buffer += sequence[i];
|
|
3318
|
+
next(2);
|
|
3319
|
+
continue;
|
|
3320
|
+
}
|
|
3321
|
+
if (escapeSequence.trimEnd().length > 0) {
|
|
3322
|
+
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
3323
|
+
if (codepoint == 0 ||
|
|
3324
|
+
// leading surrogate
|
|
3325
|
+
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
3326
|
+
// trailing surrogate
|
|
3327
|
+
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
3328
|
+
buffer += String.fromCodePoint(0xFFFD);
|
|
3329
|
+
}
|
|
3330
|
+
else {
|
|
3331
|
+
buffer += String.fromCodePoint(codepoint);
|
|
3332
|
+
}
|
|
3333
|
+
next(escapeSequence.length + 1);
|
|
3334
|
+
continue;
|
|
3335
|
+
}
|
|
3336
|
+
// buffer += value;
|
|
3337
|
+
if (ind >= iterator.length) {
|
|
3338
|
+
// drop '\\' at the end
|
|
3339
|
+
yield pushToken(buffer);
|
|
3340
|
+
break;
|
|
3341
|
+
}
|
|
3342
|
+
buffer += next(2);
|
|
3343
|
+
continue;
|
|
2821
3344
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
else {
|
|
2830
|
-
if (token.endsWith('(')) {
|
|
2831
|
-
matchFunction++;
|
|
2832
|
-
}
|
|
2833
|
-
if (token.endsWith('[')) {
|
|
2834
|
-
inAttr++;
|
|
3345
|
+
if (value == quote) {
|
|
3346
|
+
buffer += value;
|
|
3347
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
3348
|
+
next();
|
|
3349
|
+
// i += value.length;
|
|
3350
|
+
buffer = '';
|
|
3351
|
+
break;
|
|
2835
3352
|
}
|
|
2836
|
-
|
|
2837
|
-
|
|
3353
|
+
if (isNewLine(value.charCodeAt(0))) {
|
|
3354
|
+
hasNewLine = true;
|
|
2838
3355
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
3356
|
+
if (hasNewLine && value == ';') {
|
|
3357
|
+
yield pushToken(buffer, 'Bad-string');
|
|
3358
|
+
buffer = '';
|
|
3359
|
+
break;
|
|
2841
3360
|
}
|
|
2842
|
-
|
|
3361
|
+
buffer += value;
|
|
3362
|
+
// i += value.length;
|
|
3363
|
+
next();
|
|
2843
3364
|
}
|
|
2844
3365
|
}
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
}
|
|
2849
|
-
if (parentType != 'Rule') {
|
|
2850
|
-
for (const part of match) {
|
|
2851
|
-
if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
|
|
2852
|
-
return null;
|
|
2853
|
-
}
|
|
3366
|
+
function peek(count = 1) {
|
|
3367
|
+
if (count == 1) {
|
|
3368
|
+
return iterator.charAt(ind + 1);
|
|
2854
3369
|
}
|
|
3370
|
+
return iterator.slice(ind + 1, ind + count + 1);
|
|
2855
3371
|
}
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
3372
|
+
function prev(count = 1) {
|
|
3373
|
+
if (count == 1) {
|
|
3374
|
+
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3375
|
+
}
|
|
3376
|
+
return iterator.slice(ind - 1 - count, ind - 1);
|
|
2860
3377
|
}
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
3378
|
+
function next(count = 1) {
|
|
3379
|
+
let char = '';
|
|
3380
|
+
while (count-- > 0 && ind < iterator.length) {
|
|
3381
|
+
const codepoint = iterator.charCodeAt(++ind);
|
|
3382
|
+
if (isNaN(codepoint)) {
|
|
3383
|
+
return char;
|
|
3384
|
+
}
|
|
3385
|
+
char += iterator.charAt(ind);
|
|
3386
|
+
if (isNewLine(codepoint)) {
|
|
3387
|
+
lin++;
|
|
3388
|
+
col = 0;
|
|
3389
|
+
}
|
|
3390
|
+
else {
|
|
3391
|
+
col++;
|
|
2867
3392
|
}
|
|
2868
|
-
break;
|
|
2869
3393
|
}
|
|
3394
|
+
return char;
|
|
2870
3395
|
}
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
}
|
|
2877
|
-
function reduce(acc, curr) {
|
|
2878
|
-
if (acc === null) {
|
|
2879
|
-
return null;
|
|
2880
|
-
}
|
|
2881
|
-
let hasCompoundSelector = true;
|
|
2882
|
-
curr = curr.slice(match[0].length);
|
|
2883
|
-
while (curr.length > 0) {
|
|
2884
|
-
if (curr[0] == ' ') {
|
|
2885
|
-
hasCompoundSelector = false;
|
|
2886
|
-
curr.unshift('&');
|
|
2887
|
-
continue;
|
|
3396
|
+
while (value = next()) {
|
|
3397
|
+
if (ind >= iterator.length) {
|
|
3398
|
+
if (buffer.length > 0) {
|
|
3399
|
+
yield pushToken(buffer);
|
|
3400
|
+
buffer = '';
|
|
2888
3401
|
}
|
|
2889
3402
|
break;
|
|
2890
3403
|
}
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
3404
|
+
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
3405
|
+
if (buffer.length > 0) {
|
|
3406
|
+
yield pushToken(buffer);
|
|
3407
|
+
buffer = '';
|
|
3408
|
+
}
|
|
3409
|
+
while (value = next()) {
|
|
3410
|
+
if (ind >= iterator.length) {
|
|
3411
|
+
break;
|
|
3412
|
+
}
|
|
3413
|
+
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
3414
|
+
break;
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
yield pushToken('', 'Whitespace');
|
|
3418
|
+
buffer = '';
|
|
3419
|
+
if (ind >= iterator.length) {
|
|
3420
|
+
break;
|
|
3421
|
+
}
|
|
2900
3422
|
}
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
3423
|
+
switch (value) {
|
|
3424
|
+
case '/':
|
|
3425
|
+
if (buffer.length > 0) {
|
|
3426
|
+
yield pushToken(buffer);
|
|
3427
|
+
buffer = '';
|
|
3428
|
+
if (peek() != '*') {
|
|
3429
|
+
yield pushToken(value);
|
|
3430
|
+
break;
|
|
3431
|
+
}
|
|
2908
3432
|
}
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
3433
|
+
buffer += value;
|
|
3434
|
+
if (peek() == '*') {
|
|
3435
|
+
buffer += '*';
|
|
3436
|
+
// i++;
|
|
3437
|
+
next();
|
|
3438
|
+
while (value = next()) {
|
|
3439
|
+
if (ind >= iterator.length) {
|
|
3440
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3441
|
+
break;
|
|
3442
|
+
}
|
|
3443
|
+
if (value == '\\') {
|
|
3444
|
+
buffer += value;
|
|
3445
|
+
value = next();
|
|
3446
|
+
if (ind >= iterator.length) {
|
|
3447
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3448
|
+
break;
|
|
3449
|
+
}
|
|
3450
|
+
buffer += value;
|
|
3451
|
+
continue;
|
|
3452
|
+
}
|
|
3453
|
+
if (value == '*') {
|
|
3454
|
+
buffer += value;
|
|
3455
|
+
value = next();
|
|
3456
|
+
if (ind >= iterator.length) {
|
|
3457
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3458
|
+
break;
|
|
3459
|
+
}
|
|
3460
|
+
buffer += value;
|
|
3461
|
+
if (value == '/') {
|
|
3462
|
+
yield pushToken(buffer, 'Comment');
|
|
3463
|
+
buffer = '';
|
|
3464
|
+
break;
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
else {
|
|
3468
|
+
buffer += value;
|
|
3469
|
+
}
|
|
2912
3470
|
}
|
|
2913
|
-
inFunction++;
|
|
2914
3471
|
}
|
|
2915
|
-
|
|
2916
|
-
|
|
3472
|
+
break;
|
|
3473
|
+
case '<':
|
|
3474
|
+
if (buffer.length > 0) {
|
|
3475
|
+
yield pushToken(buffer);
|
|
3476
|
+
buffer = '';
|
|
2917
3477
|
}
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
acc.push([]);
|
|
3478
|
+
buffer += value;
|
|
3479
|
+
value = next();
|
|
3480
|
+
if (ind >= iterator.length) {
|
|
3481
|
+
break;
|
|
2923
3482
|
}
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
3483
|
+
if (peek(3) == '!--') {
|
|
3484
|
+
while (value = next()) {
|
|
3485
|
+
if (ind >= iterator.length) {
|
|
3486
|
+
break;
|
|
3487
|
+
}
|
|
3488
|
+
buffer += value;
|
|
3489
|
+
if (value == '>' && prev(2) == '--') {
|
|
3490
|
+
yield pushToken(buffer, 'CDOCOMM');
|
|
3491
|
+
buffer = '';
|
|
3492
|
+
break;
|
|
3493
|
+
}
|
|
2935
3494
|
}
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
// @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
|
|
2942
|
-
acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
|
|
2943
|
-
return acc;
|
|
2944
|
-
}
|
|
2945
|
-
// @ts-ignore
|
|
2946
|
-
selector1 = selector1.reduce(reduce, []);
|
|
2947
|
-
// @ts-ignore
|
|
2948
|
-
selector2 = selector2.reduce(reduce, []);
|
|
2949
|
-
return selector1 == null || selector2 == null ? null : {
|
|
2950
|
-
eq: eq(selector1, selector2),
|
|
2951
|
-
match,
|
|
2952
|
-
selector1,
|
|
2953
|
-
selector2
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
|
-
function reduceSelector(selector) {
|
|
2957
|
-
if (selector.length == 0) {
|
|
2958
|
-
return null;
|
|
2959
|
-
}
|
|
2960
|
-
const optimized = [];
|
|
2961
|
-
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
2962
|
-
let i = 0;
|
|
2963
|
-
let j;
|
|
2964
|
-
let match;
|
|
2965
|
-
for (; i < k; i++) {
|
|
2966
|
-
const item = selector[0][i];
|
|
2967
|
-
match = true;
|
|
2968
|
-
for (j = 1; j < selector.length; j++) {
|
|
2969
|
-
if (item != selector[j][i]) {
|
|
2970
|
-
match = false;
|
|
3495
|
+
}
|
|
3496
|
+
if (ind >= iterator.length) {
|
|
3497
|
+
yield pushToken(buffer, 'BADCDO');
|
|
3498
|
+
buffer = '';
|
|
3499
|
+
}
|
|
2971
3500
|
break;
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3501
|
+
case '\\':
|
|
3502
|
+
value = next();
|
|
3503
|
+
// EOF
|
|
3504
|
+
if (ind + 1 >= iterator.length) {
|
|
3505
|
+
// end of stream ignore \\
|
|
3506
|
+
yield pushToken(buffer);
|
|
3507
|
+
buffer = '';
|
|
3508
|
+
break;
|
|
3509
|
+
}
|
|
3510
|
+
buffer += value;
|
|
3511
|
+
break;
|
|
3512
|
+
case '"':
|
|
3513
|
+
case "'":
|
|
3514
|
+
yield* consumeString(value);
|
|
3515
|
+
break;
|
|
3516
|
+
case '~':
|
|
3517
|
+
case '|':
|
|
3518
|
+
if (buffer.length > 0) {
|
|
3519
|
+
yield pushToken(buffer);
|
|
3520
|
+
buffer = '';
|
|
3521
|
+
}
|
|
3522
|
+
buffer += value;
|
|
3523
|
+
value = next();
|
|
3524
|
+
if (ind >= iterator.length) {
|
|
3525
|
+
yield pushToken(buffer);
|
|
3526
|
+
buffer = '';
|
|
3527
|
+
break;
|
|
3528
|
+
}
|
|
3529
|
+
if (value == '=') {
|
|
3530
|
+
buffer += value;
|
|
3531
|
+
yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
|
|
3532
|
+
buffer = '';
|
|
3533
|
+
break;
|
|
3534
|
+
}
|
|
3535
|
+
yield pushToken(buffer);
|
|
3536
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3537
|
+
value = next();
|
|
3538
|
+
}
|
|
3539
|
+
buffer = value;
|
|
3540
|
+
break;
|
|
3541
|
+
case '>':
|
|
3542
|
+
if (buffer !== '') {
|
|
3543
|
+
yield pushToken(buffer);
|
|
3544
|
+
buffer = '';
|
|
3545
|
+
}
|
|
3546
|
+
yield pushToken('', 'Gt');
|
|
3547
|
+
consumeWhiteSpace();
|
|
3548
|
+
break;
|
|
3549
|
+
case '.':
|
|
3550
|
+
const codepoint = peek().charCodeAt(0);
|
|
3551
|
+
if (!isDigit(codepoint) && buffer !== '') {
|
|
3552
|
+
yield pushToken(buffer);
|
|
3553
|
+
buffer = value;
|
|
3554
|
+
break;
|
|
3555
|
+
}
|
|
3556
|
+
buffer += value;
|
|
3557
|
+
break;
|
|
3558
|
+
case '+':
|
|
3559
|
+
case ':':
|
|
3560
|
+
case ',':
|
|
3561
|
+
case '=':
|
|
3562
|
+
if (buffer.length > 0) {
|
|
3563
|
+
yield pushToken(buffer);
|
|
3564
|
+
buffer = '';
|
|
3565
|
+
}
|
|
3566
|
+
if (value == ':' && ':' == peek()) {
|
|
3567
|
+
buffer += value + next();
|
|
3568
|
+
break;
|
|
3569
|
+
}
|
|
3570
|
+
yield pushToken(value);
|
|
3571
|
+
buffer = '';
|
|
3572
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3573
|
+
yield pushToken(next());
|
|
3574
|
+
}
|
|
3575
|
+
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3576
|
+
next();
|
|
3577
|
+
}
|
|
3578
|
+
break;
|
|
3579
|
+
case ')':
|
|
3580
|
+
if (buffer.length > 0) {
|
|
3581
|
+
yield pushToken(buffer);
|
|
3582
|
+
buffer = '';
|
|
3583
|
+
}
|
|
3584
|
+
yield pushToken('', 'End-parens');
|
|
3585
|
+
break;
|
|
3586
|
+
case '(':
|
|
3587
|
+
if (buffer.length == 0) {
|
|
3588
|
+
yield pushToken('', 'Start-parens');
|
|
3589
|
+
break;
|
|
3590
|
+
}
|
|
3591
|
+
buffer += value;
|
|
3026
3592
|
// @ts-ignore
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3593
|
+
if (buffer == 'url(') {
|
|
3594
|
+
yield pushToken(buffer);
|
|
3595
|
+
buffer = '';
|
|
3596
|
+
// consume either string or url token
|
|
3597
|
+
let whitespace = '';
|
|
3598
|
+
value = peek();
|
|
3599
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3600
|
+
whitespace += value;
|
|
3601
|
+
}
|
|
3602
|
+
if (whitespace.length > 0) {
|
|
3603
|
+
next(whitespace.length);
|
|
3604
|
+
}
|
|
3605
|
+
value = peek();
|
|
3606
|
+
if (value == '"' || value == "'") {
|
|
3607
|
+
yield* consumeString(next());
|
|
3608
|
+
break;
|
|
3609
|
+
}
|
|
3610
|
+
else {
|
|
3611
|
+
buffer = '';
|
|
3612
|
+
do {
|
|
3613
|
+
let cp = value.charCodeAt(0);
|
|
3614
|
+
// EOF -
|
|
3615
|
+
if (cp == null) {
|
|
3616
|
+
yield pushToken('', 'Bad-url-token');
|
|
3617
|
+
break;
|
|
3618
|
+
}
|
|
3619
|
+
// ')'
|
|
3620
|
+
if (cp == 0x29 || cp == null) {
|
|
3621
|
+
if (buffer.length == 0) {
|
|
3622
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3623
|
+
}
|
|
3624
|
+
else {
|
|
3625
|
+
yield pushToken(buffer, 'Url-token');
|
|
3626
|
+
}
|
|
3627
|
+
if (cp != null) {
|
|
3628
|
+
yield pushToken(next());
|
|
3629
|
+
}
|
|
3630
|
+
break;
|
|
3631
|
+
}
|
|
3632
|
+
if (isWhiteSpace(cp)) {
|
|
3633
|
+
whitespace = next();
|
|
3634
|
+
while (true) {
|
|
3635
|
+
value = peek();
|
|
3636
|
+
cp = value.charCodeAt(0);
|
|
3637
|
+
if (isWhiteSpace(cp)) {
|
|
3638
|
+
whitespace += value;
|
|
3639
|
+
continue;
|
|
3640
|
+
}
|
|
3641
|
+
break;
|
|
3642
|
+
}
|
|
3643
|
+
if (cp == null || cp == 0x29) {
|
|
3644
|
+
continue;
|
|
3645
|
+
}
|
|
3646
|
+
// bad url token
|
|
3647
|
+
buffer += next(whitespace.length);
|
|
3648
|
+
do {
|
|
3649
|
+
value = peek();
|
|
3650
|
+
cp = value.charCodeAt(0);
|
|
3651
|
+
if (cp == null || cp == 0x29) {
|
|
3652
|
+
break;
|
|
3653
|
+
}
|
|
3654
|
+
buffer += next();
|
|
3655
|
+
} while (true);
|
|
3656
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3657
|
+
continue;
|
|
3658
|
+
}
|
|
3659
|
+
buffer += next();
|
|
3660
|
+
value = peek();
|
|
3661
|
+
} while (true);
|
|
3662
|
+
buffer = '';
|
|
3663
|
+
}
|
|
3664
|
+
break;
|
|
3665
|
+
}
|
|
3666
|
+
yield pushToken(buffer);
|
|
3667
|
+
buffer = '';
|
|
3668
|
+
break;
|
|
3669
|
+
case '[':
|
|
3670
|
+
case ']':
|
|
3671
|
+
case '{':
|
|
3672
|
+
case '}':
|
|
3673
|
+
case ';':
|
|
3674
|
+
if (buffer.length > 0) {
|
|
3675
|
+
yield pushToken(buffer);
|
|
3676
|
+
buffer = '';
|
|
3677
|
+
}
|
|
3678
|
+
yield pushToken(value);
|
|
3679
|
+
break;
|
|
3680
|
+
case '!':
|
|
3681
|
+
if (buffer.length > 0) {
|
|
3682
|
+
yield pushToken(buffer);
|
|
3683
|
+
buffer = '';
|
|
3684
|
+
}
|
|
3685
|
+
const important = peek(9);
|
|
3686
|
+
if (important == 'important') {
|
|
3687
|
+
yield pushToken('', 'Important');
|
|
3688
|
+
next(9);
|
|
3689
|
+
buffer = '';
|
|
3690
|
+
break;
|
|
3691
|
+
}
|
|
3692
|
+
buffer = '!';
|
|
3693
|
+
break;
|
|
3694
|
+
default:
|
|
3695
|
+
buffer += value;
|
|
3696
|
+
break;
|
|
3046
3697
|
}
|
|
3047
3698
|
}
|
|
3048
|
-
|
|
3049
|
-
|
|
3699
|
+
if (buffer.length > 0) {
|
|
3700
|
+
yield pushToken(buffer);
|
|
3701
|
+
}
|
|
3050
3702
|
}
|
|
3051
3703
|
|
|
3052
3704
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
3053
3705
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
3706
|
+
/**
|
|
3707
|
+
*
|
|
3708
|
+
* @param iterator
|
|
3709
|
+
* @param opt
|
|
3710
|
+
*/
|
|
3054
3711
|
async function parse$1(iterator, opt = {}) {
|
|
3055
3712
|
const errors = [];
|
|
3056
3713
|
const options = {
|
|
3057
3714
|
src: '',
|
|
3058
3715
|
sourcemap: false,
|
|
3059
|
-
|
|
3716
|
+
minify: true,
|
|
3060
3717
|
nestingRules: false,
|
|
3061
3718
|
resolveImport: false,
|
|
3062
3719
|
resolveUrls: false,
|
|
@@ -3066,208 +3723,64 @@
|
|
|
3066
3723
|
if (options.resolveImport) {
|
|
3067
3724
|
options.resolveUrls = true;
|
|
3068
3725
|
}
|
|
3069
|
-
let ind = -1;
|
|
3070
|
-
let lin = 1;
|
|
3071
|
-
let col = 0;
|
|
3072
|
-
const tokens = [];
|
|
3073
3726
|
const src = options.src;
|
|
3074
3727
|
const stack = [];
|
|
3075
3728
|
const ast = {
|
|
3076
3729
|
typ: "StyleSheet",
|
|
3077
3730
|
chi: []
|
|
3078
3731
|
};
|
|
3079
|
-
|
|
3080
|
-
ind: Math.max(ind, 0),
|
|
3081
|
-
lin: lin,
|
|
3082
|
-
col: Math.max(col, 1)
|
|
3083
|
-
};
|
|
3084
|
-
let value;
|
|
3085
|
-
let buffer = '';
|
|
3086
|
-
let total = iterator.length;
|
|
3087
|
-
let bytesIn = total;
|
|
3732
|
+
let tokens = [];
|
|
3088
3733
|
let map = new Map;
|
|
3734
|
+
let bytesIn = 0;
|
|
3089
3735
|
let context = ast;
|
|
3090
3736
|
if (options.sourcemap) {
|
|
3091
3737
|
ast.loc = {
|
|
3092
3738
|
sta: {
|
|
3093
|
-
ind:
|
|
3094
|
-
lin:
|
|
3095
|
-
col:
|
|
3739
|
+
ind: 0,
|
|
3740
|
+
lin: 1,
|
|
3741
|
+
col: 1
|
|
3096
3742
|
},
|
|
3097
3743
|
src: ''
|
|
3098
3744
|
};
|
|
3099
3745
|
}
|
|
3100
|
-
function
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3746
|
+
async function parseNode(results) {
|
|
3747
|
+
let tokens = results.map(mapToken);
|
|
3748
|
+
let i;
|
|
3749
|
+
let loc;
|
|
3750
|
+
for (i = 0; i < tokens.length; i++) {
|
|
3751
|
+
if (tokens[i].typ == 'Comment') {
|
|
3752
|
+
// @ts-ignore
|
|
3753
|
+
context.chi.push(tokens[i]);
|
|
3754
|
+
const position = map.get(tokens[i]);
|
|
3755
|
+
loc = {
|
|
3756
|
+
sta: position,
|
|
3757
|
+
src
|
|
3758
|
+
};
|
|
3759
|
+
if (options.sourcemap) {
|
|
3760
|
+
tokens[i].loc = loc;
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
else if (tokens[i].typ != 'Whitespace') {
|
|
3764
|
+
break;
|
|
3765
|
+
}
|
|
3118
3766
|
}
|
|
3119
|
-
|
|
3120
|
-
|
|
3767
|
+
tokens = tokens.slice(i);
|
|
3768
|
+
if (tokens.length == 0) {
|
|
3769
|
+
return null;
|
|
3121
3770
|
}
|
|
3122
|
-
|
|
3123
|
-
|
|
3771
|
+
let delim = tokens.at(-1);
|
|
3772
|
+
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3773
|
+
tokens.pop();
|
|
3124
3774
|
}
|
|
3125
|
-
|
|
3126
|
-
|
|
3775
|
+
else {
|
|
3776
|
+
delim = { typ: 'Semi-colon' };
|
|
3127
3777
|
}
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
val: val.slice(0, -1),
|
|
3132
|
-
chi: []
|
|
3133
|
-
}
|
|
3134
|
-
: {
|
|
3135
|
-
typ: 'Pseudo-class',
|
|
3136
|
-
val
|
|
3137
|
-
};
|
|
3778
|
+
// @ts-ignore
|
|
3779
|
+
while (['Whitespace', 'Bad-string', 'Bad-comment'].includes(tokens.at(-1)?.typ)) {
|
|
3780
|
+
tokens.pop();
|
|
3138
3781
|
}
|
|
3139
|
-
if (
|
|
3140
|
-
return
|
|
3141
|
-
typ: 'At-rule',
|
|
3142
|
-
val: val.slice(1)
|
|
3143
|
-
};
|
|
3144
|
-
}
|
|
3145
|
-
if (isFunction(val)) {
|
|
3146
|
-
val = val.slice(0, -1);
|
|
3147
|
-
return {
|
|
3148
|
-
typ: val == 'url' ? 'UrlFunc' : 'Func',
|
|
3149
|
-
val,
|
|
3150
|
-
chi: []
|
|
3151
|
-
};
|
|
3152
|
-
}
|
|
3153
|
-
if (isNumber(val)) {
|
|
3154
|
-
return {
|
|
3155
|
-
typ: 'Number',
|
|
3156
|
-
val
|
|
3157
|
-
};
|
|
3158
|
-
}
|
|
3159
|
-
if (isDimension(val)) {
|
|
3160
|
-
return parseDimension(val);
|
|
3161
|
-
}
|
|
3162
|
-
if (isPercentage(val)) {
|
|
3163
|
-
return {
|
|
3164
|
-
typ: 'Perc',
|
|
3165
|
-
val: val.slice(0, -1)
|
|
3166
|
-
};
|
|
3167
|
-
}
|
|
3168
|
-
if (val == 'currentColor') {
|
|
3169
|
-
return {
|
|
3170
|
-
typ: 'Color',
|
|
3171
|
-
val,
|
|
3172
|
-
kin: 'lit'
|
|
3173
|
-
};
|
|
3174
|
-
}
|
|
3175
|
-
if (isIdent(val)) {
|
|
3176
|
-
return {
|
|
3177
|
-
typ: 'Iden',
|
|
3178
|
-
val
|
|
3179
|
-
};
|
|
3180
|
-
}
|
|
3181
|
-
if (val.charAt(0) == '#' && isHash(val)) {
|
|
3182
|
-
return {
|
|
3183
|
-
typ: 'Hash',
|
|
3184
|
-
val
|
|
3185
|
-
};
|
|
3186
|
-
}
|
|
3187
|
-
if ('"\''.includes(val.charAt(0))) {
|
|
3188
|
-
return {
|
|
3189
|
-
typ: 'Unclosed-string',
|
|
3190
|
-
val
|
|
3191
|
-
};
|
|
3192
|
-
}
|
|
3193
|
-
return {
|
|
3194
|
-
typ: 'Literal',
|
|
3195
|
-
val
|
|
3196
|
-
};
|
|
3197
|
-
}
|
|
3198
|
-
// consume and throw away
|
|
3199
|
-
function consume(open, close) {
|
|
3200
|
-
let count = 1;
|
|
3201
|
-
let chr;
|
|
3202
|
-
while (true) {
|
|
3203
|
-
chr = next();
|
|
3204
|
-
if (chr == '\\') {
|
|
3205
|
-
if (peek() === '') {
|
|
3206
|
-
break;
|
|
3207
|
-
}
|
|
3208
|
-
continue;
|
|
3209
|
-
}
|
|
3210
|
-
else if (chr == '/' && peek() == '*') {
|
|
3211
|
-
next();
|
|
3212
|
-
while (true) {
|
|
3213
|
-
chr = next();
|
|
3214
|
-
if (chr === '') {
|
|
3215
|
-
break;
|
|
3216
|
-
}
|
|
3217
|
-
if (chr == '*' && peek() == '/') {
|
|
3218
|
-
next();
|
|
3219
|
-
break;
|
|
3220
|
-
}
|
|
3221
|
-
}
|
|
3222
|
-
}
|
|
3223
|
-
else if (chr == close) {
|
|
3224
|
-
count--;
|
|
3225
|
-
}
|
|
3226
|
-
else if (chr == open) {
|
|
3227
|
-
count++;
|
|
3228
|
-
}
|
|
3229
|
-
if (chr === '' || count == 0) {
|
|
3230
|
-
break;
|
|
3231
|
-
}
|
|
3232
|
-
}
|
|
3233
|
-
}
|
|
3234
|
-
async function parseNode(tokens) {
|
|
3235
|
-
let i;
|
|
3236
|
-
let loc;
|
|
3237
|
-
for (i = 0; i < tokens.length; i++) {
|
|
3238
|
-
if (tokens[i].typ == 'Comment') {
|
|
3239
|
-
// @ts-ignore
|
|
3240
|
-
context.chi.push(tokens[i]);
|
|
3241
|
-
const position = map.get(tokens[i]);
|
|
3242
|
-
loc = {
|
|
3243
|
-
sta: position,
|
|
3244
|
-
src
|
|
3245
|
-
};
|
|
3246
|
-
if (options.sourcemap) {
|
|
3247
|
-
tokens[i].loc = loc;
|
|
3248
|
-
}
|
|
3249
|
-
}
|
|
3250
|
-
else if (tokens[i].typ != 'Whitespace') {
|
|
3251
|
-
break;
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
tokens = tokens.slice(i);
|
|
3255
|
-
if (tokens.length == 0) {
|
|
3256
|
-
return null;
|
|
3257
|
-
}
|
|
3258
|
-
let delim = tokens.at(-1);
|
|
3259
|
-
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3260
|
-
tokens.pop();
|
|
3261
|
-
}
|
|
3262
|
-
else {
|
|
3263
|
-
delim = { typ: 'Semi-colon' };
|
|
3264
|
-
}
|
|
3265
|
-
// @ts-ignore
|
|
3266
|
-
while (['Whitespace', 'Bad-string', 'Bad-comment'].includes(tokens.at(-1)?.typ)) {
|
|
3267
|
-
tokens.pop();
|
|
3268
|
-
}
|
|
3269
|
-
if (tokens.length == 0) {
|
|
3270
|
-
return null;
|
|
3782
|
+
if (tokens.length == 0) {
|
|
3783
|
+
return null;
|
|
3271
3784
|
}
|
|
3272
3785
|
if (tokens[0]?.typ == 'At-rule') {
|
|
3273
3786
|
const atRule = tokens.shift();
|
|
@@ -3329,7 +3842,7 @@
|
|
|
3329
3842
|
// @ts-ignore
|
|
3330
3843
|
const root = await options.load(url, options.src).then((src) => {
|
|
3331
3844
|
return parse$1(src, Object.assign({}, options, {
|
|
3332
|
-
|
|
3845
|
+
minify: false,
|
|
3333
3846
|
// @ts-ignore
|
|
3334
3847
|
src: options.resolve(url, options.src).absolute
|
|
3335
3848
|
}));
|
|
@@ -3380,626 +3893,336 @@
|
|
|
3380
3893
|
// rule
|
|
3381
3894
|
if (delim.typ == 'Block-start') {
|
|
3382
3895
|
const position = map.get(tokens[0]);
|
|
3383
|
-
if (context.typ == 'Rule') {
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
}
|
|
3896
|
+
// if (context.typ == 'Rule') {
|
|
3897
|
+
//
|
|
3898
|
+
// if (tokens[0]?.typ == 'Iden') {
|
|
3899
|
+
// errors.push({action: 'drop', message: 'invalid nesting rule', location: {src, ...position}});
|
|
3900
|
+
// return null;
|
|
3901
|
+
// }
|
|
3902
|
+
// }
|
|
3389
3903
|
const uniq = new Map;
|
|
3390
|
-
parseTokens(tokens,
|
|
3904
|
+
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
3391
3905
|
if (curr.typ == 'Whitespace') {
|
|
3392
|
-
if (array[index - 1]?.
|
|
3906
|
+
if (array[index - 1]?.typ == 'Gt' ||
|
|
3907
|
+
array[index + 1]?.typ == 'Gt' ||
|
|
3908
|
+
combinators.includes(array[index - 1]?.val) ||
|
|
3909
|
+
combinators.includes(array[index + 1]?.val)) {
|
|
3393
3910
|
return acc;
|
|
3394
3911
|
}
|
|
3395
3912
|
}
|
|
3396
|
-
let t = renderToken(curr, {
|
|
3913
|
+
let t = renderToken(curr, { minify: true });
|
|
3397
3914
|
if (t == ',') {
|
|
3398
3915
|
acc.push([]);
|
|
3399
3916
|
}
|
|
3400
|
-
else {
|
|
3401
|
-
acc[acc.length - 1].push(t);
|
|
3402
|
-
}
|
|
3403
|
-
return acc;
|
|
3404
|
-
}, [[]]).reduce((acc, curr) => {
|
|
3405
|
-
acc.set(curr.join(''), curr);
|
|
3406
|
-
return acc;
|
|
3407
|
-
}, uniq);
|
|
3408
|
-
const node = {
|
|
3409
|
-
typ: 'Rule',
|
|
3410
|
-
// @ts-ignore
|
|
3411
|
-
sel: [...uniq.keys()].join(','),
|
|
3412
|
-
chi: []
|
|
3413
|
-
};
|
|
3414
|
-
let raw = [...uniq.values()];
|
|
3415
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3416
|
-
loc = {
|
|
3417
|
-
sta: position,
|
|
3418
|
-
src
|
|
3419
|
-
};
|
|
3420
|
-
if (options.sourcemap) {
|
|
3421
|
-
node.loc = loc;
|
|
3422
|
-
}
|
|
3423
|
-
// @ts-ignore
|
|
3424
|
-
context.chi.push(node);
|
|
3425
|
-
return node;
|
|
3426
|
-
}
|
|
3427
|
-
else {
|
|
3428
|
-
// declaration
|
|
3429
|
-
// @ts-ignore
|
|
3430
|
-
let name = null;
|
|
3431
|
-
// @ts-ignore
|
|
3432
|
-
let value = null;
|
|
3433
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
3434
|
-
if (tokens[i].typ == 'Comment') {
|
|
3435
|
-
continue;
|
|
3436
|
-
}
|
|
3437
|
-
if (tokens[i].typ == 'Colon') {
|
|
3438
|
-
name = tokens.slice(0, i);
|
|
3439
|
-
value = parseTokens(tokens.slice(i + 1), 'Declaration', {
|
|
3440
|
-
parseColor: true,
|
|
3441
|
-
src: options.src,
|
|
3442
|
-
resolveUrls: options.resolveUrls,
|
|
3443
|
-
resolve: options.resolve,
|
|
3444
|
-
cwd: options.cwd
|
|
3445
|
-
});
|
|
3446
|
-
}
|
|
3447
|
-
}
|
|
3448
|
-
if (name == null) {
|
|
3449
|
-
name = tokens;
|
|
3450
|
-
}
|
|
3451
|
-
const position = map.get(name[0]);
|
|
3452
|
-
if (name.length > 0) {
|
|
3453
|
-
for (let i = 1; i < name.length; i++) {
|
|
3454
|
-
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
3455
|
-
errors.push({
|
|
3456
|
-
action: 'drop',
|
|
3457
|
-
message: 'invalid declaration',
|
|
3458
|
-
location: { src, ...position }
|
|
3459
|
-
});
|
|
3460
|
-
return null;
|
|
3461
|
-
}
|
|
3462
|
-
}
|
|
3463
|
-
}
|
|
3464
|
-
if (value == null) {
|
|
3465
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3466
|
-
return null;
|
|
3467
|
-
}
|
|
3468
|
-
if (value.length == 0) {
|
|
3469
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3470
|
-
return null;
|
|
3471
|
-
}
|
|
3472
|
-
const node = {
|
|
3473
|
-
typ: 'Declaration',
|
|
3474
|
-
// @ts-ignore
|
|
3475
|
-
nam: renderToken(name.shift(), { removeComments: true }),
|
|
3476
|
-
// @ts-ignore
|
|
3477
|
-
val: value
|
|
3478
|
-
};
|
|
3479
|
-
while (node.val[0]?.typ == 'Whitespace') {
|
|
3480
|
-
node.val.shift();
|
|
3481
|
-
}
|
|
3482
|
-
if (node.val.length == 0) {
|
|
3483
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3484
|
-
return null;
|
|
3485
|
-
}
|
|
3486
|
-
// @ts-ignore
|
|
3487
|
-
context.chi.push(node);
|
|
3488
|
-
return null;
|
|
3489
|
-
}
|
|
3490
|
-
}
|
|
3491
|
-
}
|
|
3492
|
-
function peek(count = 1) {
|
|
3493
|
-
if (count == 1) {
|
|
3494
|
-
return iterator.charAt(ind + 1);
|
|
3495
|
-
}
|
|
3496
|
-
return iterator.slice(ind + 1, ind + count + 1);
|
|
3497
|
-
}
|
|
3498
|
-
function prev(count = 1) {
|
|
3499
|
-
if (count == 1) {
|
|
3500
|
-
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3501
|
-
}
|
|
3502
|
-
return iterator.slice(ind - 1 - count, ind - 1);
|
|
3503
|
-
}
|
|
3504
|
-
function next(count = 1) {
|
|
3505
|
-
let char = '';
|
|
3506
|
-
while (count-- > 0 && ind < total) {
|
|
3507
|
-
const codepoint = iterator.charCodeAt(++ind);
|
|
3508
|
-
if (isNaN(codepoint)) {
|
|
3509
|
-
return char;
|
|
3510
|
-
}
|
|
3511
|
-
char += iterator.charAt(ind);
|
|
3512
|
-
if (isNewLine(codepoint)) {
|
|
3513
|
-
lin++;
|
|
3514
|
-
col = 0;
|
|
3515
|
-
}
|
|
3516
|
-
else {
|
|
3517
|
-
col++;
|
|
3518
|
-
}
|
|
3519
|
-
}
|
|
3520
|
-
return char;
|
|
3521
|
-
}
|
|
3522
|
-
function pushToken(token) {
|
|
3523
|
-
tokens.push(token);
|
|
3524
|
-
map.set(token, { ...position });
|
|
3525
|
-
position.ind = ind;
|
|
3526
|
-
position.lin = lin;
|
|
3527
|
-
position.col = col == 0 ? 1 : col;
|
|
3528
|
-
}
|
|
3529
|
-
function consumeWhiteSpace() {
|
|
3530
|
-
let count = 0;
|
|
3531
|
-
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3532
|
-
count++;
|
|
3533
|
-
}
|
|
3534
|
-
next(count);
|
|
3535
|
-
return count;
|
|
3536
|
-
}
|
|
3537
|
-
function consumeString(quoteStr) {
|
|
3538
|
-
const quote = quoteStr;
|
|
3539
|
-
let value;
|
|
3540
|
-
let hasNewLine = false;
|
|
3541
|
-
if (buffer.length > 0) {
|
|
3542
|
-
pushToken(getType(buffer));
|
|
3543
|
-
buffer = '';
|
|
3544
|
-
}
|
|
3545
|
-
buffer += quoteStr;
|
|
3546
|
-
while (ind < total) {
|
|
3547
|
-
value = peek();
|
|
3548
|
-
if (ind >= total) {
|
|
3549
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'Unclosed-string', val: buffer });
|
|
3550
|
-
break;
|
|
3551
|
-
}
|
|
3552
|
-
if (value == '\\') {
|
|
3553
|
-
const sequence = peek(6);
|
|
3554
|
-
let escapeSequence = '';
|
|
3555
|
-
let codepoint;
|
|
3556
|
-
let i;
|
|
3557
|
-
for (i = 1; i < sequence.length; i++) {
|
|
3558
|
-
codepoint = sequence.charCodeAt(i);
|
|
3559
|
-
if (codepoint == 0x20 ||
|
|
3560
|
-
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
3561
|
-
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3562
|
-
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3563
|
-
escapeSequence += sequence[i];
|
|
3564
|
-
if (codepoint == 0x20) {
|
|
3565
|
-
break;
|
|
3566
|
-
}
|
|
3567
|
-
continue;
|
|
3568
|
-
}
|
|
3569
|
-
break;
|
|
3570
|
-
}
|
|
3571
|
-
// not hex or new line
|
|
3572
|
-
// @ts-ignore
|
|
3573
|
-
if (i == 1 && !isNewLine(codepoint)) {
|
|
3574
|
-
buffer += sequence[i];
|
|
3575
|
-
next(2);
|
|
3576
|
-
continue;
|
|
3577
|
-
}
|
|
3578
|
-
if (escapeSequence.trimEnd().length > 0) {
|
|
3579
|
-
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
3580
|
-
if (codepoint == 0 ||
|
|
3581
|
-
// leading surrogate
|
|
3582
|
-
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
3583
|
-
// trailing surrogate
|
|
3584
|
-
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
3585
|
-
buffer += String.fromCodePoint(0xFFFD);
|
|
3586
|
-
}
|
|
3587
|
-
else {
|
|
3588
|
-
buffer += String.fromCodePoint(codepoint);
|
|
3589
|
-
}
|
|
3590
|
-
next(escapeSequence.length + 1);
|
|
3591
|
-
continue;
|
|
3592
|
-
}
|
|
3593
|
-
// buffer += value;
|
|
3594
|
-
if (ind >= total) {
|
|
3595
|
-
// drop '\\' at the end
|
|
3596
|
-
pushToken(getType(buffer));
|
|
3597
|
-
break;
|
|
3598
|
-
}
|
|
3599
|
-
buffer += next(2);
|
|
3600
|
-
continue;
|
|
3601
|
-
}
|
|
3602
|
-
if (value == quote) {
|
|
3603
|
-
buffer += value;
|
|
3604
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'String', val: buffer });
|
|
3605
|
-
next();
|
|
3606
|
-
// i += value.length;
|
|
3607
|
-
buffer = '';
|
|
3608
|
-
break;
|
|
3609
|
-
}
|
|
3610
|
-
if (isNewLine(value.charCodeAt(0))) {
|
|
3611
|
-
hasNewLine = true;
|
|
3612
|
-
}
|
|
3613
|
-
if (hasNewLine && value == ';') {
|
|
3614
|
-
pushToken({ typ: 'Bad-string', val: buffer });
|
|
3615
|
-
buffer = '';
|
|
3616
|
-
break;
|
|
3617
|
-
}
|
|
3618
|
-
buffer += value;
|
|
3619
|
-
// i += value.length;
|
|
3620
|
-
next();
|
|
3621
|
-
}
|
|
3622
|
-
}
|
|
3623
|
-
while (ind < total) {
|
|
3624
|
-
value = next();
|
|
3625
|
-
if (ind >= total) {
|
|
3626
|
-
if (buffer.length > 0) {
|
|
3627
|
-
pushToken(getType(buffer));
|
|
3628
|
-
buffer = '';
|
|
3629
|
-
}
|
|
3630
|
-
break;
|
|
3631
|
-
}
|
|
3632
|
-
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
3633
|
-
if (buffer.length > 0) {
|
|
3634
|
-
pushToken(getType(buffer));
|
|
3635
|
-
buffer = '';
|
|
3636
|
-
}
|
|
3637
|
-
while (ind < total) {
|
|
3638
|
-
value = next();
|
|
3639
|
-
if (ind >= total) {
|
|
3640
|
-
break;
|
|
3641
|
-
}
|
|
3642
|
-
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
3643
|
-
break;
|
|
3644
|
-
}
|
|
3645
|
-
}
|
|
3646
|
-
pushToken({ typ: 'Whitespace' });
|
|
3647
|
-
buffer = '';
|
|
3648
|
-
if (ind >= total) {
|
|
3649
|
-
break;
|
|
3650
|
-
}
|
|
3651
|
-
}
|
|
3652
|
-
switch (value) {
|
|
3653
|
-
case '/':
|
|
3654
|
-
if (buffer.length > 0 && tokens.at(-1)?.typ == 'Whitespace') {
|
|
3655
|
-
pushToken(getType(buffer));
|
|
3656
|
-
buffer = '';
|
|
3657
|
-
if (peek() != '*') {
|
|
3658
|
-
pushToken(getType(value));
|
|
3659
|
-
break;
|
|
3660
|
-
}
|
|
3661
|
-
}
|
|
3662
|
-
buffer += value;
|
|
3663
|
-
if (peek() == '*') {
|
|
3664
|
-
buffer += '*';
|
|
3665
|
-
// i++;
|
|
3666
|
-
next();
|
|
3667
|
-
while (ind < total) {
|
|
3668
|
-
value = next();
|
|
3669
|
-
if (ind >= total) {
|
|
3670
|
-
pushToken({
|
|
3671
|
-
typ: 'Bad-comment', val: buffer
|
|
3672
|
-
});
|
|
3673
|
-
break;
|
|
3674
|
-
}
|
|
3675
|
-
if (value == '\\') {
|
|
3676
|
-
buffer += value;
|
|
3677
|
-
value = next();
|
|
3678
|
-
if (ind >= total) {
|
|
3679
|
-
pushToken({
|
|
3680
|
-
typ: 'Bad-comment',
|
|
3681
|
-
val: buffer
|
|
3682
|
-
});
|
|
3683
|
-
break;
|
|
3684
|
-
}
|
|
3685
|
-
buffer += value;
|
|
3686
|
-
continue;
|
|
3687
|
-
}
|
|
3688
|
-
if (value == '*') {
|
|
3689
|
-
buffer += value;
|
|
3690
|
-
value = next();
|
|
3691
|
-
if (ind >= total) {
|
|
3692
|
-
pushToken({
|
|
3693
|
-
typ: 'Bad-comment', val: buffer
|
|
3694
|
-
});
|
|
3695
|
-
break;
|
|
3696
|
-
}
|
|
3697
|
-
buffer += value;
|
|
3698
|
-
if (value == '/') {
|
|
3699
|
-
pushToken({ typ: 'Comment', val: buffer });
|
|
3700
|
-
buffer = '';
|
|
3701
|
-
break;
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
else {
|
|
3705
|
-
buffer += value;
|
|
3706
|
-
}
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
break;
|
|
3710
|
-
case '<':
|
|
3711
|
-
if (buffer.length > 0) {
|
|
3712
|
-
pushToken(getType(buffer));
|
|
3713
|
-
buffer = '';
|
|
3714
|
-
}
|
|
3715
|
-
buffer += value;
|
|
3716
|
-
value = next();
|
|
3717
|
-
if (ind >= total) {
|
|
3718
|
-
break;
|
|
3719
|
-
}
|
|
3720
|
-
if (peek(3) == '!--') {
|
|
3721
|
-
while (ind < total) {
|
|
3722
|
-
value = next();
|
|
3723
|
-
if (ind >= total) {
|
|
3724
|
-
break;
|
|
3725
|
-
}
|
|
3726
|
-
buffer += value;
|
|
3727
|
-
if (value == '>' && prev(2) == '--') {
|
|
3728
|
-
pushToken({
|
|
3729
|
-
typ: 'CDOCOMM',
|
|
3730
|
-
val: buffer
|
|
3731
|
-
});
|
|
3732
|
-
buffer = '';
|
|
3733
|
-
break;
|
|
3734
|
-
}
|
|
3735
|
-
}
|
|
3736
|
-
}
|
|
3737
|
-
if (ind >= total) {
|
|
3738
|
-
pushToken({ typ: 'BADCDO', val: buffer });
|
|
3739
|
-
buffer = '';
|
|
3740
|
-
}
|
|
3741
|
-
break;
|
|
3742
|
-
case '\\':
|
|
3743
|
-
value = next();
|
|
3744
|
-
// EOF
|
|
3745
|
-
if (ind + 1 >= total) {
|
|
3746
|
-
// end of stream ignore \\
|
|
3747
|
-
pushToken(getType(buffer));
|
|
3748
|
-
buffer = '';
|
|
3749
|
-
break;
|
|
3750
|
-
}
|
|
3751
|
-
buffer += value;
|
|
3752
|
-
break;
|
|
3753
|
-
case '"':
|
|
3754
|
-
case "'":
|
|
3755
|
-
consumeString(value);
|
|
3756
|
-
break;
|
|
3757
|
-
case '~':
|
|
3758
|
-
case '|':
|
|
3759
|
-
if (tokens.at(-1)?.typ == 'Whitespace') {
|
|
3760
|
-
tokens.pop();
|
|
3761
|
-
}
|
|
3762
|
-
if (buffer.length > 0) {
|
|
3763
|
-
pushToken(getType(buffer));
|
|
3764
|
-
buffer = '';
|
|
3765
|
-
}
|
|
3766
|
-
buffer += value;
|
|
3767
|
-
value = next();
|
|
3768
|
-
if (ind >= total) {
|
|
3769
|
-
pushToken(getType(buffer));
|
|
3770
|
-
buffer = '';
|
|
3771
|
-
break;
|
|
3772
|
-
}
|
|
3773
|
-
if (value == '=') {
|
|
3774
|
-
buffer += value;
|
|
3775
|
-
pushToken({
|
|
3776
|
-
typ: buffer[0] == '~' ? 'Includes' : 'Dash-matches',
|
|
3777
|
-
val: buffer
|
|
3778
|
-
});
|
|
3779
|
-
buffer = '';
|
|
3780
|
-
break;
|
|
3781
|
-
}
|
|
3782
|
-
pushToken(getType(buffer));
|
|
3783
|
-
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3784
|
-
value = next();
|
|
3785
|
-
}
|
|
3786
|
-
buffer = value;
|
|
3787
|
-
break;
|
|
3788
|
-
case '>':
|
|
3789
|
-
if (buffer !== '') {
|
|
3790
|
-
pushToken(getType(buffer));
|
|
3791
|
-
buffer = '';
|
|
3792
|
-
}
|
|
3793
|
-
if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
3794
|
-
tokens.pop();
|
|
3795
|
-
}
|
|
3796
|
-
pushToken({ typ: 'Gt' });
|
|
3797
|
-
consumeWhiteSpace();
|
|
3798
|
-
break;
|
|
3799
|
-
case '.':
|
|
3800
|
-
const codepoint = peek().charCodeAt(0);
|
|
3801
|
-
if (!isDigit(codepoint) && buffer !== '') {
|
|
3802
|
-
pushToken(getType(buffer));
|
|
3803
|
-
buffer = value;
|
|
3804
|
-
break;
|
|
3805
|
-
}
|
|
3806
|
-
buffer += value;
|
|
3807
|
-
break;
|
|
3808
|
-
case '+':
|
|
3809
|
-
case ':':
|
|
3810
|
-
case ',':
|
|
3811
|
-
case '=':
|
|
3812
|
-
if (buffer.length > 0) {
|
|
3813
|
-
pushToken(getType(buffer));
|
|
3814
|
-
buffer = '';
|
|
3815
|
-
}
|
|
3816
|
-
if (value == ':' && ':' == peek()) {
|
|
3817
|
-
buffer += value + next();
|
|
3818
|
-
break;
|
|
3819
|
-
}
|
|
3820
|
-
pushToken(getType(value));
|
|
3821
|
-
buffer = '';
|
|
3822
|
-
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3823
|
-
pushToken(getType(next()));
|
|
3824
|
-
}
|
|
3825
|
-
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3826
|
-
next();
|
|
3917
|
+
else {
|
|
3918
|
+
acc[acc.length - 1].push(t);
|
|
3919
|
+
}
|
|
3920
|
+
return acc;
|
|
3921
|
+
}, [[]]).reduce((acc, curr) => {
|
|
3922
|
+
acc.set(curr.join(''), curr);
|
|
3923
|
+
return acc;
|
|
3924
|
+
}, uniq);
|
|
3925
|
+
const node = {
|
|
3926
|
+
typ: 'Rule',
|
|
3927
|
+
// @ts-ignore
|
|
3928
|
+
sel: [...uniq.keys()].join(','),
|
|
3929
|
+
chi: []
|
|
3930
|
+
};
|
|
3931
|
+
let raw = [...uniq.values()];
|
|
3932
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3933
|
+
loc = {
|
|
3934
|
+
sta: position,
|
|
3935
|
+
src
|
|
3936
|
+
};
|
|
3937
|
+
if (options.sourcemap) {
|
|
3938
|
+
node.loc = loc;
|
|
3827
3939
|
}
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3940
|
+
// @ts-ignore
|
|
3941
|
+
context.chi.push(node);
|
|
3942
|
+
return node;
|
|
3943
|
+
}
|
|
3944
|
+
else {
|
|
3945
|
+
// declaration
|
|
3946
|
+
// @ts-ignore
|
|
3947
|
+
let name = null;
|
|
3948
|
+
// @ts-ignore
|
|
3949
|
+
let value = null;
|
|
3950
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3951
|
+
if (tokens[i].typ == 'Comment') {
|
|
3952
|
+
continue;
|
|
3953
|
+
}
|
|
3954
|
+
if (tokens[i].typ == 'Colon') {
|
|
3955
|
+
name = tokens.slice(0, i);
|
|
3956
|
+
value = parseTokens(tokens.slice(i + 1), {
|
|
3957
|
+
parseColor: true,
|
|
3958
|
+
src: options.src,
|
|
3959
|
+
resolveUrls: options.resolveUrls,
|
|
3960
|
+
resolve: options.resolve,
|
|
3961
|
+
cwd: options.cwd
|
|
3962
|
+
});
|
|
3963
|
+
}
|
|
3833
3964
|
}
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
case '(':
|
|
3837
|
-
if (buffer.length == 0) {
|
|
3838
|
-
pushToken({ typ: 'Start-parens' });
|
|
3965
|
+
if (name == null) {
|
|
3966
|
+
name = tokens;
|
|
3839
3967
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
whitespace += value;
|
|
3851
|
-
}
|
|
3852
|
-
if (whitespace.length > 0) {
|
|
3853
|
-
next(whitespace.length);
|
|
3854
|
-
}
|
|
3855
|
-
value = peek();
|
|
3856
|
-
if (value == '"' || value == "'") {
|
|
3857
|
-
consumeString(next());
|
|
3858
|
-
let token = tokens[tokens.length - 1];
|
|
3859
|
-
if (['String', 'Literal'].includes(token.typ) && urlTokenMatcher.test(token.val)) {
|
|
3860
|
-
if (token.val.slice(1, 6) != 'data:') {
|
|
3861
|
-
if (token.typ == 'String') {
|
|
3862
|
-
token.val = token.val.slice(1, -1);
|
|
3863
|
-
}
|
|
3864
|
-
// @ts-ignore
|
|
3865
|
-
token.typ = 'Url-token';
|
|
3866
|
-
}
|
|
3867
|
-
}
|
|
3868
|
-
break;
|
|
3869
|
-
}
|
|
3870
|
-
else {
|
|
3871
|
-
buffer = '';
|
|
3872
|
-
do {
|
|
3873
|
-
let cp = value.charCodeAt(0);
|
|
3874
|
-
// EOF -
|
|
3875
|
-
if (cp == null) {
|
|
3876
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3877
|
-
break;
|
|
3878
|
-
}
|
|
3879
|
-
// ')'
|
|
3880
|
-
if (cp == 0x29 || cp == null) {
|
|
3881
|
-
if (buffer.length == 0) {
|
|
3882
|
-
pushToken({ typ: 'Bad-url-token', val: '' });
|
|
3883
|
-
}
|
|
3884
|
-
else {
|
|
3885
|
-
pushToken({ typ: 'Url-token', val: buffer });
|
|
3886
|
-
}
|
|
3887
|
-
if (cp != null) {
|
|
3888
|
-
pushToken(getType(next()));
|
|
3889
|
-
}
|
|
3890
|
-
break;
|
|
3891
|
-
}
|
|
3892
|
-
if (isWhiteSpace(cp)) {
|
|
3893
|
-
whitespace = next();
|
|
3894
|
-
while (true) {
|
|
3895
|
-
value = peek();
|
|
3896
|
-
cp = value.charCodeAt(0);
|
|
3897
|
-
if (isWhiteSpace(cp)) {
|
|
3898
|
-
whitespace += value;
|
|
3899
|
-
continue;
|
|
3900
|
-
}
|
|
3901
|
-
break;
|
|
3902
|
-
}
|
|
3903
|
-
if (cp == null || cp == 0x29) {
|
|
3904
|
-
continue;
|
|
3905
|
-
}
|
|
3906
|
-
// bad url token
|
|
3907
|
-
buffer += next(whitespace.length);
|
|
3908
|
-
do {
|
|
3909
|
-
value = peek();
|
|
3910
|
-
cp = value.charCodeAt(0);
|
|
3911
|
-
if (cp == null || cp == 0x29) {
|
|
3912
|
-
break;
|
|
3913
|
-
}
|
|
3914
|
-
buffer += next();
|
|
3915
|
-
} while (true);
|
|
3916
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3917
|
-
continue;
|
|
3918
|
-
}
|
|
3919
|
-
buffer += next();
|
|
3920
|
-
value = peek();
|
|
3921
|
-
} while (true);
|
|
3922
|
-
buffer = '';
|
|
3968
|
+
const position = map.get(name[0]);
|
|
3969
|
+
if (name.length > 0) {
|
|
3970
|
+
for (let i = 1; i < name.length; i++) {
|
|
3971
|
+
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
3972
|
+
errors.push({
|
|
3973
|
+
action: 'drop',
|
|
3974
|
+
message: 'invalid declaration',
|
|
3975
|
+
location: { src, ...position }
|
|
3976
|
+
});
|
|
3977
|
+
return null;
|
|
3923
3978
|
}
|
|
3924
3979
|
}
|
|
3925
3980
|
}
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
pushToken(getType(buffer));
|
|
3934
|
-
buffer = '';
|
|
3981
|
+
if (value == null) {
|
|
3982
|
+
errors.push({
|
|
3983
|
+
action: 'drop',
|
|
3984
|
+
message: 'invalid declaration',
|
|
3985
|
+
location: { src, ...position }
|
|
3986
|
+
});
|
|
3987
|
+
return null;
|
|
3935
3988
|
}
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
context = node;
|
|
3944
|
-
}
|
|
3945
|
-
else if (value == '{') {
|
|
3946
|
-
// node == null
|
|
3947
|
-
// consume and throw away until the closing '}' or EOF
|
|
3948
|
-
consume('{', '}');
|
|
3949
|
-
}
|
|
3950
|
-
tokens.length = 0;
|
|
3951
|
-
map.clear();
|
|
3989
|
+
if (value.length == 0) {
|
|
3990
|
+
errors.push({
|
|
3991
|
+
action: 'drop',
|
|
3992
|
+
message: 'invalid declaration',
|
|
3993
|
+
location: { src, ...position }
|
|
3994
|
+
});
|
|
3995
|
+
return null;
|
|
3952
3996
|
}
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
const previousNode = stack.pop();
|
|
3997
|
+
const node = {
|
|
3998
|
+
typ: 'Declaration',
|
|
3956
3999
|
// @ts-ignore
|
|
3957
|
-
|
|
4000
|
+
nam: renderToken(name.shift(), { removeComments: true }),
|
|
3958
4001
|
// @ts-ignore
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
map.clear();
|
|
3964
|
-
buffer = '';
|
|
3965
|
-
}
|
|
3966
|
-
break;
|
|
3967
|
-
case '!':
|
|
3968
|
-
if (buffer.length > 0) {
|
|
3969
|
-
pushToken(getType(buffer));
|
|
3970
|
-
buffer = '';
|
|
4002
|
+
val: value
|
|
4003
|
+
};
|
|
4004
|
+
while (node.val[0]?.typ == 'Whitespace') {
|
|
4005
|
+
node.val.shift();
|
|
3971
4006
|
}
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
buffer = '';
|
|
3980
|
-
break;
|
|
4007
|
+
if (node.val.length == 0) {
|
|
4008
|
+
errors.push({
|
|
4009
|
+
action: 'drop',
|
|
4010
|
+
message: 'invalid declaration',
|
|
4011
|
+
location: { src, ...position }
|
|
4012
|
+
});
|
|
4013
|
+
return null;
|
|
3981
4014
|
}
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
break;
|
|
4015
|
+
// @ts-ignore
|
|
4016
|
+
context.chi.push(node);
|
|
4017
|
+
return null;
|
|
4018
|
+
}
|
|
3987
4019
|
}
|
|
3988
4020
|
}
|
|
3989
|
-
|
|
3990
|
-
|
|
4021
|
+
function mapToken(token) {
|
|
4022
|
+
const node = getTokenType(token.token, token.hint);
|
|
4023
|
+
map.set(node, token.position);
|
|
4024
|
+
return node;
|
|
4025
|
+
}
|
|
4026
|
+
const iter = tokenize(iterator);
|
|
4027
|
+
let item;
|
|
4028
|
+
while (true) {
|
|
4029
|
+
item = iter.next().value;
|
|
4030
|
+
if (item == null) {
|
|
4031
|
+
break;
|
|
4032
|
+
}
|
|
4033
|
+
tokens.push(item);
|
|
4034
|
+
bytesIn = item.bytesIn;
|
|
4035
|
+
if (item.token == ';' || item.token == '{') {
|
|
4036
|
+
let node = await parseNode(tokens);
|
|
4037
|
+
if (node != null) {
|
|
4038
|
+
stack.push(node);
|
|
4039
|
+
// @ts-ignore
|
|
4040
|
+
context = node;
|
|
4041
|
+
}
|
|
4042
|
+
else if (item.token == '{') {
|
|
4043
|
+
// node == null
|
|
4044
|
+
// consume and throw away until the closing '}' or EOF
|
|
4045
|
+
let inBlock = 1;
|
|
4046
|
+
do {
|
|
4047
|
+
item = iter.next().value;
|
|
4048
|
+
if (item == null) {
|
|
4049
|
+
break;
|
|
4050
|
+
}
|
|
4051
|
+
if (item.token == '{') {
|
|
4052
|
+
inBlock++;
|
|
4053
|
+
}
|
|
4054
|
+
else if (item.token == '}') {
|
|
4055
|
+
inBlock--;
|
|
4056
|
+
}
|
|
4057
|
+
} while (inBlock != 0);
|
|
4058
|
+
}
|
|
4059
|
+
tokens = [];
|
|
4060
|
+
map = new Map;
|
|
4061
|
+
}
|
|
4062
|
+
else if (item.token == '}') {
|
|
4063
|
+
await parseNode(tokens);
|
|
4064
|
+
const previousNode = stack.pop();
|
|
4065
|
+
// @ts-ignore
|
|
4066
|
+
context = stack[stack.length - 1] || ast;
|
|
4067
|
+
// @ts-ignore
|
|
4068
|
+
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
4069
|
+
context.chi.pop();
|
|
4070
|
+
}
|
|
4071
|
+
tokens = [];
|
|
4072
|
+
map = new Map;
|
|
4073
|
+
}
|
|
3991
4074
|
}
|
|
3992
4075
|
if (tokens.length > 0) {
|
|
3993
4076
|
await parseNode(tokens);
|
|
3994
4077
|
}
|
|
3995
|
-
if (options.
|
|
4078
|
+
if (options.minify) {
|
|
3996
4079
|
if (ast.chi.length > 0) {
|
|
3997
|
-
|
|
4080
|
+
minify(ast, options, true);
|
|
3998
4081
|
}
|
|
3999
4082
|
}
|
|
4000
4083
|
return { ast, errors, bytesIn };
|
|
4001
4084
|
}
|
|
4002
|
-
function
|
|
4085
|
+
function parseString(src, options = { location: false }) {
|
|
4086
|
+
return [...tokenize(src)].map(t => {
|
|
4087
|
+
const token = getTokenType(t.token, t.hint);
|
|
4088
|
+
if (options.location) {
|
|
4089
|
+
Object.assign(token, { loc: t.position });
|
|
4090
|
+
}
|
|
4091
|
+
return token;
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
function getTokenType(val, hint) {
|
|
4095
|
+
if (val === '' && hint == null) {
|
|
4096
|
+
throw new Error('empty string?');
|
|
4097
|
+
}
|
|
4098
|
+
if (hint != null) {
|
|
4099
|
+
return ([
|
|
4100
|
+
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
4101
|
+
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
4102
|
+
'Comma', 'Gt', 'Lt'
|
|
4103
|
+
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
4104
|
+
}
|
|
4105
|
+
if (val == ' ') {
|
|
4106
|
+
return { typ: 'Whitespace' };
|
|
4107
|
+
}
|
|
4108
|
+
if (val == ';') {
|
|
4109
|
+
return { typ: 'Semi-colon' };
|
|
4110
|
+
}
|
|
4111
|
+
if (val == '{') {
|
|
4112
|
+
return { typ: 'Block-start' };
|
|
4113
|
+
}
|
|
4114
|
+
if (val == '}') {
|
|
4115
|
+
return { typ: 'Block-end' };
|
|
4116
|
+
}
|
|
4117
|
+
if (val == '[') {
|
|
4118
|
+
return { typ: 'Attr-start' };
|
|
4119
|
+
}
|
|
4120
|
+
if (val == ']') {
|
|
4121
|
+
return { typ: 'Attr-end' };
|
|
4122
|
+
}
|
|
4123
|
+
if (val == ':') {
|
|
4124
|
+
return { typ: 'Colon' };
|
|
4125
|
+
}
|
|
4126
|
+
if (val == ')') {
|
|
4127
|
+
return { typ: 'End-parens' };
|
|
4128
|
+
}
|
|
4129
|
+
if (val == '(') {
|
|
4130
|
+
return { typ: 'Start-parens' };
|
|
4131
|
+
}
|
|
4132
|
+
if (val == '=') {
|
|
4133
|
+
return { typ: 'Delim', val };
|
|
4134
|
+
}
|
|
4135
|
+
if (val == ';') {
|
|
4136
|
+
return { typ: 'Semi-colon' };
|
|
4137
|
+
}
|
|
4138
|
+
if (val == ',') {
|
|
4139
|
+
return { typ: 'Comma' };
|
|
4140
|
+
}
|
|
4141
|
+
if (val == '<') {
|
|
4142
|
+
return { typ: 'Lt' };
|
|
4143
|
+
}
|
|
4144
|
+
if (val == '>') {
|
|
4145
|
+
return { typ: 'Gt' };
|
|
4146
|
+
}
|
|
4147
|
+
if (isPseudo(val)) {
|
|
4148
|
+
return val.endsWith('(') ? {
|
|
4149
|
+
typ: 'Pseudo-class-func',
|
|
4150
|
+
val: val.slice(0, -1),
|
|
4151
|
+
chi: []
|
|
4152
|
+
}
|
|
4153
|
+
: {
|
|
4154
|
+
typ: 'Pseudo-class',
|
|
4155
|
+
val
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4158
|
+
if (isAtKeyword(val)) {
|
|
4159
|
+
return {
|
|
4160
|
+
typ: 'At-rule',
|
|
4161
|
+
val: val.slice(1)
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4164
|
+
if (isFunction(val)) {
|
|
4165
|
+
val = val.slice(0, -1);
|
|
4166
|
+
return {
|
|
4167
|
+
typ: val == 'url' ? 'UrlFunc' : 'Func',
|
|
4168
|
+
val,
|
|
4169
|
+
chi: []
|
|
4170
|
+
};
|
|
4171
|
+
}
|
|
4172
|
+
if (isNumber(val)) {
|
|
4173
|
+
return {
|
|
4174
|
+
typ: 'Number',
|
|
4175
|
+
val
|
|
4176
|
+
};
|
|
4177
|
+
}
|
|
4178
|
+
if (isDimension(val)) {
|
|
4179
|
+
return parseDimension(val);
|
|
4180
|
+
}
|
|
4181
|
+
if (isPercentage(val)) {
|
|
4182
|
+
return {
|
|
4183
|
+
typ: 'Perc',
|
|
4184
|
+
val: val.slice(0, -1)
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
const v = val.toLowerCase();
|
|
4188
|
+
if (v == 'currentcolor' || val == 'transparent' || v in COLORS_NAMES) {
|
|
4189
|
+
return {
|
|
4190
|
+
typ: 'Color',
|
|
4191
|
+
val,
|
|
4192
|
+
kin: 'lit'
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
4195
|
+
if (isIdent(val)) {
|
|
4196
|
+
return {
|
|
4197
|
+
typ: 'Iden',
|
|
4198
|
+
val
|
|
4199
|
+
};
|
|
4200
|
+
}
|
|
4201
|
+
if (val.charAt(0) == '#' && isHexColor(val)) {
|
|
4202
|
+
return {
|
|
4203
|
+
typ: 'Color',
|
|
4204
|
+
val,
|
|
4205
|
+
kin: 'hex'
|
|
4206
|
+
};
|
|
4207
|
+
}
|
|
4208
|
+
if (val.charAt(0) == '#' && isHash(val)) {
|
|
4209
|
+
return {
|
|
4210
|
+
typ: 'Hash',
|
|
4211
|
+
val
|
|
4212
|
+
};
|
|
4213
|
+
}
|
|
4214
|
+
if ('"\''.includes(val.charAt(0))) {
|
|
4215
|
+
return {
|
|
4216
|
+
typ: 'Unclosed-string',
|
|
4217
|
+
val
|
|
4218
|
+
};
|
|
4219
|
+
}
|
|
4220
|
+
return {
|
|
4221
|
+
typ: 'Literal',
|
|
4222
|
+
val
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
4225
|
+
function parseTokens(tokens, options = {}) {
|
|
4003
4226
|
for (let i = 0; i < tokens.length; i++) {
|
|
4004
4227
|
const t = tokens[i];
|
|
4005
4228
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
@@ -4053,7 +4276,7 @@
|
|
|
4053
4276
|
if (t.chi.length > 1) {
|
|
4054
4277
|
/*(<AttrToken>t).chi =*/
|
|
4055
4278
|
// @ts-ignore
|
|
4056
|
-
parseTokens(t.chi, t.typ
|
|
4279
|
+
parseTokens(t.chi, t.typ);
|
|
4057
4280
|
}
|
|
4058
4281
|
// @ts-ignore
|
|
4059
4282
|
t.chi.forEach(val => {
|
|
@@ -4165,8 +4388,8 @@
|
|
|
4165
4388
|
// @ts-ignore
|
|
4166
4389
|
if (t.chi.length > 0) {
|
|
4167
4390
|
// @ts-ignore
|
|
4168
|
-
parseTokens(t.chi, t.typ
|
|
4169
|
-
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.
|
|
4391
|
+
parseTokens(t.chi, t.typ);
|
|
4392
|
+
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
|
|
4170
4393
|
//
|
|
4171
4394
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
4172
4395
|
if (count == 1 ||
|
|
@@ -4204,40 +4427,9 @@
|
|
|
4204
4427
|
}
|
|
4205
4428
|
return tokens;
|
|
4206
4429
|
}
|
|
4207
|
-
function getBlockType(chr) {
|
|
4208
|
-
if (chr == ';') {
|
|
4209
|
-
return { typ: 'Semi-colon' };
|
|
4210
|
-
}
|
|
4211
|
-
if (chr == '{') {
|
|
4212
|
-
return { typ: 'Block-start' };
|
|
4213
|
-
}
|
|
4214
|
-
if (chr == '}') {
|
|
4215
|
-
return { typ: 'Block-end' };
|
|
4216
|
-
}
|
|
4217
|
-
if (chr == '[') {
|
|
4218
|
-
return { typ: 'Attr-start' };
|
|
4219
|
-
}
|
|
4220
|
-
if (chr == ']') {
|
|
4221
|
-
return { typ: 'Attr-end' };
|
|
4222
|
-
}
|
|
4223
|
-
throw new Error(`unhandled token: '${chr}'`);
|
|
4224
|
-
}
|
|
4225
|
-
|
|
4226
|
-
function* walk(node) {
|
|
4227
|
-
// @ts-ignore
|
|
4228
|
-
yield* doWalk(node, null, null);
|
|
4229
|
-
}
|
|
4230
|
-
function* doWalk(node, parent, root) {
|
|
4231
|
-
yield { node, parent, root };
|
|
4232
|
-
if ('chi' in node) {
|
|
4233
|
-
for (const child of node.chi) {
|
|
4234
|
-
yield* doWalk(child, node, (root ?? node));
|
|
4235
|
-
}
|
|
4236
|
-
}
|
|
4237
|
-
}
|
|
4238
4430
|
|
|
4239
4431
|
async function transform$1(css, options = {}) {
|
|
4240
|
-
options = {
|
|
4432
|
+
options = { minify: true, removeEmpty: true, ...options };
|
|
4241
4433
|
const startTime = performance.now();
|
|
4242
4434
|
const parseResult = await parse$1(css, options);
|
|
4243
4435
|
const renderTime = performance.now();
|
|
@@ -4385,18 +4577,44 @@
|
|
|
4385
4577
|
}));
|
|
4386
4578
|
}
|
|
4387
4579
|
|
|
4388
|
-
exports.
|
|
4389
|
-
exports.deduplicateRule = deduplicateRule;
|
|
4580
|
+
exports.combinators = combinators;
|
|
4390
4581
|
exports.dirname = dirname;
|
|
4582
|
+
exports.getConfig = getConfig;
|
|
4391
4583
|
exports.hasDeclaration = hasDeclaration;
|
|
4584
|
+
exports.isAngle = isAngle;
|
|
4585
|
+
exports.isAtKeyword = isAtKeyword;
|
|
4586
|
+
exports.isDigit = isDigit;
|
|
4587
|
+
exports.isDimension = isDimension;
|
|
4588
|
+
exports.isFrequency = isFrequency;
|
|
4589
|
+
exports.isFunction = isFunction;
|
|
4590
|
+
exports.isHash = isHash;
|
|
4591
|
+
exports.isHexColor = isHexColor;
|
|
4592
|
+
exports.isHexDigit = isHexDigit;
|
|
4593
|
+
exports.isIdent = isIdent;
|
|
4594
|
+
exports.isIdentCodepoint = isIdentCodepoint;
|
|
4595
|
+
exports.isIdentStart = isIdentStart;
|
|
4596
|
+
exports.isLength = isLength;
|
|
4597
|
+
exports.isNewLine = isNewLine;
|
|
4598
|
+
exports.isNumber = isNumber;
|
|
4599
|
+
exports.isPercentage = isPercentage;
|
|
4600
|
+
exports.isPseudo = isPseudo;
|
|
4601
|
+
exports.isResolution = isResolution;
|
|
4602
|
+
exports.isTime = isTime;
|
|
4603
|
+
exports.isWhiteSpace = isWhiteSpace;
|
|
4392
4604
|
exports.load = load;
|
|
4393
4605
|
exports.matchUrl = matchUrl;
|
|
4606
|
+
exports.minify = minify;
|
|
4607
|
+
exports.minifyRule = minifyRule;
|
|
4394
4608
|
exports.parse = parse;
|
|
4609
|
+
exports.parseDimension = parseDimension;
|
|
4610
|
+
exports.parseString = parseString;
|
|
4395
4611
|
exports.reduceSelector = reduceSelector;
|
|
4396
4612
|
exports.render = render;
|
|
4397
4613
|
exports.renderToken = renderToken;
|
|
4398
4614
|
exports.resolve = resolve;
|
|
4615
|
+
exports.tokenize = tokenize;
|
|
4399
4616
|
exports.transform = transform;
|
|
4617
|
+
exports.urlTokenMatcher = urlTokenMatcher;
|
|
4400
4618
|
exports.walk = walk;
|
|
4401
4619
|
|
|
4402
4620
|
}));
|