@tbela99/css-parser 0.0.1-alpha3 → 0.0.1-alpha5
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 +2 -0
- package/README.md +2 -6
- package/dist/index-umd-web.js +649 -161
- package/dist/index.cjs +647 -159
- package/dist/index.d.ts +24 -6
- package/dist/index.js +1 -1
- package/dist/lib/parser/deduplicate.js +530 -35
- package/dist/lib/parser/parse.js +100 -98
- package/dist/lib/parser/utils/syntax.js +7 -2
- package/dist/lib/renderer/render.js +11 -23
- package/dist/lib/walker/walk.js +1 -1
- package/dist/node/index.js +2 -4
- package/dist/web/index.js +5 -7
- package/package.json +5 -4
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isWhiteSpace, isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHash, isNewLine, isIdentStart, isHexColor } from './utils/syntax.js';
|
|
1
|
+
import { isWhiteSpace, isDigit, isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHash, isNewLine, isIdentStart, isHexColor } from './utils/syntax.js';
|
|
2
2
|
import { renderToken } from '../renderer/render.js';
|
|
3
3
|
import { COLORS_NAMES } from '../renderer/utils/color.js';
|
|
4
|
-
import {
|
|
4
|
+
import { deduplicate } from './deduplicate.js';
|
|
5
5
|
|
|
6
6
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
7
7
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
@@ -11,6 +11,7 @@ async function parse(iterator, opt = {}) {
|
|
|
11
11
|
src: '',
|
|
12
12
|
sourcemap: false,
|
|
13
13
|
compress: false,
|
|
14
|
+
nestingRules: false,
|
|
14
15
|
resolveImport: false,
|
|
15
16
|
resolveUrls: false,
|
|
16
17
|
removeEmpty: true,
|
|
@@ -281,11 +282,16 @@ async function parse(iterator, opt = {}) {
|
|
|
281
282
|
try {
|
|
282
283
|
// @ts-ignore
|
|
283
284
|
const root = await options.load(url, options.src).then((src) => {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
return parse(src, Object.assign({}, options, {
|
|
286
|
+
compress: false,
|
|
287
|
+
// @ts-ignore
|
|
288
|
+
src: options.resolve(url, options.src).absolute
|
|
289
|
+
}));
|
|
287
290
|
});
|
|
288
|
-
|
|
291
|
+
bytesIn += root.bytesIn;
|
|
292
|
+
if (root.ast.chi.length > 0) {
|
|
293
|
+
context.chi.push(...root.ast.chi);
|
|
294
|
+
}
|
|
289
295
|
if (root.errors.length > 0) {
|
|
290
296
|
errors.push(...root.errors);
|
|
291
297
|
}
|
|
@@ -300,20 +306,16 @@ async function parse(iterator, opt = {}) {
|
|
|
300
306
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
301
307
|
// allowed nesting at-rules
|
|
302
308
|
// there must be a top level rule in the stack
|
|
309
|
+
const raw = tokens.reduce((acc, curr) => {
|
|
310
|
+
acc.push(renderToken(curr, { removeComments: true }));
|
|
311
|
+
return acc;
|
|
312
|
+
}, []);
|
|
303
313
|
const node = {
|
|
304
314
|
typ: 'AtRule',
|
|
305
315
|
nam: renderToken(atRule, { removeComments: true }),
|
|
306
|
-
val:
|
|
307
|
-
if (curr.typ == 'Whitespace') {
|
|
308
|
-
if (array[index + 1]?.typ == 'Start-parens' ||
|
|
309
|
-
array[index - 1]?.typ == 'End-parens' ||
|
|
310
|
-
array[index - 1]?.typ == 'Func') {
|
|
311
|
-
return acc;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return acc + renderToken(curr, { removeComments: true });
|
|
315
|
-
}, '')
|
|
316
|
+
val: raw.join('')
|
|
316
317
|
};
|
|
318
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: false, value: raw });
|
|
317
319
|
if (delim.typ == 'Block-start') {
|
|
318
320
|
node.chi = [];
|
|
319
321
|
}
|
|
@@ -338,23 +340,33 @@ async function parse(iterator, opt = {}) {
|
|
|
338
340
|
return null;
|
|
339
341
|
}
|
|
340
342
|
}
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
else {
|
|
347
|
-
acc[acc.length - 1] += curr;
|
|
343
|
+
const uniq = new Map;
|
|
344
|
+
parseTokens(tokens, 'Rule', { compress: options.compress }).reduce((acc, curr, index, array) => {
|
|
345
|
+
if (curr.typ == 'Whitespace') {
|
|
346
|
+
if (array[index - 1]?.val == '+' || array[index + 1]?.val == '+') {
|
|
347
|
+
return acc;
|
|
348
348
|
}
|
|
349
|
-
|
|
350
|
-
|
|
349
|
+
}
|
|
350
|
+
let t = renderToken(curr, { compress: true });
|
|
351
|
+
if (t == ',') {
|
|
352
|
+
acc.push([]);
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
acc[acc.length - 1].push(t);
|
|
356
|
+
}
|
|
357
|
+
return acc;
|
|
358
|
+
}, [[]]).reduce((acc, curr) => {
|
|
359
|
+
acc.set(curr.join(''), curr);
|
|
360
|
+
return acc;
|
|
361
|
+
}, uniq);
|
|
351
362
|
const node = {
|
|
352
363
|
typ: 'Rule',
|
|
353
364
|
// @ts-ignore
|
|
354
|
-
sel:
|
|
365
|
+
sel: [...uniq.keys()].join(','),
|
|
355
366
|
chi: []
|
|
356
367
|
};
|
|
357
|
-
|
|
368
|
+
let raw = [...uniq.values()];
|
|
369
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
358
370
|
loc = {
|
|
359
371
|
sta: position,
|
|
360
372
|
src
|
|
@@ -378,7 +390,13 @@ async function parse(iterator, opt = {}) {
|
|
|
378
390
|
}
|
|
379
391
|
if (tokens[i].typ == 'Colon') {
|
|
380
392
|
name = tokens.slice(0, i);
|
|
381
|
-
value = parseTokens(tokens.slice(i + 1),
|
|
393
|
+
value = parseTokens(tokens.slice(i + 1), 'Declaration', {
|
|
394
|
+
parseColor: true,
|
|
395
|
+
src: options.src,
|
|
396
|
+
resolveUrls: options.resolveUrls,
|
|
397
|
+
resolve: options.resolve,
|
|
398
|
+
cwd: options.cwd
|
|
399
|
+
});
|
|
382
400
|
}
|
|
383
401
|
}
|
|
384
402
|
if (name == null) {
|
|
@@ -397,11 +415,6 @@ async function parse(iterator, opt = {}) {
|
|
|
397
415
|
}
|
|
398
416
|
}
|
|
399
417
|
}
|
|
400
|
-
// if (name.length == 0) {
|
|
401
|
-
//
|
|
402
|
-
// errors.push({action: 'drop', message: 'invalid declaration', location: {src, ...position}});
|
|
403
|
-
// return null;
|
|
404
|
-
// }
|
|
405
418
|
if (value == null) {
|
|
406
419
|
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
407
420
|
return null;
|
|
@@ -424,16 +437,6 @@ async function parse(iterator, opt = {}) {
|
|
|
424
437
|
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
425
438
|
return null;
|
|
426
439
|
}
|
|
427
|
-
// // location not needed for declaration
|
|
428
|
-
// loc = <Location>{
|
|
429
|
-
// sta: position,
|
|
430
|
-
// src
|
|
431
|
-
// };
|
|
432
|
-
//
|
|
433
|
-
// if (options.sourcemap) {
|
|
434
|
-
//
|
|
435
|
-
// node.loc = loc
|
|
436
|
-
// }
|
|
437
440
|
// @ts-ignore
|
|
438
441
|
context.chi.push(node);
|
|
439
442
|
return null;
|
|
@@ -476,7 +479,6 @@ async function parse(iterator, opt = {}) {
|
|
|
476
479
|
position.ind = ind;
|
|
477
480
|
position.lin = lin;
|
|
478
481
|
position.col = col == 0 ? 1 : col;
|
|
479
|
-
// }
|
|
480
482
|
}
|
|
481
483
|
function consumeWhiteSpace() {
|
|
482
484
|
let count = 0;
|
|
@@ -658,11 +660,6 @@ async function parse(iterator, opt = {}) {
|
|
|
658
660
|
}
|
|
659
661
|
}
|
|
660
662
|
}
|
|
661
|
-
// else {
|
|
662
|
-
//
|
|
663
|
-
// pushToken(getType(buffer));
|
|
664
|
-
// buffer = '';
|
|
665
|
-
// }
|
|
666
663
|
break;
|
|
667
664
|
case '<':
|
|
668
665
|
if (buffer.length > 0) {
|
|
@@ -713,6 +710,9 @@ async function parse(iterator, opt = {}) {
|
|
|
713
710
|
break;
|
|
714
711
|
case '~':
|
|
715
712
|
case '|':
|
|
713
|
+
if (tokens.at(-1)?.typ == 'Whitespace') {
|
|
714
|
+
tokens.pop();
|
|
715
|
+
}
|
|
716
716
|
if (buffer.length > 0) {
|
|
717
717
|
pushToken(getType(buffer));
|
|
718
718
|
buffer = '';
|
|
@@ -734,15 +734,32 @@ async function parse(iterator, opt = {}) {
|
|
|
734
734
|
break;
|
|
735
735
|
}
|
|
736
736
|
pushToken(getType(buffer));
|
|
737
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
738
|
+
value = next();
|
|
739
|
+
}
|
|
737
740
|
buffer = value;
|
|
738
741
|
break;
|
|
739
742
|
case '>':
|
|
743
|
+
if (buffer !== '') {
|
|
744
|
+
pushToken(getType(buffer));
|
|
745
|
+
buffer = '';
|
|
746
|
+
}
|
|
740
747
|
if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
741
748
|
tokens.pop();
|
|
742
749
|
}
|
|
743
750
|
pushToken({ typ: 'Gt' });
|
|
744
751
|
consumeWhiteSpace();
|
|
745
752
|
break;
|
|
753
|
+
case '.':
|
|
754
|
+
const codepoint = peek().charCodeAt(0);
|
|
755
|
+
if (!isDigit(codepoint) && buffer !== '') {
|
|
756
|
+
pushToken(getType(buffer));
|
|
757
|
+
buffer = value;
|
|
758
|
+
break;
|
|
759
|
+
}
|
|
760
|
+
buffer += value;
|
|
761
|
+
break;
|
|
762
|
+
case '+':
|
|
746
763
|
case ':':
|
|
747
764
|
case ',':
|
|
748
765
|
case '=':
|
|
@@ -754,12 +771,11 @@ async function parse(iterator, opt = {}) {
|
|
|
754
771
|
buffer += value + next();
|
|
755
772
|
break;
|
|
756
773
|
}
|
|
757
|
-
// if (value == ',' && tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
758
|
-
//
|
|
759
|
-
// tokens.pop();
|
|
760
|
-
// }
|
|
761
774
|
pushToken(getType(value));
|
|
762
775
|
buffer = '';
|
|
776
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
777
|
+
pushToken(getType(next()));
|
|
778
|
+
}
|
|
763
779
|
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
764
780
|
next();
|
|
765
781
|
}
|
|
@@ -780,7 +796,7 @@ async function parse(iterator, opt = {}) {
|
|
|
780
796
|
pushToken(getType(buffer));
|
|
781
797
|
buffer = '';
|
|
782
798
|
const token = tokens[tokens.length - 1];
|
|
783
|
-
if (token.typ == 'UrlFunc'
|
|
799
|
+
if (token.typ == 'UrlFunc') {
|
|
784
800
|
// consume either string or url token
|
|
785
801
|
let whitespace = '';
|
|
786
802
|
value = peek();
|
|
@@ -897,15 +913,6 @@ async function parse(iterator, opt = {}) {
|
|
|
897
913
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
898
914
|
context.chi.pop();
|
|
899
915
|
}
|
|
900
|
-
else if (previousNode != null && previousNode != ast && options.compress) {
|
|
901
|
-
// @ts-ignore
|
|
902
|
-
if (hasDeclaration(previousNode)) {
|
|
903
|
-
deduplicateRule(previousNode);
|
|
904
|
-
}
|
|
905
|
-
else {
|
|
906
|
-
deduplicate(previousNode, options);
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
916
|
tokens.length = 0;
|
|
910
917
|
map.clear();
|
|
911
918
|
buffer = '';
|
|
@@ -940,28 +947,22 @@ async function parse(iterator, opt = {}) {
|
|
|
940
947
|
await parseNode(tokens);
|
|
941
948
|
}
|
|
942
949
|
if (options.compress) {
|
|
943
|
-
while (stack.length > 0) {
|
|
944
|
-
const node = stack.pop();
|
|
945
|
-
if (hasDeclaration(node)) {
|
|
946
|
-
deduplicateRule(node, options);
|
|
947
|
-
}
|
|
948
|
-
else {
|
|
949
|
-
deduplicate(node, options);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
950
|
if (ast.chi.length > 0) {
|
|
953
|
-
deduplicate(ast, options);
|
|
951
|
+
deduplicate(ast, options, true);
|
|
954
952
|
}
|
|
955
953
|
}
|
|
956
954
|
return { ast, errors, bytesIn };
|
|
957
955
|
}
|
|
958
|
-
function parseTokens(tokens, options = {}) {
|
|
956
|
+
function parseTokens(tokens, nodeType, options = {}) {
|
|
959
957
|
for (let i = 0; i < tokens.length; i++) {
|
|
960
958
|
const t = tokens[i];
|
|
961
959
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
962
960
|
i + 1 == tokens.length ||
|
|
963
|
-
['Comma'
|
|
964
|
-
(i > 0 &&
|
|
961
|
+
['Comma'].includes(tokens[i + 1].typ) ||
|
|
962
|
+
(i > 0 &&
|
|
963
|
+
tokens[i + 1]?.typ != 'Literal' &&
|
|
964
|
+
funcLike.includes(tokens[i - 1].typ) &&
|
|
965
|
+
!['var', 'calc'].includes(tokens[i - 1].val))))) {
|
|
965
966
|
tokens.splice(i--, 1);
|
|
966
967
|
continue;
|
|
967
968
|
}
|
|
@@ -1006,7 +1007,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1006
1007
|
if (t.chi.length > 1) {
|
|
1007
1008
|
/*(<AttrToken>t).chi =*/
|
|
1008
1009
|
// @ts-ignore
|
|
1009
|
-
parseTokens(t.chi, options);
|
|
1010
|
+
parseTokens(t.chi, t.typ, options);
|
|
1010
1011
|
}
|
|
1011
1012
|
// @ts-ignore
|
|
1012
1013
|
t.chi.forEach(val => {
|
|
@@ -1059,9 +1060,9 @@ function parseTokens(tokens, options = {}) {
|
|
|
1059
1060
|
// @ts-ignore
|
|
1060
1061
|
t.chi.pop();
|
|
1061
1062
|
}
|
|
1063
|
+
let isColor = true;
|
|
1062
1064
|
// @ts-ignore
|
|
1063
1065
|
if (options.parseColor && ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'].includes(t.val)) {
|
|
1064
|
-
let isColor = true;
|
|
1065
1066
|
// @ts-ignore
|
|
1066
1067
|
for (const v of t.chi) {
|
|
1067
1068
|
if (v.typ == 'Func' && v.val == 'var') {
|
|
@@ -1069,37 +1070,38 @@ function parseTokens(tokens, options = {}) {
|
|
|
1069
1070
|
break;
|
|
1070
1071
|
}
|
|
1071
1072
|
}
|
|
1072
|
-
if (
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
// @ts-ignore
|
|
1076
|
-
t.typ = 'Color';
|
|
1077
|
-
// @ts-ignore
|
|
1078
|
-
t.kin = t.val;
|
|
1079
|
-
// @ts-ignore
|
|
1080
|
-
let m = t.chi.length;
|
|
1081
|
-
while (m-- > 0) {
|
|
1073
|
+
if (isColor) {
|
|
1074
|
+
// @ts-ignore
|
|
1075
|
+
t.typ = 'Color';
|
|
1082
1076
|
// @ts-ignore
|
|
1083
|
-
|
|
1077
|
+
t.kin = t.val;
|
|
1078
|
+
// @ts-ignore
|
|
1079
|
+
let m = t.chi.length;
|
|
1080
|
+
while (m-- > 0) {
|
|
1084
1081
|
// @ts-ignore
|
|
1085
|
-
if (t.chi[m
|
|
1082
|
+
if (t.chi[m].typ == 'Literal') {
|
|
1086
1083
|
// @ts-ignore
|
|
1087
|
-
t.chi
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1084
|
+
if (t.chi[m + 1]?.typ == 'Whitespace') {
|
|
1085
|
+
// @ts-ignore
|
|
1086
|
+
t.chi.splice(m + 1, 1);
|
|
1087
|
+
}
|
|
1091
1088
|
// @ts-ignore
|
|
1092
|
-
t.chi
|
|
1093
|
-
|
|
1089
|
+
if (t.chi[m - 1]?.typ == 'Whitespace') {
|
|
1090
|
+
// @ts-ignore
|
|
1091
|
+
t.chi.splice(m - 1, 1);
|
|
1092
|
+
m--;
|
|
1093
|
+
}
|
|
1094
1094
|
}
|
|
1095
1095
|
}
|
|
1096
|
+
continue;
|
|
1096
1097
|
}
|
|
1097
1098
|
}
|
|
1098
|
-
|
|
1099
|
+
if (t.typ == 'UrlFunc') {
|
|
1099
1100
|
// @ts-ignore
|
|
1100
1101
|
if (t.chi[0]?.typ == 'String') {
|
|
1101
1102
|
// @ts-ignore
|
|
1102
1103
|
const value = t.chi[0].val.slice(1, -1);
|
|
1104
|
+
// @ts-ignore
|
|
1103
1105
|
if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
|
|
1104
1106
|
// @ts-ignore
|
|
1105
1107
|
t.chi[0].typ = 'Url-token';
|
|
@@ -1117,7 +1119,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1117
1119
|
// @ts-ignore
|
|
1118
1120
|
if (t.chi.length > 0) {
|
|
1119
1121
|
// @ts-ignore
|
|
1120
|
-
parseTokens(t.chi, options);
|
|
1122
|
+
parseTokens(t.chi, t.typ, options);
|
|
1121
1123
|
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.compress) {
|
|
1122
1124
|
//
|
|
1123
1125
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
@@ -49,7 +49,7 @@ function isIdent(name) {
|
|
|
49
49
|
// -
|
|
50
50
|
if (codepoint == 0x2d) {
|
|
51
51
|
const nextCodepoint = name.charCodeAt(1);
|
|
52
|
-
if (nextCodepoint
|
|
52
|
+
if (Number.isNaN(nextCodepoint)) {
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
// -
|
|
@@ -98,6 +98,9 @@ function isNumber(name) {
|
|
|
98
98
|
let codepoint = name.charCodeAt(0);
|
|
99
99
|
let i = 0;
|
|
100
100
|
const j = name.length;
|
|
101
|
+
if (j == 1 && !isDigit(codepoint)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
101
104
|
// '+' '-'
|
|
102
105
|
if ([0x2b, 0x2d].includes(codepoint)) {
|
|
103
106
|
i++;
|
|
@@ -241,7 +244,9 @@ function isNewLine(codepoint) {
|
|
|
241
244
|
return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
242
245
|
}
|
|
243
246
|
function isWhiteSpace(codepoint) {
|
|
244
|
-
return codepoint == 0x9 || codepoint == 0x20 ||
|
|
247
|
+
return codepoint == 0x9 || codepoint == 0x20 ||
|
|
248
|
+
// isNewLine
|
|
249
|
+
codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
245
250
|
}
|
|
246
251
|
|
|
247
252
|
export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
|
|
2
2
|
|
|
3
|
-
const indents = [];
|
|
4
3
|
function render(data, opt = {}) {
|
|
5
4
|
const options = Object.assign(opt.compress ? {
|
|
6
5
|
indent: '',
|
|
@@ -18,24 +17,12 @@ function render(data, opt = {}) {
|
|
|
18
17
|
return acc;
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
|
-
if (options.compress && curr.typ == 'Whitespace') {
|
|
22
|
-
if (original[index + 1]?.typ == 'Start-parens' ||
|
|
23
|
-
(index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
|
|
24
|
-
original[index - 1].typ == 'End-parens' ||
|
|
25
|
-
original[index - 1].typ == 'UrlFunc' ||
|
|
26
|
-
original[index - 1].typ == 'Func' ||
|
|
27
|
-
(original[index - 1].typ == 'Color' &&
|
|
28
|
-
original[index - 1].kin != 'hex' &&
|
|
29
|
-
original[index - 1].kin != 'lit')))) {
|
|
30
|
-
return acc;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
20
|
return acc + renderToken(curr, options);
|
|
34
21
|
}
|
|
35
|
-
return { code: doRender(data, options, reducer) };
|
|
22
|
+
return { code: doRender(data, options, reducer, 0) };
|
|
36
23
|
}
|
|
37
24
|
// @ts-ignore
|
|
38
|
-
function doRender(data, options, reducer, level = 0) {
|
|
25
|
+
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
39
26
|
if (indents.length < level + 1) {
|
|
40
27
|
indents.push(options.indent.repeat(level));
|
|
41
28
|
}
|
|
@@ -49,7 +36,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
49
36
|
return options.removeComments ? '' : data.val;
|
|
50
37
|
case 'StyleSheet':
|
|
51
38
|
return data.chi.reduce((css, node) => {
|
|
52
|
-
const str = doRender(node, options, reducer, level);
|
|
39
|
+
const str = doRender(node, options, reducer, level, indents);
|
|
53
40
|
if (str === '') {
|
|
54
41
|
return css;
|
|
55
42
|
}
|
|
@@ -76,7 +63,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
76
63
|
str = `@${node.nam} ${node.val};`;
|
|
77
64
|
}
|
|
78
65
|
else {
|
|
79
|
-
str = doRender(node, options, reducer, level + 1);
|
|
66
|
+
str = doRender(node, options, reducer, level + 1, indents);
|
|
80
67
|
}
|
|
81
68
|
if (css === '') {
|
|
82
69
|
return str;
|
|
@@ -84,8 +71,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
84
71
|
if (str === '') {
|
|
85
72
|
return css;
|
|
86
73
|
}
|
|
87
|
-
|
|
88
|
-
return `${css}${options.newLine}${indentSub}${str}`;
|
|
74
|
+
return `${css}${options.newLine}${indentSub}${str}`;
|
|
89
75
|
}, '');
|
|
90
76
|
if (children.endsWith(';')) {
|
|
91
77
|
children = children.slice(0, -1);
|
|
@@ -137,11 +123,15 @@ function renderToken(token, options = {}) {
|
|
|
137
123
|
if (token.kin == 'hex' || token.kin == 'lit') {
|
|
138
124
|
return token.val;
|
|
139
125
|
}
|
|
126
|
+
case 'Start-parens':
|
|
127
|
+
if (!('chi' in token)) {
|
|
128
|
+
return '(';
|
|
129
|
+
}
|
|
140
130
|
case 'Func':
|
|
141
131
|
case 'UrlFunc':
|
|
142
132
|
case 'Pseudo-class-func':
|
|
143
133
|
// @ts-ignore
|
|
144
|
-
return (options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1)
|
|
134
|
+
return ( /* options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
|
|
145
135
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
146
136
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
147
137
|
return acc;
|
|
@@ -157,8 +147,6 @@ function renderToken(token, options = {}) {
|
|
|
157
147
|
return '<';
|
|
158
148
|
case 'Gt':
|
|
159
149
|
return '>';
|
|
160
|
-
case 'Start-parens':
|
|
161
|
-
return '(';
|
|
162
150
|
case 'End-parens':
|
|
163
151
|
return ')';
|
|
164
152
|
case 'Attr-start':
|
|
@@ -234,7 +222,7 @@ function renderToken(token, options = {}) {
|
|
|
234
222
|
case 'String':
|
|
235
223
|
case 'Iden':
|
|
236
224
|
case 'Delim':
|
|
237
|
-
return options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : token.val;
|
|
225
|
+
return /* options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
238
226
|
}
|
|
239
227
|
throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
240
228
|
}
|
package/dist/lib/walker/walk.js
CHANGED
package/dist/node/index.js
CHANGED
|
@@ -6,12 +6,10 @@ import { resolve } from '../lib/fs/resolve.js';
|
|
|
6
6
|
export { dirname, matchUrl } from '../lib/fs/resolve.js';
|
|
7
7
|
|
|
8
8
|
function parse(iterator, opt = {}) {
|
|
9
|
-
Object.assign(opt, { load, resolve, cwd: opt.cwd ?? process.cwd() });
|
|
10
|
-
return parse$1(iterator, opt);
|
|
9
|
+
return parse$1(iterator, Object.assign(opt, { load, resolve, cwd: opt.cwd ?? process.cwd() }));
|
|
11
10
|
}
|
|
12
11
|
function transform(css, options = {}) {
|
|
13
|
-
Object.assign(options, { load, resolve, cwd: options.cwd ?? process.cwd() });
|
|
14
|
-
return transform$1(css, options);
|
|
12
|
+
return transform$1(css, Object.assign(options, { load, resolve, cwd: options.cwd ?? process.cwd() }));
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
export { load, parse, resolve, transform };
|
package/dist/web/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse as parse$1 } from '../lib/parser/parse.js';
|
|
2
|
-
export { deduplicate, deduplicateRule, hasDeclaration } from '../lib/parser/deduplicate.js';
|
|
2
|
+
export { deduplicate, deduplicateRule, hasDeclaration, reduceSelector } from '../lib/parser/deduplicate.js';
|
|
3
3
|
export { render, renderToken } from '../lib/renderer/render.js';
|
|
4
4
|
export { walk } from '../lib/walker/walk.js';
|
|
5
5
|
import { transform as transform$1 } from '../lib/transform.js';
|
|
@@ -8,20 +8,18 @@ import { resolve, dirname } from '../lib/fs/resolve.js';
|
|
|
8
8
|
export { matchUrl } from '../lib/fs/resolve.js';
|
|
9
9
|
|
|
10
10
|
function parse(iterator, opt = {}) {
|
|
11
|
-
Object.assign(opt, {
|
|
11
|
+
return parse$1(iterator, Object.assign(opt, {
|
|
12
12
|
load,
|
|
13
13
|
resolve,
|
|
14
14
|
cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
|
|
15
|
-
});
|
|
16
|
-
return parse$1(iterator, opt);
|
|
15
|
+
}));
|
|
17
16
|
}
|
|
18
17
|
function transform(css, options = {}) {
|
|
19
|
-
Object.assign(options, {
|
|
18
|
+
return transform$1(css, Object.assign(options, {
|
|
20
19
|
load,
|
|
21
20
|
resolve,
|
|
22
21
|
cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
|
|
23
|
-
});
|
|
24
|
-
return transform$1(css, options);
|
|
22
|
+
}));
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
export { dirname, load, parse, resolve, transform };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbela99/css-parser",
|
|
3
3
|
"description": "CSS parser for node and the browser",
|
|
4
|
-
"version": "0.0.1-
|
|
4
|
+
"version": "0.0.1-alpha5",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
7
7
|
"./web": "./dist/web/index.js",
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
"typings": "dist/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "rollup -c",
|
|
14
|
-
"debug": "web-test-runner \"test/**/*.web.js\" --manual --open --node-resolve --root-dir
|
|
15
|
-
"test": "web-test-runner \"test/**/*.web.js\" --node-resolve --root-dir
|
|
14
|
+
"debug": "web-test-runner \"test/**/*.web.js\" --manual --open --node-resolve --root-dir=.",
|
|
15
|
+
"test": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=.; mocha --reporter-options='maxDiffSize=181920' \"test/**/*.spec.js\"",
|
|
16
|
+
"test:cov": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=. --coverage; c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=181920' \"test/**/*.spec.js\""
|
|
16
17
|
},
|
|
17
18
|
"repository": {
|
|
18
19
|
"type": "git",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"@types/node": "^18.15.10",
|
|
44
45
|
"@web/test-runner": "^0.16.1",
|
|
45
46
|
"@webref/css": "^6.5.9",
|
|
46
|
-
"
|
|
47
|
+
"c8": "^8.0.1",
|
|
47
48
|
"mocha": "^10.2.0",
|
|
48
49
|
"rollup": "^3.20.1",
|
|
49
50
|
"rollup-plugin-dts": "^5.3.0",
|