@tbela99/css-parser 0.0.1-alpha4 → 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 -0
- package/dist/index-umd-web.js +454 -172
- package/dist/index.cjs +454 -172
- package/dist/index.d.ts +18 -7
- package/dist/lib/parser/deduplicate.js +416 -141
- package/dist/lib/parser/parse.js +35 -11
- package/dist/lib/renderer/render.js +5 -22
- package/dist/lib/walker/walk.js +1 -1
- package/package.json +5 -4
package/dist/index-umd-web.js
CHANGED
|
@@ -1457,7 +1457,6 @@
|
|
|
1457
1457
|
return values;
|
|
1458
1458
|
}
|
|
1459
1459
|
|
|
1460
|
-
const indents = [];
|
|
1461
1460
|
function render(data, opt = {}) {
|
|
1462
1461
|
const options = Object.assign(opt.compress ? {
|
|
1463
1462
|
indent: '',
|
|
@@ -1475,27 +1474,12 @@
|
|
|
1475
1474
|
return acc;
|
|
1476
1475
|
}
|
|
1477
1476
|
}
|
|
1478
|
-
// if (options.compress && curr.typ == 'Whitespace') {
|
|
1479
|
-
//
|
|
1480
|
-
// if (original[index + 1]?.typ == 'Start-parens' ||
|
|
1481
|
-
// (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
|
|
1482
|
-
// original[index - 1].typ == 'End-parens' ||
|
|
1483
|
-
// original[index - 1].typ == 'UrlFunc' ||
|
|
1484
|
-
// original[index - 1].typ == 'Func' ||
|
|
1485
|
-
// (
|
|
1486
|
-
// original[index - 1].typ == 'Color' &&
|
|
1487
|
-
// (<ColorToken>original[index - 1]).kin != 'hex' &&
|
|
1488
|
-
// (<ColorToken>original[index - 1]).kin != 'lit')))) {
|
|
1489
|
-
//
|
|
1490
|
-
// return acc;
|
|
1491
|
-
// }
|
|
1492
|
-
// }
|
|
1493
1477
|
return acc + renderToken(curr, options);
|
|
1494
1478
|
}
|
|
1495
|
-
return { code: doRender(data, options, reducer) };
|
|
1479
|
+
return { code: doRender(data, options, reducer, 0) };
|
|
1496
1480
|
}
|
|
1497
1481
|
// @ts-ignore
|
|
1498
|
-
function doRender(data, options, reducer, level = 0) {
|
|
1482
|
+
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
1499
1483
|
if (indents.length < level + 1) {
|
|
1500
1484
|
indents.push(options.indent.repeat(level));
|
|
1501
1485
|
}
|
|
@@ -1509,7 +1493,7 @@
|
|
|
1509
1493
|
return options.removeComments ? '' : data.val;
|
|
1510
1494
|
case 'StyleSheet':
|
|
1511
1495
|
return data.chi.reduce((css, node) => {
|
|
1512
|
-
const str = doRender(node, options, reducer, level);
|
|
1496
|
+
const str = doRender(node, options, reducer, level, indents);
|
|
1513
1497
|
if (str === '') {
|
|
1514
1498
|
return css;
|
|
1515
1499
|
}
|
|
@@ -1536,7 +1520,7 @@
|
|
|
1536
1520
|
str = `@${node.nam} ${node.val};`;
|
|
1537
1521
|
}
|
|
1538
1522
|
else {
|
|
1539
|
-
str = doRender(node, options, reducer, level + 1);
|
|
1523
|
+
str = doRender(node, options, reducer, level + 1, indents);
|
|
1540
1524
|
}
|
|
1541
1525
|
if (css === '') {
|
|
1542
1526
|
return str;
|
|
@@ -1544,8 +1528,7 @@
|
|
|
1544
1528
|
if (str === '') {
|
|
1545
1529
|
return css;
|
|
1546
1530
|
}
|
|
1547
|
-
|
|
1548
|
-
return `${css}${options.newLine}${indentSub}${str}`;
|
|
1531
|
+
return `${css}${options.newLine}${indentSub}${str}`;
|
|
1549
1532
|
}, '');
|
|
1550
1533
|
if (children.endsWith(';')) {
|
|
1551
1534
|
children = children.slice(0, -1);
|
|
@@ -2257,6 +2240,54 @@
|
|
|
2257
2240
|
}
|
|
2258
2241
|
|
|
2259
2242
|
const configuration = getConfig();
|
|
2243
|
+
const combinators = ['+', '>', '~'];
|
|
2244
|
+
const notEndingWith = ['(', '['].concat(combinators);
|
|
2245
|
+
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
2246
|
+
// @ts-ignore
|
|
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,
|
|
2256
|
+
// @ts-ignore
|
|
2257
|
+
value: match.match.map(t => t.slice())
|
|
2258
|
+
});
|
|
2259
|
+
if (pSel == '&' || pSel === '') {
|
|
2260
|
+
// @ts-ignore
|
|
2261
|
+
wrapper.chi.push(...previous.chi);
|
|
2262
|
+
// @ts-ignore
|
|
2263
|
+
if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
|
|
2264
|
+
// @ts-ignore
|
|
2265
|
+
wrapper.chi.push(...node.chi);
|
|
2266
|
+
}
|
|
2267
|
+
else {
|
|
2268
|
+
// @ts-ignore
|
|
2269
|
+
wrapper.chi.push(node);
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
else {
|
|
2273
|
+
// @ts-ignore
|
|
2274
|
+
wrapper.chi.push(previous, node);
|
|
2275
|
+
}
|
|
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
|
+
}
|
|
2260
2291
|
function deduplicate(ast, options = {}, recursive = false) {
|
|
2261
2292
|
// @ts-ignore
|
|
2262
2293
|
if (('chi' in ast) && ast.chi?.length > 0) {
|
|
@@ -2272,6 +2303,14 @@
|
|
|
2272
2303
|
}
|
|
2273
2304
|
// @ts-ignore
|
|
2274
2305
|
node = ast.chi[i];
|
|
2306
|
+
// @ts-ignore
|
|
2307
|
+
if (previous == node) {
|
|
2308
|
+
// console.error('idem!');
|
|
2309
|
+
// @ts-ignore
|
|
2310
|
+
ast.chi.splice(i, 1);
|
|
2311
|
+
i--;
|
|
2312
|
+
continue;
|
|
2313
|
+
}
|
|
2275
2314
|
if (node.typ == 'AtRule' && node.nam == 'font-face') {
|
|
2276
2315
|
continue;
|
|
2277
2316
|
}
|
|
@@ -2284,120 +2323,106 @@
|
|
|
2284
2323
|
// @ts-ignore
|
|
2285
2324
|
if (node.typ == 'Rule') {
|
|
2286
2325
|
reduceRuleSelector(node);
|
|
2326
|
+
let wrapper;
|
|
2327
|
+
let match;
|
|
2287
2328
|
// @ts-ignore
|
|
2288
|
-
if (options.nestingRules
|
|
2289
|
-
const match = [];
|
|
2329
|
+
if (options.nestingRules) {
|
|
2290
2330
|
// @ts-ignore
|
|
2291
|
-
|
|
2331
|
+
if (previous != null && previous.typ == 'Rule') {
|
|
2332
|
+
reduceRuleSelector(previous);
|
|
2292
2333
|
// @ts-ignore
|
|
2293
|
-
|
|
2294
|
-
break;
|
|
2295
|
-
}
|
|
2296
|
-
// @ts-ignore
|
|
2297
|
-
match.push(node.raw[0].shift());
|
|
2298
|
-
// @ts-ignore
|
|
2299
|
-
previous.raw[0].shift();
|
|
2300
|
-
}
|
|
2301
|
-
if (match.length > 0) {
|
|
2334
|
+
match = matchSelectors(previous.raw, node.raw, ast.typ);
|
|
2302
2335
|
// @ts-ignore
|
|
2303
|
-
|
|
2304
|
-
// @ts-ignore
|
|
2305
|
-
if (previous.raw[0].length == 0) {
|
|
2336
|
+
if (match != null) {
|
|
2306
2337
|
// @ts-ignore
|
|
2307
|
-
wrapper
|
|
2308
|
-
|
|
2309
|
-
else {
|
|
2338
|
+
wrapper = wrapNodes(previous, node, match, ast, i, nodeIndex);
|
|
2339
|
+
nodeIndex = i - 1;
|
|
2310
2340
|
// @ts-ignore
|
|
2311
|
-
previous
|
|
2312
|
-
acc.push(curr.join(''));
|
|
2313
|
-
return acc;
|
|
2314
|
-
}, []).join(',');
|
|
2315
|
-
// @ts-ignore
|
|
2316
|
-
wrapper.chi.push(previous);
|
|
2341
|
+
previous = ast.chi[nodeIndex];
|
|
2317
2342
|
}
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
if (previous.raw.length == 0) {
|
|
2322
|
-
// @ts-ignore
|
|
2323
|
-
wrapper.chi.push(...node.chi);
|
|
2324
|
-
}
|
|
2325
|
-
else {
|
|
2326
|
-
if (hasOnlyDeclarations(wrapper)) {
|
|
2327
|
-
wrapper.chi.push(...node.chi);
|
|
2328
|
-
}
|
|
2329
|
-
else {
|
|
2330
|
-
// @ts-ignore
|
|
2331
|
-
node.raw[0].push('&');
|
|
2332
|
-
// @ts-ignore
|
|
2333
|
-
node.sel = node.raw.reduce((acc, curr) => {
|
|
2334
|
-
acc.push(curr.join(''));
|
|
2335
|
-
return acc;
|
|
2336
|
-
}, []).join(',');
|
|
2337
|
-
// @ts-ignore
|
|
2338
|
-
wrapper.chi.push(node);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
else {
|
|
2343
|
-
// @ts-ignore
|
|
2344
|
-
node.sel = node.raw.reduce((acc, curr) => {
|
|
2345
|
-
acc.push(curr.join(''));
|
|
2346
|
-
return acc;
|
|
2347
|
-
}, []).join(',');
|
|
2348
|
-
// @ts-ignore
|
|
2349
|
-
wrapper.chi.push(node);
|
|
2350
|
-
}
|
|
2351
|
-
Object.defineProperty(wrapper, 'raw', { enumerable: false, writable: true, value: [match] });
|
|
2352
|
-
// @ts-ignore
|
|
2353
|
-
ast.chi.splice(i, 1, wrapper);
|
|
2354
|
-
// @ts-ignore
|
|
2355
|
-
ast.chi.splice(nodeIndex, 1);
|
|
2343
|
+
}
|
|
2344
|
+
// @ts-ignore
|
|
2345
|
+
if (wrapper != null) {
|
|
2356
2346
|
// @ts-ignore
|
|
2357
2347
|
while (i < ast.chi.length) {
|
|
2358
2348
|
// @ts-ignore
|
|
2359
2349
|
const nextNode = ast.chi[i];
|
|
2360
2350
|
// @ts-ignore
|
|
2361
|
-
if (nextNode.typ != 'Rule'
|
|
2351
|
+
if (nextNode.typ != 'Rule') {
|
|
2352
|
+
// i--;
|
|
2353
|
+
// previous = wrapper;
|
|
2354
|
+
// nodeIndex = i;
|
|
2362
2355
|
break;
|
|
2363
2356
|
}
|
|
2364
2357
|
reduceRuleSelector(nextNode);
|
|
2365
2358
|
// @ts-ignore
|
|
2366
|
-
|
|
2359
|
+
match = matchSelectors(wrapper.raw, nextNode.raw, ast.typ);
|
|
2360
|
+
// @ts-ignore
|
|
2361
|
+
if (match == null) {
|
|
2367
2362
|
break;
|
|
2368
2363
|
}
|
|
2369
2364
|
// @ts-ignore
|
|
2370
|
-
|
|
2365
|
+
wrapper = wrapNodes(wrapper, nextNode, match, ast, i, nodeIndex);
|
|
2366
|
+
}
|
|
2367
|
+
nodeIndex = --i;
|
|
2368
|
+
// @ts-ignore
|
|
2369
|
+
previous = ast.chi[nodeIndex];
|
|
2370
|
+
deduplicate(wrapper, options, recursive);
|
|
2371
|
+
continue;
|
|
2372
|
+
}
|
|
2373
|
+
// @ts-ignore
|
|
2374
|
+
else if (node.optimized != null &&
|
|
2375
|
+
// @ts-ignore
|
|
2376
|
+
node.optimized.match &&
|
|
2377
|
+
// @ts-ignore
|
|
2378
|
+
node.optimized.selector.length > 1) {
|
|
2379
|
+
// @ts-ignore
|
|
2380
|
+
wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
|
|
2381
|
+
// @ts-ignore
|
|
2382
|
+
Object.defineProperty(wrapper, 'raw', {
|
|
2383
|
+
enumerable: false,
|
|
2384
|
+
writable: true,
|
|
2371
2385
|
// @ts-ignore
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2386
|
+
value: [[node.optimized.optimized[0]]]
|
|
2387
|
+
});
|
|
2388
|
+
// @ts-ignore
|
|
2389
|
+
node.sel = node.optimized.selector.reduce(reducer, []).join(',');
|
|
2390
|
+
// @ts-ignore
|
|
2391
|
+
node.raw = node.optimized.selector.slice();
|
|
2392
|
+
// @ts-ignore
|
|
2393
|
+
wrapper.chi.push(node);
|
|
2394
|
+
// @ts-ignore
|
|
2395
|
+
ast.chi.splice(i, 1, wrapper);
|
|
2396
|
+
node = wrapper;
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
// @ts-ignore
|
|
2400
|
+
else if (node.optimized?.match) {
|
|
2401
|
+
let wrap = true;
|
|
2402
|
+
// @ts-ignore
|
|
2403
|
+
const selector = node.optimized.selector.reduce((acc, curr) => {
|
|
2404
|
+
if (curr[0] == '&') {
|
|
2405
|
+
if (curr[1] == ' ') {
|
|
2406
|
+
curr.splice(0, 2);
|
|
2407
|
+
}
|
|
2408
|
+
else {
|
|
2409
|
+
if (ast.typ != 'Rule' && combinators.includes(curr[1])) {
|
|
2410
|
+
wrap = false;
|
|
2380
2411
|
}
|
|
2381
2412
|
else {
|
|
2382
|
-
|
|
2383
|
-
nextNode.raw[0].push('&');
|
|
2413
|
+
curr.splice(0, 1);
|
|
2384
2414
|
}
|
|
2385
2415
|
}
|
|
2386
|
-
// @ts-ignore
|
|
2387
|
-
nextNode.sel = nextNode.raw.reduce((acc, curr) => {
|
|
2388
|
-
acc.push(curr.join(''));
|
|
2389
|
-
return acc;
|
|
2390
|
-
}, []).join(',');
|
|
2391
|
-
wrapper.chi.push(nextNode);
|
|
2392
|
-
// @ts-ignore
|
|
2393
|
-
ast.chi.splice(i, 1);
|
|
2394
2416
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2417
|
+
else if (combinators.includes(curr[0])) {
|
|
2418
|
+
curr.unshift('&');
|
|
2419
|
+
}
|
|
2397
2420
|
// @ts-ignore
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
}
|
|
2421
|
+
acc.push(curr.map(t => t.replaceAll('&', node.optimized.optimized[0])).join(''));
|
|
2422
|
+
return acc;
|
|
2423
|
+
}, []);
|
|
2424
|
+
// @ts-ignore
|
|
2425
|
+
node.sel = (wrap ? node.optimized.optimized[0] : '') + `:is(${selector.join(',')})`;
|
|
2401
2426
|
}
|
|
2402
2427
|
}
|
|
2403
2428
|
// @ts-ignore
|
|
@@ -2427,6 +2452,7 @@
|
|
|
2427
2452
|
ast.chi.splice(nodeIndex, 1);
|
|
2428
2453
|
// @ts-ignore
|
|
2429
2454
|
if (hasDeclaration(node)) {
|
|
2455
|
+
// @ts-ignore
|
|
2430
2456
|
deduplicateRule(node);
|
|
2431
2457
|
}
|
|
2432
2458
|
else {
|
|
@@ -2471,6 +2497,7 @@
|
|
|
2471
2497
|
if (recursive && previous != node) {
|
|
2472
2498
|
// @ts-ignore
|
|
2473
2499
|
if (hasDeclaration(previous)) {
|
|
2500
|
+
// @ts-ignore
|
|
2474
2501
|
deduplicateRule(previous);
|
|
2475
2502
|
}
|
|
2476
2503
|
else {
|
|
@@ -2488,6 +2515,7 @@
|
|
|
2488
2515
|
deduplicateRule(node);
|
|
2489
2516
|
}
|
|
2490
2517
|
else {
|
|
2518
|
+
// @ts-ignore
|
|
2491
2519
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
2492
2520
|
deduplicate(node, options, recursive);
|
|
2493
2521
|
}
|
|
@@ -2518,7 +2546,7 @@
|
|
|
2518
2546
|
}
|
|
2519
2547
|
return true;
|
|
2520
2548
|
}
|
|
2521
|
-
function deduplicateRule(ast
|
|
2549
|
+
function deduplicateRule(ast) {
|
|
2522
2550
|
// @ts-ignore
|
|
2523
2551
|
if (!('chi' in ast) || ast.chi?.length <= 1) {
|
|
2524
2552
|
return ast;
|
|
@@ -2568,15 +2596,39 @@
|
|
|
2568
2596
|
return ast;
|
|
2569
2597
|
}
|
|
2570
2598
|
function splitRule(buffer) {
|
|
2571
|
-
const result = [];
|
|
2599
|
+
const result = [[]];
|
|
2572
2600
|
let str = '';
|
|
2573
2601
|
for (let i = 0; i < buffer.length; i++) {
|
|
2574
2602
|
let chr = buffer.charAt(i);
|
|
2603
|
+
if (isWhiteSpace(chr.charCodeAt(0))) {
|
|
2604
|
+
let k = i;
|
|
2605
|
+
while (k + 1 < buffer.length) {
|
|
2606
|
+
if (isWhiteSpace(buffer[k + 1].charCodeAt(0))) {
|
|
2607
|
+
k++;
|
|
2608
|
+
continue;
|
|
2609
|
+
}
|
|
2610
|
+
break;
|
|
2611
|
+
}
|
|
2612
|
+
if (str !== '') {
|
|
2613
|
+
// @ts-ignore
|
|
2614
|
+
result.at(-1).push(str);
|
|
2615
|
+
str = '';
|
|
2616
|
+
}
|
|
2617
|
+
// @ts-ignore
|
|
2618
|
+
if (result.at(-1).length > 0) {
|
|
2619
|
+
// @ts-ignore
|
|
2620
|
+
result.at(-1).push(' ');
|
|
2621
|
+
}
|
|
2622
|
+
i = k;
|
|
2623
|
+
continue;
|
|
2624
|
+
}
|
|
2575
2625
|
if (chr == ',') {
|
|
2576
2626
|
if (str !== '') {
|
|
2577
|
-
|
|
2627
|
+
// @ts-ignore
|
|
2628
|
+
result.at(-1).push(str);
|
|
2578
2629
|
str = '';
|
|
2579
2630
|
}
|
|
2631
|
+
result.push([]);
|
|
2580
2632
|
continue;
|
|
2581
2633
|
}
|
|
2582
2634
|
str += chr;
|
|
@@ -2626,38 +2678,45 @@
|
|
|
2626
2678
|
}
|
|
2627
2679
|
}
|
|
2628
2680
|
if (str !== '') {
|
|
2629
|
-
|
|
2681
|
+
// @ts-ignore
|
|
2682
|
+
result.at(-1).push(str);
|
|
2630
2683
|
}
|
|
2631
2684
|
return result;
|
|
2632
2685
|
}
|
|
2633
2686
|
function reduceRuleSelector(node) {
|
|
2687
|
+
if (node.raw == null) {
|
|
2688
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: splitRule(node.sel) });
|
|
2689
|
+
}
|
|
2634
2690
|
// @ts-ignore
|
|
2635
|
-
if (node.raw != null) {
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
}
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2691
|
+
// if (node.raw != null) {
|
|
2692
|
+
// @ts-ignore
|
|
2693
|
+
let optimized = reduceSelector(node.raw.reduce((acc, curr) => {
|
|
2694
|
+
acc.push(curr.slice());
|
|
2695
|
+
return acc;
|
|
2696
|
+
}, []));
|
|
2697
|
+
if (optimized != null) {
|
|
2698
|
+
Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
|
|
2699
|
+
}
|
|
2700
|
+
if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
|
|
2701
|
+
const raw = [
|
|
2702
|
+
[
|
|
2703
|
+
optimized.optimized[0], ':is('
|
|
2704
|
+
].concat(optimized.selector.reduce((acc, curr) => {
|
|
2705
|
+
if (acc.length > 0) {
|
|
2706
|
+
acc.push(',');
|
|
2707
|
+
}
|
|
2708
|
+
acc.push(...curr);
|
|
2709
|
+
return acc;
|
|
2710
|
+
}, [])).concat(')')
|
|
2711
|
+
];
|
|
2712
|
+
const sel = raw[0].join('');
|
|
2713
|
+
if (sel.length < node.sel.length) {
|
|
2714
|
+
node.sel = sel;
|
|
2715
|
+
// node.raw = raw;
|
|
2716
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
2659
2717
|
}
|
|
2660
2718
|
}
|
|
2719
|
+
// }
|
|
2661
2720
|
}
|
|
2662
2721
|
function diff(n1, n2, options = {}) {
|
|
2663
2722
|
let node1 = n1;
|
|
@@ -2678,25 +2737,25 @@
|
|
|
2678
2737
|
// @ts-ignore
|
|
2679
2738
|
const raw1 = node1.raw;
|
|
2680
2739
|
// @ts-ignore
|
|
2681
|
-
const optimized1 = node1.optimized;
|
|
2740
|
+
// const optimized1 = node1.optimized;
|
|
2682
2741
|
// @ts-ignore
|
|
2683
2742
|
const raw2 = node2.raw;
|
|
2684
2743
|
// @ts-ignore
|
|
2685
|
-
const optimized2 = node2.optimized;
|
|
2744
|
+
// const optimized2 = node2.optimized;
|
|
2686
2745
|
node1 = { ...node1, chi: node1.chi.slice() };
|
|
2687
2746
|
node2 = { ...node2, chi: node2.chi.slice() };
|
|
2688
2747
|
if (raw1 != null) {
|
|
2689
2748
|
Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
|
|
2690
2749
|
}
|
|
2691
|
-
if (optimized1 != null) {
|
|
2692
|
-
|
|
2693
|
-
}
|
|
2750
|
+
// if (optimized1 != null) {
|
|
2751
|
+
// Object.defineProperty(node1, 'optimized', {enumerable: false, writable: true, value: optimized1});
|
|
2752
|
+
// }
|
|
2694
2753
|
if (raw2 != null) {
|
|
2695
2754
|
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2696
2755
|
}
|
|
2697
|
-
if (optimized2 != null) {
|
|
2698
|
-
|
|
2699
|
-
}
|
|
2756
|
+
// if (optimized2 != null) {
|
|
2757
|
+
// Object.defineProperty(node2, 'optimized', {enumerable: false, writable: true, value: optimized2});
|
|
2758
|
+
// }
|
|
2700
2759
|
const intersect = [];
|
|
2701
2760
|
while (i--) {
|
|
2702
2761
|
if (node1.chi[i].typ == 'Comment') {
|
|
@@ -2724,7 +2783,7 @@
|
|
|
2724
2783
|
const result = (intersect.length == 0 ? null : {
|
|
2725
2784
|
...node1,
|
|
2726
2785
|
// @ts-ignore
|
|
2727
|
-
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(),
|
|
2786
|
+
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(','),
|
|
2728
2787
|
chi: intersect.reverse()
|
|
2729
2788
|
});
|
|
2730
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)) {
|
|
@@ -2733,8 +2792,169 @@
|
|
|
2733
2792
|
}
|
|
2734
2793
|
return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
|
|
2735
2794
|
}
|
|
2795
|
+
function matchSelectors(selector1, selector2, parentType) {
|
|
2796
|
+
let match = [[]];
|
|
2797
|
+
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));
|
|
2798
|
+
let i = 0;
|
|
2799
|
+
let k;
|
|
2800
|
+
let l;
|
|
2801
|
+
let token;
|
|
2802
|
+
let matching = true;
|
|
2803
|
+
let matchFunction = 0;
|
|
2804
|
+
let inAttr = 0;
|
|
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;
|
|
2811
|
+
break;
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
if (matching) {
|
|
2815
|
+
l = 0;
|
|
2816
|
+
for (; l < selector2.length; l++) {
|
|
2817
|
+
if (selector2[l][i] != token) {
|
|
2818
|
+
matching = false;
|
|
2819
|
+
break;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
if (!matching) {
|
|
2824
|
+
break;
|
|
2825
|
+
}
|
|
2826
|
+
if (token == ',') {
|
|
2827
|
+
match.push([]);
|
|
2828
|
+
}
|
|
2829
|
+
else {
|
|
2830
|
+
if (token.endsWith('(')) {
|
|
2831
|
+
matchFunction++;
|
|
2832
|
+
}
|
|
2833
|
+
if (token.endsWith('[')) {
|
|
2834
|
+
inAttr++;
|
|
2835
|
+
}
|
|
2836
|
+
else if (token == ')') {
|
|
2837
|
+
matchFunction--;
|
|
2838
|
+
}
|
|
2839
|
+
else if (token == ']') {
|
|
2840
|
+
inAttr--;
|
|
2841
|
+
}
|
|
2842
|
+
match.at(-1).push(token);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
// invalid function
|
|
2846
|
+
if (matchFunction != 0 || inAttr != 0) {
|
|
2847
|
+
return null;
|
|
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
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
if (match.length > 1) {
|
|
2857
|
+
console.error(`unsupported multilevel matching`);
|
|
2858
|
+
console.error({ match, selector1, selector2 });
|
|
2859
|
+
return null;
|
|
2860
|
+
}
|
|
2861
|
+
for (const part of match) {
|
|
2862
|
+
while (part.length > 0) {
|
|
2863
|
+
const token = part.at(-1);
|
|
2864
|
+
if (token == ' ' || combinators.includes(token) || notEndingWith.includes(token.at(-1))) {
|
|
2865
|
+
part.pop();
|
|
2866
|
+
continue;
|
|
2867
|
+
}
|
|
2868
|
+
break;
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
if (match.every(t => t.length == 0)) {
|
|
2872
|
+
return null;
|
|
2873
|
+
}
|
|
2874
|
+
if (eq([['&']], match)) {
|
|
2875
|
+
return null;
|
|
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;
|
|
2888
|
+
}
|
|
2889
|
+
break;
|
|
2890
|
+
}
|
|
2891
|
+
// invalid function match
|
|
2892
|
+
if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
|
|
2893
|
+
return null;
|
|
2894
|
+
}
|
|
2895
|
+
if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
|
|
2896
|
+
return null;
|
|
2897
|
+
}
|
|
2898
|
+
if (hasCompoundSelector && curr.length > 0) {
|
|
2899
|
+
hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
2900
|
+
}
|
|
2901
|
+
if (curr[0] == ':is(') {
|
|
2902
|
+
let inFunction = 0;
|
|
2903
|
+
let canReduce = true;
|
|
2904
|
+
const isCompound = curr.reduce((acc, token, index) => {
|
|
2905
|
+
if (index == 0) {
|
|
2906
|
+
inFunction++;
|
|
2907
|
+
canReduce = curr[1] == '&';
|
|
2908
|
+
}
|
|
2909
|
+
else if (token.endsWith('(')) {
|
|
2910
|
+
if (inFunction == 0) {
|
|
2911
|
+
canReduce = false;
|
|
2912
|
+
}
|
|
2913
|
+
inFunction++;
|
|
2914
|
+
}
|
|
2915
|
+
else if (token == ')') {
|
|
2916
|
+
inFunction--;
|
|
2917
|
+
}
|
|
2918
|
+
else if (token == ',') {
|
|
2919
|
+
if (!canReduce) {
|
|
2920
|
+
canReduce = curr[index + 1] == '&';
|
|
2921
|
+
}
|
|
2922
|
+
acc.push([]);
|
|
2923
|
+
}
|
|
2924
|
+
else
|
|
2925
|
+
acc.at(-1)?.push(token);
|
|
2926
|
+
return acc;
|
|
2927
|
+
}, [[]]);
|
|
2928
|
+
if (inFunction > 0) {
|
|
2929
|
+
canReduce = false;
|
|
2930
|
+
}
|
|
2931
|
+
if (canReduce) {
|
|
2932
|
+
curr = isCompound.reduce((acc, curr) => {
|
|
2933
|
+
if (acc.length > 0) {
|
|
2934
|
+
acc.push(',');
|
|
2935
|
+
}
|
|
2936
|
+
acc.push(...curr);
|
|
2937
|
+
return acc;
|
|
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
|
+
}
|
|
2736
2956
|
function reduceSelector(selector) {
|
|
2737
|
-
if (selector.length
|
|
2957
|
+
if (selector.length == 0) {
|
|
2738
2958
|
return null;
|
|
2739
2959
|
}
|
|
2740
2960
|
const optimized = [];
|
|
@@ -2756,37 +2976,75 @@
|
|
|
2756
2976
|
}
|
|
2757
2977
|
optimized.push(item);
|
|
2758
2978
|
}
|
|
2759
|
-
|
|
2760
|
-
optimized.
|
|
2979
|
+
while (optimized.length > 0) {
|
|
2980
|
+
const last = optimized.at(-1);
|
|
2981
|
+
if ((last == ' ' || combinators.includes(last))) {
|
|
2982
|
+
optimized.pop();
|
|
2983
|
+
continue;
|
|
2984
|
+
}
|
|
2985
|
+
break;
|
|
2986
|
+
}
|
|
2987
|
+
selector.forEach((selector) => selector.splice(0, optimized.length));
|
|
2988
|
+
// combinator
|
|
2989
|
+
if (combinators.includes(optimized.at(-1))) {
|
|
2990
|
+
const combinator = optimized.pop();
|
|
2991
|
+
selector.forEach(selector => selector.unshift(combinator));
|
|
2761
2992
|
}
|
|
2762
2993
|
let reducible = optimized.length == 1;
|
|
2763
|
-
if (optimized
|
|
2764
|
-
|
|
2994
|
+
if (optimized[0] == '&' && optimized[1] == ' ') {
|
|
2995
|
+
optimized.splice(0, 2);
|
|
2996
|
+
}
|
|
2997
|
+
if (optimized.length == 0 ||
|
|
2998
|
+
(optimized[0].charAt(0) == '&' ||
|
|
2999
|
+
selector.length == 1)) {
|
|
3000
|
+
return {
|
|
3001
|
+
match: false,
|
|
3002
|
+
optimized,
|
|
3003
|
+
selector: selector.map(selector => selector[0] == '&' && selector[1] == ' ' ? selector.slice(2) : selector),
|
|
3004
|
+
reducible: selector.length > 1 && selector.every((selector) => !combinators.includes(selector[0]))
|
|
3005
|
+
};
|
|
2765
3006
|
}
|
|
2766
3007
|
return {
|
|
2767
3008
|
match: true,
|
|
2768
3009
|
optimized,
|
|
2769
3010
|
selector: selector.reduce((acc, curr) => {
|
|
2770
|
-
|
|
3011
|
+
let hasCompound = true;
|
|
3012
|
+
if (hasCompound && curr.length > 0) {
|
|
3013
|
+
hasCompound = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
3014
|
+
}
|
|
2771
3015
|
// @ts-ignore
|
|
2772
|
-
if (
|
|
2773
|
-
|
|
3016
|
+
if (hasCompound && curr[0] == ' ') {
|
|
3017
|
+
hasCompound = false;
|
|
3018
|
+
curr.unshift('&');
|
|
2774
3019
|
}
|
|
2775
|
-
if (
|
|
2776
|
-
|
|
3020
|
+
if (curr.length == 0) {
|
|
3021
|
+
curr.push('&');
|
|
3022
|
+
hasCompound = false;
|
|
2777
3023
|
}
|
|
2778
3024
|
if (reducible) {
|
|
2779
|
-
const chr =
|
|
3025
|
+
const chr = curr[0].charAt(0);
|
|
2780
3026
|
// @ts-ignore
|
|
2781
3027
|
reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
|
|
2782
3028
|
}
|
|
2783
|
-
acc.push(
|
|
3029
|
+
acc.push(hasCompound ? ['&'].concat(curr) : curr);
|
|
2784
3030
|
return acc;
|
|
2785
3031
|
}, []),
|
|
2786
|
-
reducible
|
|
3032
|
+
reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
|
|
2787
3033
|
};
|
|
2788
3034
|
}
|
|
2789
|
-
function reducer(acc, curr) {
|
|
3035
|
+
function reducer(acc, curr, index, array) {
|
|
3036
|
+
// trim :is()
|
|
3037
|
+
if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
|
|
3038
|
+
curr = curr.slice(1, -1);
|
|
3039
|
+
}
|
|
3040
|
+
if (curr[0] == '&') {
|
|
3041
|
+
if (curr[1] == ' ') {
|
|
3042
|
+
curr.splice(0, 2);
|
|
3043
|
+
}
|
|
3044
|
+
else if (combinators.includes(curr[1])) {
|
|
3045
|
+
curr.splice(0, 1);
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
2790
3048
|
acc.push(curr.join(''));
|
|
2791
3049
|
return acc;
|
|
2792
3050
|
}
|
|
@@ -3094,7 +3352,7 @@
|
|
|
3094
3352
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
3095
3353
|
// allowed nesting at-rules
|
|
3096
3354
|
// there must be a top level rule in the stack
|
|
3097
|
-
const raw = tokens.reduce((acc, curr
|
|
3355
|
+
const raw = tokens.reduce((acc, curr) => {
|
|
3098
3356
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
3099
3357
|
return acc;
|
|
3100
3358
|
}, []);
|
|
@@ -3129,7 +3387,12 @@
|
|
|
3129
3387
|
}
|
|
3130
3388
|
}
|
|
3131
3389
|
const uniq = new Map;
|
|
3132
|
-
parseTokens(tokens, { compress: options.compress }).reduce((acc, curr) => {
|
|
3390
|
+
parseTokens(tokens, 'Rule', { compress: options.compress }).reduce((acc, curr, index, array) => {
|
|
3391
|
+
if (curr.typ == 'Whitespace') {
|
|
3392
|
+
if (array[index - 1]?.val == '+' || array[index + 1]?.val == '+') {
|
|
3393
|
+
return acc;
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3133
3396
|
let t = renderToken(curr, { compress: true });
|
|
3134
3397
|
if (t == ',') {
|
|
3135
3398
|
acc.push([]);
|
|
@@ -3173,7 +3436,7 @@
|
|
|
3173
3436
|
}
|
|
3174
3437
|
if (tokens[i].typ == 'Colon') {
|
|
3175
3438
|
name = tokens.slice(0, i);
|
|
3176
|
-
value = parseTokens(tokens.slice(i + 1), {
|
|
3439
|
+
value = parseTokens(tokens.slice(i + 1), 'Declaration', {
|
|
3177
3440
|
parseColor: true,
|
|
3178
3441
|
src: options.src,
|
|
3179
3442
|
resolveUrls: options.resolveUrls,
|
|
@@ -3262,7 +3525,6 @@
|
|
|
3262
3525
|
position.ind = ind;
|
|
3263
3526
|
position.lin = lin;
|
|
3264
3527
|
position.col = col == 0 ? 1 : col;
|
|
3265
|
-
// }
|
|
3266
3528
|
}
|
|
3267
3529
|
function consumeWhiteSpace() {
|
|
3268
3530
|
let count = 0;
|
|
@@ -3494,6 +3756,9 @@
|
|
|
3494
3756
|
break;
|
|
3495
3757
|
case '~':
|
|
3496
3758
|
case '|':
|
|
3759
|
+
if (tokens.at(-1)?.typ == 'Whitespace') {
|
|
3760
|
+
tokens.pop();
|
|
3761
|
+
}
|
|
3497
3762
|
if (buffer.length > 0) {
|
|
3498
3763
|
pushToken(getType(buffer));
|
|
3499
3764
|
buffer = '';
|
|
@@ -3515,19 +3780,32 @@
|
|
|
3515
3780
|
break;
|
|
3516
3781
|
}
|
|
3517
3782
|
pushToken(getType(buffer));
|
|
3783
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3784
|
+
value = next();
|
|
3785
|
+
}
|
|
3518
3786
|
buffer = value;
|
|
3519
3787
|
break;
|
|
3520
3788
|
case '>':
|
|
3521
|
-
if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
3522
|
-
tokens.pop();
|
|
3523
|
-
}
|
|
3524
3789
|
if (buffer !== '') {
|
|
3525
3790
|
pushToken(getType(buffer));
|
|
3526
3791
|
buffer = '';
|
|
3527
3792
|
}
|
|
3793
|
+
if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
3794
|
+
tokens.pop();
|
|
3795
|
+
}
|
|
3528
3796
|
pushToken({ typ: 'Gt' });
|
|
3529
3797
|
consumeWhiteSpace();
|
|
3530
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 '+':
|
|
3531
3809
|
case ':':
|
|
3532
3810
|
case ',':
|
|
3533
3811
|
case '=':
|
|
@@ -3541,6 +3819,9 @@
|
|
|
3541
3819
|
}
|
|
3542
3820
|
pushToken(getType(value));
|
|
3543
3821
|
buffer = '';
|
|
3822
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3823
|
+
pushToken(getType(next()));
|
|
3824
|
+
}
|
|
3544
3825
|
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3545
3826
|
next();
|
|
3546
3827
|
}
|
|
@@ -3718,13 +3999,14 @@
|
|
|
3718
3999
|
}
|
|
3719
4000
|
return { ast, errors, bytesIn };
|
|
3720
4001
|
}
|
|
3721
|
-
function parseTokens(tokens, options = {}) {
|
|
4002
|
+
function parseTokens(tokens, nodeType, options = {}) {
|
|
3722
4003
|
for (let i = 0; i < tokens.length; i++) {
|
|
3723
4004
|
const t = tokens[i];
|
|
3724
4005
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
3725
4006
|
i + 1 == tokens.length ||
|
|
3726
4007
|
['Comma'].includes(tokens[i + 1].typ) ||
|
|
3727
4008
|
(i > 0 &&
|
|
4009
|
+
tokens[i + 1]?.typ != 'Literal' &&
|
|
3728
4010
|
funcLike.includes(tokens[i - 1].typ) &&
|
|
3729
4011
|
!['var', 'calc'].includes(tokens[i - 1].val))))) {
|
|
3730
4012
|
tokens.splice(i--, 1);
|
|
@@ -3771,7 +4053,7 @@
|
|
|
3771
4053
|
if (t.chi.length > 1) {
|
|
3772
4054
|
/*(<AttrToken>t).chi =*/
|
|
3773
4055
|
// @ts-ignore
|
|
3774
|
-
parseTokens(t.chi, options);
|
|
4056
|
+
parseTokens(t.chi, t.typ, options);
|
|
3775
4057
|
}
|
|
3776
4058
|
// @ts-ignore
|
|
3777
4059
|
t.chi.forEach(val => {
|
|
@@ -3883,7 +4165,7 @@
|
|
|
3883
4165
|
// @ts-ignore
|
|
3884
4166
|
if (t.chi.length > 0) {
|
|
3885
4167
|
// @ts-ignore
|
|
3886
|
-
parseTokens(t.chi, options);
|
|
4168
|
+
parseTokens(t.chi, t.typ, options);
|
|
3887
4169
|
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.compress) {
|
|
3888
4170
|
//
|
|
3889
4171
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
@@ -3949,7 +4231,7 @@
|
|
|
3949
4231
|
yield { node, parent, root };
|
|
3950
4232
|
if ('chi' in node) {
|
|
3951
4233
|
for (const child of node.chi) {
|
|
3952
|
-
yield* doWalk(child, node, (root
|
|
4234
|
+
yield* doWalk(child, node, (root ?? node));
|
|
3953
4235
|
}
|
|
3954
4236
|
}
|
|
3955
4237
|
}
|