1- <link rel =" preload" href =" {{{ uiRootPath }}} /font/NotoSansDisplay.ttf" as =" font" type =" font/ttf" fetchpriority =" high" />
2- <link rel =" preload" href =" {{{ uiRootPath }}} /font/NotoSansDisplay-Italic.ttf" as =" font" type =" font/ttf"
3- fetchpriority =" high" />
4- <link rel =" preload" href =" {{{ uiRootPath }}} /font/MonaspaceNeon-Var.woff2" as =" font" type =" font/woff2" fetchpriority =" high" />
5- <link rel =" preload" href =" {{{ uiRootPath }}} /font/MonaspaceXenon-Var.woff2" as =" font" type =" font/woff2" fetchpriority =" high" />
1+
2+ <style >html {visibility :hidden ;opacity :0 }</style >
3+
4+ <link rel =" preload" href =" {{{ uiRootPath }}} /font/NotoSansDisplay.woff2" as =" font" type =" font/woff2" crossorigin =" anonymous" />
5+ <link rel =" preload" href =" {{{ uiRootPath }}} /font/NotoSansDisplay-Italic.woff2" as =" font" type =" font/woff2" crossorigin =" anonymous" />
6+ <link rel =" preload" href =" {{{ uiRootPath }}} /font/MonaspaceNeon-Var.woff2" as =" font" type =" font/woff2" crossorigin =" anonymous" />
7+ <link rel =" preload" href =" {{{ uiRootPath }}} /font/MonaspaceXenon-Var.woff2" as =" font" type =" font/woff2" crossorigin =" anonymous" />
8+
69<script >
710(function () {
811 ' use strict' ;
9- if (! (' fonts' in document )) return ;
1012
11- document .documentElement .style .visibility = ' hidden' ;
13+ // Fallback: show page after max timeout no matter what
14+ var MAX_WAIT = 3000 ;
15+ var revealed = false ;
1216
13- var fontUrls = [
14- { family: ' Noto Sans' , url: ' {{{uiRootPath}}}/font/NotoSansDisplay.ttf' , style: ' normal' , weight: ' 400' },
15- { family: ' Noto Sans' , url: ' {{{uiRootPath}}}/font/NotoSansDisplay.ttf' , style: ' normal' , weight: ' 600' },
16- { family: ' Noto Sans' , url: ' {{{uiRootPath}}}/font/NotoSansDisplay-Italic.ttf' , style: ' italic' , weight: ' 400' },
17- { family: ' Monaspace Neon' , url: ' {{{uiRootPath}}}/font/MonaspaceNeon-Var.woff2' , style: ' normal' , weight: ' 400' },
18- { family: ' Monaspace Xenon' , url: ' {{{uiRootPath}}}/font/MonaspaceXenon-Var.woff2' , style: ' italic' , weight: ' 400' }
19- ];
20-
21- var fontPromises = fontUrls .map (function (fontConfig ) {
22- var fontFace = new FontFace (fontConfig .family , ' url(' + fontConfig .url + ' )' , {
23- style: fontConfig .style ,
24- weight: fontConfig .weight
25- });
26- return fontFace .load ().then (function (loadedFont ) {
27- document .fonts .add (loadedFont);
28- return loadedFont;
29- }).catch (function () {
30- return null ;
31- });
32- });
33-
34- var showContent = function () {
17+ var reveal = function () {
18+ if (revealed) return ;
19+ revealed = true ;
3520 document .documentElement .style .visibility = ' ' ;
21+ document .documentElement .style .opacity = ' ' ;
3622 };
3723
38- var checkFontsLoaded = function () {
39- var testString = ' abcdefghijklmnopqrstuvwxyz0123456789' ;
40- var testFonts = [
41- ' 16px "Noto Sans"' ,
42- ' 16px "Monaspace Neon"' ,
43- ' 16px "Monaspace Xenon"'
44- ];
45- var allLoaded = testFonts .every (function (font ) {
46- return document .fonts .check (font, testString);
47- });
48- return allLoaded;
49- };
24+ // Safety timeout - never block page forever
25+ setTimeout (reveal, MAX_WAIT );
5026
51- var waitForFonts = function (maxAttempts ) {
52- maxAttempts = maxAttempts || 50 ;
53- var attempts = 0 ;
54- var checkInterval = setInterval (function () {
55- attempts++ ;
56- if (checkFontsLoaded () || attempts >= maxAttempts) {
57- clearInterval (checkInterval);
58- showContent ();
59- }
60- }, 50 );
61- };
27+ // If FontFace API not supported, just wait a bit and show
28+ if (! (' FontFace' in window ) || ! (' fonts' in document )) {
29+ setTimeout (reveal, 500 );
30+ return ;
31+ }
6232
63- Promise .all (fontPromises).then (function () {
64- document .fonts .ready .then (function () {
65- if (checkFontsLoaded ()) {
66- showContent ();
67- } else {
68- waitForFonts ();
69- }
70- });
71- }).catch (function () {
72- document .fonts .ready .then (function () {
73- waitForFonts ();
74- }).catch (function () {
75- setTimeout (showContent, 100 );
33+ // Define ALL fonts we need to load
34+ var uiRoot = ' {{{uiRootPath}}}' ;
35+ var fonts = [
36+ {
37+ family: ' Noto Sans' ,
38+ url: uiRoot + ' /font/NotoSansDisplay.woff2' ,
39+ descriptors: { style: ' normal' , weight: ' 100 900' , stretch: ' 62.5% 100%' }
40+ },
41+ {
42+ family: ' Noto Sans' ,
43+ url: uiRoot + ' /font/NotoSansDisplay-Italic.woff2' ,
44+ descriptors: { style: ' italic' , weight: ' 100 900' , stretch: ' 62.5% 100%' }
45+ },
46+ {
47+ family: ' Monaspace Neon' ,
48+ url: uiRoot + ' /font/MonaspaceNeon-Var.woff2' ,
49+ descriptors: { style: ' normal' , weight: ' 400' }
50+ },
51+ {
52+ family: ' Monaspace Xenon' ,
53+ url: uiRoot + ' /font/MonaspaceXenon-Var.woff2' ,
54+ descriptors: { style: ' italic' , weight: ' 400' }
55+ }
56+ ];
57+
58+ // Load all fonts via FontFace API
59+ var loadPromises = fonts .map (function (f ) {
60+ var face = new FontFace (f .family , ' url("' + f .url + ' ")' , f .descriptors );
61+ return face .load ().then (function (loaded ) {
62+ document .fonts .add (loaded);
63+ return loaded;
7664 });
7765 });
66+
67+ Promise .all (loadPromises)
68+ .then (function () {
69+ return document .fonts .ready ;
70+ })
71+ .then (reveal)
72+ .catch (function (err ) {
73+ console .warn (' Font loading error:' , err);
74+ reveal ();
75+ });
7876})();
7977</script >
0 commit comments