Fixes #4964. Adds a statusCode object together with a new statusCode method on the...
[jquery.git] / src / ajax.js
index c307ba5..a2ef439 100644 (file)
@@ -265,6 +265,8 @@ jQuery.extend({
                        // Deferreds
                        deferred = jQuery.Deferred(),
                        completeDeferred = jQuery._Deferred(),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
                        // Headers (they are sent all at once)
                        requestHeaders = {},
                        // Response headers
@@ -365,17 +367,10 @@ jQuery.extend({
                                // Stored success
                                success,
                                // Stored error
-                               error = statusText;
-
-                       // If not timeout, force a jQuery-compliant status text
-                       if ( statusText != "timeout" ) {
-                               statusText = ( status >= 200 && status < 300 ) ?
-                                       "success" :
-                                       ( status === 304 ? "notmodified" : "error" );
-                       }
+                               error;
 
                        // If successful, handle type chaining
-                       if ( statusText === "success" || statusText === "notmodified" ) {
+                       if ( status >= 200 && status < 300 || status === 304 ) {
 
                                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                                if ( s.ifModified ) {
@@ -391,12 +386,20 @@ jQuery.extend({
                                        }
                                }
 
-                               if ( s.ifModified && statusText === "notmodified" ) {
+                               // If not modified
+                               if ( status === 304 ) {
 
-                                       success = null;
+                                       // Set the statusText accordingly
+                                       statusText = "notmodified";
+                                       // Mark as a success
                                        isSuccess = 1;
 
+                               // If we have data
                                } else {
+
+                                       // Set the statusText accordingly
+                                       statusText = "success";
+
                                        // Chain data conversions and determine the final value
                                        // (if an exception is thrown in the process, it'll be notified as an error)
                                        try {
@@ -487,17 +490,20 @@ jQuery.extend({
                                                success = response;
                                                isSuccess = 1;
 
+                                       // If an exception was thrown
                                        } catch(e) {
 
+                                               // We have a parsererror
                                                statusText = "parsererror";
                                                error = "" + e;
 
                                        }
                                }
 
-                       } else { // if not success, mark it as an error
+                       // if not success, mark it as an error
+                       } else {
 
-                                       error = error || statusText;
+                                       error = statusText = statusText || "error";
 
                                        // Set responseText if needed
                                        if ( response ) {
@@ -516,6 +522,9 @@ jQuery.extend({
                                deferred.fireReject( callbackContext , [ jXHR , statusText , error ] );
                        }
 
+                       // Status-dependent callbacks
+                       jXHR.statusCode( statusCode );
+
                        if ( s.global ) {
                                globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) ,
                                                [ jXHR , s , isSuccess ? success : error ] );
@@ -539,6 +548,28 @@ jQuery.extend({
                jXHR.error = jXHR.fail;
                jXHR.complete = completeDeferred.done;
 
+               // Status-dependent callbacks
+               jXHR.statusCode = function( map ) {
+                       if ( map ) {
+                               var resolved = jXHR.isResolved(),
+                                       tmp;
+                               if ( resolved || jXHR.isRejected() ) {
+                                       tmp = map[ jXHR.status ];
+                                       if ( tmp ) {
+                                               if ( map === statusCode ) {
+                                                       delete statusCode[ jXHR.status ];
+                                               }
+                                               jXHR[ resolved ? "done" : "fail" ]( tmp );
+                                       }
+                               } else {
+                                       for( tmp in map ) {
+                                               statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ];
+                                       }
+                               }
+                       }
+                       return this;
+               };
+
                // Remove hash character (#7531: and string promotion)
                s.url = ( "" + s.url ).replace( rhash , "" );