Skip to content

Commit 3d3d792

Browse files
author
Bart Veneman
committed
improve analysis of fonts
1 parent 39ce9a7 commit 3d3d792

File tree

8 files changed

+161
-121
lines changed

8 files changed

+161
-121
lines changed

src/__fixtures__/facebook-20190319.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36835,14 +36835,14 @@
3683536835
"Menlo, Consolas, Monaco, monospace": 1,
3683636836
"Georgia, serif": 1,
3683736837
"'Open Dyslexic'": 1,
36838+
"Helvetica,Arial,sans-serif": 1,
3683836839
"'Freight Sans Bold', Helvetica, Arial, sans-serif": 1,
3683936840
"'Freight Sans', Helvetica, Arial, sans-serif": 1,
3684036841
"'Freight Sans'": 1,
3684136842
"'Freight Sans Bold'": 1,
3684236843
"'Freight Sans', Helvetica, Arial, sans-serif ": 1,
3684336844
"'Freight Sans Bold', Helvetica, Arial, sans-serif ": 1,
36844-
"Georgia, Lucida Grande, Tahoma, Verdana, Arial, sans-serif": 3,
36845-
"Helvetica,Arial,sans-serif": 1
36845+
"Georgia, Lucida Grande, Tahoma, Verdana, Arial, sans-serif": 3
3684636846
},
3684736847
"uniquenessRatio": 0.4594594594594595
3684836848
},

src/__fixtures__/gazelle-20210905.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88036,6 +88036,7 @@
8803688036
"'Gazelle'\n": 4,
8803788037
"'ProximaNova', Helvetica, Arial, sans-serif\n": 1,
8803888038
"'luma-icons'": 2,
88039+
"Arial,Helvetica,sans-serif": 2,
8803988040
"'bluefoot-icons'": 5,
8804088041
"'bluefoot-icons'\n": 1,
8804188042
"Consolas, \"Liberation Mono\", Menlo, Courier, monospace": 1,
@@ -88045,15 +88046,14 @@
8804588046
"\"Helvetica Neue\", Helvetica, Arial, sans-serif": 3,
8804688047
"Menlo, Monaco, Consolas, \"Courier New\", monospace\n": 1,
8804788048
"serif": 1,
88049+
"a": 1,
8804888050
"Arial, Baskerville, monospace": 1,
8804988051
"\"Open Sans\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif": 4,
8805088052
"proximaNova-light": 1,
8805188053
"proximaNova-regular": 1,
8805288054
"proximaNova-bold": 1,
8805388055
"proximaNova-regular, Arial, sans-serif": 1,
88054-
"proximaNova-bold, Arial, sans-serif": 3,
88055-
"Arial,Helvetica,sans-serif": 2,
88056-
"a": 1
88056+
"proximaNova-bold, Arial, sans-serif": 3
8805788057
},
8805888058
"uniquenessRatio": 0.4727272727272727
8805988059
},

src/__fixtures__/github-20210501.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33421,14 +33421,14 @@
3342133421
"sans-serif": 1,
3342233422
"monospace, monospace": 1,
3342333423
"-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji": 1,
33424+
"SFMono-Regular,Consolas,LiberationMono,Menlo,monospace": 2,
3342433425
"SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace": 2,
3342533426
"SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace\n": 1,
33427+
"-apple-system,BlinkMacSystemFont,SegoeUI,Helvetica,Arial,sans-serif,AppleColorEmoji,SegoeUIEmoji": 1,
3342633428
"monospace": 1,
3342733429
"monospace\n": 1,
3342833430
"SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace": 1,
33429-
"Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol": 1,
33430-
"SFMono-Regular,Consolas,LiberationMono,Menlo,monospace": 2,
33431-
"-apple-system,BlinkMacSystemFont,SegoeUI,Helvetica,Arial,sans-serif,AppleColorEmoji,SegoeUIEmoji": 1
33431+
"Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol": 1
3343233432
},
3343333433
"uniquenessRatio": 0.8461538461538461
3343433434
},
@@ -33441,6 +33441,7 @@
3344133441
"75%": 1,
3344233442
"1em\n": 1,
3344333443
"14px": 14,
33444+
"11px": 2,
3344433445
"32px\n": 1,
3344533446
"24px\n": 1,
3344633447
"20px\n": 2,
@@ -33464,8 +33465,7 @@
3346433465
"70%\n": 1,
3346533466
"90%": 1,
3346633467
"0\n": 1,
33467-
"1em": 1,
33468-
"11px": 2
33468+
"1em": 1
3346933469
},
3347033470
"uniquenessRatio": 0.3448275862068966
3347133471
},

src/__fixtures__/trello-20190617.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37406,12 +37406,12 @@
3740637406
"\"Charlie Text\",sans-serif": 4,
3740737407
"SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace": 4,
3740837408
"\"Charlie Display\",sans-serif": 2,
37409+
"a": 2,
3740937410
"'Charlie Display'": 28,
3741037411
"'Charlie Text'": 24,
3741137412
"'Roboto',sans-serif": 2,
3741237413
"'Roboto'": 1,
37413-
"jaf-facitweb, \"Helvetica Neue\", Arial, sans-serif": 2,
37414-
"a": 2
37414+
"jaf-facitweb, \"Helvetica Neue\", Arial, sans-serif": 2
3741537415
},
3741637416
"uniquenessRatio": 0.14084507042253522
3741737417
},

src/index.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import walk from 'css-tree/walker'
33
import { analyzeRule } from './rules/rules.js'
44
import { analyzeSpecificity, compareSpecificity } from './selectors/specificity.js'
55
import { colorFunctions, colorNames } from './values/colors.js'
6-
import { analyzeFontFamilies } from './values/font-families.js'
7-
import { analyzeFontSizes } from './values/font-sizes.js'
6+
import { isFontFamilyKeyword, getFamilyFromFont } from './values/font-families.js'
7+
import { isFontSizeKeyword, getSizeFromFont } from './values/font-sizes.js'
88
import { isValueKeyword } from './values/values.js'
99
import { analyzeAnimations } from './values/animations.js'
1010
import { isAstVendorPrefixed } from './values/vendor-prefix.js'
@@ -103,9 +103,8 @@ const analyze = (css) => {
103103
const zindex = new CountableCollection()
104104
const textShadows = new CountableCollection()
105105
const boxShadows = new CountableCollection()
106-
const fontValues = []
107-
const fontFamilyValues = []
108-
const fontSizeValues = []
106+
const fontFamilies = new CountableCollection()
107+
const fontSizes = new CountableCollection()
109108
const animations = []
110109
const timingFunctions = []
111110
const durations = []
@@ -237,13 +236,25 @@ const analyze = (css) => {
237236
}
238237
return this.skip
239238
} else if (isProperty('font', property)) {
240-
fontValues.push(node)
239+
if (!isFontFamilyKeyword(node)) {
240+
fontFamilies.push(getFamilyFromFont(node, stringifyNode))
241+
}
242+
if (!isFontSizeKeyword(node)) {
243+
const size = getSizeFromFont(node)
244+
if (size) {
245+
fontSizes.push(size)
246+
}
247+
}
241248
break
242249
} else if (isProperty('font-size', property)) {
243-
fontSizeValues.push(stringifyNode(node))
250+
if (!isFontSizeKeyword(node)) {
251+
fontSizes.push(stringifyNode(node))
252+
}
244253
break
245254
} else if (isProperty('font-family', property)) {
246-
fontFamilyValues.push(stringifyNode(node))
255+
if (!isFontFamilyKeyword(node)) {
256+
fontFamilies.push(stringifyNode(node))
257+
}
247258
break
248259
} else if (isProperty('transition', property) || isProperty('animation', property)) {
249260
animations.push(node.children)
@@ -435,8 +446,8 @@ const analyze = (css) => {
435446
}),
436447
values: {
437448
colors: colors.count(),
438-
fontFamilies: analyzeFontFamilies({ stringifyNode, fontValues, fontFamilyValues }),
439-
fontSizes: analyzeFontSizes({ stringifyNode, fontValues, fontSizeValues }),
449+
fontFamilies: fontFamilies.count(),
450+
fontSizes: fontSizes.count(),
440451
zindexes: zindex.count(),
441452
textShadows: textShadows.count(),
442453
boxShadows: boxShadows.count(),

src/values/font-families.js

Lines changed: 92 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import walk from 'css-tree/walker'
2-
import { CountableCollection } from '../countable-collection.js'
2+
// import { CountableCollection } from '../countable-collection.js'
33

44
const systemKeywords = {
55
// Global CSS keywords
@@ -54,59 +54,102 @@ const keywordDisallowList = {
5454

5555
const COMMA = 44 // ','.charCodeAt(0) === 44
5656

57-
const analyzeFontFamilies = ({ fontValues, fontFamilyValues, stringifyNode }) => {
58-
const all = new CountableCollection(fontFamilyValues)
59-
60-
for (let index = 0; index < fontValues.length; index++) {
61-
const value = fontValues[index]
62-
63-
// Avoid tree traversal as soon as possible
64-
const firstChild = value.children.first
65-
66-
if (firstChild.type === 'Identifier' && systemKeywords[firstChild.name]) {
67-
continue
68-
}
57+
export function isFontFamilyKeyword(node) {
58+
const firstChild = node.children.first
59+
return firstChild.type === 'Identifier' && systemKeywords[firstChild.name]
60+
}
6961

70-
let parts = ''
71-
72-
walk(value, {
73-
reverse: true,
74-
enter: function (fontNode) {
75-
if (fontNode.type === 'String') {
76-
const loc = fontNode.loc.start
77-
// Stringify the first character to get the correct quote character
78-
const quote = stringifyNode({
79-
loc: {
80-
start: {
81-
line: loc.line,
82-
column: loc.column
83-
},
84-
end: {
85-
line: loc.line,
86-
column: loc.column + 1
87-
}
62+
export function getFamilyFromFont(node, stringifyNode) {
63+
let parts = ''
64+
65+
walk(node, {
66+
reverse: true,
67+
enter: function (fontNode) {
68+
if (fontNode.type === 'String') {
69+
const loc = fontNode.loc.start
70+
// Stringify the first character to get the correct quote character
71+
const quote = stringifyNode({
72+
loc: {
73+
start: {
74+
line: loc.line,
75+
column: loc.column
76+
},
77+
end: {
78+
line: loc.line,
79+
column: loc.column + 1
8880
}
89-
})
90-
return parts = quote + fontNode.value + quote + parts
91-
}
92-
if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {
93-
return parts = fontNode.value + parts
94-
}
95-
if (fontNode.type === 'Identifier') {
96-
if (keywordDisallowList[fontNode.name]) {
97-
return this.skip
9881
}
99-
return parts = fontNode.name + parts
82+
})
83+
return parts = quote + fontNode.value + quote + parts
84+
}
85+
if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {
86+
return parts = fontNode.value + parts
87+
}
88+
if (fontNode.type === 'Identifier') {
89+
if (keywordDisallowList[fontNode.name]) {
90+
return this.skip
10091
}
92+
return parts = fontNode.name + parts
10193
}
102-
})
103-
104-
all.push(parts)
105-
}
94+
}
95+
})
10696

107-
return all.count()
97+
return parts
10898
}
10999

110-
export {
111-
analyzeFontFamilies
112-
}
100+
// const analyzeFontFamilies = ({ fontValues, fontFamilyValues, stringifyNode }) => {
101+
// const all = new CountableCollection(fontFamilyValues)
102+
103+
// for (let index = 0; index < fontValues.length; index++) {
104+
// const value = fontValues[index]
105+
106+
// // Avoid tree traversal as soon as possible
107+
// const firstChild = value.children.first
108+
109+
// if (firstChild.type === 'Identifier' && systemKeywords[firstChild.name]) {
110+
// continue
111+
// }
112+
113+
// let parts = ''
114+
115+
// walk(value, {
116+
// reverse: true,
117+
// enter: function (fontNode) {
118+
// if (fontNode.type === 'String') {
119+
// const loc = fontNode.loc.start
120+
// // Stringify the first character to get the correct quote character
121+
// const quote = stringifyNode({
122+
// loc: {
123+
// start: {
124+
// line: loc.line,
125+
// column: loc.column
126+
// },
127+
// end: {
128+
// line: loc.line,
129+
// column: loc.column + 1
130+
// }
131+
// }
132+
// })
133+
// return parts = quote + fontNode.value + quote + parts
134+
// }
135+
// if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {
136+
// return parts = fontNode.value + parts
137+
// }
138+
// if (fontNode.type === 'Identifier') {
139+
// if (keywordDisallowList[fontNode.name]) {
140+
// return this.skip
141+
// }
142+
// return parts = fontNode.name + parts
143+
// }
144+
// }
145+
// })
146+
147+
// all.push(parts)
148+
// }
149+
150+
// return all.count()
151+
// }
152+
153+
// export {
154+
// analyzeFontFamilies
155+
// }

0 commit comments

Comments
 (0)