Skip to content

Commit

Permalink
Support tracing text in inline and external SVGs
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou committed Sep 4, 2021
1 parent 9bfd566 commit 7852e82
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 54 deletions.
1 change: 1 addition & 0 deletions lib/gatherStylesheetsWithPredicates.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = function gatherStylesheetsWithPredicates(
type: {
$in: [
'HtmlStyle',
'SvgStyle',
'CssImport',
'HtmlConditionalComment',
'HtmlNoscript',
Expand Down
2 changes: 1 addition & 1 deletion lib/getCssRulesByProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
existingPredicates = existingPredicates || {};

const parseTree = postcss.parse(cssSource);
let defaultNamespaceURI = 'http://www.w3.org/1999/xhtml';
let defaultNamespaceURI;
parseTree.walkAtRules('namespace', (rule) => {
const fragments = rule.params.split(/\s+/);
if (fragments.length === 1) {
Expand Down
8 changes: 5 additions & 3 deletions lib/subfont.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ module.exports = async function subfont(
isInline: false,
isLoaded: true,
type: {
$in: ['Html', 'Css', 'JavaScript'],
$in: ['Html', 'Svg', 'Css', 'JavaScript'],
},
})) {
sumSizesBefore += asset.rawSrc.length;
Expand All @@ -233,7 +233,7 @@ module.exports = async function subfont(
isInline: false,
isLoaded: true,
type: {
$in: ['Html', 'Css', 'JavaScript'],
$in: ['Html', 'Svg', 'Css', 'JavaScript'],
},
})) {
sumSizesAfter += asset.rawSrc.length;
Expand Down Expand Up @@ -370,7 +370,9 @@ module.exports = async function subfont(
}
}
log(
`HTML/JS/CSS size increase: ${prettyBytes(sumSizesAfter - sumSizesBefore)}`
`HTML/SVG/JS/CSS size increase: ${prettyBytes(
sumSizesAfter - sumSizesBefore
)}`
);
log(`Total savings: ${prettyBytes(totalSavings)}`);
if (!dryRun) {
Expand Down
111 changes: 76 additions & 35 deletions lib/subsetFonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,14 @@ async function subsetFonts(
// Collect texts by page

const memoizedGetCssRulesByProperty = memoizeSync(getCssRulesByProperty);
const htmlAssets = assetGraph.findAssets({ type: 'Html', isInline: false });
const htmlAssets = assetGraph.findAssets({
type: { $in: ['Html', 'Svg'] },
isInline: false,
});
const traversalRelationQuery = {
$or: [
{
type: { $in: ['HtmlStyle', 'CssImport'] },
type: { $in: ['HtmlStyle', 'SvgStyle', 'CssImport'] },
},
{
to: {
Expand Down Expand Up @@ -672,7 +675,7 @@ async function subsetFonts(
htmlAsset
),
getCssRulesByProperty: memoizedGetCssRulesByProperty,
htmlAsset,
asset: htmlAsset,
});
if (headlessBrowser) {
textByProps.push(...(await headlessBrowser.tracePage(htmlAsset)));
Expand Down Expand Up @@ -870,7 +873,7 @@ These glyphs are used on your site, but they don't exist in the font you applied
accumulatedFontFaceDeclarations,
} of htmlAssetTextsWithProps) {
const insertionPoint = assetGraph.findRelations({
type: 'HtmlStyle',
type: `${htmlAsset.type}Style`,
from: htmlAsset,
})[0];
const subsetFontUsages = fontUsages.filter(
Expand Down Expand Up @@ -1051,21 +1054,23 @@ These glyphs are used on your site, but they don't exist in the font you applied
// - https://caniuse.com/#search=woff2
// - https://caniuse.com/#search=preload

htmlAsset.addRelation(
{
type: 'HtmlPreloadLink',
hrefType,
to: fontAsset,
as: 'font',
},
'before',
insertionPoint
);
if (htmlAsset.type === 'Html') {
htmlAsset.addRelation(
{
type: 'HtmlPreloadLink',
hrefType,
to: fontAsset,
as: 'font',
},
'before',
insertionPoint
);
}
}
}
const cssRelation = htmlAsset.addRelation(
{
type: 'HtmlStyle',
type: `${htmlAsset.type}Style`,
hrefType: inlineCss ? 'inline' : hrefType,
to: cssAsset,
},
Expand Down Expand Up @@ -1151,18 +1156,20 @@ These glyphs are used on your site, but they don't exist in the font you applied
cssAsset.url = cssAssetUrl;
}

// Create a <link rel="stylesheet"> that asyncLoadStyleRelationWithFallback can convert to async with noscript fallback:
const fallbackHtmlStyle = htmlAsset.addRelation({
type: 'HtmlStyle',
to: cssAsset,
});
if (htmlAsset.type === 'Html') {
// Create a <link rel="stylesheet"> that asyncLoadStyleRelationWithFallback can convert to async with noscript fallback:
const fallbackHtmlStyle = htmlAsset.addRelation({
type: 'HtmlStyle',
to: cssAsset,
});

asyncLoadStyleRelationWithFallback(
htmlAsset,
fallbackHtmlStyle,
hrefType
);
relationsToRemove.add(fallbackHtmlStyle);
asyncLoadStyleRelationWithFallback(
htmlAsset,
fallbackHtmlStyle,
hrefType
);
relationsToRemove.add(fallbackHtmlStyle);
}
}
}

Expand Down Expand Up @@ -1200,11 +1207,13 @@ These glyphs are used on your site, but they don't exist in the font you applied
if (googleFontStylesheetRelation.type === 'CssImport') {
// Gather Html parents. Relevant if we are dealing with CSS @import relations
htmlParents = getParents(googleFontStylesheetRelation.to, {
type: 'Html',
type: { $in: ['Html', 'Svg'] },
isInline: false,
isLoaded: true,
});
} else if (googleFontStylesheetRelation.from.type === 'Html') {
} else if (
['Html', 'Svg'].includes(googleFontStylesheetRelation.from.type)
) {
htmlParents = [googleFontStylesheetRelation.from];
} else {
htmlParents = [];
Expand Down Expand Up @@ -1235,18 +1244,20 @@ These glyphs are used on your site, but they don't exist in the font you applied
}
const selfHostedFallbackRelation = htmlParent.addRelation(
{
type: 'HtmlStyle',
type: `${htmlParent.type}Style`,
to: selfHostedGoogleFontsCssAsset,
hrefType,
},
'lastInBody'
);
relationsToRemove.add(selfHostedFallbackRelation);
asyncLoadStyleRelationWithFallback(
htmlParent,
selfHostedFallbackRelation,
hrefType
);
if (htmlParent.type === 'Html') {
asyncLoadStyleRelationWithFallback(
htmlParent,
selfHostedFallbackRelation,
hrefType
);
}
}
relationsToRemove.add(googleFontStylesheetRelation);
}
Expand Down Expand Up @@ -1276,7 +1287,37 @@ These glyphs are used on your site, but they don't exist in the font you applied
}

let customPropertyDefinitions; // Avoid computing this unless necessary
// Inject subset font name before original webfont
// Inject subset font name before original webfont in SVG font-family attributes
const svgAssets = assetGraph.findAssets({ type: 'Svg' });
for (const svgAsset of svgAssets) {
let changesMade = false;
for (const element of Array.from(
svgAsset.parseTree.querySelectorAll('[font-family]')
)) {
const fontFamilies = cssListHelpers.splitByCommas(
element.getAttribute('font-family')
);
for (let i = 0; i < fontFamilies.length; i += 1) {
const subsetFontFamily =
webfontNameMap[fontFamily.parse(fontFamilies[i])[0].toLowerCase()];
if (subsetFontFamily && !fontFamilies.includes(subsetFontFamily)) {
fontFamilies.splice(
i,
omitFallbacks ? 1 : 0,
cssQuoteIfNecessary(subsetFontFamily)
);
i += 1;
element.setAttribute('font-family', fontFamilies.join(', '));
changesMade = true;
}
}
}
if (changesMade) {
svgAsset.markDirty();
}
}

// Inject subset font name before original webfont in CSS
const cssAssets = assetGraph.findAssets({
type: 'Css',
isLoaded: true,
Expand Down
30 changes: 15 additions & 15 deletions test/getCssRulesByProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'red',
Expand All @@ -54,7 +54,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h2',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'blue',
Expand All @@ -76,7 +76,7 @@ describe('getCssRulesByProperty', function () {
{
selector: undefined,
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [1, 0, 0, 0],
prop: 'color',
value: 'red',
Expand All @@ -99,7 +99,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'red',
Expand All @@ -108,7 +108,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'blue',
Expand All @@ -135,7 +135,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -146,7 +146,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -170,7 +170,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -181,7 +181,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -192,7 +192,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -203,7 +203,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -227,7 +227,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -238,7 +238,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font-size',
value: '10px',
Expand All @@ -247,7 +247,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -256,7 +256,7 @@ describe('getCssRulesByProperty', function () {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
namespaceURI: undefined,
specificityArray: [0, 0, 0, 1],
prop: 'font-size',
value: '20px',
Expand Down
Loading

0 comments on commit 7852e82

Please sign in to comment.