-
Notifications
You must be signed in to change notification settings - Fork 27
/
loadFonts.ts
91 lines (82 loc) 路 3.35 KB
/
loadFonts.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { applyActiveFont, applyFontPreview } from "./font-styles/declarations";
import {
createStylesheet,
fillStylesheet,
setStylesheetType,
stylesheetExists,
} from "./font-styles/stylesheets";
import extractFontStyles from "./google-fonts/extractFontStyles";
import getStylesheet from "./google-fonts/fontStylesheet";
import { Font, FontList, Script, Variant } from "./types";
/**
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants,
* only the characters needed for creating the font previews), add the necessary CSS declarations to
* apply them and add the fonts' stylesheets to the document head
*/
export async function loadFontPreviews(
fonts: FontList,
scripts: Script[],
variants: Variant[],
selectorSuffix: string,
): Promise<void> {
// Only load previews of fonts which don't have a stylesheet (for preview or full font) yet
const fontsArray: Font[] = Array.from(fonts.values());
const fontsToFetch = fontsArray
.map((font: Font): string => font.id)
.filter((fontId): boolean => !stylesheetExists(fontId));
// Create stylesheet elements for all fonts which will be fetched (this prevents other font
// pickers from loading the fonts as well)
fontsToFetch.forEach((fontId): void => createStylesheet(fontId, true));
// Get Google Fonts stylesheet containing all requested styles
const response = await getStylesheet(fontsArray, scripts, variants, true);
// Parse response and assign styles to the corresponding font
const fontStyles = extractFontStyles(response);
// Create separate stylesheets for the fonts
fontsArray.forEach((font): void => {
applyFontPreview(font, selectorSuffix);
// Add stylesheets for fonts which need to be downloaded
if (fontsToFetch.includes(font.id)) {
// Make sure response contains styles for the font
if (!(font.id in fontStyles)) {
console.error(
`Missing styles for font "${font.family}" (fontId "${font.id}") in Google Fonts response`,
);
return;
}
// Insert styles into the stylesheet element which was created earlier
fillStylesheet(font.id, fontStyles[font.id]);
}
});
}
/**
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants),
* add the necessary CSS declarations to apply it and add the font's stylesheet to the document head
*/
export async function loadActiveFont(
font: Font,
previousFontFamily: string,
scripts: Script[],
variants: Variant[],
selectorSuffix: string,
): Promise<void> {
// Only load font if it doesn't have a stylesheet yet
if (stylesheetExists(font.id, false)) {
// Add CSS declaration to apply the new active font
applyActiveFont(font, previousFontFamily, selectorSuffix);
} else {
if (stylesheetExists(font.id, true)) {
// Update the stylesheet's "data-is-preview" attribute to "false"
setStylesheetType(font.id, false);
} else {
// Create stylesheet for the font to be fetched (this prevents other font pickers from loading
// the font as well)
createStylesheet(font.id, false);
}
// Get Google Fonts stylesheet containing all requested styles
const fontStyle = await getStylesheet([font], scripts, variants, false);
// Add CSS declaration to apply the new active font
applyActiveFont(font, previousFontFamily, selectorSuffix);
// Insert styles into the stylesheet element which was created earlier
fillStylesheet(font.id, fontStyle);
}
}