/// <reference path="ITransport.ts" />
/// <reference path="../../env/UserAgent.ts" />
/// <reference path="../Request.ts" />
/// <reference path="../Response.ts" />
var econda;
(function (econda) {
var ajax;
(function (ajax) {
var transport;
(function (transport) {
var Response = econda.ajax.Response;
/**
* XHR Post transport implementation. There's no reason to use this class directly. See {@link econda.ajax.Request}.
* @class econda.ajax.transport.Post
*/
var Post = (function () {
function Post() {
this._initialized = false;
this._allHeaders = {};
}
Post.prototype.setRequest = function (request) {
this._request = request;
};
Post.prototype.getRequest = function () {
return this._request;
};
Post.prototype.hasHeaders = function () {
if (Object.keys) {
return (Object.keys(this._allHeaders).length > 0);
}
else {
var keys = [], k;
for (k in this._allHeaders) {
if (Object.prototype.hasOwnProperty.call(this._allHeaders, k)) {
keys.push(k);
}
}
return keys.length > 0;
}
};
/**
* Send request
* @param {econda.ajax.Request} request
*/
Post.prototype.init = function () {
this.initWriterInstance();
this.initXmlHttpRequestInstance();
this.appendCallbacks();
this._xhr.open("POST", this.getRequestUriWithParams(), true);
this._xhr.timeout = this._request.getTimeoutMilliseconds();
if (this._request.isXDomainRequest() && this._request.getWithCredentials() && this._xhr instanceof XMLHttpRequest) {
this._xhr.withCredentials = true;
}
this.appendHeaders();
this._initialized = true;
};
Post.prototype.send = function () {
var cmp = this;
if (!this._initialized) {
this.init();
}
setTimeout(function () {
cmp._xhr.send(cmp.getEncodedRequestData());
var callback = cmp._request.getAfterSend();
if (callback) {
callback();
}
}, 20);
};
/**
* Setup writer instance
* @returns {String}
*/
Post.prototype.initWriterInstance = function () {
var data = this._request.getData();
var writer = this._request.getWriter();
// auto detect writer?
if (writer == null && data) {
if (typeof data == 'object') {
writer = new econda.ajax.writer.FormEncodedWriter();
}
}
if (writer) {
writer.setData(this._request.getData());
this._writer = writer;
}
};
* Add headers from request and writer to XMLHttpRequest object.
* @private
*/
Post.prototype.appendHeaders = function () {
var headers = {
"Content-Type": "text/plain"
};
if (this._request.isXDomainRequest() == false) {
// only for local requests, it would cause x-domain requests to be "not so simple requests"
// and so this would cause a prefly options request
headers["X-Requested-With"] = "XMLHttpRequest";
}
// add headers from writer, e.g. content type
if (this._writer) {
var headersFromWriter = this._writer.getHeaders();
if (headersFromWriter) {
for (var name in headersFromWriter) {
headers[name] = headersFromWriter[name];
}
}
}
// add headers from request object
var headersFromRequest = this._request.getHeaders();
if (headersFromRequest) {
for (var name in headersFromRequest) {
headers[name] = headersFromRequest[name];
}
}
this._allHeaders = headers;
// append to xhr object (not possible on XDomainRequest objects, <= IE10)
if (typeof this._xhr.setRequestHeader != 'undefined') {
for (var name in headers) {
this._xhr.setRequestHeader(name, headers[name]);
}
}
return this;
};
/**
* Get data from request using configured writer. This is not the right place for auto detection of content type (s. initWriter).
* @private
*/
Post.prototype.getEncodedRequestData = function () {
var ret = "";
if (this._writer) {
ret = this._writer.getBody();
}
else {
ret = "" + this._request.getData();
}
return ret;
};
/**
* Checks if given request can be send with current browser
* @returns {Boolean}
*/
Post.prototype.isSupportedRequest = function () {
this.initXmlHttpRequestInstance();
var isXDomainRequest = this._request.isXDomainRequest();
var ok = true;
// ie <= v 8 does not support xdomain request
ok = ok && (isXDomainRequest == false || this._isOldIE() == false);
// xdomain has header restrictions - FIXME, some headers are allowed, others not - we have to check this here
ok = ok && (this.hasHeaders() == false)
|| ((typeof this._xhr['setRequestHeader'] != 'undefined') && (this._isOldIE() == false));
// withCredentials is not supported on XDomainRequest (IE 8)
ok = ok && (this._request.getWithCredentials() == false || this._xhr instanceof XMLHttpRequest);
return ok;
};
/**
* This old ie versions do have a setRequestHeader method, but they will show a confirm dialog to users if we
* use the XDomainRequest object to perform x domain requests
* @private
*/
Post.prototype._isOldIE = function () {
var ua = econda.env.UserAgent;
if (ua.getName() != ua.INTERNET_EXPLORER) {
return false;
}
if (ua.getVersion() >= 8) {
return false;
}
return true;
};
/**
* Create and return instance of XmlHttpRequest object for all browsers.
* @private
* @returns {XMLHttpRequest}
*/
Post.prototype.initXmlHttpRequestInstance = function () {
var isXDomainRequest = this._request.isXDomainRequest();
// init xhr only if not already done. We need this for unit tests
if (!this._xhr) {
if (isXDomainRequest && typeof window["XDomainRequest"] != 'undefined') {
this._xhr = new window["XDomainRequest"]();
}
else if (typeof XMLHttpRequest != 'undefined') {
this._xhr = new XMLHttpRequest();
}
else {
this._xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
}
};
/**
* Get uri from request object with parameters appended
* @param {String} url
* @param {Object} params
* @returns {String} request uri incl. parameters
* @private
*/
Post.prototype.getRequestUriWithParams = function () {
var uri = this._request.getUri();
var params = this._request.getParams();
return uri.clone().appendParams(params).toString();
};
/**
* @private
*/
Post.prototype.appendCallbacks = function () {
var cmp = this;
this._xhr.onreadystatechange = function () {
cmp.onReadyStateChange.apply(cmp, arguments);
};
return this;
};
/**
* Callback for xhr onreadystatechange. Must inform the request when it's done.
* @private
*/
Post.prototype.onReadyStateChange = function () {
var xhr = this._xhr; // XmlHttpRequest
var request = this._request; // econda.ajax.IRequest
if (xhr.readyState == 4) {
var result = new Response();
result.responseText = xhr.responseText;
result.status = xhr.status;
result.isError = (xhr.status != 200);
request.handleResponse(result);
}
};
return Post;
}());
transport.Post = Post; // end of class
})(transport = ajax.transport || (ajax.transport = {}));
})(ajax = econda.ajax || (econda.ajax = {}));
})(econda || (econda = {})); // end of module