Skip to content

Commit ad8198a

Browse files
authored
fix: do not crash on var(--font-stack, family1, family2, etc) (#436)
1 parent b148fac commit ad8198a

File tree

4 files changed

+45
-21
lines changed

4 files changed

+45
-21
lines changed

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ export function analyze(css, options = {}) {
444444
let { property, important } = declaration
445445
let complexity = 1
446446

447+
// i.e. `background-image: -webkit-linear-gradient()`
447448
if (isValuePrefixed(node)) {
448449
vendorPrefixedValues.p(stringifyNode(node), node.loc)
449450
complexity++
@@ -484,9 +485,11 @@ export function analyze(css, options = {}) {
484485
if (font_family) {
485486
fontFamilies.p(font_family, loc)
486487
}
488+
487489
if (font_size) {
488490
fontSizes.p(font_size, loc)
489491
}
492+
490493
if (line_height) {
491494
lineHeights.p(line_height, loc)
492495
}

src/values/destructure-font-shorthand.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ export function isSystemFont(node) {
4141
*/
4242
export function destructure(value, stringifyNode, cb) {
4343
let font_family = Array.from({ length: 2 })
44+
/** @type {string | undefined} */
4445
let font_size
46+
/** @type {string | undefined} */
4547
let line_height
4648

49+
// FIXME: in case of a var(--my-stack, fam1, fam2, fam3) this forEach also loops over all children of the var()
4750
value.children.forEach(function (node, item) {
4851
let prev = item.prev ? item.prev.data : undefined
4952
let next = item.next ? item.next.data : undefined
@@ -76,7 +79,7 @@ export function destructure(value, stringifyNode, cb) {
7679
) {
7780
font_family[0] = node
7881

79-
if (!font_size && prev !== null) {
82+
if (!font_size && prev) {
8083
font_size = stringifyNode(prev)
8184
}
8285

@@ -112,21 +115,22 @@ export function destructure(value, stringifyNode, cb) {
112115
}
113116
})
114117

118+
let family = (font_family[0] || font_family[1])
119+
? stringifyNode({
120+
loc: {
121+
start: {
122+
offset: (font_family[0] || font_family[1]).loc.start.offset,
123+
},
124+
end: {
125+
offset: font_family[1].loc.end.offset,
126+
},
127+
},
128+
})
129+
: null
130+
115131
return {
116132
font_size,
117133
line_height,
118-
font_family:
119-
font_family[0] || font_family[1]
120-
? stringifyNode({
121-
loc: {
122-
start: {
123-
offset: (font_family[0] || font_family[1]).loc.start.offset,
124-
},
125-
end: {
126-
offset: font_family[1].loc.end.offset,
127-
},
128-
},
129-
})
130-
: null,
134+
font_family: family,
131135
}
132136
}

src/values/font-families.test.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,44 @@ FontFamilies('extracts the `font` shorthand', () => {
5353
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
5454
font: 0/0 a; /* As generated by some css minifiers */
5555
font: 1.2em/1.2em; /* Found in indiatimes.com */
56+
font: 12px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); /* From github.com */
5657
5758
/* Unrelated */
5859
color: brown;
59-
font-size: 12px;
60+
font-size: 123456789px;
6061
}
6162
`
6263
const actual = analyze(fixture).values.fontFamilies
6364
const expected = {
64-
total: 10,
65-
totalUnique: 6,
65+
total: 12,
66+
totalUnique: 8,
6667
unique: {
6768
[`'Noto Sans'`]: 1,
6869
'"Source Sans Pro", serif': 1,
6970
'serif': 5,
7071
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"': 1,
7172
'Consolas, "Liberation Mono", Menlo, Courier, monospace': 1,
7273
'a': 1,
74+
'var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace)': 1,
75+
// This entry exists due to a ??bug?? in CSSTree, but it's better than not counting the value above this as well
76+
'ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace': 1,
7377
},
74-
uniquenessRatio: 6 / 10
78+
uniquenessRatio: 8 / 12
7579
}
7680
assert.equal(actual, expected)
7781
})
7882

83+
FontFamilies('does not crash on `12px var(...)', () => {
84+
const fixture = `
85+
test {
86+
font: 12px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);
87+
}
88+
`
89+
assert.not.throws(() => {
90+
analyze(fixture).values.fontFamilies
91+
})
92+
})
93+
7994
FontFamilies('handles system fonts', () => {
8095
// Source: https://drafts.csswg.org/css-fonts-3/#font-prop
8196
const fixture = `

src/values/font-sizes.test.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ FontSizes('extracts the `font` shorthand', () => {
4848
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
4949
font: 0/0 a; /* As generated by some css minifiers */
5050
font: 10PX sans-serif;
51+
font: 12px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); /* from github.com */
5152
5253
/* Unrelated */
5354
color: brown;
@@ -56,8 +57,8 @@ FontSizes('extracts the `font` shorthand', () => {
5657
`
5758
const actual = analyze(fixture).values.fontSizes
5859
const expected = {
59-
total: 12,
60-
totalUnique: 8,
60+
total: 13,
61+
totalUnique: 9,
6162
unique: {
6263
'0': 1,
6364
'large': 1,
@@ -67,8 +68,9 @@ FontSizes('extracts the `font` shorthand', () => {
6768
'2em': 1,
6869
'11px': 2,
6970
'10PX': 1,
71+
'12px': 1,
7072
},
71-
uniquenessRatio: 8 / 12
73+
uniquenessRatio: 9 / 13
7274
}
7375
assert.equal(actual, expected)
7476
})

0 commit comments

Comments
 (0)