/*
* Portions of this file are based on pieces of Yahoo User Interface Library
* Copyright (c) 2007, Yahoo! Inc. All rights reserved.
* YUI licensed under the BSD License:
* http://developer.yahoo.net/yui/license.txt
*/
Ext.lib.Ajax = function() {
var activeX = ['MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'];
// private
function setHeader(o) {
var conn = o.conn,
prop;
function setTheHeaders(conn, headers){
for (prop in headers) {
if (headers.hasOwnProperty(prop)) {
conn.setRequestHeader(prop, headers[prop]);
}
}
}
if (pub.defaultHeaders) {
setTheHeaders(conn, pub.defaultHeaders);
}
if (pub.headers) {
setTheHeaders(conn, pub.headers);
pub.headers = null;
}
}
// private
function createExceptionObject(tId, callbackArg, isAbort) {
return {
tId : tId,
status : isAbort ? -1 : 0,
statusText : isAbort ? 'transaction aborted' : 'communication failure',
argument : callbackArg
};
}
// private
function initHeader(label, value) {
(pub.headers = pub.headers || {})[label] = value;
}
// private
function createResponseObject(o, callbackArg) {
var headerObj = {},
headerStr,
conn = o.conn;
try {
headerStr = o.conn.getAllResponseHeaders();
Ext.each(headerStr.split('\n'), function(v){
var t = v.split(':');
headerObj[t[0]] = t[1];
});
} catch(e) {}
return {
tId : o.tId,
status : conn.status,
statusText : conn.statusText,
getResponseHeader : headerObj,
getAllResponseHeaders : headerStr,
responseText : conn.responseText,
responseXML : conn.responseXML,
argument : callbackArg
};
}
// private
function handleTransactionResponse(o, callback, isAbort) {
var status = o.conn.status,
httpStatus,
responseObject;
if (callback) {
// Not sure the point of the try catch...?
//try {
httpStatus = status || 13030;
//} catch(e) {
// httpStatus = 13030;
//}
if (httpStatus >= 200 && httpStatus < 300) {
responseObject = createResponseObject(o, callback.argument);
if (callback.success) {
callback.success.call(callback.scope, responseObject);
}
} else {
if ([12002, 12029, 12030, 12031, 12152, 13030].indexOf( httpStatus ) > -1) {
responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
if (callback.failure) {
callback.failure.call(callback.scope, responseObject);
}
} else {
responseObject = createResponseObject(o, callback.argument);
if (callback.failure) {
callback.failure.call(callback.scope, responseObject);
}
}
}
}
o = o.conn = responseObject = null;
}
// private
function handleReadyState(o, callback){
callback = callback || {};
var conn = o.conn,
tId = o.tId,
poll = pub.poll,
cbTimeout = callback.timeout || null;
if (cbTimeout) {
pub.timeout[tId] = setTimeout(function() {
pub.abort(o, callback, true);
}, cbTimeout);
}
poll[tId] = setInterval(
function() {
if (conn && conn.readyState == 4) {
clearInterval(poll[tId]);
poll[tId] = null;
if (cbTimeout) {
clearTimeout(pub.timeout[tId]);
pub.timeout[tId] = null;
}
handleTransactionResponse(o, callback);
}
},
pub.pollInterval);
}
// private
function asyncRequest(method, uri, callback, postData) {
var o = getConnectionObject() || null;
if (o) {
o.conn.open(method, uri, true);
if (pub.useDefaultXhrHeader) {
initHeader('X-Requested-With', pub.defaultXhrHeader);
}
if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers['Content-Type'])){
initHeader('Content-Type', pub.defaultPostHeader);
}
if (pub.defaultHeaders || pub.headers) {
setHeader(o);
}
handleReadyState(o, callback);
o.conn.send(postData || null);
}
return o;
}
// private
function getConnectionObject() {
var o;
try {
if (o = createXhrObject(pub.transactionId)) {
pub.transactionId++;
}
} catch(e) {
} finally {
return o;
}
}
// private
function createXhrObject(transactionId) {
var http;
try {
http = new XMLHttpRequest();
} catch(e) {
for (var i = 0; i < activeX.length; ++i) {
try {
http = new ActiveXObject(activeX[i]);
break;
} catch(e) {}
}
} finally {
return {conn : http, tId : transactionId};
}
}
var pub = {
request : function(method, uri, cb, data, options) {
if(options){
var me = this,
xmlData = options.xmlData,
jsonData = options.jsonData;
Ext.applyIf(me, options);
if(xmlData || jsonData){
initHeader('Content-Type', xmlData ? 'text/xml' : 'application/json');
data = xmlData || Ext.encode(jsonData);
}
}
return asyncRequest(method || options.method || "POST", uri, cb, data);
},
serializeForm : function(form) {
var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
hasSubmit = false,
encoder = encodeURIComponent,
element,
options,
name,
val,
data = '',
type;
Ext.each(fElements, function(element) {
name = element.name;
type = element.type;
if (!element.disabled && name){
if(/select-(one|multiple)/i.test(type)){
Ext.each(element.options, function(opt) {
if (opt.selected) {
data += String.format("{0}={1}&",
encoder(name),
(opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttribute('value') !== null) ? opt.value : opt.text);
}
});
} else if(!/file|undefined|reset|button/i.test(type)) {
if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){
data += encoder(name) + '=' + encoder(element.value) + '&';
hasSubmit = /submit/i.test(type);
}
}
}
});
return data.substr(0, data.length - 1);
},
useDefaultHeader : true,
defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
useDefaultXhrHeader : true,
defaultXhrHeader : 'XMLHttpRequest',
poll : {},
timeout : {},
pollInterval : 50,
transactionId : 0,
// This is never called - Is it worth exposing this?
// setProgId : function(id) {
// activeX.unshift(id);
// },
// This is never called - Is it worth exposing this?
// setDefaultPostHeader : function(b) {
// this.useDefaultHeader = b;
// },
// This is never called - Is it worth exposing this?
// setDefaultXhrHeader : function(b) {
// this.useDefaultXhrHeader = b;
// },
// This is never called - Is it worth exposing this?
// setPollingInterval : function(i) {
// if (typeof i == 'number' && isFinite(i)) {
// this.pollInterval = i;
// }
// },
// This is never called - Is it worth exposing this?
// resetDefaultHeaders : function() {
// this.defaultHeaders = null;
// },
abort : function(o, callback, isTimeout) {
var me = this,
tId = o.tId,
isAbort = false;
if (me.isCallInProgress(o)) {
o.conn.abort();
clearInterval(me.poll[tId]);
me.poll[tId] = null;
if (isTimeout) {
me.timeout[tId] = null;
}
handleTransactionResponse(o, callback, (isAbort = true));
}
return isAbort;
},
isCallInProgress : function(o) {
return o.conn && !{1:1,4:4}[o.conn.readyState];
}
};
return pub;
}();