From 0daf7223d08e2da983179e37e6c422abe90d6b82 Mon Sep 17 00:00:00 2001
From: jaubourg <aubourg.julian@gmail.com>
Date: Tue, 21 Dec 2010 13:06:41 +0100
Subject: [PATCH] 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.

---
 src/ajax.js              |    9 ++-
 src/transports/jsonp.js  |   14 ++--
 src/transports/script.js |    2 +-
 src/transports/xhr.js    |    2 +-
 src/xhr.js               |  195 ++++++++++++++++++++++------------------------
 5 files changed, 104 insertions(+), 118 deletions(-)

diff --git a/src/ajax.js b/src/ajax.js
index 3f4f732..258694c 100644
--- a/src/ajax.js
+++ b/src/ajax.js
@@ -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
diff --git a/src/transports/jsonp.js b/src/transports/jsonp.js
index d9e77f2..6c9fb70 100644
--- a/src/transports/jsonp.js
+++ b/src/transports/jsonp.js
@@ -11,12 +11,14 @@ 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];
+	var transportDataType = s.dataTypes[ 0 ];
+	
+	s.dataTypes[ 0 ] = "json";
 	
 	if ( s.jsonp ||
 		transportDataType === "jsonp" ||
@@ -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 ) {
 		
diff --git a/src/transports/script.js b/src/transports/script.js
index fe38735..ebc2302 100644
--- a/src/transports/script.js
+++ b/src/transports/script.js
@@ -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 ) {
diff --git a/src/transports/xhr.js b/src/transports/xhr.js
index 783ee46..978f6c2 100644
--- a/src/transports/xhr.js
+++ b/src/transports/xhr.js
@@ -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 ) {
diff --git a/src/xhr.js b/src/xhr.js
index 8e9a2b0..208a734 100644
--- a/src/xhr.js
+++ b/src/xhr.js
@@ -86,14 +86,9 @@ jQuery.xhr = function( _native ) {
 		if ( data && s.processData && typeof data != "string" ) {
 			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,100 +601,18 @@ jQuery.xhr = function( _native ) {
 	return xhr;
 };
 
-jQuery.extend(jQuery.xhr, {
-	
-	// 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,
-			i,
-			start = 0,
-			length = args.length,
-			dataTypes = [ "*" ],
-			functors = [],
-			functor,
-			first,
-			append,
-			list,
-			transports = jQuery.ajaxSettings.transports;
-			
-		if ( length ) {
-				
-			if ( ! isFunction( args[ 0 ] ) ) {
-				
-				dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
-				start = 1;
-				
-			}
-			
-			if ( dataTypes.length && start < length ) {
-				
-				for ( i = start; i < length; i++ ) {
-					functor = args[i];
-					if ( isFunction(functor) ) {
-						functors.push( functor );
-					}
-				}
-						
-				if ( functors.length ) {
-							
-					jQuery.each ( dataTypes, function( _ , dataType ) {
-						
-						first = /^\+/.test( dataType );
-						
-						if (first) {
-							dataType = dataType.substr(1);
-						}
-						
-						if ( dataType !== "" ) {
-						
-							append = Array.prototype[ first ? "unshift" : "push" ];
-							
-							list = transports[ dataType ];
-					
-							jQuery.each ( functors, function( _ , functor ) {
-									
-								if ( ! list ) {
-									
-									list = transports[ dataType ] = [ functor ];
-									
-								} else {
-									
-									append.call( list , functor );
-								}
-							} );
-						}
-									
-					} );
-				}
-			}
-		}
-		
-		return this;
-	}
-
-	
-});
-
-// Select a transport given options
-function selectTransport( s ) {
+// Execute or select from functions in a given structure of options
+function xhr_selectOrExecute( structure , s ) {
 
 	var dataTypes = s.dataTypes,
 		transportDataType,
-		transportsList,
-		transport,
+		list,
+		selected,
 		i,
 		length,
 		checked = {},
-		flag;
+		flag,
+		noSelect = structure !== "transports";
 		
 	function initSearch( dataType ) {
 
@@ -709,9 +622,9 @@ function selectTransport( s ) {
 			
 			checked[ dataType ] = 1;
 			transportDataType = dataType;
-			transportsList = s.transports[ dataType ];
+			list = s[ structure ][ dataType ];
 			i = -1;
-			length = transportsList ? transportsList.length : 0 ;
+			length = list ? list.length : 0 ;
 		}
 
 		return flag;
@@ -719,7 +632,7 @@ function selectTransport( s ) {
 	
 	initSearch( dataTypes[ 0 ] );
 
-	for ( i = 0 ; ! transport && i <= length ; i++ ) {
+	for ( i = 0 ; ( noSelect || ! selected ) && i <= length ; i++ ) {
 		
 		if ( i === length ) {
 			
@@ -727,21 +640,95 @@ function selectTransport( s ) {
 			
 		} else {
 
-			transport = transportsList[ i ]( s , determineDataType );
+			selected = list[ 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 ) ) {
+			if ( typeof( selected ) === "string" &&
+				initSearch( selected ) ) {
 
-				dataTypes.unshift( transport );
-				transport = 0;
+				dataTypes.unshift( selected );
+				selected = 0;
 			}
 		}
 	}
 
-	return transport;
+	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 = [],
+		first,
+		append,
+		list;
+		
+	if ( length ) {
+		
+		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 ( dLength && start < length ) {
+			
+			functors = sliceFunc.call( args , start );
+			
+			length -= start;
+					
+			for( i = 0 ; i < dLength ; i++ ) {
+				
+				dataType = dataTypes[ i ];
+				
+				first = /^\+/.test( dataType );
+				
+				if (first) {
+					dataType = dataType.substr(1);
+				}
+				
+				if ( dataType !== "" ) {
+				
+					append = Array.prototype[ first ? "unshift" : "push" ];
+					
+					list = structure[ dataType ] = structure[ dataType ] || [];
+			
+					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 );
+	};
+} );
 	
 // Utility function that handles dataType when response is received
 // (for those transports that can give text or xml responses)
-- 
1.7.10.4