@awayjs/core
Version:
AwayJS core classes
353 lines (352 loc) • 12.3 kB
JavaScript
import { __extends } from "tslib";
import { URLLoaderDataFormat } from '../net/URLLoaderDataFormat';
import { URLRequestMethod } from '../net/URLRequestMethod';
import { URLVariables } from '../net/URLVariables';
import { EventDispatcher } from '../events/EventDispatcher';
import { URLLoaderEvent } from '../events/URLLoaderEvent';
/**
* The URLLoader is used to load a single file, as part of a resource.
*
* While URLLoader can be used directly, e.g. to create a third-party asset
* management system, it's recommended to use any of the classes Loader3D, Loader
* and AssetLibrary instead in most cases.
*
* @see Loader
* @see away.library.AssetLibrary
*/
var URLLoader = /** @class */ (function (_super) {
__extends(URLLoader, _super);
/**
* Creates a new URLLoader object.
*/
function URLLoader() {
var _this = _super.call(this) || this;
_this._bytesLoaded = 0;
_this._bytesTotal = 0;
_this._dataFormat = URLLoaderDataFormat.TEXT;
_this._loadError = false;
return _this;
}
Object.defineProperty(URLLoader.prototype, "url", {
/**
*
*/
get: function () {
return this._request ? this._request.url : '';
},
enumerable: false,
configurable: true
});
Object.defineProperty(URLLoader.prototype, "data", {
/**
*
*/
get: function () {
return this._data;
},
enumerable: false,
configurable: true
});
Object.defineProperty(URLLoader.prototype, "dataFormat", {
get: function () {
return this._dataFormat;
},
/**
*
* URLLoaderDataFormat.BINARY
* URLLoaderDataFormat.TEXT
* URLLoaderDataFormat.VARIABLES
*
* @param format
*/
set: function (format) {
this._dataFormat = format;
},
enumerable: false,
configurable: true
});
Object.defineProperty(URLLoader.prototype, "bytesLoaded", {
/**
*
* @returns {number}
*/
get: function () {
return this._bytesLoaded;
},
enumerable: false,
configurable: true
});
Object.defineProperty(URLLoader.prototype, "bytesTotal", {
/**
*
* @returns {number}
*/
get: function () {
return this._bytesTotal;
},
enumerable: false,
configurable: true
});
/**
* Load a resource from a file.
*
* @param request The URLRequest object containing the URL of the object to be loaded.
*/
URLLoader.prototype.load = function (request) {
this._request = request;
this.initXHR();
if (request.method === URLRequestMethod.POST)
this.postRequest(request);
else
this.getRequest(request);
};
URLLoader.prototype.isSupported = function () {
return window != null;
};
/**
*
*/
URLLoader.prototype.close = function () {
this._XHR.abort();
this.disposeXHR();
};
/**
*
*/
URLLoader.prototype.dispose = function () {
if (this._XHR)
this._XHR.abort();
this.disposeXHR();
};
/**
*
* @param xhr
* @param responseType
*/
URLLoader.prototype.setResponseType = function (xhr, responseType) {
switch (responseType) {
case URLLoaderDataFormat.ARRAY_BUFFER:
case URLLoaderDataFormat.BLOB:
case URLLoaderDataFormat.TEXT:
xhr.responseType = responseType;
break;
case URLLoaderDataFormat.VARIABLES:
xhr.responseType = URLLoaderDataFormat.TEXT;
break;
case URLLoaderDataFormat.BINARY:
xhr.responseType = '';
break;
default:
}
};
/**
*
* @param request {URLRequest}
*/
URLLoader.prototype.getRequest = function (request) {
try {
this._XHR.open(request.method, request.url, request.async);
this.setResponseType(this._XHR, this._dataFormat);
this._XHR.send(); // No data to send
}
catch (e /* <XMLHttpRequestException> */) {
this.handleXmlHttpRequestException(e);
}
};
/**
*
* @param request {URLRequest}
*/
URLLoader.prototype.postRequest = function (request) {
this._loadError = false;
this._XHR.open(request.method, request.url, request.async);
if (request.data != null) {
if (request.data instanceof URLVariables) {
var urlVars = request.data;
try {
this._XHR.responseType = 'text';
this._XHR.send(urlVars.formData);
}
catch (e /* <XMLHttpRequestException> */) {
this.handleXmlHttpRequestException(e);
}
}
else {
this.setResponseType(this._XHR, this._dataFormat);
if (request.data)
this._XHR.send(request.data); // TODO: Test
else
this._XHR.send(); // no data to send
}
}
else {
this._XHR.send(); // No data to send
}
};
/**
*
* @param error {XMLHttpRequestException}
*/
URLLoader.prototype.handleXmlHttpRequestException = function (error /* <XMLHttpRequestException> */) {
switch (error.code) {
/***********************************************************************************************************
*
* XMLHttpRequestException { message: "NETWORK_ERR: XMLHttpRequest Exception 101", name: "NETWORK_ERR",
* code: 101, stack: "Error: A network error occurred in synchronous req…",NETWORK_ERR: 101… }
* code: 101 , message: "NETWORK_ERR: XMLHttpRequest Exception 101" , name: "NETWORK_ERR"
*
**********************************************************************************************************/
case 101:
// Note: onLoadError event throws IO_ERROR event - this case is already Covered
break;
}
};
/**
*
*/
URLLoader.prototype.initXHR = function () {
var _this = this;
if (!this._XHR) {
this._XHR = new XMLHttpRequest();
// loadstart- When the request starts.
this._XHR.onloadstart = function (event) { return _this.onLoadStart(event); };
//progress - While loading and sending data.
this._XHR.onprogress = function (event) { return _this.onProgress(event); };
//abort - When the request has been aborted, either by invoking the abort() method or navigating away from
//the page.
this._XHR.onabort = function (event) { return _this.onAbort(event); };
// error - When the request has failed.
this._XHR.onerror = function (event) { return _this.onLoadError(event); };
// load - When the request has successfully completed.
this._XHR.onload = function (event) { return _this.onLoadComplete(event); };
// timeout - When the author specified timeout has passed before the request could complete.
this._XHR.ontimeout = function (event) { return _this.onTimeOut(event); };
// loadend - When the request has completed, regardless of whether or not it was successful.
this._XHR.onloadend = function (event) { return _this.onLoadEnd(event); };
// onreadystatechange - When XHR state changes
this._XHR.onreadystatechange = function (event) { return _this.onReadyStateChange(event); };
}
};
/**
*
*/
URLLoader.prototype.disposeXHR = function () {
if (this._XHR !== null) {
this._XHR.onloadstart = null;
this._XHR.onprogress = null;
this._XHR.onabort = null;
this._XHR.onerror = null;
this._XHR.onload = null;
this._XHR.ontimeout = null;
this._XHR.onloadend = null;
this._XHR = null;
}
};
/**
*
* @param source
*/
URLLoader.prototype.decodeURLVariables = function (source) {
var result = new Object();
source = source.split('+').join(' ');
var re = /[?&]?([^=]+)=([^&]*)/g;
var tokens;
while ((tokens = re.exec(source)))
result[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
return result;
};
// XMLHttpRequest - Event Handlers
/**
* When XHR state changes
* @param event
*/
URLLoader.prototype.onReadyStateChange = function (event) {
if (this._XHR.readyState == 4) {
this._status = this._XHR.status;
if (this._status == 404) {
this._loadError = true;
this.dispatchEvent(this._loadErrorEvent
|| (this._loadErrorEvent = new URLLoaderEvent(URLLoaderEvent.LOAD_ERROR, this)));
}
this.dispatchEvent(this._statusEvent
|| (this._statusEvent = new URLLoaderEvent(URLLoaderEvent.HTTP_STATUS, this)));
}
};
/**
* When the request has completed, regardless of whether or not it was successful.
* @param event
*/
URLLoader.prototype.onLoadEnd = function (event) {
if (this._loadError === true)
return;
};
/**
* When the author specified timeout has passed before the request could complete.
* @param event
*/
URLLoader.prototype.onTimeOut = function (event) {
//TODO: Timeout not currently implemented ( also not part of AS3 API )
};
/**
* When the request has been aborted, either by invoking the abort() method or navigating away from the page.
* @param event
*/
URLLoader.prototype.onAbort = function (event) {
// TODO: investigate whether this needs to be an IOError
};
/**
* While loading and sending data.
* @param event
*/
URLLoader.prototype.onProgress = function (event) {
this._bytesTotal = event.total;
this._bytesLoaded = event.loaded;
this.dispatchEvent(this._progressEvent
|| (this._progressEvent = new URLLoaderEvent(URLLoaderEvent.LOAD_PROGRESS, this)));
};
/**
* When the request starts.
* @param event
*/
URLLoader.prototype.onLoadStart = function (event) {
this.dispatchEvent(this._loadStartEvent
|| (this._loadStartEvent = new URLLoaderEvent(URLLoaderEvent.LOAD_START, this)));
};
/**
* When the request has successfully completed.
* @param event
*/
URLLoader.prototype.onLoadComplete = function (event) {
if (this._loadError === true)
return;
switch (this._dataFormat) {
case URLLoaderDataFormat.TEXT:
this._data = this._XHR.responseText;
break;
case URLLoaderDataFormat.VARIABLES:
this._data = this.decodeURLVariables(this._XHR.responseText);
break;
case URLLoaderDataFormat.BLOB:
case URLLoaderDataFormat.ARRAY_BUFFER:
case URLLoaderDataFormat.BINARY:
this._data = this._XHR.response;
break;
default:
this._data = this._XHR.responseText;
break;
}
this.dispatchEvent(this._loadCompleteEvent
|| (this._loadCompleteEvent = new URLLoaderEvent(URLLoaderEvent.LOAD_COMPLETE, this)));
};
/**
* When the request has failed. ( due to network issues ).
* @param event
*/
URLLoader.prototype.onLoadError = function (event) {
this._loadError = true;
this.dispatchEvent(this._loadErrorEvent
|| (this._loadErrorEvent = new URLLoaderEvent(URLLoaderEvent.LOAD_ERROR, this)));
};
return URLLoader;
}(EventDispatcher));
export { URLLoader };