-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathfontListener.ts
80 lines (64 loc) · 2.18 KB
/
fontListener.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
import { info, warn } from './logger';
import { convertToFVD, parseFontInfo } from './parseFontInfo';
export type FontInfo = { fontName: string; fontStyle: string; fontWeight: string }
export const fontListener = ({ fontNames, scope, timeout, interval }) => {
const hasFonts = fontNames && Boolean(fontNames.length);
const targetElement = scope === "html" ? "documentElement" : "body";
const apiAvailable = "fonts" in document;
let parsedFont: FontInfo[] = [];
function handleLoadComplete() {
addClassName("all");
}
function handleFontLoad(fontInfo: FontInfo) {
const fvd = convertToFVD(fontInfo)
addClassName(fvd);
}
function fontMapper(fontDetail: FontInfo) {
const fontFace = [fontDetail.fontStyle, fontDetail.fontWeight, '1rem', fontDetail.fontName].join(' ')
const startTime = Date.now();
return new Promise((resolve, reject) => {
const recursiveFn = () => {
const currTime = Date.now();
if ((currTime - startTime) >= timeout) {
reject('font listener timeout ' + fontFace);
} else {
document.fonts.load(fontFace).then((fonts) => {
if (fonts.length >= 1) {
handleFontLoad(fontDetail);
resolve(true);
} else {
setTimeout(recursiveFn, interval);
}
}).catch((err) => {
reject(err);
});
}
};
recursiveFn()
});
}
function loadFonts() {
const fonts = parsedFont.map(fontMapper);
Promise.all(fonts).then(handleLoadComplete).catch(errorFallback);
}
function errorFallback(e) {
warn('error in omni font loader', e)
parsedFont.forEach((fontInfo) => addClassName(convertToFVD(fontInfo)));
}
function handleApiError(error) {
info(`document.fonts API error: ${error}`);
info(`Replacing fonts instantly. FOUT handling failed.`);
errorFallback(error);
}
function addClassName(fontName: string) {
document[targetElement].classList.add(`wf-${fontName}`);
}
if (!apiAvailable) {
handleApiError("Font loading API not available");
return;
}
if (hasFonts && apiAvailable) {
parsedFont = parseFontInfo(fontNames)
loadFonts();
}
};