FileLoader.js 4.5 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

B
bentok 已提交
5 6
import { Cache } from './Cache.js';
import { DefaultLoadingManager } from './LoadingManager.js';
M
Mr.doob 已提交
7

M
Mr.doob 已提交
8
function FileLoader( manager ) {
M
Mr.doob 已提交
9

R
Rich Harris 已提交
10
	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
M
Mr.doob 已提交
11

M
Mr.doob 已提交
12
}
M
Mr.doob 已提交
13

M
Mr.doob 已提交
14
Object.assign( FileLoader.prototype, {
M
Mr.doob 已提交
15 16 17

	load: function ( url, onLoad, onProgress, onError ) {

18 19
		if ( url === undefined ) url = '';

M
Mr.doob 已提交
20 21
		if ( this.path !== undefined ) url = this.path + url;

22
		url = this.manager.resolveURL( url );
23

24 25
		var scope = this;

R
Rich Harris 已提交
26
		var cached = Cache.get( url );
27 28 29

		if ( cached !== undefined ) {

30
			scope.manager.itemStart( url );
D
dubejf 已提交
31

32 33
			setTimeout( function () {

M
Mr.doob 已提交
34
				if ( onLoad ) onLoad( cached );
D
dubejf 已提交
35

36
				scope.manager.itemEnd( url );
D
dubejf 已提交
37

38
			}, 0 );
D
dubejf 已提交
39

40
			return cached;
41 42 43

		}

44 45 46
		// Check for data: URI
		var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
		var dataUriRegexResult = url.match( dataUriRegex );
M
Mr.doob 已提交
47

48 49
		// Safari can not handle Data URIs through XMLHttpRequest so process manually
		if ( dataUriRegexResult ) {
M
Mr.doob 已提交
50

M
Mr.doob 已提交
51 52 53
			var mimeType = dataUriRegexResult[ 1 ];
			var isBase64 = !! dataUriRegexResult[ 2 ];
			var data = dataUriRegexResult[ 3 ];
M
Mr.doob 已提交
54

M
Mr.doob 已提交
55
			data = window.decodeURIComponent( data );
56

M
Mr.doob 已提交
57
			if ( isBase64 ) data = window.atob( data );
58

59
			try {
60

61 62
				var response;
				var responseType = ( this.responseType || '' ).toLowerCase();
63

64
				switch ( responseType ) {
65

66 67
					case 'arraybuffer':
					case 'blob':
68

K
kkruups 已提交
69
						var view = new Uint8Array( data.length );
M
Mr.doob 已提交
70

71
						for ( var i = 0; i < data.length; i ++ ) {
M
Mr.doob 已提交
72

M
Mr.doob 已提交
73
							view[ i ] = data.charCodeAt( i );
M
Mr.doob 已提交
74

75
						}
76

77
						if ( responseType === 'blob' ) {
M
Mr.doob 已提交
78

K
kkruups 已提交
79
							response = new Blob( [ view.buffer ], { type: mimeType } );
M
Mr.doob 已提交
80

K
kkruups 已提交
81
						} else {
M
Mugen87 已提交
82 83 84 85

							response = view.buffer;

						}
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

						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;

				}

K
kkruups 已提交
110
				// Wait for next browser tick like standard XMLHttpRequest event dispatching does
M
Mr.doob 已提交
111
				window.setTimeout( function () {
112 113 114 115 116

					if ( onLoad ) onLoad( response );

					scope.manager.itemEnd( url );

M
Mr.doob 已提交
117
				}, 0 );
118 119 120

			} catch ( error ) {

K
kkruups 已提交
121
				// Wait for next browser tick like standard XMLHttpRequest event dispatching does
M
Mr.doob 已提交
122
				window.setTimeout( function () {
123 124 125

					if ( onError ) onError( error );

126
					scope.manager.itemEnd( url );
127 128
					scope.manager.itemError( url );

M
Mr.doob 已提交
129
				}, 0 );
130

131
			}
M
Mr.doob 已提交
132

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
		} 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.

M
Mr.doob 已提交
155
					console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
156 157 158 159

					if ( onLoad ) onLoad( response );

					scope.manager.itemEnd( url );
M
Mr.doob 已提交
160

161
				} else {
M
Mr.doob 已提交
162

163
					if ( onError ) onError( event );
M
Mr.doob 已提交
164

165
					scope.manager.itemEnd( url );
166 167 168
					scope.manager.itemError( url );

				}
M
Mr.doob 已提交
169 170 171

			}, false );

172 173 174 175 176 177 178 179 180 181 182
			if ( onProgress !== undefined ) {

				request.addEventListener( 'progress', function ( event ) {

					onProgress( event );

				}, false );

			}

			request.addEventListener( 'error', function ( event ) {
M
Mr.doob 已提交
183

184
				if ( onError ) onError( event );
M
Mr.doob 已提交
185

186
				scope.manager.itemEnd( url );
187
				scope.manager.itemError( url );
M
Mr.doob 已提交
188

189
			}, false );
M
Mr.doob 已提交
190

191 192
			if ( this.responseType !== undefined ) request.responseType = this.responseType;
			if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
M
Mr.doob 已提交
193

194
			if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
M
Mr.doob 已提交
195

T
Takahiro 已提交
196
			for ( var header in this.requestHeader ) {
197

T
Takahiro 已提交
198
				request.setRequestHeader( header, this.requestHeader[ header ] );
199 200 201

			}

202
			request.send( null );
203

204
		}
M
Mr.doob 已提交
205

M
Mr.doob 已提交
206 207
		scope.manager.itemStart( url );

J
Josh Sacks 已提交
208 209
		return request;

M
Mr.doob 已提交
210 211
	},

212
	setPath: function ( value ) {
M
Mr.doob 已提交
213

214
		this.path = value;
M
Mr.doob 已提交
215
		return this;
M
Mr.doob 已提交
216 217 218

	},

219 220 221
	setResponseType: function ( value ) {

		this.responseType = value;
M
Mr.doob 已提交
222
		return this;
223 224 225

	},

226 227 228
	setWithCredentials: function ( value ) {

		this.withCredentials = value;
M
Mr.doob 已提交
229
		return this;
230

231 232 233 234 235 236 237
	},

	setMimeType: function ( value ) {

		this.mimeType = value;
		return this;

238 239 240 241 242 243 244
	},

	setRequestHeader: function ( value ) {

		this.requestHeader = value;
		return this;

M
Mr.doob 已提交
245 246
	}

M
Mr.doob 已提交
247
} );
R
Rich Harris 已提交
248 249


M
Mr.doob 已提交
250
export { FileLoader };