Renamed jQuery.xhr.bindTransport as jQuery.xhr.transport. Generalized the implementation and made prefilters use the same logic. Cleaned up code and removed as many loops and each as possible.

This commit is contained in:
jaubourg 2010-12-21 13:06:41 +01:00 committed by unknown
parent 56628c7adf
commit 0daf7223d0
5 changed files with 104 additions and 118 deletions

View file

@ -206,15 +206,16 @@ jQuery.extend({
// 2) These are called:
// * BEFORE asking for a transport
// * AFTER param serialization (s.data is a string if s.processData is true)
// 3) They MUST be order agnostic
prefilters: [],
// 3) key is the dataType
// 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: {
},
transports: {},
// Checkers
// 1) key is dataType

View file

@ -11,13 +11,15 @@ jQuery.ajaxSettings.jsonpCallback = function() {
// Normalize jsonp queries
// 1) put callback parameter in url or data
// 2) ensure transportDataType is json
// 2) sneakily ensure transportDataType is json
// 3) ensure options jsonp is always provided so that jsonp requests are always
// json request with the jsonp option set
jQuery.xhr.prefilter( function(s) {
jQuery.xhr.prefilter("json jsonp", function(s) {
var transportDataType = s.dataTypes[ 0 ];
s.dataTypes[ 0 ] = "json";
if ( s.jsonp ||
transportDataType === "jsonp" ||
transportDataType === "json" && ( jsre.test(s.url) || typeof(s.data) === "string" && jsre.test(s.data) ) ) {
@ -34,14 +36,10 @@ jQuery.xhr.prefilter( function(s) {
s.url = url;
s.data = data;
s.dataTypes[0] = "json";
}
});
// Bind transport to json dataType
jQuery.xhr.bindTransport("json", function(s) {
}).transport("json", function(s) {
if ( s.jsonp ) {

View file

@ -17,7 +17,7 @@ jQuery.extend( true, jQuery.ajaxSettings , {
} );
// Bind script tag hack transport
jQuery.xhr.bindTransport("script", function(s) {
jQuery.xhr.transport("script", function(s) {
// Handle cache special case
if ( s.cache === undefined ) {

View file

@ -10,7 +10,7 @@ var // Next fake timer id
xhrUnloadAbortMarker = [];
jQuery.xhr.bindTransport( function( s , determineDataType ) {
jQuery.xhr.transport( function( s , determineDataType ) {
// Cross domain only allowed if supported through XMLHttpRequest
if ( ! s.crossDomain || jQuery.support.cors ) {

View file

@ -87,13 +87,8 @@ jQuery.xhr = function( _native ) {
data = s.data = jQuery.param( data , s.traditional );
}
// Apply option prefilters
for ( i = 0; i < prefilters.length; i++ ) {
prefilters[i](s);
}
// Get internal
internal = selectTransport( s );
internal = jQuery.xhr.prefilter( s ).transport( s );
// Re-actualize url & data
url = s.url;
@ -606,52 +601,103 @@ jQuery.xhr = function( _native ) {
return xhr;
};
jQuery.extend(jQuery.xhr, {
// Execute or select from functions in a given structure of options
function xhr_selectOrExecute( structure , s ) {
// Add new prefilter
prefilter: function (functor) {
if ( isFunction(functor) ) {
jQuery.ajaxSettings.prefilters.push( functor );
}
return this;
},
// Bind a transport to one or more dataTypes
bindTransport: function () {
var args = arguments,
var dataTypes = s.dataTypes,
transportDataType,
list,
selected,
i,
length,
checked = {},
flag,
noSelect = structure !== "transports";
function initSearch( dataType ) {
flag = transportDataType !== dataType && ! checked[ dataType ];
if ( flag ) {
checked[ dataType ] = 1;
transportDataType = dataType;
list = s[ structure ][ dataType ];
i = -1;
length = list ? list.length : 0 ;
}
return flag;
}
initSearch( dataTypes[ 0 ] );
for ( i = 0 ; ( noSelect || ! selected ) && i <= length ; i++ ) {
if ( i === length ) {
initSearch( "*" );
} else {
selected = list[ i ]( s , determineDataType );
// If we got redirected to another dataType
// Search there (if not in progress or already tried)
if ( typeof( selected ) === "string" &&
initSearch( selected ) ) {
dataTypes.unshift( selected );
selected = 0;
}
}
}
return noSelect ? jQuery.xhr : selected;
}
// Add an element to one of the xhr structures in ajaxSettings
function xhr_addElement( structure , args ) {
var i,
j,
start = 0,
length = args.length,
dataTypes = [ "*" ],
dLength = 1,
dataType,
functors = [],
functor,
first,
append,
list,
transports = jQuery.ajaxSettings.transports;
list;
if ( length ) {
if ( ! isFunction( args[ 0 ] ) ) {
first = jQuery.type( args[ 0 ] );
if ( first === "object" ) {
return xhr_selectOrExecute( structure , args[ 0 ] );
}
structure = jQuery.ajaxSettings[ structure ];
if ( first !== "function" ) {
dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
dLength = dataTypes.length;
start = 1;
}
if ( dataTypes.length && start < length ) {
if ( dLength && start < length ) {
for ( i = start; i < length; i++ ) {
functor = args[i];
if ( isFunction(functor) ) {
functors.push( functor );
}
}
functors = sliceFunc.call( args , start );
if ( functors.length ) {
length -= start;
jQuery.each ( dataTypes, function( _ , dataType ) {
for( i = 0 ; i < dLength ; i++ ) {
dataType = dataTypes[ i ];
first = /^\+/.test( dataType );
@ -663,85 +709,26 @@ jQuery.extend(jQuery.xhr, {
append = Array.prototype[ first ? "unshift" : "push" ];
list = transports[ dataType ];
list = structure[ dataType ] = structure[ dataType ] || [];
jQuery.each ( functors, function( _ , functor ) {
if ( ! list ) {
list = transports[ dataType ] = [ functor ];
} else {
append.call( list , functor );
for ( j = 0; j < length; j++ ) {
append.call( list , functors[ j ] );
}
}
}
}
}
return jQuery.xhr;
}
// Install prefilter & transport methods
jQuery.each( [ "prefilter" , "transport" ] , function( _ , name ) {
_ = name + "s";
jQuery.xhr[ name ] = function() {
return xhr_addElement( _ , arguments );
};
} );
}
} );
}
}
}
return this;
}
});
// Select a transport given options
function selectTransport( s ) {
var dataTypes = s.dataTypes,
transportDataType,
transportsList,
transport,
i,
length,
checked = {},
flag;
function initSearch( dataType ) {
flag = transportDataType !== dataType && ! checked[ dataType ];
if ( flag ) {
checked[ dataType ] = 1;
transportDataType = dataType;
transportsList = s.transports[ dataType ];
i = -1;
length = transportsList ? transportsList.length : 0 ;
}
return flag;
}
initSearch( dataTypes[ 0 ] );
for ( i = 0 ; ! transport && i <= length ; i++ ) {
if ( i === length ) {
initSearch( "*" );
} else {
transport = transportsList[ i ]( s , determineDataType );
// If we got redirected to another dataType
// Search there (if not in progress or already tried)
if ( typeof( transport ) === "string" &&
initSearch( transport ) ) {
dataTypes.unshift( transport );
transport = 0;
}
}
}
return transport;
}
// Utility function that handles dataType when response is received
// (for those transports that can give text or xml responses)