@tbela99/css-parser 0.0.1-rc4 → 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 +3742 -3489
- package/dist/index.cjs +3742 -3489
- package/dist/index.d.ts +38 -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 +2 -1
- package/dist/lib/parser/declaration/map.js +10 -1
- package/dist/lib/parser/parse.js +60 -53
- package/dist/lib/parser/tokenize.js +144 -124
- package/dist/lib/parser/utils/syntax.js +36 -28
- package/dist/lib/parser/utils/type.js +1 -1
- package/dist/lib/renderer/render.js +21 -28
- package/dist/lib/transform.js +5 -1
- package/dist/node/index.js +8 -7
- package/dist/web/index.js +8 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -119,7 +119,7 @@ interface CDOCommentToken {
|
|
|
119
119
|
val: string;
|
|
120
120
|
}
|
|
121
121
|
interface BadCDOCommentToken {
|
|
122
|
-
typ: '
|
|
122
|
+
typ: 'Bad-cdo';
|
|
123
123
|
val: string;
|
|
124
124
|
}
|
|
125
125
|
interface IncludesToken {
|
|
@@ -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;
|
|
@@ -642,10 +672,12 @@ declare function isResolution(dimension: DimensionToken): boolean;
|
|
|
642
672
|
declare function isAngle(dimension: DimensionToken): boolean;
|
|
643
673
|
declare function isTime(dimension: DimensionToken): boolean;
|
|
644
674
|
declare function isFrequency(dimension: DimensionToken): boolean;
|
|
675
|
+
declare function isColor(token: Token): boolean;
|
|
645
676
|
declare function isIdentStart(codepoint: number): boolean;
|
|
646
677
|
declare function isDigit(codepoint: number): boolean;
|
|
647
678
|
declare function isIdentCodepoint(codepoint: number): boolean;
|
|
648
679
|
declare function isIdent(name: string): boolean;
|
|
680
|
+
declare function isNonPrintable(codepoint: number): boolean;
|
|
649
681
|
declare function isPseudo(name: string): boolean;
|
|
650
682
|
declare function isHash(name: string): boolean;
|
|
651
683
|
declare function isNumber(name: string): boolean;
|
|
@@ -653,7 +685,6 @@ declare function isDimension(name: string): boolean;
|
|
|
653
685
|
declare function isPercentage(name: string): boolean;
|
|
654
686
|
declare function parseDimension(name: string): DimensionToken | LengthToken | AngleToken;
|
|
655
687
|
declare function isHexColor(name: string): boolean;
|
|
656
|
-
declare function isHexDigit(name: string): boolean;
|
|
657
688
|
declare function isFunction(name: string): boolean;
|
|
658
689
|
declare function isAtKeyword(name: string): boolean;
|
|
659
690
|
declare function isNewLine(codepoint: number): boolean;
|
|
@@ -661,28 +692,9 @@ declare function isWhiteSpace(codepoint: number): boolean;
|
|
|
661
692
|
|
|
662
693
|
declare const getConfig: () => PropertiesConfig;
|
|
663
694
|
|
|
695
|
+
declare const funcList: string[];
|
|
664
696
|
declare function matchType(val: Token, properties: PropertyMapType): boolean;
|
|
665
697
|
|
|
666
|
-
declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
|
|
667
|
-
declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string): string;
|
|
668
|
-
|
|
669
|
-
declare const combinators: string[];
|
|
670
|
-
declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean): AstNode;
|
|
671
|
-
declare function reduceSelector(selector: string[][]): {
|
|
672
|
-
match: boolean;
|
|
673
|
-
optimized: string[];
|
|
674
|
-
selector: string[][];
|
|
675
|
-
reducible: boolean;
|
|
676
|
-
} | null;
|
|
677
|
-
declare function hasDeclaration(node: AstRule): boolean;
|
|
678
|
-
declare function minifyRule(ast: AstRule | AstAtRule): AstRule | AstAtRule;
|
|
679
|
-
|
|
680
|
-
declare function walk(node: AstNode): Generator<{
|
|
681
|
-
node: AstNode;
|
|
682
|
-
parent?: AstRuleList;
|
|
683
|
-
root?: AstRuleList;
|
|
684
|
-
}>;
|
|
685
|
-
|
|
686
698
|
declare function load(url: string, currentFile: string): Promise<string>;
|
|
687
699
|
|
|
688
700
|
declare const matchUrl: RegExp;
|
|
@@ -695,4 +707,4 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
|
|
|
695
707
|
declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
|
|
696
708
|
declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
|
|
697
709
|
|
|
698
|
-
export { combinators, dirname, getConfig, hasDeclaration, isAngle, isAtKeyword, 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,7 +1,8 @@
|
|
|
1
1
|
import { PropertySet } from './set.js';
|
|
2
|
-
import
|
|
2
|
+
import '../../renderer/utils/color.js';
|
|
3
3
|
import { PropertyMap } from './map.js';
|
|
4
4
|
import { parseString } from '../parse.js';
|
|
5
|
+
import { getConfig } from '../utils/config.js';
|
|
5
6
|
|
|
6
7
|
const config = getConfig();
|
|
7
8
|
class PropertyList {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { eq } from '../utils/eq.js';
|
|
2
|
+
import { renderToken } from '../../renderer/render.js';
|
|
3
|
+
import '../../renderer/utils/color.js';
|
|
2
4
|
import { getConfig } from '../utils/config.js';
|
|
3
5
|
import { matchType } from '../utils/type.js';
|
|
4
|
-
import { renderToken } from '../../renderer/render.js';
|
|
5
6
|
import { parseString } from '../parse.js';
|
|
6
7
|
import { PropertySet } from './set.js';
|
|
7
8
|
|
|
@@ -339,6 +340,14 @@ class PropertyMap {
|
|
|
339
340
|
acc.push(...curr);
|
|
340
341
|
return acc;
|
|
341
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
|
+
}
|
|
342
351
|
iterable = [{
|
|
343
352
|
typ: 'Declaration',
|
|
344
353
|
nam: this.config.shorthand,
|