Skip to content

Commit

Permalink
fix: Discarding used font-families due to mixed quotation types
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Felchlin committed Mar 27, 2019
1 parent 8d4610a commit 5195c60
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
18 changes: 12 additions & 6 deletions packages/postcss-discard-unused/src/__tests__/index.js
Expand Up @@ -75,21 +75,27 @@ test(
test(
'should remove unused fonts & keep used fonts',
processCSS,
'@font-face {font-family:"Does Not Exist";src:url("fonts/does-not-exist.ttf") format("truetype")}@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font-family:"Does Exist",Helvetica,Arial,sans-serif}',
'@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font-family:"Does Exist",Helvetica,Arial,sans-serif}'
'@font-face {font-family:"Does Not Exist";src:url("fonts/does-not-exist.ttf") format("truetype")}@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font-family: "Does Exist", Helvetica, Arial, sans-serif}',
'@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font-family: "Does Exist", Helvetica, Arial, sans-serif}'
);

test(
'should work with the font shorthand',
passthroughCSS,
'@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font: 10px/1.5 "Does Exist",Helvetica,Arial,sans-serif}'
'@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font: 10px/1.5 "Does Exist", Helvetica, Arial, sans-serif}'
);

test(
'should not be responsible for normalising fonts',
"should handle font properties that don't include a font-family",
processCSS,
'@font-face {font-family:"Does Exist";src:url("fonts/does-exist.ttf") format("truetype")}body{font-family:Does Exist}',
'body{font-family:Does Exist}'
'@font-face {font-family:"Does Exist";src: url("fonts/does-exist.ttf") format("truetype")}body{font: italic bold 10px/1.5}',
'body{font: italic bold 10px/1.5}'
);

test(
'should work with mixed quote styles',
passthroughCSS,
'@font-face {font-family:"Does Exist";src:url("fonts/does-exist.ttf") format("truetype")}@font-face {font-family:\'DoesExist\';src:url("fonts/does-exist.ttf") format("truetype")}body{font-family: Does Exist; font: 10px DoesExist}'
);

test(
Expand Down
26 changes: 12 additions & 14 deletions packages/postcss-discard-unused/src/index.js
Expand Up @@ -8,6 +8,11 @@ const atrule = 'atrule';
const decl = 'decl';
const rule = 'rule';

function normalizeFontName (value) {
// Ignore casing and wrapping quotes when checking for font use.
return value.toLowerCase().replace(/^\s*(['"])(.*?)(\1)\s*$/, '$2');
}

function addValues (cache, {value}) {
return comma(value).reduce((memo, val) => [...memo, ...space(val)], cache);
}
Expand Down Expand Up @@ -36,24 +41,15 @@ function filterNamespace ({atRules, rules}) {
});
}

function hasFont (fontFamily, cache) {
return comma(fontFamily).some(font => cache.some(c => ~c.indexOf(font)));
}

// fonts have slightly different logic
function filterFont ({atRules, values}) {
values = uniqs(values);
atRules.forEach(r => {
const families = r.nodes.filter(({prop}) => prop === 'font-family');
// Discard the @font-face if it has no font-family
if (!families.length) {
return r.remove();
const fontFamilyRule = r.nodes.find(({prop}) => prop === 'font-family');
// Discard the @font-face if it has no font-family rule or if it is unused
if (!fontFamilyRule || !values.includes(normalizeFontName(fontFamilyRule.value))) {
r.remove();
}
families.forEach(family => {
if (!hasFont(family.value.toLowerCase(), values)) {
r.remove();
}
});
});
}

Expand Down Expand Up @@ -94,7 +90,9 @@ export default plugin('postcss-discard-unused', opts => {
counterStyleCache.values = addValues(counterStyleCache.values, node);
}
if (fontFace && node.parent.type === rule && /font(|-family)/.test(prop)) {
fontCache.values = fontCache.values.concat(comma(node.value.toLowerCase()));
const fontFamilies = prop === 'font-family' ? comma(node.value) :
[].concat(...space(node.value).map(comma));
fontCache.values.push(...fontFamilies.map(normalizeFontName));
}
if (keyframes && /animation/.test(prop)) {
keyframesCache.values = addValues(keyframesCache.values, node);
Expand Down

0 comments on commit 5195c60

Please sign in to comment.