Moves determineResponse logic into main ajax callback. Puts responseXXX fields definitions into ajaxSettings.

This commit is contained in:
jaubourg 2011-01-20 19:40:51 +01:00
parent 8ad2b31ff6
commit 3dbd600e19
2 changed files with 79 additions and 84 deletions

View file

@ -199,6 +199,11 @@ jQuery.extend({
json: /json/ json: /json/
}, },
responseFields: {
xml: "responseXML",
text: "responseText"
},
// Prefilters // Prefilters
// 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example) // 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
// 2) These are called: // 2) These are called:
@ -231,52 +236,7 @@ jQuery.extend({
// Parse text as xml // Parse text as xml
"text xml": jQuery.parseXML "text xml": jQuery.parseXML
},
// Utility function that handles dataType when response is received
// (for those transports that can give text or xml responses)
determineResponse: function( responses , ct ) {
var s = this,
contents = s.contents,
type,
regexp,
dataTypes = s.dataTypes,
transportDataType = dataTypes[0],
response;
// Auto (xml, json, script or text determined given headers)
if ( ct && transportDataType === "*" ) {
for ( type in contents ) {
if ( ( regexp = contents[ type ] ) && regexp.test( ct ) ) {
transportDataType = dataTypes[0] = type;
break;
}
}
}
// Get response
for( type in responses ) {
if ( type === transportDataType ) {
break;
}
}
// Get final response
response = responses[ type ];
// If it's not the right dataType, handle the dataTypeList
if ( transportDataType !== type ) {
if ( transportDataType === "*" ) {
dataTypes.shift();
}
dataTypes.unshift( type );
}
return response;
} }
}, },
ajaxPrefilter: function( a , b ) { ajaxPrefilter: function( a , b ) {
@ -387,7 +347,7 @@ jQuery.extend({
// Callback for when everything is done // Callback for when everything is done
// It is defined here because jslint complains if it is declared // It is defined here because jslint complains if it is declared
// at the end of the function (which would be more logical and readable) // at the end of the function (which would be more logical and readable)
function done( status , statusText , response , headers) { function done( status , statusText , responses , headers) {
// Called once // Called once
if ( state === 2 ) { if ( state === 2 ) {
@ -398,7 +358,7 @@ jQuery.extend({
state = 2; state = 2;
// Dereference transport for early garbage collection // Dereference transport for early garbage collection
// (no matter how long the jXHR transport will be used // (no matter how long the jXHR object will be used)
transport = undefined; transport = undefined;
// Set readyState // Set readyState
@ -412,20 +372,73 @@ jQuery.extend({
clearTimeout(timeoutTimer); clearTimeout(timeoutTimer);
} }
var // Reference url var // Reference dataTypes and responseFields
url = s.url, dataTypes = s.dataTypes,
// and ifModified status responseFields = s.responseFields,
ifModified = s.ifModified, responseField,
// Is it a success? // Flag to mark as success
isSuccess = 0, isSuccess,
// Stored success // Stored success
success, success,
// Stored error // Stored error
error, error,
// To keep track of statusCode based callbacks // To keep track of statusCode based callbacks
oldStatusCode; oldStatusCode,
// Actual response
response;
// If we got responses:
// - find the right one
// - update dataTypes accordingly
// - set responseXXX accordingly too
if ( responses ) {
var contents = s.contents,
transportDataType = dataTypes[0],
ct,
type,
finalDataType;
// Auto (xml, json, script or text determined given headers)
if ( transportDataType === "*" && ( ct = jXHR.getResponseHeader( "content-type" ) ) ) {
for ( type in contents ) {
if ( contents[ type ] && contents[ type ].test( ct ) ) {
transportDataType = dataTypes[0] = type;
break;
}
}
type = undefined;
}
// Get final dataType
for( type in responses ) {
if ( ! finalDataType && type === transportDataType ) {
finalDataType = type;
}
responseField = responseFields[ type ];
if ( responseField && ! ( responseField in jXHR ) ) {
jXHR[ responseField ] = responses[ type ];
}
}
// If no response with the expected dataType was provided
// Take the last response as a default if it exists
if ( ! finalDataType && type ) {
finalDataType = type;
if ( transportDataType === "*" ) {
dataTypes.shift();
}
dataTypes.unshift( finalDataType );
}
// Get final response
response = responses[ finalDataType ];
}
// If successful, handle type chaining // If successful, handle type chaining
if ( status >= 200 && status < 300 || status === 304 ) { if ( status >= 200 && status < 300 || status === 304 ) {
@ -447,15 +460,12 @@ jQuery.extend({
// If not modified // If not modified
if ( status === 304 ) { if ( status === 304 ) {
// Set the statusText accordingly
statusText = "notmodified"; statusText = "notmodified";
// Mark as a success
isSuccess = 1; isSuccess = 1;
// If we have data // If we have data
} else { } else {
// Set the statusText accordingly
statusText = "success"; statusText = "success";
// Chain data conversions and determine the final value // Chain data conversions and determine the final value
@ -474,14 +484,8 @@ jQuery.extend({
// Conversion functions (when text is used in-between) // Conversion functions (when text is used in-between)
conv1, conv1,
conv2, conv2,
// Local references to dataTypes & converters // Local references to converters
dataTypes = s.dataTypes, converters = s.converters;
converters = s.converters,
// DataType to responseXXX field mapping
responses = {
"xml": "XML",
"text": "Text"
};
// For each dataType in the chain // For each dataType in the chain
for( i = 0 ; i < dataTypes.length ; i++ ) { for( i = 0 ; i < dataTypes.length ; i++ ) {
@ -490,11 +494,9 @@ jQuery.extend({
// If a responseXXX field for this dataType exists // If a responseXXX field for this dataType exists
// and if it hasn't been set yet // and if it hasn't been set yet
if ( responses[ current ] ) { responseField = responseFields[ current ];
// Set it if ( responseField && ! ( responseField in jXHR ) ) {
jXHR[ "response" + responses[ current ] ] = response; jXHR[ responseField ] = response;
// Mark it as set
responses[ current ] = 0;
} }
// If this is not the first element // If this is not the first element
@ -562,13 +564,7 @@ jQuery.extend({
// if not success, mark it as an error // if not success, mark it as an error
} else { } else {
error = statusText = statusText || "error"; error = statusText = statusText || "error";
// Set responseText if needed
if ( response ) {
jXHR.responseText = response;
}
} }
// Set data for the fake xhr object // Set data for the fake xhr object

View file

@ -149,6 +149,12 @@ if ( jQuery.support.ajax ) {
responses = {}, responses = {},
xml = xhr.responseXML; xml = xhr.responseXML;
// Construct response list
if ( xml && xml.documentElement /* #4958 */ ) {
responses.xml = xml;
}
responses.text = xhr.responseText;
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
statusText = xhr.statusText; statusText = xhr.statusText;
@ -184,15 +190,8 @@ if ( jQuery.support.ajax ) {
status status
); );
// Construct response list
if ( xml && xml.documentElement /* #4958 */ ) {
responses.xml = xml;
}
responses.text = xhr.responseText;
// Call complete // Call complete
complete(status,statusText,s.determineResponse( responses, complete(status,statusText,responses,responseHeaders);
xhr.getResponseHeader( "content-type" ) ),responseHeaders);
} }
} }
}; };