|
@@ -15,6 +15,8 @@ Object.assign( XHRLoader.prototype, {
|
|
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
|
|
+ if ( url === undefined ) url = '';
|
|
|
+
|
|
|
if ( this.path !== undefined ) url = this.path + url;
|
|
|
|
|
|
var scope = this;
|
|
@@ -37,66 +39,156 @@ Object.assign( XHRLoader.prototype, {
|
|
|
|
|
|
}
|
|
|
|
|
|
- var request = new XMLHttpRequest();
|
|
|
- request.open( 'GET', url, true );
|
|
|
+ // Check for data: URI
|
|
|
+ var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
|
|
|
+ var dataUriRegexResult = url.match( dataUriRegex );
|
|
|
|
|
|
- request.addEventListener( 'load', function ( event ) {
|
|
|
+ // Safari can not handle Data URIs through XMLHttpRequest so process manually
|
|
|
+ if ( dataUriRegexResult ) {
|
|
|
|
|
|
- var response = event.target.response;
|
|
|
+ var mimeType = dataUriRegexResult[1];
|
|
|
+ var isBase64 = !!dataUriRegexResult[2];
|
|
|
+ var data = dataUriRegexResult[3];
|
|
|
|
|
|
- Cache.add( url, response );
|
|
|
+ data = window.decodeURIComponent(data);
|
|
|
|
|
|
- if ( this.status === 200 ) {
|
|
|
+ if( isBase64 ) {
|
|
|
+ data = window.atob(data);
|
|
|
+ }
|
|
|
|
|
|
- if ( onLoad ) onLoad( response );
|
|
|
+ try {
|
|
|
|
|
|
- scope.manager.itemEnd( url );
|
|
|
+ var response;
|
|
|
+ var responseType = ( this.responseType || '' ).toLowerCase();
|
|
|
|
|
|
- } else if ( this.status === 0 ) {
|
|
|
+ switch ( responseType ) {
|
|
|
|
|
|
- // Some browsers return HTTP Status 0 when using non-http protocol
|
|
|
- // e.g. 'file://' or 'data://'. Handle as success.
|
|
|
+ case 'arraybuffer':
|
|
|
+ case 'blob':
|
|
|
|
|
|
- console.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );
|
|
|
+ response = new ArrayBuffer( data.length );
|
|
|
+ var view = new Uint8Array( response );
|
|
|
+ for ( var i = 0; i < data.length; i ++ ) {
|
|
|
|
|
|
- if ( onLoad ) onLoad( response );
|
|
|
+ view[ i ] = data.charCodeAt( i );
|
|
|
|
|
|
- scope.manager.itemEnd( url );
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ if ( responseType === 'blob' ) {
|
|
|
|
|
|
- if ( onError ) onError( event );
|
|
|
+ response = new Blob( [ response ], { "type" : mimeType } );
|
|
|
|
|
|
- scope.manager.itemError( url );
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'document':
|
|
|
+
|
|
|
+ var parser = new DOMParser();
|
|
|
+ response = parser.parseFromString( data, mimeType );
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'json':
|
|
|
+
|
|
|
+ response = JSON.parse( data );
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ default: // 'text' or other
|
|
|
+
|
|
|
+ response = data;
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // Wait for next browser tick
|
|
|
+ window.setTimeout( function() {
|
|
|
+
|
|
|
+ if ( onLoad ) onLoad( response );
|
|
|
+
|
|
|
+ scope.manager.itemEnd( url );
|
|
|
+
|
|
|
+ }, 0);
|
|
|
+
|
|
|
+ } catch ( error ) {
|
|
|
+
|
|
|
+ // Wait for next browser tick
|
|
|
+ window.setTimeout( function() {
|
|
|
+
|
|
|
+ if ( onError ) onError( error );
|
|
|
+
|
|
|
+ scope.manager.itemError( url );
|
|
|
+
|
|
|
+ }, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
- }, false );
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var request = new XMLHttpRequest();
|
|
|
+ request.open( 'GET', url, true );
|
|
|
+
|
|
|
+ request.addEventListener( 'load', function ( event ) {
|
|
|
+
|
|
|
+ var response = event.target.response;
|
|
|
+
|
|
|
+ Cache.add( url, response );
|
|
|
+
|
|
|
+ if ( this.status === 200 ) {
|
|
|
+
|
|
|
+ if ( onLoad ) onLoad( response );
|
|
|
+
|
|
|
+ scope.manager.itemEnd( url );
|
|
|
+
|
|
|
+ } else if ( this.status === 0 ) {
|
|
|
+
|
|
|
+ // Some browsers return HTTP Status 0 when using non-http protocol
|
|
|
+ // e.g. 'file://' or 'data://'. Handle as success.
|
|
|
+
|
|
|
+ console.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );
|
|
|
+
|
|
|
+ if ( onLoad ) onLoad( response );
|
|
|
+
|
|
|
+ scope.manager.itemEnd( url );
|
|
|
|
|
|
- if ( onProgress !== undefined ) {
|
|
|
+ } else {
|
|
|
|
|
|
- request.addEventListener( 'progress', function ( event ) {
|
|
|
+ if ( onError ) onError( event );
|
|
|
|
|
|
- onProgress( event );
|
|
|
+ scope.manager.itemError( url );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}, false );
|
|
|
|
|
|
- }
|
|
|
+ if ( onProgress !== undefined ) {
|
|
|
+
|
|
|
+ request.addEventListener( 'progress', function ( event ) {
|
|
|
+
|
|
|
+ onProgress( event );
|
|
|
+
|
|
|
+ }, false );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ request.addEventListener( 'error', function ( event ) {
|
|
|
|
|
|
- request.addEventListener( 'error', function ( event ) {
|
|
|
+ if ( onError ) onError( event );
|
|
|
|
|
|
- if ( onError ) onError( event );
|
|
|
+ scope.manager.itemError( url );
|
|
|
|
|
|
- scope.manager.itemError( url );
|
|
|
+ }, false );
|
|
|
|
|
|
- }, false );
|
|
|
+ if ( this.responseType !== undefined ) request.responseType = this.responseType;
|
|
|
+ if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
|
|
|
|
|
|
- if ( this.responseType !== undefined ) request.responseType = this.responseType;
|
|
|
- if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
|
|
|
+ if ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );
|
|
|
|
|
|
- if ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );
|
|
|
+ request.send( null );
|
|
|
|
|
|
- request.send( null );
|
|
|
+ }
|
|
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|