-
Notifications
You must be signed in to change notification settings - Fork 32
/
loader.js
117 lines (92 loc) · 3.19 KB
/
loader.js
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function insertFontFaceRule(inlineStyle) {
// set document head
var head = document.head || document.getElementsByTagName('head')[0];
// set style element
var style = head.appendChild(document.createElement('style'));
// return style element text
return style.appendChild(
document.createTextNode('@font-face{' + inlineStyle + '}')
);
}
function insertFontFaceDetector(inlineStyle, family, fallback) {
// set inline style
var inlineStyle = inlineStyle.concat(detectorStyle);
// generate font detection element
var detectBlock = document.createElement('font-detection');
// configure font detection element
detectBlock.appendChild(document.createTextNode(detectorText));
// update inline style to use fallback
inlineStyle[0] = 'font-family:' + fallback;
detectBlock.setAttribute('style', inlineStyle.join(';'));
// append element to document body
document.body.appendChild(detectBlock);
var returnValue = {
element: detectBlock,
width: detectBlock.offsetWidth,
height: detectBlock.offsetHeight
};
// update inline style to use family before fallback
inlineStyle[0] = 'font-family:' + family + ',' + fallback;
detectBlock.setAttribute('style', inlineStyle.join(';'));
// return data about the element
return returnValue;
}
function loadFont(family, weight, style, src) {
// set generated family
var familyGenerated = family + Math.floor(Math.random() * 99999999);
// set inline style
var inlineStyle = [
'font-family:' + family,
'font-style:' + style,
'font-weight:' + weight
];
// set font face rule
var styleText = insertFontFaceRule(
inlineStyle.concat('src:' + src).join(';')
);
function onready() {
if (document.readyState === 'complete') {
// set detectors
var detectors = {
monospace: insertFontFaceDetector(inlineStyle, family, 'monospace'),
sansserif: insertFontFaceDetector(inlineStyle, family, 'sans-serif'),
serif: insertFontFaceDetector(inlineStyle, family, 'serif')
};
// set timeout
function timeout() {
if (
detectors.monospace.width === detectors.monospace.element.offsetWidth &&
detectors.monospace.height === detectors.monospace.element.offsetHeight &&
detectors.sansserif.width === detectors.sansserif.element.offsetWidth &&
detectors.sansserif.height === detectors.sansserif.element.offsetHeight &&
detectors.serif.width === detectors.serif.element.offsetWidth &&
detectors.serif.height === detectors.serif.element.offsetHeight
) setImmediate(timeout);
else {
document.body.removeChild(detectors.monospace.element);
document.body.removeChild(detectors.sansserif.element);
document.body.removeChild(detectors.serif.element);
styleText.nodeValue = styleText.nodeValue.replace(familyGenerated, family);
}
}
timeout();
} else setImmediate(onready);
}
onready();
}
function loadFonts(fonts) {
var index = -1;
while (font = fonts[++index]) {
loadFont(font.family, font.weight, font.style, font.src);
}
}
// set detect styles
var detectorStyle = [
'clip:rect(0 0 0 0)',
'overflow: hidden',
'position: absolute'
];
// set detector text
var detectorText = 'AxmTYklsjo190QW';
// set immediate method
var setImmediate = window.requestAnimationFrame || window.setTimeout;