Skip to content

Commit 64360d7

Browse files
authored
add support for analyzing pseudo-classes (#433)
closes #432
1 parent 9372da6 commit 64360d7

14 files changed

+372
-1
lines changed

src/__fixtures__/bol-com-20231008.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54964,6 +54964,39 @@
5496454964
"uniquenessRatio": 0,
5496554965
"ratio": 0
5496654966
},
54967+
"pseudoClasses": {
54968+
"total": 2010,
54969+
"totalUnique": 26,
54970+
"unique": {
54971+
"not": 167,
54972+
"root": 3,
54973+
"-moz-focusring": 8,
54974+
"focus": 94,
54975+
"focus-visible": 66,
54976+
"first-child": 57,
54977+
"after": 447,
54978+
"before": 586,
54979+
"hover": 280,
54980+
"active": 131,
54981+
"has": 2,
54982+
"last-child": 45,
54983+
"checked": 35,
54984+
"focus-within": 13,
54985+
"empty": 1,
54986+
"-moz-placeholder": 3,
54987+
"-ms-input-placeholder": 3,
54988+
"last-of-type": 5,
54989+
"nth-of-type": 11,
54990+
"first-of-type": 2,
54991+
"nth-child": 4,
54992+
"disabled": 34,
54993+
"placeholder-shown": 6,
54994+
"only-child": 2,
54995+
"indeterminate": 3,
54996+
"first-letter": 2
54997+
},
54998+
"uniquenessRatio": 0.012935323383084577
54999+
},
5496755000
"accessibility": {
5496855001
"total": 2,
5496955002
"totalUnique": 2,

src/__fixtures__/bootstrap-5.3.2.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25889,6 +25889,37 @@
2588925889
"uniquenessRatio": 0,
2589025890
"ratio": 0
2589125891
},
25892+
"pseudoClasses": {
25893+
"total": 467,
25894+
"totalUnique": 24,
25895+
"unique": {
25896+
"root": 3,
25897+
"hover": 47,
25898+
"not": 145,
25899+
"focus": 66,
25900+
"focus-visible": 11,
25901+
"disabled": 27,
25902+
"last-child": 34,
25903+
"first-child": 36,
25904+
"nth-of-type": 1,
25905+
"nth-child": 2,
25906+
"-moz-focusring": 1,
25907+
"active": 11,
25908+
"checked": 13,
25909+
"indeterminate": 1,
25910+
"-moz-placeholder-shown": 4,
25911+
"placeholder-shown": 4,
25912+
"-webkit-autofill": 3,
25913+
"focus-within": 7,
25914+
"nth-last-child": 5,
25915+
"valid": 17,
25916+
"invalid": 17,
25917+
"empty": 6,
25918+
"first-of-type": 3,
25919+
"last-of-type": 3
25920+
},
25921+
"uniquenessRatio": 0.05139186295503212
25922+
},
2589225923
"accessibility": {
2589325924
"total": 1,
2589425925
"totalUnique": 1,

src/__fixtures__/cnn-20231008.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31271,6 +31271,33 @@
3127131271
"uniquenessRatio": 1,
3127231272
"ratio": 0.0004955401387512388
3127331273
},
31274+
"pseudoClasses": {
31275+
"total": 2476,
31276+
"totalUnique": 20,
31277+
"unique": {
31278+
"root": 6,
31279+
"hover": 301,
31280+
"after": 113,
31281+
"not": 1363,
31282+
"last-child": 67,
31283+
"has": 76,
31284+
"first-child": 178,
31285+
"nth-child": 107,
31286+
"before": 127,
31287+
"active": 34,
31288+
"focus": 49,
31289+
"empty": 10,
31290+
"only-child": 9,
31291+
"is": 1,
31292+
"first-of-type": 13,
31293+
"last-of-type": 6,
31294+
"-ms-input-placeholder": 2,
31295+
"checked": 10,
31296+
"disabled": 2,
31297+
"nth-of-type": 2
31298+
},
31299+
"uniquenessRatio": 0.008077544426494346
31300+
},
3127431301
"accessibility": {
3127531302
"total": 4,
3127631303
"totalUnique": 4,

src/__fixtures__/css-tricks-20231008.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12512,6 +12512,31 @@
1251212512
"uniquenessRatio": 0.8913043478260869,
1251312513
"ratio": 0.030223390275952694
1251412514
},
12515+
"pseudoClasses": {
12516+
"total": 386,
12517+
"totalUnique": 18,
12518+
"unique": {
12519+
"after": 19,
12520+
"before": 75,
12521+
"not": 130,
12522+
"nth-child": 2,
12523+
"first-child": 12,
12524+
"last-child": 17,
12525+
"focus": 47,
12526+
"hover": 46,
12527+
"is": 2,
12528+
"target": 6,
12529+
"first-of-type": 8,
12530+
"empty": 1,
12531+
"first-letter": 1,
12532+
"nth-of-type": 1,
12533+
"focus-within": 3,
12534+
"active": 2,
12535+
"root": 2,
12536+
"where": 12
12537+
},
12538+
"uniquenessRatio": 0.046632124352331605
12539+
},
1251512540
"accessibility": {
1251612541
"total": 2,
1251712542
"totalUnique": 2,

src/__fixtures__/gazelle-20231008.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87405,6 +87405,37 @@
8740587405
"uniquenessRatio": 0.8229508196721311,
8740687406
"ratio": 0.05726086548390125
8740787407
},
87408+
"pseudoClasses": {
87409+
"total": 2883,
87410+
"totalUnique": 24,
87411+
"unique": {
87412+
"not": 269,
87413+
"active": 128,
87414+
"hover": 437,
87415+
"root": 2,
87416+
"after": 275,
87417+
"before": 821,
87418+
"visited": 6,
87419+
"focus": 278,
87420+
"last-child": 208,
87421+
"first-child": 220,
87422+
"nth-of-type": 7,
87423+
"-ms-input-placeholder": 1,
87424+
"empty": 4,
87425+
"link": 5,
87426+
"last-of-type": 39,
87427+
"first-of-type": 46,
87428+
"checked": 58,
87429+
"disabled": 34,
87430+
"nth-child": 35,
87431+
"first-letter": 1,
87432+
"has": 6,
87433+
"where": 1,
87434+
"-moz-focusring": 1,
87435+
"-moz-ui-invalid": 1
87436+
},
87437+
"uniquenessRatio": 0.008324661810613945
87438+
},
8740887439
"accessibility": {
8740987440
"total": 16,
8741087441
"totalUnique": 13,

src/__fixtures__/github-20231008.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91789,6 +91789,46 @@
9178991789
"uniquenessRatio": 1,
9179091790
"ratio": 0.0011177347242921013
9179191791
},
91792+
"pseudoClasses": {
91793+
"total": 1942,
91794+
"totalUnique": 33,
91795+
"unique": {
91796+
"root": 65,
91797+
"not": 344,
91798+
"hover": 484,
91799+
"focus": 252,
91800+
"focus-visible": 112,
91801+
"disabled": 57,
91802+
"only-child": 6,
91803+
"active": 107,
91804+
"first-child": 91,
91805+
"last-child": 87,
91806+
"checked": 22,
91807+
"focus-within": 11,
91808+
"first-of-type": 14,
91809+
"last-of-type": 14,
91810+
"nth-child": 10,
91811+
"nth-last-child": 1,
91812+
"target": 16,
91813+
"empty": 13,
91814+
"is": 4,
91815+
"popover-open": 1,
91816+
"before": 113,
91817+
"after": 71,
91818+
"indeterminate": 1,
91819+
"nth-of-type": 30,
91820+
"has": 2,
91821+
"placeholder-shown": 3,
91822+
"placeholder": 1,
91823+
"dir": 2,
91824+
"defined": 1,
91825+
"-webkit-autofill": 2,
91826+
"invalid": 2,
91827+
"nth-last-of-type": 1,
91828+
"visited": 2
91829+
},
91830+
"uniquenessRatio": 0.016992790937178166
91831+
},
9179291832
"accessibility": {
9179391833
"total": 331,
9179491834
"totalUnique": 317,

src/__fixtures__/indiatimes-20231008.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56553,6 +56553,29 @@
5655356553
"uniquenessRatio": 0.90625,
5655456554
"ratio": 0.003918207420105302
5655556555
},
56556+
"pseudoClasses": {
56557+
"total": 1081,
56558+
"totalUnique": 16,
56559+
"unique": {
56560+
"first-of-type": 13,
56561+
"after": 108,
56562+
"last-child": 255,
56563+
"checked": 3,
56564+
"first-child": 20,
56565+
"before": 294,
56566+
"last-of-type": 40,
56567+
"focus": 8,
56568+
"not": 110,
56569+
"hover": 103,
56570+
"nth-child": 119,
56571+
"nth-last-child": 3,
56572+
"active": 1,
56573+
"empty": 2,
56574+
"root": 1,
56575+
"Georgia": 1
56576+
},
56577+
"uniquenessRatio": 0.014801110083256245
56578+
},
5655656579
"accessibility": {
5655756580
"total": 0,
5655856581
"totalUnique": 0,

src/__fixtures__/smashing-magazine-20231008.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48874,6 +48874,40 @@
4887448874
"uniquenessRatio": 0.875,
4887548875
"ratio": 0.0027590963959303327
4887648876
},
48877+
"pseudoClasses": {
48878+
"total": 1259,
48879+
"totalUnique": 27,
48880+
"unique": {
48881+
"not": 306,
48882+
"before": 83,
48883+
"after": 82,
48884+
"root": 3,
48885+
"-moz-focusring": 11,
48886+
"nth-of-type": 28,
48887+
"last-child": 25,
48888+
"active": 127,
48889+
"focus": 178,
48890+
"hover": 191,
48891+
"first-of-type": 21,
48892+
"nth-child": 49,
48893+
"-moz-placeholder": 2,
48894+
"-ms-input-placeholder": 10,
48895+
"target": 11,
48896+
"empty": 7,
48897+
"vertical": 1,
48898+
"horizontal": 1,
48899+
"first-child": 48,
48900+
"last-of-type": 20,
48901+
"-webkit-autofill": 29,
48902+
"checked": 12,
48903+
"nth-last-child": 4,
48904+
"visited": 1,
48905+
"-moz-placeholder-shown": 4,
48906+
"placeholder-shown": 4,
48907+
"first-line": 1
48908+
},
48909+
"uniquenessRatio": 0.021445591739475776
48910+
},
4887748911
"accessibility": {
4887848912
"total": 29,
4887948913
"totalUnique": 29,

src/__fixtures__/trello-20231008.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10428,6 +10428,27 @@
1042810428
"uniquenessRatio": 1,
1042910429
"ratio": 0.003469210754553339
1043010430
},
10431+
"pseudoClasses": {
10432+
"total": 493,
10433+
"totalUnique": 14,
10434+
"unique": {
10435+
"hover": 85,
10436+
"focus": 120,
10437+
"not": 44,
10438+
"focus-visible": 40,
10439+
"disabled": 4,
10440+
"root": 1,
10441+
"last-child": 170,
10442+
"active": 17,
10443+
"last-of-type": 2,
10444+
"nth-child": 3,
10445+
"-ms-input-placeholder": 2,
10446+
"after": 1,
10447+
"before": 1,
10448+
"first-child": 3
10449+
},
10450+
"uniquenessRatio": 0.028397565922920892
10451+
},
1043110452
"accessibility": {
1043210453
"total": 0,
1043310454
"totalUnique": 0,

src/index.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import parse from 'css-tree/parser'
22
import walk from 'css-tree/walker'
33
import { calculate } from '@bramus/specificity/core'
44
import { isSupportsBrowserhack, isMediaBrowserhack } from './atrules/atrules.js'
5-
import { getCombinators, getComplexity, isAccessibility, isPrefixed } from './selectors/utils.js'
5+
import { getCombinators, getComplexity, isAccessibility, isPrefixed, hasPseudoClass } from './selectors/utils.js'
66
import { colorFunctions, colorKeywords, namedColors, systemColors } from './values/colors.js'
77
import { destructure, isSystemFont } from './values/destructure-font-shorthand.js'
88
import { isValueKeyword, keywords } from './values/values.js'
@@ -156,6 +156,7 @@ export function analyze(css, options = {}) {
156156
let specificities = []
157157
let ids = new Collection(useLocations)
158158
let a11y = new Collection(useLocations)
159+
let pseudoClasses = new Collection(useLocations)
159160
let combinators = new Collection(useLocations)
160161

161162
// Declarations
@@ -307,6 +308,13 @@ export function analyze(css, options = {}) {
307308
a11y.p(selector, node.loc)
308309
}
309310

311+
let pseudos = hasPseudoClass(node)
312+
if (pseudos !== false) {
313+
for (let pseudo of pseudos) {
314+
pseudoClasses.p(pseudo, node.loc)
315+
}
316+
}
317+
310318
let complexity = getComplexity(node)
311319

312320
if (isPrefixed(node)) {
@@ -820,6 +828,7 @@ export function analyze(css, options = {}) {
820828
ids.c(), {
821829
ratio: ratio(ids.size(), totalSelectors),
822830
}),
831+
pseudoClasses: pseudoClasses.c(),
823832
accessibility: assign(
824833
a11y.c(), {
825834
ratio: ratio(a11y.size(), totalSelectors),

0 commit comments

Comments
 (0)