1 | import { Cache } from './Cache.js';
|
2 | import { Loader } from './Loader.js';
|
3 |
|
4 | const loading = {};
|
5 |
|
6 | function FileLoader( manager ) {
|
7 |
|
8 | Loader.call( this, manager );
|
9 |
|
10 | }
|
11 |
|
12 | FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
13 |
|
14 | constructor: FileLoader,
|
15 |
|
16 | load: function ( url, onLoad, onProgress, onError ) {
|
17 |
|
18 | if ( url === undefined ) url = '';
|
19 |
|
20 | if ( this.path !== undefined ) url = this.path + url;
|
21 |
|
22 | url = this.manager.resolveURL( url );
|
23 |
|
24 | const scope = this;
|
25 |
|
26 | const cached = Cache.get( url );
|
27 |
|
28 | if ( cached !== undefined ) {
|
29 |
|
30 | scope.manager.itemStart( url );
|
31 |
|
32 | setTimeout( function () {
|
33 |
|
34 | if ( onLoad ) onLoad( cached );
|
35 |
|
36 | scope.manager.itemEnd( url );
|
37 |
|
38 | }, 0 );
|
39 |
|
40 | return cached;
|
41 |
|
42 | }
|
43 |
|
44 |
|
45 |
|
46 | if ( loading[ url ] !== undefined ) {
|
47 |
|
48 | loading[ url ].push( {
|
49 |
|
50 | onLoad: onLoad,
|
51 | onProgress: onProgress,
|
52 | onError: onError
|
53 |
|
54 | } );
|
55 |
|
56 | return;
|
57 |
|
58 | }
|
59 |
|
60 |
|
61 | const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
|
62 | const dataUriRegexResult = url.match( dataUriRegex );
|
63 | let request;
|
64 |
|
65 |
|
66 | if ( dataUriRegexResult ) {
|
67 |
|
68 | const mimeType = dataUriRegexResult[ 1 ];
|
69 | const isBase64 = !! dataUriRegexResult[ 2 ];
|
70 |
|
71 | let data = dataUriRegexResult[ 3 ];
|
72 | data = decodeURIComponent( data );
|
73 |
|
74 | if ( isBase64 ) data = atob( data );
|
75 |
|
76 | try {
|
77 |
|
78 | let response;
|
79 | const responseType = ( this.responseType || '' ).toLowerCase();
|
80 |
|
81 | switch ( responseType ) {
|
82 |
|
83 | case 'arraybuffer':
|
84 | case 'blob':
|
85 |
|
86 | const view = new Uint8Array( data.length );
|
87 |
|
88 | for ( let i = 0; i < data.length; i ++ ) {
|
89 |
|
90 | view[ i ] = data.charCodeAt( i );
|
91 |
|
92 | }
|
93 |
|
94 | if ( responseType === 'blob' ) {
|
95 |
|
96 | response = new Blob( [ view.buffer ], { type: mimeType } );
|
97 |
|
98 | } else {
|
99 |
|
100 | response = view.buffer;
|
101 |
|
102 | }
|
103 |
|
104 | break;
|
105 |
|
106 | case 'document':
|
107 |
|
108 | const parser = new DOMParser();
|
109 | response = parser.parseFromString( data, mimeType );
|
110 |
|
111 | break;
|
112 |
|
113 | case 'json':
|
114 |
|
115 | response = JSON.parse( data );
|
116 |
|
117 | break;
|
118 |
|
119 | default:
|
120 |
|
121 | response = data;
|
122 |
|
123 | break;
|
124 |
|
125 | }
|
126 |
|
127 |
|
128 | setTimeout( function () {
|
129 |
|
130 | if ( onLoad ) onLoad( response );
|
131 |
|
132 | scope.manager.itemEnd( url );
|
133 |
|
134 | }, 0 );
|
135 |
|
136 | } catch ( error ) {
|
137 |
|
138 |
|
139 | setTimeout( function () {
|
140 |
|
141 | if ( onError ) onError( error );
|
142 |
|
143 | scope.manager.itemError( url );
|
144 | scope.manager.itemEnd( url );
|
145 |
|
146 | }, 0 );
|
147 |
|
148 | }
|
149 |
|
150 | } else {
|
151 |
|
152 |
|
153 |
|
154 | loading[ url ] = [];
|
155 |
|
156 | loading[ url ].push( {
|
157 |
|
158 | onLoad: onLoad,
|
159 | onProgress: onProgress,
|
160 | onError: onError
|
161 |
|
162 | } );
|
163 |
|
164 | request = new XMLHttpRequest();
|
165 |
|
166 | request.open( 'GET', url, true );
|
167 |
|
168 | request.addEventListener( 'load', function ( event ) {
|
169 |
|
170 | const response = this.response;
|
171 |
|
172 | const callbacks = loading[ url ];
|
173 |
|
174 | delete loading[ url ];
|
175 |
|
176 | if ( this.status === 200 || this.status === 0 ) {
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
|
182 |
|
183 |
|
184 |
|
185 | Cache.add( url, response );
|
186 |
|
187 | for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
|
188 |
|
189 | const callback = callbacks[ i ];
|
190 | if ( callback.onLoad ) callback.onLoad( response );
|
191 |
|
192 | }
|
193 |
|
194 | scope.manager.itemEnd( url );
|
195 |
|
196 | } else {
|
197 |
|
198 | for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
|
199 |
|
200 | const callback = callbacks[ i ];
|
201 | if ( callback.onError ) callback.onError( event );
|
202 |
|
203 | }
|
204 |
|
205 | scope.manager.itemError( url );
|
206 | scope.manager.itemEnd( url );
|
207 |
|
208 | }
|
209 |
|
210 | }, false );
|
211 |
|
212 | request.addEventListener( 'progress', function ( event ) {
|
213 |
|
214 | const callbacks = loading[ url ];
|
215 |
|
216 | for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
|
217 |
|
218 | const callback = callbacks[ i ];
|
219 | if ( callback.onProgress ) callback.onProgress( event );
|
220 |
|
221 | }
|
222 |
|
223 | }, false );
|
224 |
|
225 | request.addEventListener( 'error', function ( event ) {
|
226 |
|
227 | const callbacks = loading[ url ];
|
228 |
|
229 | delete loading[ url ];
|
230 |
|
231 | for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
|
232 |
|
233 | const callback = callbacks[ i ];
|
234 | if ( callback.onError ) callback.onError( event );
|
235 |
|
236 | }
|
237 |
|
238 | scope.manager.itemError( url );
|
239 | scope.manager.itemEnd( url );
|
240 |
|
241 | }, false );
|
242 |
|
243 | request.addEventListener( 'abort', function ( event ) {
|
244 |
|
245 | const callbacks = loading[ url ];
|
246 |
|
247 | delete loading[ url ];
|
248 |
|
249 | for ( let i = 0, il = callbacks.length; i < il; i ++ ) {
|
250 |
|
251 | const callback = callbacks[ i ];
|
252 | if ( callback.onError ) callback.onError( event );
|
253 |
|
254 | }
|
255 |
|
256 | scope.manager.itemError( url );
|
257 | scope.manager.itemEnd( url );
|
258 |
|
259 | }, false );
|
260 |
|
261 | if ( this.responseType !== undefined ) request.responseType = this.responseType;
|
262 | if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
|
263 |
|
264 | if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
|
265 |
|
266 | for ( const header in this.requestHeader ) {
|
267 |
|
268 | request.setRequestHeader( header, this.requestHeader[ header ] );
|
269 |
|
270 | }
|
271 |
|
272 | request.send( null );
|
273 |
|
274 | }
|
275 |
|
276 | scope.manager.itemStart( url );
|
277 |
|
278 | return request;
|
279 |
|
280 | },
|
281 |
|
282 | setResponseType: function ( value ) {
|
283 |
|
284 | this.responseType = value;
|
285 | return this;
|
286 |
|
287 | },
|
288 |
|
289 | setMimeType: function ( value ) {
|
290 |
|
291 | this.mimeType = value;
|
292 | return this;
|
293 |
|
294 | }
|
295 |
|
296 | } );
|
297 |
|
298 |
|
299 | export { FileLoader };
|