@@ -15,6 +15,8 @@ Object.assign( XHRLoader.prototype, {
15
15
16
16
load : function ( url , onLoad , onProgress , onError ) {
17
17
18
+ if ( url === undefined ) url = '' ;
19
+
18
20
if ( this . path !== undefined ) url = this . path + url ;
19
21
20
22
var scope = this ;
@@ -37,66 +39,156 @@ Object.assign( XHRLoader.prototype, {
37
39
38
40
}
39
41
40
- var request = new XMLHttpRequest ( ) ;
41
- request . open ( 'GET' , url , true ) ;
42
+ // Check for data: URI
43
+ var dataUriRegex = / ^ d a t a : ( .* ?) ( ; b a s e 6 4 ) ? , ( .* ) $ / ;
44
+ var dataUriRegexResult = url . match ( dataUriRegex ) ;
42
45
43
- request . addEventListener ( 'load' , function ( event ) {
46
+ // Safari can not handle Data URIs through XMLHttpRequest so process manually
47
+ if ( dataUriRegexResult ) {
44
48
45
- var response = event . target . response ;
49
+ var mimeType = dataUriRegexResult [ 1 ] ;
50
+ var isBase64 = ! ! dataUriRegexResult [ 2 ] ;
51
+ var data = dataUriRegexResult [ 3 ] ;
46
52
47
- Cache . add ( url , response ) ;
53
+ data = window . decodeURIComponent ( data ) ;
48
54
49
- if ( this . status === 200 ) {
55
+ if ( isBase64 ) {
56
+ data = window . atob ( data ) ;
57
+ }
50
58
51
- if ( onLoad ) onLoad ( response ) ;
59
+ try {
52
60
53
- scope . manager . itemEnd ( url ) ;
61
+ var response ;
62
+ var responseType = ( this . responseType || '' ) . toLowerCase ( ) ;
54
63
55
- } else if ( this . status === 0 ) {
64
+ switch ( responseType ) {
56
65
57
- // Some browsers return HTTP Status 0 when using non-http protocol
58
- // e.g. 'file://' or 'data://'. Handle as success.
66
+ case 'arraybuffer' :
67
+ case 'blob' :
59
68
60
- console . warn ( 'THREE.XHRLoader: HTTP Status 0 received.' ) ;
69
+ response = new ArrayBuffer ( data . length ) ;
70
+ var view = new Uint8Array ( response ) ;
71
+ for ( var i = 0 ; i < data . length ; i ++ ) {
61
72
62
- if ( onLoad ) onLoad ( response ) ;
73
+ view [ i ] = data . charCodeAt ( i ) ;
63
74
64
- scope . manager . itemEnd ( url ) ;
75
+ }
65
76
66
- } else {
77
+ if ( responseType === 'blob' ) {
67
78
68
- if ( onError ) onError ( event ) ;
79
+ response = new Blob ( [ response ] , { "type" : mimeType } ) ;
69
80
70
- scope . manager . itemError ( url ) ;
81
+ }
82
+
83
+ break ;
84
+
85
+ case 'document' :
86
+
87
+ var parser = new DOMParser ( ) ;
88
+ response = parser . parseFromString ( data , mimeType ) ;
89
+
90
+ break ;
91
+
92
+ case 'json' :
93
+
94
+ response = JSON . parse ( data ) ;
95
+
96
+ break ;
97
+
98
+ default : // 'text' or other
99
+
100
+ response = data ;
101
+
102
+ break ;
103
+
104
+ }
105
+
106
+ // Wait for next browser tick
107
+ window . setTimeout ( function ( ) {
108
+
109
+ if ( onLoad ) onLoad ( response ) ;
110
+
111
+ scope . manager . itemEnd ( url ) ;
112
+
113
+ } , 0 ) ;
114
+
115
+ } catch ( error ) {
116
+
117
+ // Wait for next browser tick
118
+ window . setTimeout ( function ( ) {
119
+
120
+ if ( onError ) onError ( error ) ;
121
+
122
+ scope . manager . itemError ( url ) ;
123
+
124
+ } , 0 ) ;
71
125
72
126
}
73
127
74
- } , false ) ;
128
+ } else {
129
+
130
+ var request = new XMLHttpRequest ( ) ;
131
+ request . open ( 'GET' , url , true ) ;
132
+
133
+ request . addEventListener ( 'load' , function ( event ) {
134
+
135
+ var response = event . target . response ;
136
+
137
+ Cache . add ( url , response ) ;
138
+
139
+ if ( this . status === 200 ) {
140
+
141
+ if ( onLoad ) onLoad ( response ) ;
142
+
143
+ scope . manager . itemEnd ( url ) ;
144
+
145
+ } else if ( this . status === 0 ) {
146
+
147
+ // Some browsers return HTTP Status 0 when using non-http protocol
148
+ // e.g. 'file://' or 'data://'. Handle as success.
149
+
150
+ console . warn ( 'THREE.XHRLoader: HTTP Status 0 received.' ) ;
151
+
152
+ if ( onLoad ) onLoad ( response ) ;
153
+
154
+ scope . manager . itemEnd ( url ) ;
75
155
76
- if ( onProgress !== undefined ) {
156
+ } else {
77
157
78
- request . addEventListener ( 'progress' , function ( event ) {
158
+ if ( onError ) onError ( event ) ;
79
159
80
- onProgress ( event ) ;
160
+ scope . manager . itemError ( url ) ;
161
+
162
+ }
81
163
82
164
} , false ) ;
83
165
84
- }
166
+ if ( onProgress !== undefined ) {
167
+
168
+ request . addEventListener ( 'progress' , function ( event ) {
169
+
170
+ onProgress ( event ) ;
171
+
172
+ } , false ) ;
173
+
174
+ }
175
+
176
+ request . addEventListener ( 'error' , function ( event ) {
85
177
86
- request . addEventListener ( 'error' , function ( event ) {
178
+ if ( onError ) onError ( event ) ;
87
179
88
- if ( onError ) onError ( event ) ;
180
+ scope . manager . itemError ( url ) ;
89
181
90
- scope . manager . itemError ( url ) ;
182
+ } , false ) ;
91
183
92
- } , false ) ;
184
+ if ( this . responseType !== undefined ) request . responseType = this . responseType ;
185
+ if ( this . withCredentials !== undefined ) request . withCredentials = this . withCredentials ;
93
186
94
- if ( this . responseType !== undefined ) request . responseType = this . responseType ;
95
- if ( this . withCredentials !== undefined ) request . withCredentials = this . withCredentials ;
187
+ if ( request . overrideMimeType ) request . overrideMimeType ( 'text/plain' ) ;
96
188
97
- if ( request . overrideMimeType ) request . overrideMimeType ( 'text/plain' ) ;
189
+ request . send ( null ) ;
98
190
99
- request . send ( null ) ;
191
+ }
100
192
101
193
scope . manager . itemStart ( url ) ;
102
194
0 commit comments