subfont 6.9.0 → 6.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/lib/getCssRulesByProperty.js +50 -24
- package/lib/parseFontVariationSettings.js +39 -0
- package/lib/subsetFonts.js +184 -19
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
### v6.10.0 (2022-08-29)
|
|
2
|
+
|
|
3
|
+
- [Update @hookun\/parse-animation-shorthand to ^0.1.4 to make sure we get the fix for hookhookun\/parse-animation-shorthand\#16](https://github.com/Munter/subfont/commit/4db17826245e289e987c6dc02d3f67ebf5891e6f) ([Andreas Lind](mailto:andreas.lind@workday.com))
|
|
4
|
+
- [Disable notice about unused variation axis ranges when there's an out-of-bounds cubic-bezier animation timing function in play](https://github.com/Munter/subfont/commit/1cf4ff46bb6099f8df8602968c7dc0fefb1c1f21) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
5
|
+
- [Update font-tracer to ^3.6.0](https://github.com/Munter/subfont/commit/2a47adc03122aad50ba2a01f116a2d1fe0f2b29e) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
6
|
+
- [Remove accidentally committed commented out code](https://github.com/Munter/subfont/commit/e0c677f9b2c7a9af123045cf29bc78a4f9a56550) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
7
|
+
- [Warn about unused variation axis ranges, not just fully unused axes](https://github.com/Munter/subfont/commit/32fc472327b1c8fc87090d4c1e5f1085533ad8fa) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
8
|
+
- [+13 more](https://github.com/Munter/subfont/compare/v6.9.0...v6.10.0)
|
|
9
|
+
|
|
1
10
|
### v6.9.0 (2022-08-07)
|
|
2
11
|
|
|
3
12
|
- [Update font-tracer to ^3.3.0 Adds support for tracing ::marker, fixes \#166](https://github.com/Munter/subfont/commit/e46c79bac9cb3e62c70deb357823b7963114863b) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const specificity = require('specificity');
|
|
2
2
|
const postcss = require('postcss');
|
|
3
3
|
const unquote = require('./unquote');
|
|
4
|
+
const parseAnimationShorthand = require('@hookun/parse-animation-shorthand');
|
|
4
5
|
|
|
5
6
|
const counterRendererNames = new Set([
|
|
6
7
|
'none',
|
|
@@ -144,34 +145,59 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
|
|
|
144
145
|
});
|
|
145
146
|
});
|
|
146
147
|
}
|
|
147
|
-
} else if (
|
|
148
|
-
propName === 'animation' &&
|
|
149
|
-
properties.includes('animation-name')
|
|
150
|
-
) {
|
|
148
|
+
} else if (propName === 'animation') {
|
|
151
149
|
// Shorthand
|
|
152
|
-
const
|
|
150
|
+
const parsedAnimation = parseAnimationShorthand.parseSingle(node.value);
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
if (properties.includes('animation-name')) {
|
|
153
|
+
// Split up combined selectors as they might have different specificity
|
|
154
|
+
specificity
|
|
155
|
+
.calculate(node.parent.selector)
|
|
156
|
+
.forEach((specificityObject) => {
|
|
157
|
+
const isStyleAttribute =
|
|
158
|
+
specificityObject.selector === 'bogusselector';
|
|
160
159
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
160
|
+
rulesByProperty['animation-name'].push({
|
|
161
|
+
predicates: getCurrentPredicates(),
|
|
162
|
+
namespaceURI: defaultNamespaceURI,
|
|
163
|
+
selector: isStyleAttribute
|
|
164
|
+
? undefined
|
|
165
|
+
: specificityObject.selector.trim(),
|
|
166
|
+
specificityArray: isStyleAttribute
|
|
167
|
+
? [1, 0, 0, 0]
|
|
168
|
+
: specificityObject.specificityArray,
|
|
169
|
+
prop: 'animation-name',
|
|
170
|
+
value: parsedAnimation.name,
|
|
171
|
+
important: !!node.important,
|
|
172
|
+
});
|
|
173
173
|
});
|
|
174
|
-
|
|
174
|
+
}
|
|
175
|
+
if (properties.includes('animation-timing-function')) {
|
|
176
|
+
// Split up combined selectors as they might have different specificity
|
|
177
|
+
specificity
|
|
178
|
+
.calculate(node.parent.selector)
|
|
179
|
+
.forEach((specificityObject) => {
|
|
180
|
+
const isStyleAttribute =
|
|
181
|
+
specificityObject.selector === 'bogusselector';
|
|
182
|
+
|
|
183
|
+
rulesByProperty['animation-timing-function'].push({
|
|
184
|
+
predicates: getCurrentPredicates(),
|
|
185
|
+
namespaceURI: defaultNamespaceURI,
|
|
186
|
+
selector: isStyleAttribute
|
|
187
|
+
? undefined
|
|
188
|
+
: specificityObject.selector.trim(),
|
|
189
|
+
specificityArray: isStyleAttribute
|
|
190
|
+
? [1, 0, 0, 0]
|
|
191
|
+
: specificityObject.specificityArray,
|
|
192
|
+
prop: 'animation-timing-function',
|
|
193
|
+
value: parseAnimationShorthand.serialize({
|
|
194
|
+
name: '',
|
|
195
|
+
timingFunction: parsedAnimation.timingFunction,
|
|
196
|
+
}),
|
|
197
|
+
important: !!node.important,
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
175
201
|
} else if (propName === 'transition') {
|
|
176
202
|
// Shorthand
|
|
177
203
|
const transitionProperties = [];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const postcssValueParser = require('postcss-value-parser');
|
|
2
|
+
|
|
3
|
+
module.exports = function* parseFontVariationSettings(value) {
|
|
4
|
+
let state = 'BEFORE_AXIS_NAME';
|
|
5
|
+
let axisName;
|
|
6
|
+
for (const token of postcssValueParser(value).nodes) {
|
|
7
|
+
if (token.type === 'space') {
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
switch (state) {
|
|
11
|
+
case 'BEFORE_AXIS_NAME': {
|
|
12
|
+
if (token.type !== 'string') {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
axisName = token.value.toUpperCase();
|
|
16
|
+
state = 'AFTER_AXIS_NAME';
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
case 'AFTER_AXIS_NAME': {
|
|
20
|
+
if (token.type === 'word') {
|
|
21
|
+
const axisValue = parseFloat(token.value);
|
|
22
|
+
if (!isNaN(axisValue)) {
|
|
23
|
+
yield [axisName, axisValue];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
state = 'AFTER_AXIS_VALUE';
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case 'AFTER_AXIS_VALUE': {
|
|
30
|
+
if (token.type !== 'div' || token.value !== ',') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
axisName = undefined;
|
|
34
|
+
state = 'BEFORE_AXIS_NAME';
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
package/lib/subsetFonts.js
CHANGED
|
@@ -13,13 +13,14 @@ const HeadlessBrowser = require('./HeadlessBrowser');
|
|
|
13
13
|
const gatherStylesheetsWithPredicates = require('./gatherStylesheetsWithPredicates');
|
|
14
14
|
const findCustomPropertyDefinitions = require('./findCustomPropertyDefinitions');
|
|
15
15
|
const extractReferencedCustomPropertyNames = require('./extractReferencedCustomPropertyNames');
|
|
16
|
+
const parseFontVariationSettings = require('./parseFontVariationSettings');
|
|
17
|
+
const parseAnimationShorthand = require('@hookun/parse-animation-shorthand');
|
|
16
18
|
const stripLocalTokens = require('./stripLocalTokens');
|
|
17
19
|
const injectSubsetDefinitions = require('./injectSubsetDefinitions');
|
|
18
20
|
const cssFontParser = require('css-font-parser');
|
|
19
21
|
const cssListHelpers = require('css-list-helpers');
|
|
20
22
|
const LinesAndColumns = require('lines-and-columns').default;
|
|
21
23
|
const fontkit = require('fontkit');
|
|
22
|
-
const fontFamily = require('font-family-papandreou');
|
|
23
24
|
const crypto = require('crypto');
|
|
24
25
|
|
|
25
26
|
const unquote = require('./unquote');
|
|
@@ -41,6 +42,14 @@ const contentTypeByFontFormat = {
|
|
|
41
42
|
truetype: 'font/ttf',
|
|
42
43
|
};
|
|
43
44
|
|
|
45
|
+
function stringifyFontFamily(name) {
|
|
46
|
+
if (/[^a-z0-9_-]/i.test(name)) {
|
|
47
|
+
return name.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
48
|
+
} else {
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
function uniqueChars(text) {
|
|
45
54
|
return [...new Set([...text])].sort().join('');
|
|
46
55
|
}
|
|
@@ -79,6 +88,21 @@ function getPreferredFontUrl(cssFontFaceSrcRelations = []) {
|
|
|
79
88
|
}
|
|
80
89
|
}
|
|
81
90
|
|
|
91
|
+
function isOutOfBoundsAnimationTimingFunction(animationTimingFunctionStr) {
|
|
92
|
+
if (typeof animationTimingFunctionStr !== 'string') {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const { timingFunction } = parseAnimationShorthand.parseSingle(
|
|
96
|
+
`${animationTimingFunctionStr} ignored-name`
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (timingFunction.type === 'cubic-bezier') {
|
|
100
|
+
const [, y1, , y2] = timingFunction.value;
|
|
101
|
+
return y1 > 1 || y1 < 0 || y2 > 1 || y2 < 0;
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
82
106
|
// Hack to extract '@font-face { ... }' with all absolute urls
|
|
83
107
|
function getFontFaceDeclarationText(node, relations) {
|
|
84
108
|
const originalHrefTypeByRelation = new Map();
|
|
@@ -145,8 +169,8 @@ function groupTextsByFontFamilyProps(
|
|
|
145
169
|
return [];
|
|
146
170
|
}
|
|
147
171
|
// Find all the families in the traced font-family that we have @font-face declarations for:
|
|
148
|
-
const families =
|
|
149
|
-
.
|
|
172
|
+
const families = cssFontParser
|
|
173
|
+
.parseFontFamily(family)
|
|
150
174
|
.filter((family) =>
|
|
151
175
|
availableFontFaceDeclarations.some(
|
|
152
176
|
(fontFace) =>
|
|
@@ -159,7 +183,7 @@ function groupTextsByFontFamilyProps(
|
|
|
159
183
|
availableFontFaceDeclarations,
|
|
160
184
|
{
|
|
161
185
|
...textAndProps.props,
|
|
162
|
-
'font-family':
|
|
186
|
+
'font-family': stringifyFontFamily(family),
|
|
163
187
|
}
|
|
164
188
|
);
|
|
165
189
|
|
|
@@ -173,6 +197,9 @@ function groupTextsByFontFamilyProps(
|
|
|
173
197
|
return {
|
|
174
198
|
htmlOrSvgAsset: textAndProps.htmlOrSvgAsset,
|
|
175
199
|
text: textAndProps.text,
|
|
200
|
+
fontVariationSettings: textAndProps.props['font-variation-settings'],
|
|
201
|
+
animationTimingFunction:
|
|
202
|
+
textAndProps.props['animation-timing-function'],
|
|
176
203
|
props,
|
|
177
204
|
fontRelations: relations,
|
|
178
205
|
fontUrl,
|
|
@@ -190,6 +217,18 @@ function groupTextsByFontFamilyProps(
|
|
|
190
217
|
const fontFamilies = new Set(
|
|
191
218
|
textsPropsArray.map((obj) => obj.props['font-family'])
|
|
192
219
|
);
|
|
220
|
+
const fontVariationSettings = new Set(
|
|
221
|
+
textsPropsArray
|
|
222
|
+
.map((obj) => obj.fontVariationSettings)
|
|
223
|
+
.filter(
|
|
224
|
+
(fontVariationSettings) =>
|
|
225
|
+
fontVariationSettings &&
|
|
226
|
+
fontVariationSettings.toLowerCase() !== 'normal'
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
const hasOutOfBoundsAnimationTimingFunction = textsPropsArray.some((obj) =>
|
|
230
|
+
isOutOfBoundsAnimationTimingFunction(obj.animationTimingFunction)
|
|
231
|
+
);
|
|
193
232
|
|
|
194
233
|
let smallestOriginalSize;
|
|
195
234
|
let smallestOriginalFormat;
|
|
@@ -217,6 +256,8 @@ function groupTextsByFontFamilyProps(
|
|
|
217
256
|
props: { ...textsPropsArray[0].props },
|
|
218
257
|
fontUrl,
|
|
219
258
|
fontFamilies,
|
|
259
|
+
fontVariationSettings,
|
|
260
|
+
hasOutOfBoundsAnimationTimingFunction,
|
|
220
261
|
preload,
|
|
221
262
|
};
|
|
222
263
|
});
|
|
@@ -497,9 +538,9 @@ async function createSelfHostedGoogleFontsCssAsset(
|
|
|
497
538
|
assetGraph,
|
|
498
539
|
googleFontsCssAsset,
|
|
499
540
|
formats,
|
|
500
|
-
hrefType
|
|
541
|
+
hrefType,
|
|
542
|
+
subsetUrl
|
|
501
543
|
) {
|
|
502
|
-
const baseUrl = assetGraph.resolveUrl(assetGraph.root, '/subfont/');
|
|
503
544
|
const lines = [];
|
|
504
545
|
for (const cssFontFaceSrc of assetGraph.findRelations({
|
|
505
546
|
from: googleFontsCssAsset,
|
|
@@ -516,9 +557,12 @@ async function createSelfHostedGoogleFontsCssAsset(
|
|
|
516
557
|
const srcFragments = [];
|
|
517
558
|
for (const format of formats) {
|
|
518
559
|
const rawSrc = await fontverter.convert(cssFontFaceSrc.to.rawSrc, format);
|
|
519
|
-
const url =
|
|
520
|
-
|
|
521
|
-
|
|
560
|
+
const url = assetGraph.resolveUrl(
|
|
561
|
+
subsetUrl,
|
|
562
|
+
`${cssFontFaceSrc.to.baseName}-${md5HexPrefix(rawSrc)}${
|
|
563
|
+
extensionByFormat[format]
|
|
564
|
+
}`
|
|
565
|
+
);
|
|
522
566
|
const fontAsset =
|
|
523
567
|
assetGraph.findAssets({ url })[0] ||
|
|
524
568
|
(await assetGraph.addAsset({
|
|
@@ -526,7 +570,7 @@ async function createSelfHostedGoogleFontsCssAsset(
|
|
|
526
570
|
rawSrc,
|
|
527
571
|
}));
|
|
528
572
|
srcFragments.push(
|
|
529
|
-
`url(${assetGraph.buildHref(fontAsset.url,
|
|
573
|
+
`url(${assetGraph.buildHref(fontAsset.url, subsetUrl, {
|
|
530
574
|
hrefType,
|
|
531
575
|
})}) format('${format}')`
|
|
532
576
|
);
|
|
@@ -542,7 +586,7 @@ async function createSelfHostedGoogleFontsCssAsset(
|
|
|
542
586
|
const text = lines.join('\n');
|
|
543
587
|
const fallbackAsset = assetGraph.addAsset({
|
|
544
588
|
type: 'Css',
|
|
545
|
-
url:
|
|
589
|
+
url: assetGraph.resolveUrl(subsetUrl, `fallback-${md5HexPrefix(text)}.css`),
|
|
546
590
|
text,
|
|
547
591
|
});
|
|
548
592
|
return fallbackAsset;
|
|
@@ -664,6 +708,124 @@ These glyphs are used on your site, but they don't exist in the font you applied
|
|
|
664
708
|
}
|
|
665
709
|
}
|
|
666
710
|
|
|
711
|
+
const standardVariationAxes = new Set(['WGHT', 'ITAL', 'SLNT', 'OPSZ']);
|
|
712
|
+
|
|
713
|
+
function warnAboutUnusedCustomVariationAxes(
|
|
714
|
+
htmlOrSvgAssetTextsWithProps,
|
|
715
|
+
assetGraph
|
|
716
|
+
) {
|
|
717
|
+
const seenAxisValuesByFontUrlAndAxisName = new Map();
|
|
718
|
+
const outOfBoundsAxesByFontUrl = new Map();
|
|
719
|
+
|
|
720
|
+
for (const { fontUsages } of htmlOrSvgAssetTextsWithProps) {
|
|
721
|
+
for (const {
|
|
722
|
+
fontUrl,
|
|
723
|
+
fontVariationSettings,
|
|
724
|
+
hasOutOfBoundsAnimationTimingFunction,
|
|
725
|
+
} of fontUsages) {
|
|
726
|
+
let seenAxes = seenAxisValuesByFontUrlAndAxisName.get(fontUrl);
|
|
727
|
+
if (!seenAxes) {
|
|
728
|
+
seenAxes = new Map();
|
|
729
|
+
seenAxisValuesByFontUrlAndAxisName.set(fontUrl, seenAxes);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
for (const fontVariationSettingsValue of fontVariationSettings) {
|
|
733
|
+
for (const [axisName, axisValue] of parseFontVariationSettings(
|
|
734
|
+
fontVariationSettingsValue
|
|
735
|
+
)) {
|
|
736
|
+
const seenAxisValues = seenAxes.get(axisName);
|
|
737
|
+
if (seenAxisValues) {
|
|
738
|
+
seenAxisValues.push(axisValue);
|
|
739
|
+
} else {
|
|
740
|
+
seenAxes.set(axisName, [axisValue]);
|
|
741
|
+
}
|
|
742
|
+
if (hasOutOfBoundsAnimationTimingFunction) {
|
|
743
|
+
let outOfBoundsAxes = outOfBoundsAxesByFontUrl.get(fontUrl);
|
|
744
|
+
if (!outOfBoundsAxes) {
|
|
745
|
+
outOfBoundsAxes = new Set();
|
|
746
|
+
outOfBoundsAxesByFontUrl.set(fontUrl, outOfBoundsAxes);
|
|
747
|
+
}
|
|
748
|
+
outOfBoundsAxes.add(axisName);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const warnings = [];
|
|
756
|
+
for (const [
|
|
757
|
+
fontUrl,
|
|
758
|
+
seenAxisValuesByAxisName,
|
|
759
|
+
] of seenAxisValuesByFontUrlAndAxisName.entries()) {
|
|
760
|
+
const outOfBoundsAxes = outOfBoundsAxesByFontUrl.get(fontUrl) || new Set();
|
|
761
|
+
let font;
|
|
762
|
+
try {
|
|
763
|
+
font = fontkit.create(assetGraph.findAssets({ url: fontUrl })[0].rawSrc);
|
|
764
|
+
} catch (err) {
|
|
765
|
+
// Don't break if we encounter an invalid font or one that's unsupported by fontkit
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
const unusedAxes = [];
|
|
769
|
+
const underutilizedAxes = [];
|
|
770
|
+
for (const { name, min, max, default: defaultValue } of Object.values(
|
|
771
|
+
font.variationAxes
|
|
772
|
+
)) {
|
|
773
|
+
const axisName = name.toUpperCase();
|
|
774
|
+
if (standardVariationAxes.has(axisName)) {
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (
|
|
778
|
+
seenAxisValuesByAxisName.has(axisName) &&
|
|
779
|
+
!outOfBoundsAxes.has(axisName)
|
|
780
|
+
) {
|
|
781
|
+
const usedValues = [
|
|
782
|
+
defaultValue,
|
|
783
|
+
...seenAxisValuesByAxisName.get(axisName),
|
|
784
|
+
];
|
|
785
|
+
const minUsed = Math.min(...usedValues);
|
|
786
|
+
const maxUsed = Math.max(...usedValues);
|
|
787
|
+
if (minUsed > min || maxUsed < max) {
|
|
788
|
+
underutilizedAxes.push({
|
|
789
|
+
name: axisName,
|
|
790
|
+
minUsed,
|
|
791
|
+
maxUsed,
|
|
792
|
+
min,
|
|
793
|
+
max,
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
} else {
|
|
797
|
+
unusedAxes.push(axisName);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (unusedAxes.length > 0 || underutilizedAxes.length > 0) {
|
|
802
|
+
let message = `${fontUrl}:\n`;
|
|
803
|
+
if (unusedAxes.length > 0) {
|
|
804
|
+
message += ` Unused axes: ${unusedAxes.join(', ')}\n`;
|
|
805
|
+
}
|
|
806
|
+
if (underutilizedAxes.length > 0) {
|
|
807
|
+
message += ` Underutilized axes:\n${underutilizedAxes
|
|
808
|
+
.map(
|
|
809
|
+
({ name, min, max, minUsed, maxUsed }) =>
|
|
810
|
+
` ${name}: ${minUsed}-${maxUsed} used (${min}-${max} available)`
|
|
811
|
+
)
|
|
812
|
+
.join('\n')}\n`;
|
|
813
|
+
}
|
|
814
|
+
warnings.push(message);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (warnings.length > 0) {
|
|
819
|
+
assetGraph.info(
|
|
820
|
+
new Error(`🪓 Unused custom variation axes detected in your variable fonts.
|
|
821
|
+
The below variable fonts contain custom axes that do not appear to be fully used on any of your pages.
|
|
822
|
+
This bloats your fonts and also the subset fonts that subfont creates.
|
|
823
|
+
Consider removing the unused axis ranges using a tool like Slice <https://slice-gui.netlify.app/>
|
|
824
|
+
${warnings.join('\n')}`)
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
667
829
|
async function collectTextsByPage(
|
|
668
830
|
assetGraph,
|
|
669
831
|
htmlOrSvgAssets,
|
|
@@ -722,9 +884,8 @@ async function collectTextsByPage(
|
|
|
722
884
|
node.walkDecls((declaration) => {
|
|
723
885
|
const propName = declaration.prop.toLowerCase();
|
|
724
886
|
if (propName === 'font-family') {
|
|
725
|
-
fontFaceDeclaration[propName] =
|
|
726
|
-
declaration.value
|
|
727
|
-
)[0];
|
|
887
|
+
fontFaceDeclaration[propName] =
|
|
888
|
+
cssFontParser.parseFontFamily(declaration.value)[0];
|
|
728
889
|
} else {
|
|
729
890
|
fontFaceDeclaration[propName] = declaration.value;
|
|
730
891
|
}
|
|
@@ -951,6 +1112,7 @@ async function subsetFonts(
|
|
|
951
1112
|
);
|
|
952
1113
|
|
|
953
1114
|
warnAboutMissingGlyphs(htmlOrSvgAssetTextsWithProps, assetGraph);
|
|
1115
|
+
warnAboutUnusedCustomVariationAxes(htmlOrSvgAssetTextsWithProps, assetGraph);
|
|
954
1116
|
|
|
955
1117
|
// Insert subsets:
|
|
956
1118
|
|
|
@@ -1119,7 +1281,7 @@ async function subsetFonts(
|
|
|
1119
1281
|
|
|
1120
1282
|
if (
|
|
1121
1283
|
fontAsset.contentType === 'font/woff2' &&
|
|
1122
|
-
fontRelation.to.
|
|
1284
|
+
fontRelation.to.url.startsWith(subsetUrl)
|
|
1123
1285
|
) {
|
|
1124
1286
|
const fontFaceDeclaration = fontRelation.node;
|
|
1125
1287
|
const originalFontFamily = unquote(
|
|
@@ -1323,7 +1485,8 @@ async function subsetFonts(
|
|
|
1323
1485
|
assetGraph,
|
|
1324
1486
|
googleFontStylesheetRelation.to,
|
|
1325
1487
|
formats,
|
|
1326
|
-
hrefType
|
|
1488
|
+
hrefType,
|
|
1489
|
+
subsetUrl
|
|
1327
1490
|
);
|
|
1328
1491
|
await selfHostedGoogleFontsCssAsset.minify();
|
|
1329
1492
|
selfHostedGoogleCssByUrl.set(
|
|
@@ -1388,7 +1551,9 @@ async function subsetFonts(
|
|
|
1388
1551
|
);
|
|
1389
1552
|
for (let i = 0; i < fontFamilies.length; i += 1) {
|
|
1390
1553
|
const subsetFontFamily =
|
|
1391
|
-
webfontNameMap[
|
|
1554
|
+
webfontNameMap[
|
|
1555
|
+
cssFontParser.parseFontFamily(fontFamilies[i])[0].toLowerCase()
|
|
1556
|
+
];
|
|
1392
1557
|
if (subsetFontFamily && !fontFamilies.includes(subsetFontFamily)) {
|
|
1393
1558
|
fontFamilies.splice(
|
|
1394
1559
|
i,
|
|
@@ -1448,7 +1613,7 @@ async function subsetFonts(
|
|
|
1448
1613
|
for (let i = 0; i < fontFamilies.length; i += 1) {
|
|
1449
1614
|
const subsetFontFamily =
|
|
1450
1615
|
webfontNameMap[
|
|
1451
|
-
|
|
1616
|
+
cssFontParser.parseFontFamily(fontFamilies[i])[0].toLowerCase()
|
|
1452
1617
|
];
|
|
1453
1618
|
if (subsetFontFamily && !fontFamilies.includes(subsetFontFamily)) {
|
|
1454
1619
|
fontFamilies.splice(
|
|
@@ -1462,7 +1627,7 @@ async function subsetFonts(
|
|
|
1462
1627
|
}
|
|
1463
1628
|
}
|
|
1464
1629
|
} else if (propName === 'font') {
|
|
1465
|
-
const fontProperties = cssFontParser(cssRule.value);
|
|
1630
|
+
const fontProperties = cssFontParser.parseFont(cssRule.value);
|
|
1466
1631
|
const fontFamilies =
|
|
1467
1632
|
fontProperties && fontProperties['font-family'].map(unquote);
|
|
1468
1633
|
if (fontFamilies) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subfont",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.10.0",
|
|
4
4
|
"description": "Speeds up your pages initial paint by automatically subsetting local or Google fonts and loading them optimally",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=10.0.0"
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"homepage": "https://github.com/Munter/subfont#readme",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@gustavnikolaj/async-main-wrap": "^3.0.1",
|
|
50
|
+
"@hookun/parse-animation-shorthand": "^0.1.4",
|
|
50
51
|
"assetgraph": "^7.8.1",
|
|
51
52
|
"browserslist": "^4.13.0",
|
|
52
|
-
"css-font-parser": "^0.
|
|
53
|
+
"css-font-parser": "^2.0.0",
|
|
53
54
|
"css-font-weight-names": "^0.2.1",
|
|
54
55
|
"css-list-helpers": "^2.0.0",
|
|
55
|
-
"font-family-papandreou": "^0.2.0-patch2",
|
|
56
56
|
"font-snapper": "^1.2.0",
|
|
57
|
-
"font-tracer": "^3.
|
|
57
|
+
"font-tracer": "^3.6.0",
|
|
58
58
|
"fontkit": "^1.8.0",
|
|
59
59
|
"fontverter": "^2.0.0",
|
|
60
60
|
"gettemporaryfilepath": "^1.0.1",
|