1
1
'use strict'
2
2
import PropTypes from 'prop-types'
3
- import React , { PureComponent } from 'react'
3
+ import React , { PureComponent , useEffect } from 'react'
4
4
import serialize from 'serialize-javascript'
5
+ import DOMPurify from 'dompurify'
5
6
6
7
// @twreporter
7
8
import webfonts from '@twreporter/react-components/lib/text/utils/webfonts'
@@ -16,6 +17,53 @@ const _ = {
16
17
map,
17
18
}
18
19
20
+ const TYPEKIT_CONFIG = {
21
+ kitId : 'vlk1qbe' ,
22
+ scriptTimeout : 3000 ,
23
+ async : true
24
+ }
25
+
26
+ const TypekitLoader = ( ) => {
27
+ useEffect ( ( ) => {
28
+ // Add wf-loading class immediately
29
+ const h = document . documentElement
30
+ h . className += ' wf-loading'
31
+
32
+ // Create timeout to handle inactive state
33
+ const t = setTimeout ( ( ) => {
34
+ h . className = h . className . replace ( / \b w f - l o a d i n g \b / g, '' ) + ' wf-inactive'
35
+ } , TYPEKIT_CONFIG . scriptTimeout )
36
+
37
+ // Create and load the script
38
+ const script = document . createElement ( 'script' )
39
+ script . src = `https://use.typekit.net/${ TYPEKIT_CONFIG . kitId } .js`
40
+ script . async = true
41
+
42
+ script . onload = script . onreadystatechange = function ( ) {
43
+ const state = this . readyState
44
+ if ( state && state !== 'complete' && state !== 'loaded' ) return
45
+
46
+ try {
47
+ Typekit . load ( TYPEKIT_CONFIG )
48
+ } catch ( e ) {
49
+ console . error ( 'Failed to load Typekit:' , e )
50
+ }
51
+ }
52
+
53
+ document . head . appendChild ( script )
54
+
55
+ // Cleanup function
56
+ return ( ) => {
57
+ clearTimeout ( t )
58
+ if ( script . parentNode ) {
59
+ document . head . removeChild ( script )
60
+ }
61
+ }
62
+ } , [ ] ) // Empty dependency array - only run once
63
+
64
+ return null
65
+ }
66
+
19
67
export default class Html extends PureComponent {
20
68
static propTypes = {
21
69
scripts : PropTypes . array . isRequired ,
@@ -110,34 +158,32 @@ export default class Html extends PureComponent {
110
158
{ styleElement }
111
159
</ head >
112
160
< body >
113
- < div id = "root" dangerouslySetInnerHTML = { { __html : contentMarkup } } />
161
+ < div id = "root" dangerouslySetInnerHTML = { { __html : DOMPurify . sanitize ( contentMarkup ) } } />
114
162
< script
115
163
defer
116
164
src = "https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.zh-Hant-TW"
117
165
/>
118
166
< script
119
- dangerouslySetInnerHTML = { {
120
- __html : `window.__REDUX_STATE__=${ serialize ( store . getState ( ) ) } ;` ,
121
- } }
122
- charSet = "UTF-8"
123
- />
167
+ id = "initial-state"
168
+ type = "application/json"
169
+ >
170
+ { serialize ( store . getState ( ) , { isJSON : true } ) }
171
+ </ script >
172
+ < script >
173
+ { `
174
+ try {
175
+ window.__REDUX_STATE__ = JSON.parse(document.getElementById('initial-state').textContent);
176
+ } catch (e) {
177
+ console.error('Failed to parse initial state:', e);
178
+ window.__REDUX_STATE__ = {};
179
+ }
180
+ ` }
181
+ </ script >
124
182
{ _ . map ( scripts , ( script , key ) => (
125
183
< script src = { script } key = { 'scripts' + key } charSet = "UTF-8" />
126
184
) ) }
127
185
{ scriptElement }
128
- < script
129
- dangerouslySetInnerHTML = { {
130
- __html : `(function(d) {
131
- var config = {
132
- kitId: 'vlk1qbe',
133
- scriptTimeout: 3000,
134
- async: true
135
- },
136
- h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
137
- })(document);
138
- ` ,
139
- } }
140
- />
186
+ < TypekitLoader />
141
187
</ body >
142
188
</ html >
143
189
)
0 commit comments