xhr: function() {
return new window.XMLHttpRequest();
},
- xhrResponseFields: {
- xml: "XML",
- text: "Text",
- json: "JSON"
- },
-
+
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
json: "application/json, text/javascript",
"*": "*/*"
},
-
+
autoDataType: {
xml: /xml/,
html: /html/,
json: /json/
},
-
+
// Prefilters
// 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
// 2) These are called:
// 4) the catchall symbol "*" can be used
// 5) execution will start with transport dataType and THEN continue down to "*" if needed
prefilters: {},
-
+
// Transports bindings
// 1) key is the dataType
// 2) the catchall symbol "*" can be used
// 3) selection will start with transport dataType and THEN go to "*" if needed
transports: {},
-
+
// Checkers
// 1) key is dataType
// 2) they are called to control successful response
// 3) error throws is used as error data
dataCheckers: {
-
+
// Check if data is a string
"text": function(data) {
if ( typeof data != "string" ) {
jQuery.error("typeerror");
}
},
-
+
// Check if xml has been properly parsed
"xml": function(data) {
var documentElement = data ? data.documentElement : data;
}
}
},
-
+
// List of data converters
// 1) key format is "source_type => destination_type" (spaces required)
// 2) the catchall symbol "*" can be used for source_type
dataConverters: {
-
+
// Convert anything to text
"* => text": function(data) {
return "" + data;
},
-
+
// Text to html (no transformation)
"text => html": function(data) {
return data;
},
-
+
// Evaluate text as a json expression
"text => json": jQuery.parseJSON,
-
+
// Parse text as xml
"text => xml": function(data) {
var xml, parser;
rts = /([?&])_=[^&]*/,
rurl = /^(\w+:)?\/\/([^\/?#]+)/,
- sliceFunc = Array.prototype.slice,
-
- isFunction = jQuery.isFunction;
+ sliceFunc = Array.prototype.slice;
// Creates a jQuery xhr object
jQuery.xhr = function( _native ) {
if ( data && s.processData && typeof data != "string" ) {
data = s.data = jQuery.param( data , s.traditional );
}
-
+
// Get internal
internal = jQuery.xhr.prefilter( s ).transport( s );
requestHeaders[ i.toLowerCase() ] = headers[ i ];
}
}
-
+
callbackContext = s.context || s;
globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
// (if an exception is thrown in the process, it'll be notified as an error)
try {
- function checkData(data) {
- if ( data !== undefined ) {
- var testFunction = s.dataCheckers[srcDataType];
- if ( isFunction( testFunction ) ) {
- testFunction(data);
- }
- }
- }
-
- function convertData (data) {
- var conversionFunction = dataConverters[srcDataType+" => "+destDataType] ||
- dataConverters["* => "+destDataType],
- noFunction = ! isFunction( conversionFunction );
- if ( noFunction ) {
- if ( srcDataType != "text" && destDataType != "text" ) {
- // We try to put text inbetween
- var first = dataConverters[srcDataType+" => text"] ||
- dataConverters["* => text"],
- second = dataConverters["text => "+destDataType] ||
- dataConverters["* => "+destDataType],
- areFunctions = isFunction( first ) && isFunction( second );
- if ( areFunctions ) {
- conversionFunction = function (data) {
- return second( first ( data ) );
- };
- }
- noFunction = ! areFunctions;
- }
- if ( noFunction ) {
- jQuery.error( "no data converter between " + srcDataType + " and " + destDataType );
- }
-
- }
- return conversionFunction(data);
- }
-
- var dataTypes = s.dataTypes,
- i,
- length,
- data = response,
+ var i,
+ current,
+ prev,
+ checker,
+ conv1,
+ conv2,
+ oneConv,
+ convertion,
+ dataTypes = s.dataTypes,
+ dataCheckers = s.dataCheckers,
dataConverters = s.dataConverters,
- srcDataType,
- destDataType,
- responseTypes = s.xhrResponseFields;
+ dataFilter = s.dataFilter,
+ responses = {
+ "xml": "XML",
+ "text": "Text"
+ };
+
+ for( i = 0 ; i < dataTypes.length ; i++ ) {
- for ( i = 0, length = dataTypes.length ; i < length ; i++ ) {
-
- destDataType = dataTypes[i];
+ current = dataTypes[ i ];
- if ( !srcDataType ) { // First time
+ if ( i ) {
- // Copy type
- srcDataType = destDataType;
- // Check
- checkData(data);
- // Apply dataFilter
- if ( isFunction( s.dataFilter ) ) {
- data = s.dataFilter(data, s.dataType);
- // Recheck data
- checkData(data);
- }
-
- } else { // Subsequent times
+ prev = dataTypes[ i - 1 ];
- // handle auto
- // JULIAN: for reasons unknown to me === doesn't work here
- if (destDataType == "*") {
-
- destDataType = srcDataType;
+ if ( prev === "*" ) {
- } else if ( srcDataType != destDataType ) {
+ prev = current;
- // Convert
- data = convertData(data);
- // Copy type & check
- srcDataType = destDataType;
- checkData(data);
+ } else if ( current !== "*" && prev !== current ) {
+
+ oneConv = conv1 =
+ dataConverters[ ( conversion = prev + " => " + current ) ] ||
+ dataConverters[ "* => " + current ];
+ if ( ! oneConv && prev !== "text" && current !== "text" ) {
+ conv1 = dataConverters[ prev + " => text" ] || dataConverters[ "* => text" ];
+ conv2 = dataConverters[ "text => " + current ];
+ }
+ if ( oneConv || conv1 && conv2 ) {
+ response = oneConv ? conv1( response ) : conv2( conv1( response ) );
+ } else {
+ throw "no " + conversion;
+ }
}
-
}
-
- // Copy response into the xhr if it hasn't been already
- var responseDataType,
- responseType = responseTypes[srcDataType];
- if ( responseType ) {
-
- responseDataType = srcDataType;
-
- } else {
-
- responseType = responseTypes[ responseDataType = "text" ];
-
+ checker = dataCheckers[ current ];
+
+ if ( response != null && checker ) {
+ checker( response );
}
-
- if ( responseType !== 1 ) {
- xhr[ "response" + responseType ] = data;
- responseTypes[ responseType ] = 1;
+
+ if ( responses[ current ] ) {
+ xhr[ "response" + responses[ current ] ] = response;
+ responses[ current ] = 0;
}
+ if ( ! i && dataFilter ) {
+
+ response = dataFilter( response );
+
+ dataTypes = s.dataTypes;
+ dataFilter = 0;
+ i--;
+ }
}
// We have a real success
- success = data;
+ success = response;
isSuccess = 1;
} catch(e) {
// Ready state change
function setState( value ) {
xhr.readyState = value;
- if ( isFunction( xhr.onreadystatechange ) ) {
+ if ( jQuery.isFunction( xhr.onreadystatechange ) ) {
xhr.onreadystatechange();
}
}