Skip to content

Commit a401060

Browse files
authored
add specificity.max (#156)
Closes #114
1 parent d0f08a6 commit a401060

File tree

3 files changed

+77
-21
lines changed

3 files changed

+77
-21
lines changed
Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
1-
const specificity = require('specificity')
1+
const {compare, calculate} = require('specificity')
2+
const uniquer = require('../../utils/uniquer')
23

34
module.exports = selectors => {
4-
const all = [...selectors]
5-
.sort()
6-
.reverse()
7-
.sort(specificity.compare)
8-
.reverse()
5+
if (selectors.length === 0) {
6+
return {
7+
max: {
8+
count: 0,
9+
selectors: [],
10+
value: null
11+
},
12+
top: []
13+
}
14+
}
915

10-
const top = count => {
11-
return [...all].slice(0, count).map(selector => {
12-
const [a, b, c, d] = specificity
13-
.calculate(selector)
14-
.shift().specificityArray
16+
const all = uniquer(selectors)
17+
.unique.map(({value, count}) => {
18+
const [a, b, c, d] = calculate(value).shift().specificityArray
1519

1620
return {
17-
value: selector,
21+
count,
22+
value,
1823
specificity: {a, b, c, d}
1924
}
2025
})
21-
}
26+
.sort((a, b) => compare(b.value, a.value))
27+
28+
const [maxSpecificitySelector] = all
29+
const maxSpecificity = maxSpecificitySelector.specificity
30+
const maxSpecificitySelectors = all.filter(
31+
selector => compare(selector.value, maxSpecificitySelector.value) === 0
32+
)
2233

2334
return {
24-
top: top(5)
35+
top: [...all].slice(0, 5),
36+
max: {
37+
value: maxSpecificity,
38+
count: maxSpecificitySelectors.length,
39+
selectors: maxSpecificitySelectors
40+
}
2541
}
2642
}

test/analyzer/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,16 @@ test('it returns the correct analysis object structure', async t => {
9191
'selectors.js.total': 0,
9292
'selectors.js.totalUnique': 0,
9393
'selectors.js.unique': [],
94+
'selectors.specificity.max.count': 1,
95+
'selectors.specificity.max.selectors': [
96+
{value: 'foo', specificity: {a: 0, b: 0, c: 0, d: 1}, count: 1}
97+
],
98+
'selectors.specificity.max.value.a': 0,
99+
'selectors.specificity.max.value.b': 0,
100+
'selectors.specificity.max.value.c': 0,
101+
'selectors.specificity.max.value.d': 1,
94102
'selectors.specificity.top': [
95-
{value: 'foo', specificity: {a: 0, b: 0, c: 0, d: 1}}
103+
{value: 'foo', specificity: {a: 0, b: 0, c: 0, d: 1}, count: 1}
96104
],
97105
'selectors.total': 1,
98106
'selectors.totalUnique': 1,

test/analyzer/selectors/specificity.js

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,37 @@ test('it responds with the correct structure', t => {
66
const actual = analyze(fixture)
77

88
t.deepEqual(actual, {
9-
top: []
9+
top: [],
10+
max: {
11+
value: null,
12+
count: 0,
13+
selectors: []
14+
}
1015
})
1116
})
1217

18+
test('it finds the max specificity selectors', t => {
19+
const fixture = [
20+
'a',
21+
'a b',
22+
'a b c',
23+
'#a .b c', // <- Max.
24+
'a .b #c', // <- Max.
25+
'a .b #c' // <- Max. (dupe)
26+
]
27+
const {max: actual} = analyze(fixture)
28+
const expected = {
29+
count: 2,
30+
value: {a: 0, b: 1, c: 1, d: 1},
31+
selectors: [
32+
{count: 1, value: '#a .b c', specificity: {a: 0, b: 1, c: 1, d: 1}},
33+
{count: 2, value: 'a .b #c', specificity: {a: 0, b: 1, c: 1, d: 1}}
34+
]
35+
}
36+
37+
t.deepEqual(actual, expected)
38+
})
39+
1340
test('it finds the top 5 specificity selectors and sorts them by specificity', t => {
1441
const fixture = [
1542
'a10',
@@ -24,24 +51,29 @@ test('it finds the top 5 specificity selectors and sorts them by specificity', t
2451
{
2552
value:
2653
'.Foo > .Bar ~ .Baz [type="text"] + span:before #bazz #fizz #buzz #brick #house',
27-
specificity: {a: 0, b: 5, c: 4, d: 2}
54+
specificity: {a: 0, b: 5, c: 4, d: 2},
55+
count: 1
2856
},
2957
{
3058
value:
3159
'.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t .u .v .w .x .y .z',
32-
specificity: {a: 0, b: 0, c: 26, d: 0}
60+
specificity: {a: 0, b: 0, c: 26, d: 0},
61+
count: 1
3362
},
3463
{
3564
value: 'a',
36-
specificity: {a: 0, b: 0, c: 0, d: 1}
65+
specificity: {a: 0, b: 0, c: 0, d: 1},
66+
count: 1
3767
},
3868
{
3969
value: 'a1',
40-
specificity: {a: 0, b: 0, c: 0, d: 1}
70+
specificity: {a: 0, b: 0, c: 0, d: 1},
71+
count: 1
4172
},
4273
{
4374
value: 'a10',
44-
specificity: {a: 0, b: 0, c: 0, d: 1}
75+
specificity: {a: 0, b: 0, c: 0, d: 1},
76+
count: 1
4577
}
4678
]
4779

0 commit comments

Comments
 (0)