FileLoader.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. import { Cache } from './Cache';
  5. import { DefaultLoadingManager } from './LoadingManager';
  6. function FileLoader( manager ) {
  7. this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
  8. }
  9. Object.assign( FileLoader.prototype, {
  10. load: function ( url, onLoad, onProgress, onError ) {
  11. if ( url === undefined ) url = '';
  12. if ( this.path !== undefined ) url = this.path + url;
  13. var scope = this;
  14. var cached = Cache.get( url );
  15. if ( cached !== undefined ) {
  16. scope.manager.itemStart( url );
  17. setTimeout( function () {
  18. if ( onLoad ) onLoad( cached );
  19. scope.manager.itemEnd( url );
  20. }, 0 );
  21. return cached;
  22. }
  23. // Check for data: URI
  24. var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
  25. var dataUriRegexResult = url.match( dataUriRegex );
  26. // Safari can not handle Data URIs through XMLHttpRequest so process manually
  27. if ( dataUriRegexResult ) {
  28. var mimeType = dataUriRegexResult[ 1 ];
  29. var isBase64 = !! dataUriRegexResult[ 2 ];
  30. var data = dataUriRegexResult[ 3 ];
  31. data = window.decodeURIComponent( data );
  32. if ( isBase64 ) data = window.atob( data );
  33. try {
  34. var response;
  35. var responseType = ( this.responseType || '' ).toLowerCase();
  36. switch ( responseType ) {
  37. case 'arraybuffer':
  38. case 'blob':
  39. response = new ArrayBuffer( data.length );
  40. var view = new Uint8Array( response );
  41. for ( var i = 0; i < data.length; i ++ ) {
  42. view[ i ] = data.charCodeAt( i );
  43. }
  44. if ( responseType === 'blob' ) {
  45. response = new Blob( [ response ], { type: mimeType } );
  46. }
  47. break;
  48. case 'document':
  49. var parser = new DOMParser();
  50. response = parser.parseFromString( data, mimeType );
  51. break;
  52. case 'json':
  53. response = JSON.parse( data );
  54. break;
  55. default: // 'text' or other
  56. response = data;
  57. break;
  58. }
  59. // Wait for next browser tick
  60. window.setTimeout( function () {
  61. if ( onLoad ) onLoad( response );
  62. scope.manager.itemEnd( url );
  63. }, 0 );
  64. } catch ( error ) {
  65. // Wait for next browser tick
  66. window.setTimeout( function () {
  67. if ( onError ) onError( error );
  68. scope.manager.itemError( url );
  69. }, 0 );
  70. }
  71. } else {
  72. var request = new XMLHttpRequest();
  73. request.open( 'GET', url, true );
  74. request.addEventListener( 'load', function ( event ) {
  75. var response = event.target.response;
  76. Cache.add( url, response );
  77. if ( this.status === 200 ) {
  78. if ( onLoad ) onLoad( response );
  79. scope.manager.itemEnd( url );
  80. } else if ( this.status === 0 ) {
  81. // Some browsers return HTTP Status 0 when using non-http protocol
  82. // e.g. 'file://' or 'data://'. Handle as success.
  83. console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
  84. if ( onLoad ) onLoad( response );
  85. scope.manager.itemEnd( url );
  86. } else {
  87. if ( onError ) onError( event );
  88. scope.manager.itemError( url );
  89. }
  90. }, false );
  91. if ( onProgress !== undefined ) {
  92. request.addEventListener( 'progress', function ( event ) {
  93. onProgress( event );
  94. }, false );
  95. }
  96. request.addEventListener( 'error', function ( event ) {
  97. if ( onError ) onError( event );
  98. scope.manager.itemError( url );
  99. }, false );
  100. if ( this.responseType !== undefined ) request.responseType = this.responseType;
  101. if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
  102. if ( this.mimeType && request.overrideMimeType ) request.overrideMimeType( this.mimeType );
  103. request.send( null );
  104. }
  105. scope.manager.itemStart( url );
  106. return request;
  107. },
  108. setPath: function ( value ) {
  109. this.path = value;
  110. return this;
  111. },
  112. setResponseType: function ( value ) {
  113. this.responseType = value;
  114. return this;
  115. },
  116. setWithCredentials: function ( value ) {
  117. this.withCredentials = value;
  118. return this;
  119. },
  120. setMimeType: function ( value ) {
  121. this.mimeType = value;
  122. return this;
  123. }
  124. } );
  125. export { FileLoader };