Skip to content

Commit fafb7dc

Browse files
author
Bart Veneman
committed
reduce memory usage for selector analysis
1 parent 7ad0988 commit fafb7dc

File tree

4 files changed

+36
-32
lines changed

4 files changed

+36
-32
lines changed

src/__fixtures__/github-20210501.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25997,8 +25997,8 @@
2599725997
"ratio": 0
2599825998
},
2599925999
"accessibility": {
26000-
"total": 56,
26001-
"totalUnique": 55,
26000+
"total": 57,
26001+
"totalUnique": 56,
2600226002
"unique": {
2600326003
".breadcrumb-item[aria-current]:not([aria-current=false])": 1,
2600426004
".breadcrumb-item[aria-current]:not([aria-current=false]):after": 1,
@@ -26051,13 +26051,14 @@
2605126051
".pagination [aria-disabled=true]": 1,
2605226052
".pagination [aria-disabled=true]:hover": 1,
2605326053
"body.intent-mouse [role=button]:focus": 1,
26054+
"body.intent-mouse [role=tabpanel][tabindex=\"0\"]:focus": 1,
2605426055
".jump-to-suggestions-results-container [aria-selected=true] .jump-to-octicon": 1,
2605526056
".jump-to-suggestions-results-container [aria-selected=true] .jump-to-suggestions-path": 1,
2605626057
".jump-to-suggestions-results-container [aria-selected=true] mark": 1,
2605726058
".jump-to-suggestions-results-container [aria-selected=true] .d-on-nav-focus": 1
2605826059
},
26059-
"uniquenessRatio": 0.9821428571428571,
26060-
"ratio": 0.018549188473004307
26060+
"uniquenessRatio": 0.9824561403508771,
26061+
"ratio": 0.01888042398145081
2606126062
},
2606226063
"keyframes": {
2606326064
"total": 24,

src/index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import parse from 'css-tree/parser'
22
import walk from 'css-tree/walker'
33
import { isSupportsBrowserhack, isMediaBrowserhack } from './atrules/atrules.js'
4-
import { analyzeSpecificity, compareSpecificity } from './selectors/specificity.js'
4+
import { analyzeSelector, compareSpecificity } from './selectors/specificity.js'
55
import { colorFunctions, colorNames } from './values/colors.js'
66
import { isFontFamilyKeyword, getFamilyFromFont } from './values/font-families.js'
77
import { isFontSizeKeyword, getSizeFromFont } from './values/font-sizes.js'
@@ -233,13 +233,15 @@ const analyze = (css) => {
233233
return this.skip
234234
}
235235

236-
const { specificity, complexity, isId, isA11y } = analyzeSpecificity(node)
236+
const analysis = analyzeSelector(node)
237+
const specificity = analysis.splice(0, 3)
238+
const [complexity, isA11y] = analysis
237239

238-
if (isId) {
240+
if (specificity[0] > 0) {
239241
ids.push(selector)
240242
}
241243

242-
if (isA11y) {
244+
if (isA11y === 1) {
243245
a11y.push(selector)
244246
}
245247

src/selectors/selectors.test.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,23 +232,25 @@ Selectors('counts Accessibility selectors', () => {
232232
const fixture = `
233233
[aria-hidden],
234234
img[role="presentation"],
235-
.selector:not([role="tablist"]) {}
235+
.selector:not([role="tablist"]),
236+
body.intent-mouse·[role=tabpanel][tabindex="0"]:focus,
236237
237238
/* false positives */
238239
img[loading="lazy"],
239240
[hidden] {}
240241
`
241242
const actual = analyze(fixture).selectors.accessibility
242243
const expected = {
243-
total: 3,
244-
totalUnique: 3,
244+
total: 4,
245+
totalUnique: 4,
245246
unique: {
246247
'[aria-hidden]': 1,
247248
'img[role="presentation"]': 1,
248249
'.selector:not([role="tablist"])': 1,
250+
'body.intent-mouse·[role=tabpanel][tabindex="0"]:focus': 1,
249251
},
250252
uniquenessRatio: 1 / 1,
251-
ratio: 3 / 5
253+
ratio: 4 / 6,
252254
}
253255

254256
assert.equal(actual, expected)

src/selectors/specificity.js

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import walk from 'css-tree/walker'
2-
import { startsWith } from '../string-utils.js'
2+
import { startsWith, strEquals } from '../string-utils.js'
33
import { hasVendorPrefix } from '../vendor-prefix.js'
44

5+
const COMPLEXITY = 3
6+
const IS_A11Y = 4
7+
58
/**
69
* Compare specificity A to Specificity B
710
* @param {[number,number,number]} a - Specificity A
@@ -30,23 +33,19 @@ function selectorListSpecificities(selectorListAst) {
3033
walk(selectorListAst, {
3134
visit: 'Selector',
3235
enter(node) {
33-
childSelectors.push(analyzeSpecificity(node))
36+
childSelectors.push(analyzeSelector(node))
3437
}
3538
})
3639

37-
return childSelectors.sort((a, b) => compareSpecificity(a.specificity, b.specificity))
40+
return childSelectors.sort((a, b) => compareSpecificity([a[0], a[1], a[2]], [b[0], b[1], b[2]]))
3841
}
3942

4043
/**
4144
* Get the Specificity for the AST of a Selector Node
4245
* @param {import('css-tree').Selector} ast - AST Node for a Selector
43-
* @return {Object}
44-
* @property {[number,number,number]} specificity
45-
* @property {number} complexity
46-
* @property {Boolean} isId
47-
* @property {Boolean} isA11y
46+
* @return {[number, number, number, number, number]} - Array with SpecificityA, SpecificityB, SpecificityC, complexity, isA11y
4847
*/
49-
const analyzeSpecificity = (node) => {
48+
const analyzeSelector = (node) => {
5049
let A = 0
5150
let B = 0
5251
let C = 0
@@ -74,7 +73,9 @@ const analyzeSpecificity = (node) => {
7473
complexity++
7574
}
7675

77-
isA11y = selector.name.name === 'role' || startsWith('aria-', selector.name.name)
76+
if (strEquals('role', selector.name.name) || startsWith('aria-', selector.name.name)) {
77+
isA11y = true
78+
}
7879
break
7980
}
8081
case 'PseudoElementSelector':
@@ -137,18 +138,18 @@ const analyzeSpecificity = (node) => {
137138
// The specificity of a :where() pseudo-class is replaced by zero,
138139
// but it does count towards complexity.
139140
if (selector.name !== 'where') {
140-
const [topA, topB, topC] = selectorList[0].specificity
141+
const [topA, topB, topC] = selectorList[0]
141142
A += topA
142143
B += topB
143144
C += topC
144145
}
145146

146147
for (let i = 0; i < selectorList.length; i++) {
147148
const listItem = selectorList[i]
148-
if (listItem.isA11y) {
149+
if (listItem[IS_A11Y] === 1) {
149150
isA11y = true
150151
}
151-
complexity += listItem.complexity
152+
complexity += listItem[COMPLEXITY]
152153
}
153154

154155
complexity++
@@ -170,16 +171,14 @@ const analyzeSpecificity = (node) => {
170171
}
171172
})
172173

173-
return {
174-
/** @type {[number,number,number]} */
175-
specificity: [A, B, C],
174+
return [
175+
A, B, C,
176176
complexity,
177-
isId: A > 0,
178-
isA11y
179-
}
177+
isA11y ? 1 : 0,
178+
]
180179
}
181180

182181
export {
183-
analyzeSpecificity,
182+
analyzeSelector,
184183
compareSpecificity,
185184
}

0 commit comments

Comments
 (0)