@@ -15,6 +15,8 @@ Object.assign( XHRLoader.prototype, {
1515
1616 load : function ( url , onLoad , onProgress , onError ) {
1717
18+ if ( url === undefined ) url = '' ;
19+
1820 if ( this . path !== undefined ) url = this . path + url ;
1921
2022 var scope = this ;
@@ -37,66 +39,156 @@ Object.assign( XHRLoader.prototype, {
3739
3840 }
3941
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 ) ;
4245
43- request . addEventListener ( 'load' , function ( event ) {
46+ // Safari can not handle Data URIs through XMLHttpRequest so process manually
47+ if ( dataUriRegexResult ) {
4448
45- var response = event . target . response ;
49+ var mimeType = dataUriRegexResult [ 1 ] ;
50+ var isBase64 = ! ! dataUriRegexResult [ 2 ] ;
51+ var data = dataUriRegexResult [ 3 ] ;
4652
47- Cache . add ( url , response ) ;
53+ data = window . decodeURIComponent ( data ) ;
4854
49- if ( this . status === 200 ) {
55+ if ( isBase64 ) {
56+ data = window . atob ( data ) ;
57+ }
5058
51- if ( onLoad ) onLoad ( response ) ;
59+ try {
5260
53- scope . manager . itemEnd ( url ) ;
61+ var response ;
62+ var responseType = ( this . responseType || '' ) . toLowerCase ( ) ;
5463
55- } else if ( this . status === 0 ) {
64+ switch ( responseType ) {
5665
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' :
5968
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 ++ ) {
6172
62- if ( onLoad ) onLoad ( response ) ;
73+ view [ i ] = data . charCodeAt ( i ) ;
6374
64- scope . manager . itemEnd ( url ) ;
75+ }
6576
66- } else {
77+ if ( responseType === 'blob' ) {
6778
68- if ( onError ) onError ( event ) ;
79+ response = new Blob ( [ response ] , { "type" : mimeType } ) ;
6980
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 ) ;
71125
72126 }
73127
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 ) ;
75155
76- if ( onProgress !== undefined ) {
156+ } else {
77157
78- request . addEventListener ( 'progress' , function ( event ) {
158+ if ( onError ) onError ( event ) ;
79159
80- onProgress ( event ) ;
160+ scope . manager . itemError ( url ) ;
161+
162+ }
81163
82164 } , false ) ;
83165
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 ) {
85177
86- request . addEventListener ( 'error' , function ( event ) {
178+ if ( onError ) onError ( event ) ;
87179
88- if ( onError ) onError ( event ) ;
180+ scope . manager . itemError ( url ) ;
89181
90- scope . manager . itemError ( url ) ;
182+ } , false ) ;
91183
92- } , false ) ;
184+ if ( this . responseType !== undefined ) request . responseType = this . responseType ;
185+ if ( this . withCredentials !== undefined ) request . withCredentials = this . withCredentials ;
93186
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' ) ;
96188
97- if ( request . overrideMimeType ) request . overrideMimeType ( 'text/plain' ) ;
189+ request . send ( null ) ;
98190
99- request . send ( null ) ;
191+ }
100192
101193 scope . manager . itemStart ( url ) ;
102194
0 commit comments