Skip to content

Commit b8332bc

Browse files
authored
Analyze selector browser hacks (#71)
This references #3
1 parent b211652 commit b8332bc

File tree

9 files changed

+112
-96
lines changed

9 files changed

+112
-96
lines changed

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"css-color-names": "^1.0.0",
4747
"css-media-query-browser-h4cks-analyzer": "^1.0.0",
4848
"css-property-browser-h4cks-analyzer": "^1.0.1",
49+
"css-selector-browser-h4cks-analyzer": "^1.0.1",
4950
"css-shorthand-expand": "^1.2.0",
5051
"css-unit-sort": "^1.1.1",
5152
"css-value-browser-h4cks-analyzer": "^1.0.1",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const isBrowserHack = require('css-selector-browser-h4cks-analyzer')
2+
const uniquer = require('../../utils/uniquer.js')
3+
4+
module.exports = selectors => {
5+
const all = selectors.filter(isBrowserHack)
6+
7+
return {
8+
total: all.length,
9+
...uniquer(all)
10+
}
11+
}

src/analyzer/selectors/identifiers.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const specificity = require('specificity')
2+
const {caseInsensitive: stringCompare} = require('string-natural-compare')
23

34
module.exports = selectors => {
45
const totalSelectors = selectors.length
@@ -17,17 +18,16 @@ module.exports = selectors => {
1718
const average = totalIdentifiers / totalSelectors
1819

1920
const top = count => {
21+
// Sort by identifiers count, then by alphabet
2022
const sorter = (a, b) => {
2123
if (a.identifiers === b.identifiers) {
22-
return a.selector.localeCompare(b.selector)
24+
return stringCompare(a, b)
2325
}
2426

2527
return b.identifiers - a.identifiers
2628
}
2729

28-
return identifiersPerSelector
29-
.sort(sorter)
30-
.slice(0, count)
30+
return identifiersPerSelector.sort(sorter).slice(0, count)
3131
}
3232

3333
return {

src/analyzer/selectors/index.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
module.exports = selectors => {
22
const all = selectors
33
const unique = [...new Set(all)]
4-
const js = require('./js')(all)
5-
const id = require('./id')(all)
6-
const universal = require('./universal')(all)
7-
const accessibility = require('./accessibility')(all)
8-
const specificity = require('./specificity')(all)
9-
const identifiers = require('./identifiers')(all)
4+
const js = require('./js.js')(all)
5+
const id = require('./id.js')(all)
6+
const universal = require('./universal.js')(all)
7+
const accessibility = require('./accessibility.js')(all)
8+
const specificity = require('./specificity.js')(all)
9+
const identifiers = require('./identifiers.js')(all)
10+
const browserhacks = require('./browserhacks.js')(all)
1011

1112
return {
1213
total: all.length,
@@ -16,6 +17,7 @@ module.exports = selectors => {
1617
universal,
1718
accessibility,
1819
specificity,
19-
identifiers
20+
identifiers,
21+
browserhacks
2022
}
2123
}

test/analyzer/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ test('Returns the correct analysis object structure', async t => {
138138
total: 0,
139139
totalUnique: 0,
140140
unique: []
141+
},
142+
browserhacks: {
143+
total: 0,
144+
unique: [],
145+
totalUnique: 0
141146
}
142147
},
143148
stylesheets: {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const test = require('ava')
2+
const analyze = require('../../../src/analyzer/selectors/browserhacks.js')
3+
4+
test('It responds with the correct structure', t => {
5+
const actual = analyze([])
6+
const expected = {
7+
total: 0,
8+
unique: [],
9+
totalUnique: 0
10+
}
11+
12+
t.deepEqual(actual, expected)
13+
})
14+
15+
test('It recognizes browser hacks correctly', t => {
16+
const actual = analyze(['* html .selector'])
17+
const expected = {
18+
total: 1,
19+
unique: [
20+
{
21+
value: '* html .selector',
22+
count: 1
23+
}
24+
],
25+
totalUnique: 1
26+
}
27+
28+
t.deepEqual(actual, expected)
29+
})
30+
31+
test('It does not report values that are not browser hacks', t => {
32+
const expected = {
33+
total: 0,
34+
unique: [],
35+
totalUnique: 0
36+
}
37+
38+
const actual = analyze(['html'])
39+
40+
t.deepEqual(actual, expected)
41+
})

test/analyzer/selectors/input.css

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -64,37 +64,6 @@
6464
* Contains universal selectors
6565
*/
6666
* html .selector {}
67-
*:first-child + html .selector {}
68-
*:first-child+html .selector {}
69-
* + html .selector {}
70-
*+html .selector {}
71-
body*.selector {}
72-
html > body .selector {}
73-
html>body .selector {}
74-
.selector\ {}
75-
:root .selector {}
76-
body:last-child .selector {}
77-
body:nth-of-type(1) .selector {}
78-
body:first-of-type .selector {}
79-
.selector:not([attr*='']) {}
80-
.selector:not([attr*=""]) {}
81-
.selector:not(*:root) {}
82-
body:empty .selector {}
83-
x:-moz-any-link {}
84-
body:not(:-moz-handler-blocked) .selector {}
85-
_::-moz-progress-bar {}
86-
_::-moz-range-track {}
87-
_:-moz-tree-row(hover) {}
88-
_::selection {}
89-
x:-IE7 {}
90-
_:-ms-fullscreen {}
91-
_:-ms-input-placeholder {}
92-
html:first-child .selector {}
93-
_:-o-prefocus {}
94-
*|html[xmlns*=""] .selector {}
95-
html[xmlns*=""] body:last-child .selector {}
96-
html[xmlns*=""]:root .selector {}
97-
_::-moz-svg-foreign-content {}
9867

9968
/* Don't report these ones (Issue #88) */
10069
tbody:first-child {}

test/analyzer/selectors/output.json

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"total": 57,
3-
"totalUnique": 56,
2+
"total": 26,
3+
"totalUnique": 25,
44
"js": {
55
"total": 6,
66
"totalUnique": 6,
@@ -54,52 +54,24 @@
5454
]
5555
},
5656
"universal": {
57-
"total": 12,
58-
"totalUnique": 11,
57+
"total": 5,
58+
"totalUnique": 4,
5959
"unique": [
6060
{
6161
"value": "*",
6262
"count": 1
6363
},
64-
{
65-
"value": "* + html .selector",
66-
"count": 1
67-
},
6864
{
6965
"value": "* html .selector",
7066
"count": 2
7167
},
72-
{
73-
"value": "*+html .selector",
74-
"count": 1
75-
},
76-
{
77-
"value": "*:first-child + html .selector",
78-
"count": 1
79-
},
80-
{
81-
"value": "*:first-child+html .selector",
82-
"count": 1
83-
},
84-
{
85-
"value": "*|html[xmlns*=\"\"] .selector",
86-
"count": 1
87-
},
8868
{
8969
"value": ".foo *",
9070
"count": 1
9171
},
9272
{
9373
"value": ".foo * .bar",
9474
"count": 1
95-
},
96-
{
97-
"value": ".selector:not(*:root)",
98-
"count": 1
99-
},
100-
{
101-
"value": "body*.selector",
102-
"count": 1
10375
}
10476
]
10577
},
@@ -183,28 +155,38 @@
183155
]
184156
},
185157
"identifiers": {
186-
"average": 2.6491228070175437,
158+
"average": 2.8461538461538463,
187159
"top": [
188-
{
189-
"identifiers": 26,
190-
"selector": ".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"
191-
},
192-
{
193-
"identifiers": 11,
194-
"selector": ".Foo > .Bar ~ .Baz [type=\"text\"] + span:before #bazz #fizz #buzz #drank #drugs"
195-
},
196-
{
197-
"identifiers": 5,
198-
"selector": "#multipe #ids #counted #as #one"
199-
},
200-
{
201-
"identifiers": 5,
202-
"selector": "html[xmlns*=\"\"] body:last-child .selector"
203-
},
204-
{
205-
"identifiers": 4,
206-
"selector": "html[xmlns*=\"\"]:root .selector"
207-
}
208-
]
160+
{
161+
"identifiers": 26,
162+
"selector": ".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"
163+
},
164+
{
165+
"identifiers": 11,
166+
"selector": ".Foo > .Bar ~ .Baz [type=\"text\"] + span:before #bazz #fizz #buzz #drank #drugs"
167+
},
168+
{
169+
"identifiers": 5,
170+
"selector": "#multipe #ids #counted #as #one"
171+
},
172+
{
173+
"identifiers": 3,
174+
"selector": "[role=\"menuitem\"][aria-checked=\"true\"]::before"
175+
},
176+
{
177+
"identifiers": 2,
178+
"selector": "* html .selector"
179+
}
180+
]
181+
},
182+
"browserhacks": {
183+
"total": 2,
184+
"unique": [
185+
{
186+
"value": "* html .selector",
187+
"count": 2
188+
}
189+
],
190+
"totalUnique": 1
209191
}
210192
}

0 commit comments

Comments
 (0)