93,7 → 93,7 |
* boolean setAsync(optional boolean bAsync = true); |
* // async=bAsync |
* |
* boolean setData(optional string sData = ""); |
* boolean setData(optional (ArrayBufferView or Blob or Document or DOMString or FormData)? sData = null); |
* // data=sData |
* |
* boolean setRequestType( |
100,7 → 100,7 |
* optional string sRequestType = "application/x-www-form-urlencoded"); |
* // requestType=sRequestType |
* |
* boolean send(optional string sData = null, |
* boolean send(optional (ArrayBufferView or Blob or Document or DOMString or FormData)? sData = null, |
* optional string sURL = document.URL, |
* optional string sMethod = HTTPMethod.GET, |
* optional boolean bAsync = true); |
156,6 → 156,7 |
this.setAsync(bAsync); |
this.setSuccessListener(fSuccessListener); |
this.setErrorListener(fErrorListener); |
this.setResponseListener(); |
this.setData(); |
this.setRequestType(); |
} |
265,6 → 266,9 |
|
useCache: true, |
|
_handledSuccess: false, |
_handledError: false, |
|
/** |
* Method to be called onreadystatechange |
* |
271,37 → 275,8 |
* @private |
* @function |
*/ |
_responseListener: (function() { |
var |
Request = jsx.net.http.Request, |
jsx_object = jsx.object, |
oStatus = Request.status; |
_responseListener: void 0, |
|
/** |
* @param {XMLHttpRequest} response |
*/ |
return function (response) { |
if (response.readyState === Request.readyState.COMPLETED) |
{ |
var reqStatus = response.status; |
if (oStatus.OK_EXPR.test(reqStatus)) |
{ |
if (jsx_object.isMethod(this.successListener)) |
{ |
return this.successListener(response); |
} |
} |
else if (oStatus.FAILED_EXPR.test(reqStatus)) |
{ |
if (jsx_object.isMethod(this.errorListener)) |
{ |
this.errorListener(response); |
} |
} |
} |
}; |
}()), |
|
/** |
* Sets the <code>URL</code> property. |
* |
463,13 → 438,13 |
/** |
* Sets the <code>data</code> property. |
* |
* @param {string} sData (optional) |
* @param {ArrayBufferView|Blob|Document|string|FormData} sData (optional) |
* If not provided or a false-value, sets |
* the property to the empty string. |
* the property to <code>null</code>. |
* @see HTTPRequest.prototype#resetData() |
*/ |
setData: function (sData) { |
this.data = (sData || ""); |
this.data = (sData || null); |
return this; |
}, |
|
571,7 → 546,8 |
* @return {jsx.net.http.Request} |
* This object |
*/ |
return function (obj) { |
function _setRequestHeaders (obj) |
{ |
for (var name in obj) |
{ |
if (_hasOwnProperty(obj, name)) |
581,7 → 557,9 |
} |
|
return this; |
}; |
} |
|
return _setRequestHeaders; |
}()), |
|
dontCache: function () { |
595,243 → 573,270 |
* a new object if necessary; |
* |
* @protected |
* @return {IXMLHttpRequest} |
* A reference to an XML HTTP Request object or <code>null</code>, |
* if no such object can be created. |
* @function |
*/ |
_getXHR: function () { |
var |
jsx_global = jsx.global, |
jsx_object = jsx.object, |
x = this._xhr; |
_getXHR: (function () { |
var jsx_global = jsx.global, |
_isMethod = jsx.object.isMethod; |
|
/* Reuse existing XHR instance if possible */ |
if (x !== null |
&& x.readyState == this.constructor.readyState.COMPLETED) |
/** |
* @return {IXMLHttpRequest} |
* A reference to an XML HTTP Request object or <code>null</code>, |
* if no such object can be created. |
*/ |
function _getXHR () |
{ |
return x; |
} |
var x = this._xhr; |
|
/* |
* Create new XHR instance: |
* Feature detection based on Jim Ley's XML HTTP Request tutorial |
* at <http://jibbering.com/2002/4/httprequest.html> |
*/ |
/* Reuse existing XHR instance if possible */ |
if (x !== null |
&& x.readyState == this.constructor.readyState.COMPLETED) |
{ |
return x; |
} |
|
/* Initialize to detect failure later */ |
x = null; |
/* |
* Create new XHR instance: |
* Feature detection based on Jim Ley's XML HTTP Request tutorial |
* at <http://jibbering.com/2002/4/httprequest.html> |
*/ |
|
/* |
* IE 6+ (JScript allows for conditional compilation; an ordinary comment |
* to other script engines). Note that IE 7 supports XMLHttpRequest() but |
* currently not for `file:' URIs, so we don't prefer that wrapper (see |
* <http://xhab.blogspot.com/2006/11/ie7-support-for-xmlhttprequest.html>). |
*/ |
if (jsx_object.isMethod(jsx_global, "ActiveXObject")) |
{ |
/*@cc_on @*/ |
/*@if (@_jscript_version >= 5) |
try |
{ |
// TODO: Try this first? |
// new ActiveXObject("Msxml2.XMLHTTP"); |
/* Initialize to detect failure later */ |
x = null; |
|
// MSXML 3.0- |
x = new ActiveXObject("Microsoft.XMLHTTP"); |
} |
catch (e) |
{ |
x = null; |
} |
@end @*/ |
} |
/* |
* IE 6+ (JScript allows for conditional compilation; an ordinary comment |
* to other script engines). Note that IE 7 supports XMLHttpRequest() but |
* currently not for `file:' URIs, so we don't prefer that wrapper (see |
* <http://xhab.blogspot.com/2006/11/ie7-support-for-xmlhttprequest.html>). |
*/ |
if (_isMethod(jsx_global, "ActiveXObject")) |
{ |
/*@cc_on @*/ |
/*@if (@_jscript_version >= 5) |
try |
{ |
// TODO: Try this first? |
// new ActiveXObject("Msxml2.XMLHTTP"); |
|
/* Gecko and Opera 8.1+ */ |
if (!x && jsx_object.isMethod(jsx_global, "XMLHttpRequest")) |
{ |
jsx.tryThis( |
function () { x = new XMLHttpRequest(); }, |
function () { x = null; }); |
} |
// MSXML 3.0- |
x = new ActiveXObject("Microsoft.XMLHTTP"); |
} |
catch (e) |
{ |
x = null; |
} |
@end @*/ |
} |
|
/* IceBrowser */ |
if (!x && typeof window != "undefined" |
&& jsx_object.isMethod(window, "createRequest")) |
{ |
jsx.tryThis( |
function () { x = window.createRequest(); }, |
function () { x = null; }); |
} |
/* Gecko and Opera 8.1+ */ |
if (!x && _isMethod(jsx_global, "XMLHttpRequest")) |
{ |
jsx.tryThis( |
function () { x = new XMLHttpRequest(); }, |
function () { x = null; }); |
} |
|
/* Update cache if unused */ |
if (x && this._xhr === null) |
{ |
this._xhr = x; |
/* IceBrowser */ |
if (!x && typeof window != "undefined" |
&& _isMethod(window, "createRequest")) |
{ |
jsx.tryThis( |
function () { x = window.createRequest(); }, |
function () { x = null; }); |
} |
|
/* Update cache if unused */ |
if (x && this._xhr === null) |
{ |
this._xhr = x; |
} |
|
return x; |
} |
|
return x; |
}, |
return _getXHR; |
}()), |
|
/** |
* Submits the HTTP request. |
* |
* @param {string} sData (optional) |
* The data to form the request body. If the request method is "GET", |
* this argument is ignored and <code>null</code> is used instead (no body). |
* If the request method is "POST", and this value is not provided, the |
* value defaults to that of the <code>data</code> property, which is |
* the empty string if not set different previously. |
* @param {string} sURL (optional) |
* The request URL. If not provided, this value defaults to that of the |
* <code>URL</code> property, which is the empty string if not set |
* different previously. |
* @param {string} sMethod (optional) |
* The request method. If not provided, this value defaults to that of |
* the <code>HTTPRequest.method.GET</code> property, which is "GET". |
* @param {boolean} bAsync (optional) |
* The request is asynchronous if <code>true</code> is passed, synchronous |
* if <code>false</code> is passed. If not provided, this value defaults |
* to that of the <code>async</code> property, which is <code>true</code> |
* if not set different previously. |
* @return {boolean} |
* <code>true</code> (async) or what was returned by the success |
* listener (sync) if the XHR object could be created and |
* <code>IXMLHTTPRequest::send()</code> was successful; |
* <code>false</code> otherwise. Note that for asynchronous handling |
* "successful" does not imply that the server has actually received |
* the message, and responded with an OK status code; only that the |
* method could be called successfully. |
* @function |
*/ |
send: function (sData, sURL, sMethod, bAsync) { |
var |
jsx_object = jsx.object, |
C = this.constructor, |
x = this._getXHR(); |
send: (function () { |
var _isMethod = jsx.object.isMethod; |
|
if (!x || !jsx_object.isMethod(x, "open")) |
/** |
* @param {ArrayBufferView|Blob|Document|string|FormData} sData (optional) |
* The data to form the request body. If the request method is "GET", |
* this argument is ignored and <code>null</code> is used instead (no body). |
* If the request method is "POST", and this value is not provided, the |
* value defaults to that of the <code>data</code> property, which is |
* <code>null</code> if not set differently before. |
* @param {string} sURL (optional) |
* The request URL. If not provided, this value defaults to that of the |
* <code>URL</code> property, which is the empty string if not set |
* different previously. |
* @param {string} sMethod (optional) |
* The request method. If not provided, this value defaults to that of |
* the <code>HTTPRequest.method.GET</code> property, which is "GET". |
* @param {boolean} bAsync (optional) |
* The request is asynchronous if <code>true</code> is passed, synchronous |
* if <code>false</code> is passed. If not provided, this value defaults |
* to that of the <code>async</code> property, which is <code>true</code> |
* if not set different previously. |
* @return {boolean} |
* <code>true</code> (async) or what was returned by the success |
* listener (sync) if the XHR object could be created and |
* <code>IXMLHTTPRequest::send()</code> was successful; |
* <code>false</code> otherwise. Note that for asynchronous handling |
* "successful" does not imply that the server has actually received |
* the message, and responded with an OK status code; only that the |
* method could be called successfully. |
*/ |
function _send (sData, sURL, sMethod, bAsync) |
{ |
return false; |
} |
var |
C = this.constructor, |
x = this._getXHR(); |
|
/* Assume everything goes smoothly from here */ |
var result = true; |
if (!x || !_isMethod(x, "open")) |
{ |
return false; |
} |
|
if (arguments.length < 1) |
{ |
sData = this.data; |
} |
/* Assume everything goes smoothly from here */ |
var result = true; |
|
if (arguments.length < 2) |
{ |
sURL = this.URL; |
} |
if (arguments.length < 1) |
{ |
sData = this.data; |
} |
|
if (arguments.length < 3) |
{ |
sMethod = this.method; |
} |
if (arguments.length < 2) |
{ |
sURL = this.URL; |
} |
|
sMethod = sMethod.toUpperCase(); |
if (arguments.length < 3) |
{ |
sMethod = this.method; |
} |
|
var bGET = (sMethod == C.method.GET); |
sMethod = sMethod.toUpperCase(); |
|
bAsync = (arguments.length > 3) ? !!bAsync : this.async; |
var bGET = (sMethod == C.method.GET); |
|
x.open( |
sMethod, |
sURL |
+ ((bGET && (sData || !this.useCache)) |
? (!/[?&]$/.test(sURL) |
? (sURL.indexOf("?") < 0 ? "?" : "&") |
: "") |
+ sData |
+ (!this.useCache |
? (sData ? "&" : "") |
+ "timestamp=" + (new Date()).getTime() |
bAsync = (arguments.length > 3) ? !!bAsync : this.async; |
|
x.open( |
sMethod, |
sURL |
+ ((bGET && (sData || !this.useCache)) |
? (!/[?&]$/.test(sURL) |
? (sURL.indexOf("?") < 0 ? "?" : "&") |
: "") |
: ""), |
bAsync); |
+ sData |
+ (!this.useCache |
? (sData ? "&" : "") |
+ "timestamp=" + (new Date()).getTime() |
: "") |
: ""), |
bAsync); |
|
var me = this; |
var me = this; |
|
if (jsx_object.isMethod(x, "setRequestHeader")) |
{ |
/* NOTE: Failure to call this method is _not_ considered a fatal error. */ |
jsx.tryThis( |
function () { |
x.setRequestHeader("Content-Type", me.requestType); |
if (_isMethod(x, "setRequestHeader")) |
{ |
/* NOTE: Failure to call this method is _not_ considered a fatal error. */ |
jsx.tryThis( |
function () { |
x.setRequestHeader("Content-Type", me.requestType); |
|
if (!this.useCache) |
{ |
this.setRequestHeaders({ |
"If-Modified-Since": (new Date(0)).toUTCString() |
}); |
if (!this.useCache) |
{ |
this.setRequestHeaders({ |
"If-Modified-Since": (new Date(0)).toUTCString() |
}); |
} |
|
var requestHeaders = me.requestHeaders; |
var names = jsx.object.getKeys(requestHeaders); |
for (var i = 0, len = names.length; i < len; ++i) |
{ |
var name = names[i]; |
x.setRequestHeader(name, requestHeaders[name]); |
} |
} |
); |
} |
|
var _hasOwnProperty = jsx.object._hasOwnProperty; |
var requestHeaders = me.requestHeaders; |
this._handledSuccess = this._handledError = false; |
|
for (var name in requestHeaders) |
{ |
if (_hasOwnProperty(requestHeaders, name)) |
if (bAsync) |
{ |
if (typeof x.onload != "undefined") |
{ |
x.onload = function (response) { |
if (!this._handledSuccess) |
{ |
x.setRequestHeader(name, requestHeaders[name]); |
return me.successListener(response); |
} |
} |
}; |
} |
); |
} |
|
if (bAsync) |
{ |
x.onreadystatechange = (function(x2) { |
return function () { |
// alert(x.readyState); |
// alert(x.status); |
if (typeof x.onerror != "undefined") |
{ |
x.onerror = function (response) { |
if (!this._handledError) |
{ |
return this.errorListener(response); |
} |
}; |
} |
|
// console.log("readyState = %i, status = %i", x.readyState, x.status); |
// console.log(C.status.OK_EXPR); |
|
if (jsx_object.isMethod(me._responseListener)) |
x.onreadystatechange = (function (x2) { |
function _onReadyStateChange () |
{ |
me._responseListener(x2); |
if (_isMethod(me._responseListener)) |
{ |
me._responseListener(x2); |
} |
} |
|
/* Let the garbage collector handle this per the closure */ |
// if (x2.readyState == C.readyState.COMPLETED) |
// { |
// x2 = null; |
// } |
}; |
}(x)); |
} |
return _onReadyStateChange; |
}(x)); |
} |
|
jsx.tryThis( |
function () { x.send(bGET ? null : (sData || me.data)); }, |
function () { result = false; me.errorListener(x); }); |
jsx.tryThis( |
function () { x.send(bGET ? null : (sData || me.data)); }, |
function () { result = false; me.errorListener(x); }); |
|
if (!bAsync) |
{ |
if (jsx_object.isMethod(this._responseListener)) |
if (!bAsync) |
{ |
result = this._responseListener(x); |
if (_isMethod(this._responseListener)) |
{ |
result = this._responseListener(x); |
} |
|
/* Handle stopped servers */ |
// jsx.tryThis( |
// function () { |
// if (C.status.OK_EXPR.test(x.status)) { |
// result = true; |
// } |
// } |
// ); |
|
/* TODO: Is this error-prone? */ |
// x = null; |
} |
|
/* Handle stopped servers */ |
// jsx.tryThis( |
// function () { |
// if (C.status.OK_EXPR.test(x.status)) { |
// result = true; |
// } |
// } |
// ); |
|
/* TODO: Is this error-prone? */ |
// x = null; |
return result; |
} |
|
return result; |
} |
return _send; |
}()) |
}; |
|
/** |
854,7 → 859,39 |
* @constructor |
*/ |
jsx.net.http.ResponseListener = function (sCode) { |
return Function("x", sCode + "" || ""); |
var |
Request = jsx.net.http.Request, |
oStatus = Request.status; |
|
return (sCode |
? Function("x", String(sCode)) |
: /** |
* @param {XMLHttpRequest} x |
*/ |
function (x) { |
if (x.readyState === Request.readyState.COMPLETED) |
{ |
var reqStatus = x.status; |
if (oStatus.OK_EXPR.test(reqStatus)) |
{ |
if (typeof this.successListener == "function" |
&& !this._handledSuccess) |
{ |
this._handledSuccess = true; |
return this.successListener(x); |
} |
} |
else if (oStatus.FAILED_EXPR.test(reqStatus)) |
{ |
if (typeof this.errorListener == "function" |
&& !this._handledError) |
{ |
this._handledError = true; |
this.errorListener(x); |
} |
} |
} |
}); |
}; |
|
/* Usage: */ |