@@ -6,14 +6,16 @@ let SCRIPT_MAP = {};
6
6
// A counter used to generate a unique id for each component that uses the function
7
7
let idCount = 0 ;
8
8
9
- export default function makeAsyncScript ( Component , scriptURL , options ) {
9
+ export default function makeAsyncScript ( Component , getScriptURL , options ) {
10
10
options = options || { } ;
11
- const wrappedComponentName = Component . displayName || Component . name || "Component" ;
11
+ const wrappedComponentName =
12
+ Component . displayName || Component . name || "Component" ;
12
13
13
14
class AsyncScriptLoader extends React . Component {
14
15
constructor ( ) {
15
16
super ( ) ;
16
17
this . state = { } ;
18
+ this . __scriptURL = "" ;
17
19
}
18
20
19
21
asyncScriptLoaderGetScriptLoaderID ( ) {
@@ -23,11 +25,33 @@ export default function makeAsyncScript(Component, scriptURL, options) {
23
25
return this . __scriptLoaderID ;
24
26
}
25
27
28
+ setupScriptURL ( ) {
29
+ this . __scriptURL =
30
+ typeof getScriptURL === "function" ? getScriptURL ( ) : getScriptURL ;
31
+ return this . __scriptURL ;
32
+ }
33
+
26
34
getComponent ( ) {
27
- return this . childComponent ;
35
+ return this . __childComponent ;
36
+ }
37
+
38
+ asyncScriptLoaderHandleLoad ( state ) {
39
+ this . setState ( state , this . props . asyncScriptOnLoad ) ;
40
+ }
41
+
42
+ asyncScriptLoaderTriggerOnScriptLoaded ( ) {
43
+ let mapEntry = SCRIPT_MAP [ this . __scriptURL ] ;
44
+ if ( ! mapEntry || ! mapEntry . loaded ) {
45
+ throw new Error ( "Script is not loaded." ) ;
46
+ }
47
+ for ( let obsKey in mapEntry . observers ) {
48
+ mapEntry . observers [ obsKey ] ( mapEntry ) ;
49
+ }
50
+ delete window [ options . callbackName ] ;
28
51
}
29
52
30
53
componentDidMount ( ) {
54
+ const scriptURL = this . setupScriptURL ( ) ;
31
55
const key = this . asyncScriptLoaderGetScriptLoaderID ( ) ;
32
56
const { globalName, callbackName } = options ;
33
57
if ( globalName && typeof window [ globalName ] !== "undefined" ) {
@@ -40,12 +64,12 @@ export default function makeAsyncScript(Component, scriptURL, options) {
40
64
this . asyncScriptLoaderHandleLoad ( entry ) ;
41
65
return ;
42
66
}
43
- entry . observers [ key ] = ( entry ) => this . asyncScriptLoaderHandleLoad ( entry ) ;
67
+ entry . observers [ key ] = entry => this . asyncScriptLoaderHandleLoad ( entry ) ;
44
68
return ;
45
69
}
46
70
47
71
let observers = { } ;
48
- observers [ key ] = ( entry ) => this . asyncScriptLoaderHandleLoad ( entry ) ;
72
+ observers [ key ] = entry => this . asyncScriptLoaderHandleLoad ( entry ) ;
49
73
SCRIPT_MAP [ scriptURL ] = {
50
74
loaded : false ,
51
75
observers,
@@ -54,9 +78,9 @@ export default function makeAsyncScript(Component, scriptURL, options) {
54
78
let script = document . createElement ( "script" ) ;
55
79
56
80
script . src = scriptURL ;
57
- script . async = 1 ;
81
+ script . async = true ;
58
82
59
- let callObserverFuncAndRemoveObserver = ( func ) => {
83
+ let callObserverFuncAndRemoveObserver = func => {
60
84
if ( SCRIPT_MAP [ scriptURL ] ) {
61
85
let mapEntry = SCRIPT_MAP [ scriptURL ] ;
62
86
let observersMap = mapEntry . observers ;
@@ -70,14 +94,15 @@ export default function makeAsyncScript(Component, scriptURL, options) {
70
94
} ;
71
95
72
96
if ( callbackName && typeof window !== "undefined" ) {
73
- window [ callbackName ] = AsyncScriptLoader . asyncScriptLoaderTriggerOnScriptLoaded ;
97
+ window [ callbackName ] = ( ) =>
98
+ this . asyncScriptLoaderTriggerOnScriptLoaded ( ) ;
74
99
}
75
100
76
101
script . onload = ( ) => {
77
102
let mapEntry = SCRIPT_MAP [ scriptURL ] ;
78
103
if ( mapEntry ) {
79
104
mapEntry . loaded = true ;
80
- callObserverFuncAndRemoveObserver ( ( observer ) => {
105
+ callObserverFuncAndRemoveObserver ( observer => {
81
106
if ( callbackName ) {
82
107
return false ;
83
108
}
@@ -86,11 +111,11 @@ export default function makeAsyncScript(Component, scriptURL, options) {
86
111
} ) ;
87
112
}
88
113
} ;
89
- script . onerror = ( event ) => {
114
+ script . onerror = event => {
90
115
let mapEntry = SCRIPT_MAP [ scriptURL ] ;
91
116
if ( mapEntry ) {
92
117
mapEntry . errored = true ;
93
- callObserverFuncAndRemoveObserver ( ( observer ) => {
118
+ callObserverFuncAndRemoveObserver ( observer => {
94
119
observer ( mapEntry ) ;
95
120
return true ;
96
121
} ) ;
@@ -113,15 +138,12 @@ export default function makeAsyncScript(Component, scriptURL, options) {
113
138
document . body . appendChild ( script ) ;
114
139
}
115
140
116
- asyncScriptLoaderHandleLoad ( state ) {
117
- this . setState ( state , this . props . asyncScriptOnLoad ) ;
118
- }
119
-
120
141
componentWillUnmount ( ) {
121
142
// Remove tag script
143
+ const scriptURL = this . __scriptURL ;
122
144
if ( options . removeOnUnmount === true ) {
123
145
const allScripts = document . getElementsByTagName ( "script" ) ;
124
- for ( let i = 0 ; i < allScripts . length ; i += 1 ) {
146
+ for ( let i = 0 ; i < allScripts . length ; i += 1 ) {
125
147
if ( allScripts [ i ] . src . indexOf ( scriptURL ) > - 1 ) {
126
148
if ( allScripts [ i ] . parentNode ) {
127
149
allScripts [ i ] . parentNode . removeChild ( allScripts [ i ] ) ;
@@ -144,25 +166,25 @@ export default function makeAsyncScript(Component, scriptURL, options) {
144
166
// remove asyncScriptOnLoad from childprops
145
167
let { asyncScriptOnLoad, ...childProps } = this . props ;
146
168
if ( globalName && typeof window !== "undefined" ) {
147
- childProps [ globalName ] = typeof window [ globalName ] !== "undefined" ? window [ globalName ] : undefined ;
169
+ childProps [ globalName ] =
170
+ typeof window [ globalName ] !== "undefined"
171
+ ? window [ globalName ]
172
+ : undefined ;
148
173
}
149
- return < Component ref = { ( comp ) => { this . childComponent = comp ; } } { ...childProps } /> ;
174
+ return (
175
+ < Component
176
+ ref = { comp => {
177
+ this . __childComponent = comp ;
178
+ } }
179
+ { ...childProps }
180
+ />
181
+ ) ;
150
182
}
151
183
}
152
184
AsyncScriptLoader . displayName = `AsyncScriptLoader(${ wrappedComponentName } )` ;
153
185
AsyncScriptLoader . propTypes = {
154
186
asyncScriptOnLoad : PropTypes . func ,
155
187
} ;
156
- AsyncScriptLoader . asyncScriptLoaderTriggerOnScriptLoaded = function ( ) {
157
- let mapEntry = SCRIPT_MAP [ scriptURL ] ;
158
- if ( ! mapEntry || ! mapEntry . loaded ) {
159
- throw new Error ( "Script is not loaded." ) ;
160
- }
161
- for ( let obsKey in mapEntry . observers ) {
162
- mapEntry . observers [ obsKey ] ( mapEntry ) ;
163
- }
164
- delete window [ options . callbackName ] ;
165
- } ;
166
188
167
189
if ( options . exposeFuncs ) {
168
190
options . exposeFuncs . forEach ( funcToExpose => {
0 commit comments