]> source.dussan.org Git - jquery.git/commitdiff
Rewrote the data conversion logic in ajax. Should be cleaner and faster.
authorjaubourg <aubourg.julian@gmail.com>
Tue, 21 Dec 2010 15:58:52 +0000 (16:58 +0100)
committerunknown <Julian@.(none)>
Fri, 24 Dec 2010 11:59:02 +0000 (12:59 +0100)
src/ajax.js
src/xhr.js

index 258694c81d50f74460fe7aa564e4e27dbe0c53c8..25ac8cf0c4c3c09b30c049e42b07b0fff302a420 100644 (file)
@@ -181,12 +181,7 @@ jQuery.extend({
                xhr: function() {
                        return new window.XMLHttpRequest();
                },
-               xhrResponseFields: {
-                       xml: "XML",
-                       text: "Text",
-                       json: "JSON"
-               },
-                       
+
                accepts: {
                        xml: "application/xml, text/xml",
                        html: "text/html",
@@ -194,13 +189,13 @@ jQuery.extend({
                        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:
@@ -210,26 +205,26 @@ jQuery.extend({
                // 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;
@@ -241,25 +236,25 @@ jQuery.extend({
                                }
                        }
                },
-               
+
                // 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;
index 208a734b491ff70356f02940a9b1dc9c374c73fb..1993e0b5d1fe4fb19c60483f5c504af157f4d269 100644 (file)
@@ -7,9 +7,7 @@ var rquery_xhr = /\?/,
        rts = /([?&])_=[^&]*/,
        rurl = /^(\w+:)?\/\/([^\/?#]+)/,
        
-       sliceFunc = Array.prototype.slice,
-       
-       isFunction = jQuery.isFunction;
+       sliceFunc = Array.prototype.slice;
        
 // Creates a jQuery xhr object
 jQuery.xhr = function( _native ) {
@@ -147,7 +145,7 @@ jQuery.xhr = function( _native ) {
                                requestHeaders[ i.toLowerCase() ] = headers[ i ];
                        }                       
                }
-                       
+               
                callbackContext = s.context || s;
                globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
                
@@ -224,111 +222,76 @@ jQuery.xhr = function( _native ) {
                                // (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
-                                                       
-                                                       // Copy type
-                                                       srcDataType = destDataType;
-                                                       // Check
-                                                       checkData(data);
-                                                       // Apply dataFilter
-                                                       if ( isFunction( s.dataFilter ) ) {
-                                                               data = s.dataFilter(data, s.dataType);
-                                                               // Recheck data
-                                                               checkData(data);
-                                                       }
+                                               if ( i ) {
                                                        
-                                               } 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) {
@@ -406,7 +369,7 @@ jQuery.xhr = function( _native ) {
        // Ready state change
        function setState( value ) {
                xhr.readyState = value;
-               if ( isFunction( xhr.onreadystatechange ) ) {
+               if ( jQuery.isFunction( xhr.onreadystatechange ) ) {
                        xhr.onreadystatechange();
                }
        }