@tbela99/css-parser 0.0.1-rc5 → 0.0.1-rc6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -1
- package/dist/config.json.js +49 -0
- package/dist/index-umd-web.js +2509 -2223
- package/dist/index.cjs +2509 -2223
- package/dist/index.d.ts +35 -26
- package/dist/lib/ast/expand.js +159 -0
- package/dist/lib/ast/minify.js +89 -87
- package/dist/lib/ast/walk.js +10 -1
- package/dist/lib/parser/declaration/list.js +1 -1
- package/dist/lib/parser/declaration/map.js +8 -0
- package/dist/lib/parser/parse.js +36 -22
- package/dist/lib/parser/tokenize.js +136 -74
- package/dist/lib/parser/utils/syntax.js +10 -17
- package/dist/lib/renderer/render.js +16 -24
- package/dist/lib/transform.js +4 -1
- package/dist/node/index.js +5 -4
- package/dist/web/index.js +5 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -477,9 +477,9 @@ interface BorderRadius {
|
|
|
477
477
|
interface ErrorDescription {
|
|
478
478
|
|
|
479
479
|
// drop rule or declaration | fix rule or declaration
|
|
480
|
-
action: 'drop';
|
|
480
|
+
action: 'drop' | 'ignore';
|
|
481
481
|
message: string;
|
|
482
|
-
location
|
|
482
|
+
location?: {
|
|
483
483
|
src: string,
|
|
484
484
|
lin: number,
|
|
485
485
|
col: number;
|
|
@@ -505,6 +505,7 @@ interface ParserOptions {
|
|
|
505
505
|
interface RenderOptions {
|
|
506
506
|
|
|
507
507
|
minify?: boolean;
|
|
508
|
+
expandNestingRules?: boolean;
|
|
508
509
|
preserveLicense?: boolean;
|
|
509
510
|
indent?: string;
|
|
510
511
|
newLine?: string;
|
|
@@ -529,6 +530,7 @@ interface ParseResult {
|
|
|
529
530
|
|
|
530
531
|
interface RenderResult {
|
|
531
532
|
code: string ;
|
|
533
|
+
errors: ErrorDescription[];
|
|
532
534
|
stats: {
|
|
533
535
|
total: string;
|
|
534
536
|
}
|
|
@@ -577,7 +579,7 @@ interface Node {
|
|
|
577
579
|
|
|
578
580
|
interface AstComment extends Node {
|
|
579
581
|
|
|
580
|
-
typ: 'Comment',
|
|
582
|
+
typ: 'Comment' | 'CDOCOMM',
|
|
581
583
|
val: string;
|
|
582
584
|
}
|
|
583
585
|
interface AstDeclaration extends Node {
|
|
@@ -630,6 +632,34 @@ type AstNode =
|
|
|
630
632
|
| AstRule
|
|
631
633
|
| AstDeclaration;
|
|
632
634
|
|
|
635
|
+
declare const combinators: string[];
|
|
636
|
+
declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean, errors?: ErrorDescription[]): AstNode;
|
|
637
|
+
declare function reduceSelector(selector: string[][]): {
|
|
638
|
+
match: boolean;
|
|
639
|
+
optimized: string[];
|
|
640
|
+
selector: string[][];
|
|
641
|
+
reducible: boolean;
|
|
642
|
+
} | null;
|
|
643
|
+
declare function hasDeclaration(node: AstRule): boolean;
|
|
644
|
+
declare function minifyRule(ast: AstRule | AstAtRule): AstRule | AstAtRule;
|
|
645
|
+
declare function splitRule(buffer: string): string[][];
|
|
646
|
+
|
|
647
|
+
declare function walk(node: AstNode): Generator<{
|
|
648
|
+
node: AstNode;
|
|
649
|
+
parent?: AstRuleList;
|
|
650
|
+
root?: AstRuleList;
|
|
651
|
+
}>;
|
|
652
|
+
declare function walkValues(values: Token[], parent?: Token): Generator<{
|
|
653
|
+
value: Token;
|
|
654
|
+
parent: Token | null;
|
|
655
|
+
}>;
|
|
656
|
+
|
|
657
|
+
declare function expand(ast: AstNode): AstNode;
|
|
658
|
+
|
|
659
|
+
declare const colorsFunc: string[];
|
|
660
|
+
declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
|
|
661
|
+
declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string, errors?: ErrorDescription[]): string;
|
|
662
|
+
|
|
633
663
|
declare const urlTokenMatcher: RegExp;
|
|
634
664
|
declare function parseString(src: string, options?: {
|
|
635
665
|
location: boolean;
|
|
@@ -647,6 +677,7 @@ declare function isIdentStart(codepoint: number): boolean;
|
|
|
647
677
|
declare function isDigit(codepoint: number): boolean;
|
|
648
678
|
declare function isIdentCodepoint(codepoint: number): boolean;
|
|
649
679
|
declare function isIdent(name: string): boolean;
|
|
680
|
+
declare function isNonPrintable(codepoint: number): boolean;
|
|
650
681
|
declare function isPseudo(name: string): boolean;
|
|
651
682
|
declare function isHash(name: string): boolean;
|
|
652
683
|
declare function isNumber(name: string): boolean;
|
|
@@ -654,7 +685,6 @@ declare function isDimension(name: string): boolean;
|
|
|
654
685
|
declare function isPercentage(name: string): boolean;
|
|
655
686
|
declare function parseDimension(name: string): DimensionToken | LengthToken | AngleToken;
|
|
656
687
|
declare function isHexColor(name: string): boolean;
|
|
657
|
-
declare function isHexDigit(name: string): boolean;
|
|
658
688
|
declare function isFunction(name: string): boolean;
|
|
659
689
|
declare function isAtKeyword(name: string): boolean;
|
|
660
690
|
declare function isNewLine(codepoint: number): boolean;
|
|
@@ -665,27 +695,6 @@ declare const getConfig: () => PropertiesConfig;
|
|
|
665
695
|
declare const funcList: string[];
|
|
666
696
|
declare function matchType(val: Token, properties: PropertyMapType): boolean;
|
|
667
697
|
|
|
668
|
-
declare const colorsFunc: string[];
|
|
669
|
-
declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
|
|
670
|
-
declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string): string;
|
|
671
|
-
|
|
672
|
-
declare const combinators: string[];
|
|
673
|
-
declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean): AstNode;
|
|
674
|
-
declare function reduceSelector(selector: string[][]): {
|
|
675
|
-
match: boolean;
|
|
676
|
-
optimized: string[];
|
|
677
|
-
selector: string[][];
|
|
678
|
-
reducible: boolean;
|
|
679
|
-
} | null;
|
|
680
|
-
declare function hasDeclaration(node: AstRule): boolean;
|
|
681
|
-
declare function minifyRule(ast: AstRule | AstAtRule): AstRule | AstAtRule;
|
|
682
|
-
|
|
683
|
-
declare function walk(node: AstNode): Generator<{
|
|
684
|
-
node: AstNode;
|
|
685
|
-
parent?: AstRuleList;
|
|
686
|
-
root?: AstRuleList;
|
|
687
|
-
}>;
|
|
688
|
-
|
|
689
698
|
declare function load(url: string, currentFile: string): Promise<string>;
|
|
690
699
|
|
|
691
700
|
declare const matchUrl: RegExp;
|
|
@@ -698,4 +707,4 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
|
|
|
698
707
|
declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
|
|
699
708
|
declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
|
|
700
709
|
|
|
701
|
-
export { colorsFunc, combinators, dirname, funcList, getConfig, hasDeclaration, isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor,
|
|
710
|
+
export { colorsFunc, combinators, dirname, expand, funcList, getConfig, hasDeclaration, isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, load, matchType, matchUrl, minify, minifyRule, parse, parseDimension, parseString, reduceSelector, render, renderToken, resolve, splitRule, tokenize, transform, urlTokenMatcher, walk, walkValues };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { splitRule, combinators } from './minify.js';
|
|
2
|
+
import { parseString } from '../parser/parse.js';
|
|
3
|
+
import { renderToken } from '../renderer/render.js';
|
|
4
|
+
import '../renderer/utils/color.js';
|
|
5
|
+
import { walkValues } from './walk.js';
|
|
6
|
+
|
|
7
|
+
function expand(ast) {
|
|
8
|
+
//
|
|
9
|
+
if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
|
|
10
|
+
return ast;
|
|
11
|
+
}
|
|
12
|
+
if ('Rule' == ast.typ) {
|
|
13
|
+
return {
|
|
14
|
+
typ: 'StyleSheet',
|
|
15
|
+
chi: expandRule(ast)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (!('chi' in ast)) {
|
|
19
|
+
return { ...ast };
|
|
20
|
+
}
|
|
21
|
+
const result = { ...ast, chi: [] };
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
for (let i = 0; i < ast.chi.length; i++) {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
const node = ast.chi[i];
|
|
26
|
+
if (node.typ == 'Rule') {
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
result.chi.push(...expandRule(node));
|
|
29
|
+
// i += expanded.length - 1;
|
|
30
|
+
}
|
|
31
|
+
else if (node.typ == 'AtRule' && 'chi' in node) {
|
|
32
|
+
let hasRule = false;
|
|
33
|
+
let j = node.chi.length;
|
|
34
|
+
while (j--) {
|
|
35
|
+
if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
|
|
36
|
+
hasRule = true;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
result.chi.push({ ...(hasRule ? expand(node) : node) });
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
result.chi.push(node);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
function expandRule(node) {
|
|
51
|
+
const ast = { ...node, chi: node.chi.slice() };
|
|
52
|
+
const result = [];
|
|
53
|
+
if (ast.typ == 'Rule') {
|
|
54
|
+
let i = 0;
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
delete ast.raw;
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
delete ast.optimized;
|
|
59
|
+
for (; i < ast.chi.length; i++) {
|
|
60
|
+
if (ast.chi[i].typ == 'Rule') {
|
|
61
|
+
const rule = ast.chi[i];
|
|
62
|
+
if (!rule.sel.includes('&')) {
|
|
63
|
+
const selRule = splitRule(rule.sel);
|
|
64
|
+
selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
|
|
65
|
+
rule.sel = selRule.reduce((acc, curr) => {
|
|
66
|
+
acc.push(curr.join(''));
|
|
67
|
+
return acc;
|
|
68
|
+
}, []).join(',');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
rule.sel = replaceCompount(rule.sel, ast.sel);
|
|
72
|
+
}
|
|
73
|
+
delete rule.raw;
|
|
74
|
+
delete rule.optimized;
|
|
75
|
+
ast.chi.splice(i--, 1);
|
|
76
|
+
result.push(...expandRule(rule));
|
|
77
|
+
}
|
|
78
|
+
else if (ast.chi[i].typ == 'AtRule') {
|
|
79
|
+
let astAtRule = ast.chi[i];
|
|
80
|
+
const values = [];
|
|
81
|
+
if (astAtRule.nam == 'scope') {
|
|
82
|
+
if (astAtRule.val.includes('&')) {
|
|
83
|
+
astAtRule.val = replaceCompount(astAtRule.val, ast.sel);
|
|
84
|
+
}
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
astAtRule = expand(astAtRule);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
const clone = { ...ast, chi: astAtRule.chi.slice() };
|
|
91
|
+
// @ts-ignore
|
|
92
|
+
astAtRule.chi.length = 0;
|
|
93
|
+
for (const r of expandRule(clone)) {
|
|
94
|
+
if (r.typ == 'AtRule' && 'chi' in r) {
|
|
95
|
+
if (astAtRule.val !== '' && r.val !== '') {
|
|
96
|
+
if (astAtRule.nam == 'media' && r.nam == 'media') {
|
|
97
|
+
r.val = astAtRule.val + ' and ' + r.val;
|
|
98
|
+
}
|
|
99
|
+
else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
|
|
100
|
+
r.val = astAtRule.val + '.' + r.val;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
values.push(r);
|
|
105
|
+
}
|
|
106
|
+
else if (r.typ == 'Rule') {
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
astAtRule.chi.push(...expandRule(r));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
astAtRule.chi.push(r);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
|
|
118
|
+
ast.chi.splice(i--, 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// @ts-ignore
|
|
123
|
+
return ast.chi.length > 0 ? [ast].concat(result) : result;
|
|
124
|
+
}
|
|
125
|
+
function replaceCompount(input, replace) {
|
|
126
|
+
const tokens = parseString(input);
|
|
127
|
+
for (const t of walkValues(tokens)) {
|
|
128
|
+
if (t.value.typ == 'Literal') {
|
|
129
|
+
if (t.value.val == '&') {
|
|
130
|
+
t.value.val = replace;
|
|
131
|
+
}
|
|
132
|
+
else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
|
|
133
|
+
t.value.val = replaceCompoundLiteral(t.value.val, replace);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
|
|
138
|
+
}
|
|
139
|
+
function replaceCompoundLiteral(selector, replace) {
|
|
140
|
+
const tokens = [''];
|
|
141
|
+
let i = 0;
|
|
142
|
+
for (; i < selector.length; i++) {
|
|
143
|
+
if (selector.charAt(i) == '&') {
|
|
144
|
+
tokens.push('&');
|
|
145
|
+
tokens.push('');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
tokens[tokens.length - 1] += selector.charAt(i);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return tokens.sort((a, b) => {
|
|
152
|
+
if (a == '&') {
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
return b == '&' ? -1 : 0;
|
|
156
|
+
}).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { expand };
|
package/dist/lib/ast/minify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isIdentStart, isIdent, isFunction
|
|
1
|
+
import { isIdentStart, isWhiteSpace, isIdent, isFunction } from '../parser/utils/syntax.js';
|
|
2
2
|
import { PropertyList } from '../parser/declaration/list.js';
|
|
3
3
|
import { eq } from '../parser/utils/eq.js';
|
|
4
4
|
import { render } from '../renderer/render.js';
|
|
@@ -6,7 +6,8 @@ import '../renderer/utils/color.js';
|
|
|
6
6
|
|
|
7
7
|
const combinators = ['+', '>', '~'];
|
|
8
8
|
const notEndingWith = ['(', '['].concat(combinators);
|
|
9
|
-
|
|
9
|
+
const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
|
|
10
|
+
function minify(ast, options = {}, recursive = false, errors) {
|
|
10
11
|
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
11
12
|
// @ts-ignore
|
|
12
13
|
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
@@ -15,9 +16,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
15
16
|
// @ts-ignore
|
|
16
17
|
const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
|
|
17
18
|
// @ts-ignore
|
|
18
|
-
Object.defineProperty(wrapper, 'raw', {
|
|
19
|
-
enumerable: false,
|
|
20
|
-
writable: true,
|
|
19
|
+
Object.defineProperty(wrapper, 'raw', { ...definedPropertySettings,
|
|
21
20
|
// @ts-ignore
|
|
22
21
|
value: match.match.map(t => t.slice())
|
|
23
22
|
});
|
|
@@ -25,7 +24,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
25
24
|
// @ts-ignore
|
|
26
25
|
wrapper.chi.push(...previous.chi);
|
|
27
26
|
// @ts-ignore
|
|
28
|
-
if ((nSel == '&' || nSel === '')
|
|
27
|
+
if ((nSel == '&' || nSel === '')) {
|
|
29
28
|
// @ts-ignore
|
|
30
29
|
wrapper.chi.push(...node.chi);
|
|
31
30
|
}
|
|
@@ -96,10 +95,10 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
96
95
|
node1 = { ...node1, chi: node1.chi.slice() };
|
|
97
96
|
node2 = { ...node2, chi: node2.chi.slice() };
|
|
98
97
|
if (raw1 != null) {
|
|
99
|
-
Object.defineProperty(node1, 'raw', {
|
|
98
|
+
Object.defineProperty(node1, 'raw', { ...definedPropertySettings, value: raw1 });
|
|
100
99
|
}
|
|
101
100
|
if (raw2 != null) {
|
|
102
|
-
Object.defineProperty(node2, 'raw', {
|
|
101
|
+
Object.defineProperty(node2, 'raw', { ...definedPropertySettings, value: raw2 });
|
|
103
102
|
}
|
|
104
103
|
const intersect = [];
|
|
105
104
|
while (i--) {
|
|
@@ -199,8 +198,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
199
198
|
}
|
|
200
199
|
}
|
|
201
200
|
if (match.length > 1) {
|
|
202
|
-
|
|
203
|
-
console.error({ match, selector1, selector2 });
|
|
201
|
+
errors?.push({ action: 'ignore', message: `minify: unsupported multilevel matching\n${JSON.stringify({ match, selector1, selector2 }, null, 1)}` });
|
|
204
202
|
return null;
|
|
205
203
|
}
|
|
206
204
|
for (const part of match) {
|
|
@@ -350,7 +348,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
350
348
|
minifyRule(node);
|
|
351
349
|
}
|
|
352
350
|
else {
|
|
353
|
-
minify(node, options, recursive);
|
|
351
|
+
minify(node, options, recursive, errors);
|
|
354
352
|
}
|
|
355
353
|
previous = node;
|
|
356
354
|
nodeIndex = i;
|
|
@@ -404,7 +402,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
404
402
|
nodeIndex = --i;
|
|
405
403
|
// @ts-ignore
|
|
406
404
|
previous = ast.chi[nodeIndex];
|
|
407
|
-
minify(wrapper, options, recursive);
|
|
405
|
+
minify(wrapper, options, recursive, errors);
|
|
408
406
|
continue;
|
|
409
407
|
}
|
|
410
408
|
// @ts-ignore
|
|
@@ -417,8 +415,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
417
415
|
wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
|
|
418
416
|
// @ts-ignore
|
|
419
417
|
Object.defineProperty(wrapper, 'raw', {
|
|
420
|
-
|
|
421
|
-
writable: true,
|
|
418
|
+
...definedPropertySettings,
|
|
422
419
|
// @ts-ignore
|
|
423
420
|
value: [[node.optimized.optimized[0]]]
|
|
424
421
|
});
|
|
@@ -474,82 +471,97 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
474
471
|
}
|
|
475
472
|
}
|
|
476
473
|
// @ts-ignore
|
|
477
|
-
if (previous != null
|
|
474
|
+
if (previous != null) {
|
|
478
475
|
// @ts-ignore
|
|
479
|
-
if (previous
|
|
480
|
-
let shouldMerge = true;
|
|
476
|
+
if ('chi' in previous && ('chi' in node)) {
|
|
481
477
|
// @ts-ignore
|
|
482
|
-
|
|
483
|
-
|
|
478
|
+
if (previous.typ == node.typ) {
|
|
479
|
+
let shouldMerge = true;
|
|
484
480
|
// @ts-ignore
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
// @ts-ignore
|
|
489
|
-
shouldMerge = previous.chi[k].typ == 'Declaration';
|
|
490
|
-
break;
|
|
491
|
-
}
|
|
492
|
-
if (shouldMerge) {
|
|
493
|
-
// @ts-ignore
|
|
494
|
-
if ((node.typ == 'Rule' && node.sel == previous.sel) ||
|
|
481
|
+
let k = previous.chi.length;
|
|
482
|
+
while (k-- > 0) {
|
|
495
483
|
// @ts-ignore
|
|
496
|
-
(
|
|
497
|
-
|
|
498
|
-
|
|
484
|
+
if (previous.chi[k].typ == 'Comment') {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
499
487
|
// @ts-ignore
|
|
500
|
-
|
|
488
|
+
shouldMerge = previous.chi[k].typ == 'Declaration';
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
if (shouldMerge) {
|
|
501
492
|
// @ts-ignore
|
|
502
|
-
if (
|
|
493
|
+
if ((node.typ == 'Rule' && node.sel == previous.sel) ||
|
|
503
494
|
// @ts-ignore
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
nodeIndex = i;
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
else if (node.typ == 'Rule' && previous?.typ == 'Rule') {
|
|
515
|
-
const intersect = diff(previous, node, options);
|
|
516
|
-
if (intersect != null) {
|
|
517
|
-
if (intersect.node1.chi.length == 0) {
|
|
518
|
-
// @ts-ignore
|
|
519
|
-
ast.chi.splice(i--, 1);
|
|
495
|
+
(node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
|
|
496
|
+
// @ts-ignore
|
|
497
|
+
node.chi.unshift(...previous.chi);
|
|
498
|
+
// @ts-ignore
|
|
499
|
+
ast.chi.splice(nodeIndex, 1);
|
|
500
|
+
// @ts-ignore
|
|
501
|
+
if (hasDeclaration(node)) {
|
|
520
502
|
// @ts-ignore
|
|
521
|
-
node
|
|
503
|
+
minifyRule(node);
|
|
522
504
|
}
|
|
523
505
|
else {
|
|
524
|
-
|
|
525
|
-
ast.chi.splice(i, 1, intersect.node1);
|
|
526
|
-
node = intersect.node1;
|
|
506
|
+
minify(node, options, recursive, errors);
|
|
527
507
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
508
|
+
i--;
|
|
509
|
+
previous = node;
|
|
510
|
+
nodeIndex = i;
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
else if (node.typ == 'Rule' && previous?.typ == 'Rule') {
|
|
514
|
+
const intersect = diff(previous, node, options);
|
|
515
|
+
if (intersect != null) {
|
|
516
|
+
if (intersect.node1.chi.length == 0) {
|
|
517
|
+
// @ts-ignore
|
|
518
|
+
ast.chi.splice(i--, 1);
|
|
519
|
+
// @ts-ignore
|
|
520
|
+
node = ast.chi[i];
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
// @ts-ignore
|
|
524
|
+
ast.chi.splice(i, 1, intersect.node1);
|
|
525
|
+
node = intersect.node1;
|
|
526
|
+
}
|
|
527
|
+
if (intersect.node2.chi.length == 0) {
|
|
528
|
+
// @ts-ignore
|
|
529
|
+
ast.chi.splice(nodeIndex, 1, intersect.result);
|
|
530
|
+
previous = intersect.result;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
// @ts-ignore
|
|
534
|
+
ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
|
|
535
|
+
previous = intersect.result;
|
|
536
|
+
// @ts-ignore
|
|
537
|
+
i = nodeIndex;
|
|
538
|
+
}
|
|
539
539
|
}
|
|
540
540
|
}
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
|
-
}
|
|
544
|
-
// @ts-ignore
|
|
545
|
-
if (recursive && previous != node) {
|
|
546
543
|
// @ts-ignore
|
|
547
|
-
if (
|
|
544
|
+
if (recursive && previous != node) {
|
|
548
545
|
// @ts-ignore
|
|
549
|
-
|
|
546
|
+
if (hasDeclaration(previous)) {
|
|
547
|
+
// @ts-ignore
|
|
548
|
+
minifyRule(previous);
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
minify(previous, options, recursive, errors);
|
|
552
|
+
}
|
|
550
553
|
}
|
|
551
|
-
|
|
552
|
-
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
if ('chi' in previous) {
|
|
557
|
+
// @ts-ignore
|
|
558
|
+
if (hasDeclaration(previous)) {
|
|
559
|
+
// @ts-ignore
|
|
560
|
+
minifyRule(previous);
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
minify(previous, options, recursive, errors);
|
|
564
|
+
}
|
|
553
565
|
}
|
|
554
566
|
}
|
|
555
567
|
}
|
|
@@ -565,7 +577,7 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
565
577
|
else {
|
|
566
578
|
// @ts-ignore
|
|
567
579
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
568
|
-
minify(node, options, recursive);
|
|
580
|
+
minify(node, options, recursive, errors);
|
|
569
581
|
}
|
|
570
582
|
}
|
|
571
583
|
}
|
|
@@ -651,16 +663,6 @@ function reduceSelector(selector) {
|
|
|
651
663
|
reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
|
|
652
664
|
};
|
|
653
665
|
}
|
|
654
|
-
function hasOnlyDeclarations(node) {
|
|
655
|
-
let k = node.chi.length;
|
|
656
|
-
while (k--) {
|
|
657
|
-
if (node.chi[k].typ == 'Comment') {
|
|
658
|
-
continue;
|
|
659
|
-
}
|
|
660
|
-
return node.chi[k].typ == 'Declaration';
|
|
661
|
-
}
|
|
662
|
-
return true;
|
|
663
|
-
}
|
|
664
666
|
function hasDeclaration(node) {
|
|
665
667
|
// @ts-ignore
|
|
666
668
|
for (let i = 0; i < node.chi?.length; i++) {
|
|
@@ -786,7 +788,7 @@ function splitRule(buffer) {
|
|
|
786
788
|
}
|
|
787
789
|
function reduceRuleSelector(node) {
|
|
788
790
|
if (node.raw == null) {
|
|
789
|
-
Object.defineProperty(node, 'raw', {
|
|
791
|
+
Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });
|
|
790
792
|
}
|
|
791
793
|
// @ts-ignore
|
|
792
794
|
// if (node.raw != null) {
|
|
@@ -796,7 +798,7 @@ function reduceRuleSelector(node) {
|
|
|
796
798
|
return acc;
|
|
797
799
|
}, []));
|
|
798
800
|
if (optimized != null) {
|
|
799
|
-
Object.defineProperty(node, 'optimized', {
|
|
801
|
+
Object.defineProperty(node, 'optimized', { ...definedPropertySettings, value: optimized });
|
|
800
802
|
}
|
|
801
803
|
if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
|
|
802
804
|
const raw = [
|
|
@@ -814,10 +816,10 @@ function reduceRuleSelector(node) {
|
|
|
814
816
|
if (sel.length < node.sel.length) {
|
|
815
817
|
node.sel = sel;
|
|
816
818
|
// node.raw = raw;
|
|
817
|
-
Object.defineProperty(node, 'raw', {
|
|
819
|
+
Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
|
|
818
820
|
}
|
|
819
821
|
}
|
|
820
822
|
// }
|
|
821
823
|
}
|
|
822
824
|
|
|
823
|
-
export { combinators, hasDeclaration, minify, minifyRule, reduceSelector };
|
|
825
|
+
export { combinators, hasDeclaration, minify, minifyRule, reduceSelector, splitRule };
|
package/dist/lib/ast/walk.js
CHANGED
|
@@ -10,5 +10,14 @@ function* doWalk(node, parent, root) {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
function* walkValues(values, parent) {
|
|
14
|
+
for (const value of values) {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
yield { value, parent };
|
|
17
|
+
if ('chi' in value) {
|
|
18
|
+
yield* walkValues(value.chi, value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
13
22
|
|
|
14
|
-
export { walk };
|
|
23
|
+
export { walk, walkValues };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PropertySet } from './set.js';
|
|
2
2
|
import '../../renderer/utils/color.js';
|
|
3
|
-
import { getConfig } from '../utils/config.js';
|
|
4
3
|
import { PropertyMap } from './map.js';
|
|
5
4
|
import { parseString } from '../parse.js';
|
|
5
|
+
import { getConfig } from '../utils/config.js';
|
|
6
6
|
|
|
7
7
|
const config = getConfig();
|
|
8
8
|
class PropertyList {
|
|
@@ -340,6 +340,14 @@ class PropertyMap {
|
|
|
340
340
|
acc.push(...curr);
|
|
341
341
|
return acc;
|
|
342
342
|
}, []);
|
|
343
|
+
if (this.config.mapping != null) {
|
|
344
|
+
const val = values.reduce((acc, curr) => acc + renderToken(curr, { removeComments: true }), '');
|
|
345
|
+
if (val in this.config.mapping) {
|
|
346
|
+
values.length = 0;
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
values.push({ typ: ['"', "'"].includes(val.charAt(0)) ? 'String' : 'Iden', val: this.config.mapping[val] });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
343
351
|
iterable = [{
|
|
344
352
|
typ: 'Declaration',
|
|
345
353
|
nam: this.config.shorthand,
|