@projectwallace/css-analyzer 9.6.0 → 9.6.2
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/dist/atrules/index.d.ts +1 -1
- package/dist/atrules/index.js +1 -1
- package/dist/{atrules-CskmpIdJ.js → atrules-Bnb0wvNR.js} +19 -19
- package/dist/atrules-CXLSfmpu.d.ts +16 -0
- package/dist/browserhacks-BtVwVqdU.js +347 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +114 -196
- package/dist/selectors/index.d.ts +1 -1
- package/dist/selectors/index.js +1 -2
- package/dist/{specificity-BKdu6JZr.js → specificity-DKo9lvB5.js} +33 -37
- package/dist/{utils-DJb_IpTO.d.ts → utils-yIUD7vGy.d.ts} +2 -2
- package/dist/values/index.d.ts +26 -4
- package/dist/values/index.js +2 -3
- package/dist/{values-B5nDaGc_.d.ts → values-DgD2lJqZ.d.ts} +2 -2
- package/package.json +35 -35
- package/readme.md +285 -285
- package/dist/atrules-C8lZ1H_5.d.ts +0 -16
- package/dist/browserhacks-Ckz2JiOQ.js +0 -222
package/dist/index.js
CHANGED
|
@@ -1,89 +1,10 @@
|
|
|
1
|
-
import { n as isSupportsBrowserhack, t as isMediaBrowserhack } from "./atrules-
|
|
1
|
+
import { n as isSupportsBrowserhack, t as isMediaBrowserhack } from "./atrules-Bnb0wvNR.js";
|
|
2
2
|
import { t as KeywordSet } from "./keyword-set-qSyAMR9o.js";
|
|
3
3
|
import { n as unquote, t as endsWith } from "./string-utils-C97yyuqE.js";
|
|
4
|
-
import { a as getComplexity, i as getCombinators, n as calculateForAST, o as isAccessibility, s as isPrefixed, t as calculate } from "./specificity-
|
|
5
|
-
import { a as
|
|
4
|
+
import { a as getComplexity, i as getCombinators, n as calculateForAST, o as isAccessibility, s as isPrefixed, t as calculate } from "./specificity-DKo9lvB5.js";
|
|
5
|
+
import { a as keywords, c as namedColors, i as isValueReset, l as systemColors, n as SYSTEM_FONTS, o as colorFunctions, r as destructure, s as colorKeywords, t as isIe9Hack } from "./browserhacks-BtVwVqdU.js";
|
|
6
6
|
import { a as shorthand_properties, i as isHack, n as basename, r as border_radius_properties, t as SPACING_RESET_PROPERTIES } from "./property-utils-B3n9KkA9.js";
|
|
7
|
-
import {
|
|
8
|
-
//#region src/values/destructure-font-shorthand.ts
|
|
9
|
-
const SYSTEM_FONTS = new KeywordSet([
|
|
10
|
-
"caption",
|
|
11
|
-
"icon",
|
|
12
|
-
"menu",
|
|
13
|
-
"message-box",
|
|
14
|
-
"small-caption",
|
|
15
|
-
"status-bar"
|
|
16
|
-
]);
|
|
17
|
-
const SIZE_KEYWORDS = new KeywordSet([
|
|
18
|
-
"xx-small",
|
|
19
|
-
"x-small",
|
|
20
|
-
"small",
|
|
21
|
-
"medium",
|
|
22
|
-
"large",
|
|
23
|
-
"x-large",
|
|
24
|
-
"xx-large",
|
|
25
|
-
"xxx-large",
|
|
26
|
-
"smaller",
|
|
27
|
-
"larger"
|
|
28
|
-
]);
|
|
29
|
-
const COMMA = 44;
|
|
30
|
-
const SLASH = 47;
|
|
31
|
-
function destructure(value, cb) {
|
|
32
|
-
let font_family = [void 0, void 0];
|
|
33
|
-
let font_size;
|
|
34
|
-
let line_height;
|
|
35
|
-
if (value.first_child.type === FUNCTION && value.first_child.name?.toLowerCase() === "var") return null;
|
|
36
|
-
let prev;
|
|
37
|
-
for (let node of value.children) {
|
|
38
|
-
let next = node.next_sibling;
|
|
39
|
-
if (node.type === IDENTIFIER && keywords.has(node.name)) cb({
|
|
40
|
-
type: "keyword",
|
|
41
|
-
value: node.name
|
|
42
|
-
});
|
|
43
|
-
if (next && next.type === OPERATOR && next.text.charCodeAt(0) === SLASH) {
|
|
44
|
-
font_size = node.text;
|
|
45
|
-
prev = node;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (prev?.type === OPERATOR && prev.text.charCodeAt(0) === SLASH) {
|
|
49
|
-
line_height = node.text;
|
|
50
|
-
prev = node;
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (next?.type === OPERATOR && next.text.charCodeAt(0) === COMMA && !font_family[0]) {
|
|
54
|
-
font_family[0] = node;
|
|
55
|
-
if (!font_size && prev) font_size = prev.text;
|
|
56
|
-
prev = node;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (node.next_sibling === null) {
|
|
60
|
-
font_family[1] = node;
|
|
61
|
-
if (!font_size && !font_family[0] && prev) font_size = prev.text;
|
|
62
|
-
prev = node;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (node.type === NUMBER) {
|
|
66
|
-
prev = node;
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
if (node.type === IDENTIFIER) {
|
|
70
|
-
let name = node.name;
|
|
71
|
-
if (name && SIZE_KEYWORDS.has(name)) {
|
|
72
|
-
font_size = name;
|
|
73
|
-
prev = node;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
prev = node;
|
|
78
|
-
}
|
|
79
|
-
let family = font_family[0] || font_family[1] ? value.text.substring((font_family?.[0] || font_family?.[1] || { start: value.start }).start - value.start, font_family[1] ? font_family[1].end - value.start : value.text.length) : null;
|
|
80
|
-
return {
|
|
81
|
-
font_size,
|
|
82
|
-
line_height,
|
|
83
|
-
font_family: family
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
7
|
+
import { SKIP, is_atrule, is_atrule_prelude, is_attribute_selector, is_container_query, is_custom, is_declaration, is_dimension, is_function, is_hash, is_identifier, is_layer_name, is_media_feature, is_operator, is_pseudo_class_selector, is_pseudo_element_selector, is_raw, is_rule, is_selector, is_selector_list, is_supports_query, is_type_selector, is_url, is_vendor_prefixed, parse, str_starts_with, walk } from "@projectwallace/css-parser";
|
|
87
8
|
//#region src/values/animations.ts
|
|
88
9
|
const TIMING_KEYWORDS = new KeywordSet([
|
|
89
10
|
"linear",
|
|
@@ -95,38 +16,35 @@ const TIMING_KEYWORDS = new KeywordSet([
|
|
|
95
16
|
"step-end"
|
|
96
17
|
]);
|
|
97
18
|
const TIMING_FUNCTION_VALUES = new KeywordSet(["cubic-bezier", "steps"]);
|
|
98
|
-
function analyzeAnimation(
|
|
19
|
+
function analyzeAnimation(value, cb) {
|
|
99
20
|
let durationFound = false;
|
|
100
|
-
for (let
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
} else if (type === IDENTIFIER && name) {
|
|
111
|
-
if (TIMING_KEYWORDS.has(name)) cb({
|
|
112
|
-
type: "fn",
|
|
113
|
-
value: child
|
|
114
|
-
});
|
|
115
|
-
else if (keywords.has(name)) cb({
|
|
116
|
-
type: "keyword",
|
|
117
|
-
value: child
|
|
118
|
-
});
|
|
119
|
-
} else if (type === FUNCTION && name && TIMING_FUNCTION_VALUES.has(name)) cb({
|
|
21
|
+
for (let node of value) if (is_operator(node)) durationFound = false;
|
|
22
|
+
else if (is_dimension(node) && durationFound === false) {
|
|
23
|
+
durationFound = true;
|
|
24
|
+
cb({
|
|
25
|
+
type: "duration",
|
|
26
|
+
value: node
|
|
27
|
+
});
|
|
28
|
+
} else if (is_identifier(node)) {
|
|
29
|
+
if (TIMING_KEYWORDS.has(node.name)) cb({
|
|
120
30
|
type: "fn",
|
|
121
|
-
value:
|
|
31
|
+
value: node
|
|
122
32
|
});
|
|
123
|
-
|
|
33
|
+
else if (keywords.has(node.name)) cb({
|
|
34
|
+
type: "keyword",
|
|
35
|
+
value: node
|
|
36
|
+
});
|
|
37
|
+
} else if (is_function(node) && TIMING_FUNCTION_VALUES.has(node.name)) cb({
|
|
38
|
+
type: "fn",
|
|
39
|
+
value: node
|
|
40
|
+
});
|
|
124
41
|
}
|
|
125
42
|
//#endregion
|
|
126
43
|
//#region src/values/vendor-prefix.ts
|
|
127
|
-
function isValuePrefixed(
|
|
128
|
-
walk(
|
|
129
|
-
if (
|
|
44
|
+
function isValuePrefixed(value, on_value) {
|
|
45
|
+
walk(value, function(node) {
|
|
46
|
+
if (node.is_vendor_prefixed) if (is_identifier(node) || is_function(node)) on_value(node.name);
|
|
47
|
+
else on_value(node.text);
|
|
130
48
|
});
|
|
131
49
|
}
|
|
132
50
|
//#endregion
|
|
@@ -320,7 +238,7 @@ function getEmbedType(embed) {
|
|
|
320
238
|
//#region src/vendor-prefix.ts
|
|
321
239
|
/**
|
|
322
240
|
* Kept for backwards compatibility
|
|
323
|
-
* @deprecated
|
|
241
|
+
* @deprecated Will be removed in next major version
|
|
324
242
|
* */
|
|
325
243
|
function hasVendorPrefix(keyword) {
|
|
326
244
|
return is_vendor_prefixed(keyword);
|
|
@@ -449,7 +367,7 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
449
367
|
walk(ast, (node, depth) => {
|
|
450
368
|
if (keyframesDepth >= 0 && depth <= keyframesDepth) keyframesDepth = -1;
|
|
451
369
|
let inKeyframes = keyframesDepth >= 0 && depth > keyframesDepth;
|
|
452
|
-
if (node
|
|
370
|
+
if (is_atrule(node)) {
|
|
453
371
|
let atruleLoc = toLoc(node);
|
|
454
372
|
atruleNesting.push(depth);
|
|
455
373
|
uniqueAtruleNesting.p(depth, atruleLoc);
|
|
@@ -458,12 +376,12 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
458
376
|
if (normalized_name === "font-face") {
|
|
459
377
|
let descriptors = Object.create(null);
|
|
460
378
|
if (useLocations) fontfaces_with_loc.p(node.start, toLoc(node));
|
|
461
|
-
let block = node.
|
|
462
|
-
for (let descriptor of block?.children || []) if (descriptor
|
|
379
|
+
let block = node.block;
|
|
380
|
+
for (let descriptor of block?.children || []) if (is_declaration(descriptor) && descriptor.value) descriptors[descriptor.property] = descriptor.value.text;
|
|
463
381
|
atRuleComplexities.push(1);
|
|
464
382
|
fontfaces.push(descriptors);
|
|
465
383
|
}
|
|
466
|
-
if (node.
|
|
384
|
+
if (!node.has_prelude) {
|
|
467
385
|
if (normalized_name === "layer") {
|
|
468
386
|
layers.p("<anonymous>", toLoc(node));
|
|
469
387
|
atRuleComplexities.push(2);
|
|
@@ -493,14 +411,16 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
493
411
|
} else if (normalized_name === "layer") for (let layer of node.prelude.text.split(",").map((s) => s.trim())) layers.p(layer, toLoc(node));
|
|
494
412
|
else if (normalized_name === "import") {
|
|
495
413
|
imports.p(node.prelude.text, toLoc(node));
|
|
496
|
-
if (node.prelude.has_children) {
|
|
497
|
-
for (let child of node.prelude) if (child
|
|
498
|
-
else if (child
|
|
414
|
+
if (is_atrule_prelude(node.prelude) && node.prelude.has_children) {
|
|
415
|
+
for (let child of node.prelude) if (is_supports_query(child)) supports.p(child.value, toLoc(child));
|
|
416
|
+
else if (is_layer_name(child) && child.value) layers.p(child.value, toLoc(child));
|
|
499
417
|
}
|
|
500
418
|
} else if (normalized_name === "container") {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
419
|
+
let { prelude } = node;
|
|
420
|
+
containers.p(prelude.text, toLoc(node));
|
|
421
|
+
if (is_atrule_prelude(prelude) && is_container_query(prelude.first_child)) {
|
|
422
|
+
let container_name = prelude.first_child.first_child;
|
|
423
|
+
if (container_name && is_identifier(container_name)) containerNames.p(container_name.text, toLoc(node));
|
|
504
424
|
}
|
|
505
425
|
} else if (normalized_name === "property") registeredProperties.p(node.prelude.text, toLoc(node));
|
|
506
426
|
else if (normalized_name === "function") {
|
|
@@ -511,19 +431,19 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
511
431
|
else if (normalized_name === "scope") scopes.p(node.prelude.text, toLoc(node));
|
|
512
432
|
atRuleComplexities.push(complexity);
|
|
513
433
|
}
|
|
514
|
-
} else if (node
|
|
515
|
-
if (node.prelude
|
|
434
|
+
} else if (is_rule(node)) if (inKeyframes && node.has_prelude) {
|
|
435
|
+
if (is_selector_list(node.prelude) && node.prelude.child_count > 0) for (let keyframe_selector of node.prelude) keyframeSelectors.p(keyframe_selector.text, toLoc(keyframe_selector));
|
|
516
436
|
} else {
|
|
517
437
|
totalRules++;
|
|
518
438
|
if (node.block?.is_empty) emptyRules++;
|
|
519
439
|
let numSelectors = 0;
|
|
520
440
|
let numDeclarations = 0;
|
|
521
441
|
let loc = toLoc(node);
|
|
522
|
-
if (node.prelude) {
|
|
523
|
-
for (const selector of node.prelude
|
|
442
|
+
if (node.has_prelude && is_selector_list(node.prelude)) {
|
|
443
|
+
for (const selector of node.prelude) if (is_selector(selector)) numSelectors++;
|
|
524
444
|
}
|
|
525
445
|
if (node.block) {
|
|
526
|
-
for (const declaration of node.block
|
|
446
|
+
for (const declaration of node.block) if (is_declaration(declaration)) numDeclarations++;
|
|
527
447
|
}
|
|
528
448
|
ruleSizes.push(numSelectors + numDeclarations);
|
|
529
449
|
uniqueRuleSize.p(numSelectors + numDeclarations, loc);
|
|
@@ -534,7 +454,7 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
534
454
|
ruleNesting.push(depth);
|
|
535
455
|
uniqueRuleNesting.p(depth, loc);
|
|
536
456
|
}
|
|
537
|
-
else if (node
|
|
457
|
+
else if (is_selector(node)) {
|
|
538
458
|
if (inKeyframes) return SKIP;
|
|
539
459
|
let loc = toLoc(node);
|
|
540
460
|
selectorNesting.push(depth > 0 ? depth - 1 : 0);
|
|
@@ -550,10 +470,10 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
550
470
|
a11y.p(a11y_selector, loc);
|
|
551
471
|
});
|
|
552
472
|
walk(node, (child) => {
|
|
553
|
-
if (child
|
|
554
|
-
else if (child
|
|
555
|
-
else if (child
|
|
556
|
-
else if (child
|
|
473
|
+
if (is_attribute_selector(child)) attributeSelectors.p(child.name.toLowerCase(), loc);
|
|
474
|
+
else if (is_type_selector(child) && !child.name.startsWith("--") && child.name.includes("-")) customElementSelectors.p(child.name.toLowerCase(), loc);
|
|
475
|
+
else if (is_pseudo_class_selector(child)) pseudoClasses.p(child.name.toLowerCase(), loc);
|
|
476
|
+
else if (is_pseudo_element_selector(child)) pseudoElements.p(child.name.toLowerCase(), loc);
|
|
557
477
|
});
|
|
558
478
|
getCombinators(node, (combinator) => {
|
|
559
479
|
let name = combinator.name.trim() === "" ? " " : combinator.name;
|
|
@@ -572,9 +492,10 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
572
492
|
specificities.push(specificity);
|
|
573
493
|
if (sa > 0) ids.p(node.text, loc);
|
|
574
494
|
return SKIP;
|
|
575
|
-
} else if (node
|
|
495
|
+
} else if (is_declaration(node)) {
|
|
576
496
|
totalDeclarations++;
|
|
577
|
-
|
|
497
|
+
let declaration = node.text;
|
|
498
|
+
uniqueDeclarations.add(declaration);
|
|
578
499
|
let loc = toLoc(node);
|
|
579
500
|
let declarationDepth = depth > 0 ? depth - 1 : 0;
|
|
580
501
|
declarationNesting.push(declarationDepth);
|
|
@@ -582,7 +503,7 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
582
503
|
let complexity = 1;
|
|
583
504
|
if (node.is_important) {
|
|
584
505
|
complexity++;
|
|
585
|
-
if (!
|
|
506
|
+
if (!declaration.toLowerCase().includes("!important")) valueBrowserhacks.p("!ie", toLoc(node.value));
|
|
586
507
|
if (inKeyframes) {
|
|
587
508
|
importantsInKeyframes++;
|
|
588
509
|
complexity++;
|
|
@@ -610,6 +531,8 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
610
531
|
if (shorthand_properties.has(normalizedProperty)) shorthands.p(property, propertyLoc);
|
|
611
532
|
{
|
|
612
533
|
let value = node.value;
|
|
534
|
+
if (!value) return;
|
|
535
|
+
if (is_raw(value)) return;
|
|
613
536
|
let { text } = value;
|
|
614
537
|
let valueLoc = toLoc(value);
|
|
615
538
|
let complexity = 1;
|
|
@@ -638,8 +561,8 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
638
561
|
return SKIP;
|
|
639
562
|
} else if (normalizedProperty === "font") {
|
|
640
563
|
if (!SYSTEM_FONTS.has(text)) {
|
|
641
|
-
let result = destructure(value, function(
|
|
642
|
-
|
|
564
|
+
let result = destructure(value, function(keyword) {
|
|
565
|
+
valueKeywords.p(keyword.toLowerCase(), valueLoc);
|
|
643
566
|
});
|
|
644
567
|
if (!result) return SKIP;
|
|
645
568
|
let { font_size, line_height, font_family } = result;
|
|
@@ -661,91 +584,86 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
661
584
|
if (normalized.includes("var(")) lineHeights.p(text, valueLoc);
|
|
662
585
|
else lineHeights.p(normalized, valueLoc);
|
|
663
586
|
} else if (normalizedProperty === "transition" || normalizedProperty === "animation") {
|
|
664
|
-
analyzeAnimation(value
|
|
587
|
+
analyzeAnimation(value, function(item) {
|
|
665
588
|
if (item.type === "fn") timingFunctions.p(item.value.text.toLowerCase(), valueLoc);
|
|
666
589
|
else if (item.type === "duration") durations.p(item.value.text.toLowerCase(), valueLoc);
|
|
667
590
|
else if (item.type === "keyword") valueKeywords.p(item.value.text.toLowerCase(), valueLoc);
|
|
668
591
|
});
|
|
669
592
|
return SKIP;
|
|
670
593
|
} else if (normalizedProperty === "animation-duration" || normalizedProperty === "transition-duration") {
|
|
671
|
-
for (let child of value.children) if (child
|
|
594
|
+
for (let child of value.children) if (!is_operator(child)) {
|
|
672
595
|
let text = child.text;
|
|
673
596
|
if (/var\(/i.test(text)) durations.p(text, valueLoc);
|
|
674
597
|
else durations.p(text.toLowerCase(), valueLoc);
|
|
675
598
|
}
|
|
676
599
|
} else if (normalizedProperty === "transition-timing-function" || normalizedProperty === "animation-timing-function") {
|
|
677
|
-
for (let child of value.children) if (child
|
|
600
|
+
for (let child of value.children) if (!is_operator(child)) timingFunctions.p(child.text, valueLoc);
|
|
678
601
|
} else if (normalizedProperty === "container-name") containerNames.p(text, valueLoc);
|
|
679
602
|
else if (normalizedProperty === "container") {
|
|
680
|
-
if (value.first_child
|
|
603
|
+
if (value.first_child && is_identifier(value.first_child)) containerNames.p(value.first_child.text, valueLoc);
|
|
681
604
|
} else if (border_radius_properties.has(normalizedProperty)) borderRadiuses.push(text, property, valueLoc);
|
|
682
605
|
else if (normalizedProperty === "text-shadow") textShadows.p(text, valueLoc);
|
|
683
606
|
else if (normalizedProperty === "box-shadow") boxShadows.p(text, valueLoc);
|
|
684
607
|
let valueHasIe9Hack = isIe9Hack(value);
|
|
685
608
|
walk(value, (valueNode) => {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
609
|
+
if (is_dimension(valueNode)) {
|
|
610
|
+
let unit = valueNode.unit.toLowerCase();
|
|
611
|
+
let loc = toLoc(valueNode);
|
|
612
|
+
units.push(unit, property, loc);
|
|
613
|
+
return SKIP;
|
|
614
|
+
}
|
|
615
|
+
if (is_hash(valueNode)) {
|
|
616
|
+
let hashText = valueNode.text;
|
|
617
|
+
if (!hashText || !hashText.startsWith("#")) return SKIP;
|
|
618
|
+
let hashValue = hashText.toLowerCase();
|
|
619
|
+
if (valueHasIe9Hack && !hashValue.endsWith("\\9")) hashValue = hashValue + "\\9";
|
|
620
|
+
let hexLength = hashValue.length - 1;
|
|
621
|
+
if (endsWith("\\9", hashValue)) hexLength = hexLength - 2;
|
|
622
|
+
let hashLoc = toLoc(valueNode);
|
|
623
|
+
colors.push(hashValue, property, hashLoc);
|
|
624
|
+
colorFormats.p(`hex` + hexLength, hashLoc);
|
|
625
|
+
return SKIP;
|
|
626
|
+
}
|
|
627
|
+
if (is_identifier(valueNode)) {
|
|
628
|
+
let identifierText = valueNode.text;
|
|
629
|
+
let identifierLoc = toLoc(valueNode);
|
|
630
|
+
if (normalizedProperty === "font" || normalizedProperty === "font-family") return SKIP;
|
|
631
|
+
if (keywords.has(identifierText)) valueKeywords.p(identifierText.toLowerCase(), identifierLoc);
|
|
632
|
+
let nodeLen = identifierText.length;
|
|
633
|
+
if (nodeLen > 20 || nodeLen < 3) return SKIP;
|
|
634
|
+
if (colorKeywords.has(identifierText)) {
|
|
635
|
+
let colorKeyword = identifierText.toLowerCase();
|
|
636
|
+
colors.push(colorKeyword, property, identifierLoc);
|
|
637
|
+
colorFormats.p(colorKeyword, identifierLoc);
|
|
638
|
+
return;
|
|
692
639
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
if (valueHasIe9Hack && !hashValue.endsWith("\\9")) hashValue = hashValue + "\\9";
|
|
698
|
-
let hexLength = hashValue.length - 1;
|
|
699
|
-
if (endsWith("\\9", hashValue)) hexLength = hexLength - 2;
|
|
700
|
-
let hashLoc = toLoc(valueNode);
|
|
701
|
-
colors.push(hashValue, property, hashLoc);
|
|
702
|
-
colorFormats.p(`hex` + hexLength, hashLoc);
|
|
703
|
-
return SKIP;
|
|
640
|
+
if (namedColors.has(identifierText)) {
|
|
641
|
+
colors.push(identifierText.toLowerCase(), property, identifierLoc);
|
|
642
|
+
colorFormats.p("named", identifierLoc);
|
|
643
|
+
return;
|
|
704
644
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
if (keywords.has(identifierText)) valueKeywords.p(identifierText.toLowerCase(), identifierLoc);
|
|
710
|
-
let nodeLen = identifierText.length;
|
|
711
|
-
if (nodeLen > 20 || nodeLen < 3) return SKIP;
|
|
712
|
-
if (colorKeywords.has(identifierText)) {
|
|
713
|
-
let colorKeyword = identifierText.toLowerCase();
|
|
714
|
-
colors.push(colorKeyword, property, identifierLoc);
|
|
715
|
-
colorFormats.p(colorKeyword, identifierLoc);
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
718
|
-
if (namedColors.has(identifierText)) {
|
|
719
|
-
colors.push(identifierText.toLowerCase(), property, identifierLoc);
|
|
720
|
-
colorFormats.p("named", identifierLoc);
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
if (systemColors.has(identifierText)) {
|
|
724
|
-
colors.push(identifierText.toLowerCase(), property, identifierLoc);
|
|
725
|
-
colorFormats.p("system", identifierLoc);
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
return SKIP;
|
|
645
|
+
if (systemColors.has(identifierText)) {
|
|
646
|
+
colors.push(identifierText.toLowerCase(), property, identifierLoc);
|
|
647
|
+
colorFormats.p("system", identifierLoc);
|
|
648
|
+
return;
|
|
729
649
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
gradients.p(valueNode.text, funcLoc);
|
|
740
|
-
return;
|
|
741
|
-
}
|
|
650
|
+
return SKIP;
|
|
651
|
+
}
|
|
652
|
+
if (is_function(valueNode)) {
|
|
653
|
+
let funcName = valueNode.name;
|
|
654
|
+
let funcLoc = toLoc(valueNode);
|
|
655
|
+
if (colorFunctions.has(funcName)) {
|
|
656
|
+
colors.push(valueNode.text, property, funcLoc);
|
|
657
|
+
colorFormats.p(funcName.toLowerCase(), funcLoc);
|
|
658
|
+
return;
|
|
742
659
|
}
|
|
660
|
+
if (endsWith("gradient", funcName)) gradients.p(valueNode.text, funcLoc);
|
|
743
661
|
}
|
|
744
662
|
});
|
|
745
663
|
}
|
|
746
|
-
} else if (node
|
|
664
|
+
} else if (is_url(node)) {
|
|
747
665
|
let { value } = node;
|
|
748
|
-
let embed = unquote(value
|
|
666
|
+
let embed = unquote(value ?? "");
|
|
749
667
|
if (str_starts_with(embed, "data:")) {
|
|
750
668
|
let size = embed.length;
|
|
751
669
|
let type = getEmbedType(embed);
|
|
@@ -772,8 +690,8 @@ function analyzeInternal(css, options, useLocations) {
|
|
|
772
690
|
embedTypes.unique.set(type, item);
|
|
773
691
|
}
|
|
774
692
|
}
|
|
775
|
-
} else if (node
|
|
776
|
-
|
|
693
|
+
} else if (is_media_feature(node)) {
|
|
694
|
+
mediaFeatures.p(node.property?.toLowerCase(), toLoc(node));
|
|
777
695
|
return SKIP;
|
|
778
696
|
}
|
|
779
697
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as calculate, i as isPrefixed, n as getComplexity, o as calculateForAST, r as isAccessibility, s as compare, t as getCombinators } from "../utils-
|
|
1
|
+
import { a as calculate, i as isPrefixed, n as getComplexity, o as calculateForAST, r as isAccessibility, s as compare, t as getCombinators } from "../utils-yIUD7vGy.js";
|
|
2
2
|
export { compare as compareSpecificity, getCombinators, getComplexity, calculate as getSpecificity, calculateForAST as getSpecificityForAST, isAccessibility, isPrefixed };
|
package/dist/selectors/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import { a as getComplexity, i as getCombinators, n as calculateForAST, o as isAccessibility, r as compare, s as isPrefixed, t as calculate } from "../specificity-BKdu6JZr.js";
|
|
1
|
+
import { a as getComplexity, i as getCombinators, n as calculateForAST, o as isAccessibility, r as compare, s as isPrefixed, t as calculate } from "../specificity-DKo9lvB5.js";
|
|
3
2
|
export { compare as compareSpecificity, getCombinators, getComplexity, calculate as getSpecificity, calculateForAST as getSpecificityForAST, isAccessibility, isPrefixed };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as KeywordSet } from "./keyword-set-qSyAMR9o.js";
|
|
2
2
|
import { n as unquote } from "./string-utils-C97yyuqE.js";
|
|
3
|
-
import { ATTRIBUTE_SELECTOR, CLASS_SELECTOR,
|
|
3
|
+
import { ATTRIBUTE_SELECTOR, CLASS_SELECTOR, ID_SELECTOR, PSEUDO_CLASS_SELECTOR, PSEUDO_ELEMENT_SELECTOR, SKIP, TYPE_SELECTOR, is_attribute_selector, is_combinator, is_nth_of_selector, is_nth_selector, is_pseudo_class_selector, is_pseudo_element_selector, is_selector, is_selector_list, is_type_selector, str_equals, str_starts_with, walk } from "@projectwallace/css-parser";
|
|
4
4
|
import { parse_selector } from "@projectwallace/css-parser/parse-selector";
|
|
5
5
|
//#region src/selectors/utils.ts
|
|
6
6
|
const PSEUDO_FUNCTIONS = new KeywordSet([
|
|
@@ -16,12 +16,12 @@ const PSEUDO_FUNCTIONS = new KeywordSet([
|
|
|
16
16
|
]);
|
|
17
17
|
function isPrefixed(selector, on_selector) {
|
|
18
18
|
walk(selector, function(node) {
|
|
19
|
-
if (node
|
|
19
|
+
if (is_pseudo_element_selector(node) || is_pseudo_class_selector(node) || is_type_selector(node)) {
|
|
20
20
|
if (node.is_vendor_prefixed) {
|
|
21
21
|
let prefix = "";
|
|
22
|
-
if (node
|
|
23
|
-
else if (node
|
|
24
|
-
on_selector(prefix +
|
|
22
|
+
if (is_pseudo_class_selector(node)) prefix = ":";
|
|
23
|
+
else if (is_pseudo_element_selector(node)) prefix = "::";
|
|
24
|
+
on_selector(prefix + node.name);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
});
|
|
@@ -36,7 +36,7 @@ function isAccessibility(selector, on_selector) {
|
|
|
36
36
|
return "[" + clone.name?.toLowerCase() + "]";
|
|
37
37
|
}
|
|
38
38
|
walk(selector, function(node) {
|
|
39
|
-
if (node
|
|
39
|
+
if (is_attribute_selector(node)) {
|
|
40
40
|
const name = node.name || "";
|
|
41
41
|
if (str_equals("role", name) || str_starts_with(name, "aria-")) on_selector(normalize(node));
|
|
42
42
|
}
|
|
@@ -49,31 +49,31 @@ function isAccessibility(selector, on_selector) {
|
|
|
49
49
|
*/
|
|
50
50
|
function getComplexity(selector) {
|
|
51
51
|
let complexity = 0;
|
|
52
|
-
function findSelectors(
|
|
53
|
-
walk(
|
|
54
|
-
if (
|
|
52
|
+
function findSelectors(tree, complexities) {
|
|
53
|
+
walk(tree, function(node) {
|
|
54
|
+
if (is_selector(node)) complexities.push(getComplexity(node));
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
walk(selector, function(node) {
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
if (
|
|
61
|
-
if (node.text
|
|
58
|
+
node.type;
|
|
59
|
+
if (is_selector(node)) return;
|
|
60
|
+
if (is_nth_selector(node)) {
|
|
61
|
+
if (node.text.trim()) complexity++;
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
complexity++;
|
|
65
|
-
if (
|
|
65
|
+
if (is_pseudo_class_selector(node) || is_type_selector(node) || is_pseudo_element_selector(node)) {
|
|
66
66
|
if (node.is_vendor_prefixed) complexity++;
|
|
67
67
|
}
|
|
68
|
-
if (
|
|
68
|
+
if (is_attribute_selector(node)) {
|
|
69
69
|
if (node.value) complexity++;
|
|
70
70
|
return SKIP;
|
|
71
71
|
}
|
|
72
|
-
if (
|
|
73
|
-
const name = node.name
|
|
72
|
+
if (is_pseudo_class_selector(node)) {
|
|
73
|
+
const name = node.name;
|
|
74
74
|
if (PSEUDO_FUNCTIONS.has(name.toLowerCase())) {
|
|
75
75
|
const childComplexities = [];
|
|
76
|
-
if (node.has_children) for (const child of node) if (child
|
|
76
|
+
if (node.has_children) for (const child of node) if (is_selector(child)) childComplexities.push(getComplexity(child));
|
|
77
77
|
else findSelectors(child, childComplexities);
|
|
78
78
|
if (childComplexities.length > 0) {
|
|
79
79
|
for (const c of childComplexities) complexity += c;
|
|
@@ -89,8 +89,8 @@ function getComplexity(selector) {
|
|
|
89
89
|
*/
|
|
90
90
|
function getCombinators(selector, onMatch) {
|
|
91
91
|
walk(selector, function(node) {
|
|
92
|
-
if (node
|
|
93
|
-
name: node.name
|
|
92
|
+
if (is_combinator(node)) onMatch({
|
|
93
|
+
name: node.name.trim() === "" ? " " : node.name,
|
|
94
94
|
loc: {
|
|
95
95
|
offset: node.start,
|
|
96
96
|
line: node.line,
|
|
@@ -130,7 +130,7 @@ const calculateForAST = (selectorAST) => {
|
|
|
130
130
|
b += 1;
|
|
131
131
|
break;
|
|
132
132
|
case PSEUDO_CLASS_SELECTOR:
|
|
133
|
-
switch (current.name
|
|
133
|
+
switch (current.name.toLowerCase()) {
|
|
134
134
|
case "where": break;
|
|
135
135
|
case "-webkit-any":
|
|
136
136
|
case "any":
|
|
@@ -143,7 +143,7 @@ const calculateForAST = (selectorAST) => {
|
|
|
143
143
|
case "has":
|
|
144
144
|
if (current.has_children) {
|
|
145
145
|
const childSelectorList = current.first_child;
|
|
146
|
-
if (childSelectorList
|
|
146
|
+
if (is_selector_list(childSelectorList)) {
|
|
147
147
|
const max1 = max(calculate(childSelectorList));
|
|
148
148
|
a += max1[0];
|
|
149
149
|
b += max1[1];
|
|
@@ -155,7 +155,7 @@ const calculateForAST = (selectorAST) => {
|
|
|
155
155
|
case "nth-last-child":
|
|
156
156
|
b += 1;
|
|
157
157
|
const nthOf = current.first_child;
|
|
158
|
-
if (nthOf
|
|
158
|
+
if (is_nth_of_selector(nthOf) && nthOf.selector) {
|
|
159
159
|
const max2 = max(calculate(nthOf.selector));
|
|
160
160
|
a += max2[0];
|
|
161
161
|
b += max2[1];
|
|
@@ -165,11 +165,11 @@ const calculateForAST = (selectorAST) => {
|
|
|
165
165
|
case "host-context":
|
|
166
166
|
case "host":
|
|
167
167
|
b += 1;
|
|
168
|
-
const childSelector = current.first_child
|
|
169
|
-
if (childSelector
|
|
168
|
+
const childSelector = current.first_child.first_child;
|
|
169
|
+
if (childSelector && is_selector(childSelector)) {
|
|
170
170
|
let childPart = childSelector.first_child;
|
|
171
171
|
while (childPart) {
|
|
172
|
-
if (childPart
|
|
172
|
+
if (is_combinator(childPart)) break;
|
|
173
173
|
const partSpecificity = calculateForAST({
|
|
174
174
|
type_name: "Selector",
|
|
175
175
|
first_child: childPart,
|
|
@@ -194,14 +194,14 @@ const calculateForAST = (selectorAST) => {
|
|
|
194
194
|
}
|
|
195
195
|
break;
|
|
196
196
|
case PSEUDO_ELEMENT_SELECTOR:
|
|
197
|
-
switch (current.name
|
|
197
|
+
switch (current.name.toLowerCase()) {
|
|
198
198
|
case "slotted":
|
|
199
199
|
c += 1;
|
|
200
|
-
const childSelector = current.first_child
|
|
201
|
-
if (childSelector
|
|
200
|
+
const childSelector = current.first_child.first_child;
|
|
201
|
+
if (is_selector(childSelector)) {
|
|
202
202
|
let childPart = childSelector.first_child;
|
|
203
203
|
while (childPart) {
|
|
204
|
-
if (childPart
|
|
204
|
+
if (is_combinator(childPart)) break;
|
|
205
205
|
const partSpecificity = calculateForAST({
|
|
206
206
|
type_name: "Selector",
|
|
207
207
|
first_child: childPart,
|
|
@@ -249,20 +249,16 @@ const convertToAST = (source) => {
|
|
|
249
249
|
throw new TypeError(`Could not convert passed in source '${source}' to SelectorList: ${message}`);
|
|
250
250
|
}
|
|
251
251
|
if (source instanceof Object) {
|
|
252
|
-
if (source
|
|
252
|
+
if (is_selector_list(source)) return source;
|
|
253
253
|
throw new TypeError(`Passed in source is an Object but no AST / AST of the type SelectorList`);
|
|
254
254
|
}
|
|
255
255
|
throw new TypeError(`Passed in source is not a String nor an Object. I don't know what to do with it.`);
|
|
256
256
|
};
|
|
257
257
|
const calculate = (selector) => {
|
|
258
258
|
if (!selector) return [];
|
|
259
|
-
const
|
|
259
|
+
const selector_list = convertToAST(selector);
|
|
260
260
|
const specificities = [];
|
|
261
|
-
|
|
262
|
-
while (selectorNode) {
|
|
263
|
-
specificities.push(calculateForAST(selectorNode));
|
|
264
|
-
selectorNode = selectorNode.next_sibling;
|
|
265
|
-
}
|
|
261
|
+
for (const selector_node of selector_list) specificities.push(calculateForAST(selector_node));
|
|
266
262
|
return specificities;
|
|
267
263
|
};
|
|
268
264
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSNode } from "@projectwallace/css-parser";
|
|
1
|
+
import { CSSNode, Selector } from "@projectwallace/css-parser";
|
|
2
2
|
|
|
3
3
|
//#region src/collection.d.ts
|
|
4
4
|
type Location = {
|
|
@@ -25,7 +25,7 @@ type Specificity = [number, number, number];
|
|
|
25
25
|
* @returns 0 if s1 equals s2, a negative number if s1 is lower than s2, or a positive number if s1 higher than s2
|
|
26
26
|
*/
|
|
27
27
|
declare function compare(s1: Specificity, s2: Specificity): number;
|
|
28
|
-
declare const calculateForAST: (selectorAST:
|
|
28
|
+
declare const calculateForAST: (selectorAST: Selector) => Specificity;
|
|
29
29
|
declare const calculate: (selector: string | CSSNode) => Specificity[];
|
|
30
30
|
//#endregion
|
|
31
31
|
//#region src/selectors/utils.d.ts
|