@@ -319,6 +319,7 @@ jQuery.extend({
319
319
username: null,
320
320
password: null,
321
321
cache: null,
322
+ throws: false,
322
323
traditional: false,
323
324
headers: {},
324
325
*/
@@ -480,6 +481,8 @@ jQuery.extend({
480
481
// It is defined here because jslint complains if it is declared
481
482
// at the end of the function (which would be more logical and readable)
482
483
function done ( status , nativeStatusText , responses , headers ) {
484
+ var isSuccess , success , error , response , modified ,
485
+ statusText = nativeStatusText ;
483
486
484
487
// Called once
485
488
if ( state === 2 ) {
@@ -504,25 +507,24 @@ jQuery.extend({
504
507
// Set readyState
505
508
jqXHR . readyState = status > 0 ? 4 : 0 ;
506
509
507
- var isSuccess ,
508
- success ,
509
- error ,
510
- statusText = nativeStatusText ,
511
- response = responses ? ajaxHandleResponses ( s , jqXHR , responses ) : undefined ,
512
- lastModified ,
513
- etag ;
510
+ // Get response data
511
+ if ( responses ) {
512
+ response = ajaxHandleResponses ( s , jqXHR , responses ) ;
513
+ }
514
514
515
515
// If successful, handle type chaining
516
516
if ( status >= 200 && status < 300 || status === 304 ) {
517
517
518
518
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
519
519
if ( s . ifModified ) {
520
520
521
- if ( ( lastModified = jqXHR . getResponseHeader ( "Last-Modified" ) ) ) {
522
- jQuery . lastModified [ ifModifiedKey ] = lastModified ;
521
+ modified = jqXHR . getResponseHeader ( "Last-Modified" ) ;
522
+ if ( modified ) {
523
+ jQuery . lastModified [ ifModifiedKey ] = modified ;
523
524
}
524
- if ( ( etag = jqXHR . getResponseHeader ( "Etag" ) ) ) {
525
- jQuery . etag [ ifModifiedKey ] = etag ;
525
+ modified = jqXHR . getResponseHeader ( "Etag" ) ;
526
+ if ( modified ) {
527
+ jQuery . etag [ ifModifiedKey ] = modified ;
526
528
}
527
529
}
528
530
@@ -535,15 +537,11 @@ jQuery.extend({
535
537
// If we have data
536
538
} else {
537
539
538
- try {
539
- success = ajaxConvert ( s , response ) ;
540
- statusText = "success" ;
541
- isSuccess = true ;
542
- } catch ( e ) {
543
- // We have a parsererror
544
- statusText = "parsererror" ;
545
- error = e ;
546
- }
540
+ isSuccess = ajaxConvert ( s , response ) ;
541
+ statusText = isSuccess . state ;
542
+ success = isSuccess . data ;
543
+ error = isSuccess . error ;
544
+ isSuccess = ! error ;
547
545
}
548
546
} else {
549
547
// We extract error from statusText
@@ -913,86 +911,87 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
913
911
// Chain conversions given the request and the original response
914
912
function ajaxConvert ( s , response ) {
915
913
914
+ var conv , conv2 , current , tmp ,
915
+ // Work with a copy of dataTypes in case we need to modify it for conversion
916
+ dataTypes = s . dataTypes . slice ( ) ,
917
+ prev = dataTypes [ 0 ] ,
918
+ converters = { } ,
919
+ i = 0 ;
920
+
916
921
// Apply the dataFilter if provided
917
922
if ( s . dataFilter ) {
918
923
response = s . dataFilter ( response , s . dataType ) ;
919
924
}
920
925
921
- var dataTypes = s . dataTypes ,
922
- converters = { } ,
923
- i ,
924
- key ,
925
- length = dataTypes . length ,
926
- tmp ,
927
- // Current and previous dataTypes
928
- current = dataTypes [ 0 ] ,
929
- prev ,
930
- // Conversion expression
931
- conversion ,
932
- // Conversion function
933
- conv ,
934
- // Conversion functions (transitive conversion)
935
- conv1 ,
936
- conv2 ;
937
-
938
- // For each dataType in the chain
939
- for ( i = 1 ; i < length ; i ++ ) {
940
-
941
- // Create converters map
942
- // with lowercased keys
943
- if ( i === 1 ) {
944
- for ( key in s . converters ) {
945
- if ( typeof key === "string" ) {
946
- converters [ key . toLowerCase ( ) ] = s . converters [ key ] ;
947
- }
948
- }
926
+ // Create converters map with lowercased keys
927
+ if ( dataTypes [ 1 ] ) {
928
+ for ( conv in s . converters ) {
929
+ converters [ conv . toLowerCase ( ) ] = s . converters [ conv ] ;
949
930
}
931
+ }
932
+
933
+ // Convert to each sequential dataType, tolerating list modification
934
+ for ( ; ( current = dataTypes [ ++ i ] ) ; ) {
935
+
936
+ // There's only work to do if current dataType is non-auto
937
+ if ( current !== "*" ) {
938
+
939
+ // Convert response if prev dataType is non-auto and differs from current
940
+ if ( prev !== "*" && prev !== current ) {
941
+
942
+ // Seek a direct converter
943
+ conv = converters [ prev + " " + current ] || converters [ "* " + current ] ;
950
944
951
- // Get the dataTypes
952
- prev = current ;
953
- current = dataTypes [ i ] ;
954
-
955
- // If current is auto dataType, update it to prev
956
- if ( current === "*" ) {
957
- current = prev ;
958
- // If no auto and dataTypes are actually different
959
- } else if ( prev !== "*" && prev !== current ) {
960
-
961
- // Get the converter
962
- conversion = prev + " " + current ;
963
- conv = converters [ conversion ] || converters [ "* " + current ] ;
964
-
965
- // If there is no direct converter, search transitively
966
- if ( ! conv ) {
967
- conv2 = undefined ;
968
- for ( conv1 in converters ) {
969
- tmp = conv1 . split ( " " ) ;
970
- if ( tmp [ 0 ] === prev || tmp [ 0 ] === "*" ) {
971
- conv2 = converters [ tmp [ 1 ] + " " + current ] ;
972
- if ( conv2 ) {
973
- conv1 = converters [ conv1 ] ;
974
- if ( conv1 === true ) {
975
- conv = conv2 ;
976
- } else if ( conv2 === true ) {
977
- conv = conv1 ;
945
+ // If none found, seek a pair
946
+ if ( ! conv ) {
947
+ for ( conv2 in converters ) {
948
+
949
+ // If conv2 outputs current
950
+ tmp = conv2 . split ( " " ) ;
951
+ if ( tmp [ 1 ] === current ) {
952
+
953
+ // If prev can be converted to accepted input
954
+ conv = converters [ prev + " " + tmp [ 0 ] ] ||
955
+ converters [ "* " + tmp [ 0 ] ] ;
956
+ if ( conv ) {
957
+ // Condense equivalence converters
958
+ if ( conv === true ) {
959
+ conv = converters [ conv2 ] ;
960
+
961
+ // Otherwise, insert the intermediate dataType
962
+ } else if ( converters [ conv2 ] !== true ) {
963
+ current = tmp [ 0 ] ;
964
+ dataTypes . splice ( i -- , 0 , current ) ;
965
+ }
966
+
967
+ break ;
978
968
}
979
- break ;
969
+ }
970
+ }
971
+ }
972
+
973
+ // Apply converter (if not an equivalence)
974
+ if ( conv !== true ) {
975
+
976
+ // Unless errors are allowed to bubble, catch and return them
977
+ if ( conv && s . throws ) {
978
+ response = conv ( response ) ;
979
+ } else {
980
+ try {
981
+ response = conv ( response ) ;
982
+ } catch ( e ) {
983
+ return { state : "parsererror" , error : conv ? e : "No conversion from " + prev + " to " + current } ;
980
984
}
981
985
}
982
986
}
983
987
}
984
- // If we found no converter, dispatch an error
985
- if ( ! ( conv || conv2 ) ) {
986
- jQuery . error ( "No conversion from " + conversion . replace ( " " , " to " ) ) ;
987
- }
988
- // If found converter is not an equivalence
989
- if ( conv !== true ) {
990
- // Convert with 1 or 2 converters accordingly
991
- response = conv ? conv ( response ) : conv2 ( conv1 ( response ) ) ;
992
- }
988
+
989
+ // Update prev for next iteration
990
+ prev = current ;
993
991
}
994
992
}
995
- return response ;
993
+
994
+ return { state : "success" , data : response } ;
996
995
}
997
996
998
997
} ) ( jQuery ) ;
0 commit comments