Permalink
Browse files

Fixes #9887: ajax now supports circular references into objects passe…

…d as context. Prefilter and transport developpers should add their own custom option into flatOptions when needed. Unit test added.
  • Loading branch information...
1 parent 28b470d commit e6a99fdb0ee9e0fd7552d5de8bc4acbe982e98b7 @jaubourg jaubourg committed Jul 23, 2011
Showing with 50 additions and 16 deletions.
  1. +34 −16 src/ajax.js
  2. +16 −0 test/unit/ajax.js
View
@@ -135,6 +135,22 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
return selection;
}
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var key, deep,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+ for( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+}
+
jQuery.fn.extend({
load: function( url, params, callback ) {
if ( typeof url !== "string" && _load ) {
@@ -278,23 +294,16 @@ jQuery.extend({
// Creates a full fledged settings object into target
// with both ajaxSettings and settings fields.
// If target is omitted, writes into ajaxSettings.
- ajaxSetup: function ( target, settings ) {
- if ( !settings ) {
- // Only one parameter, we extend ajaxSettings
- settings = target;
- target = jQuery.extend( true, jQuery.ajaxSettings, settings );
+ ajaxSetup: function( target, settings ) {
+ if ( settings ) {
+ // Building a settings object
+ ajaxExtend( target, jQuery.ajaxSettings );
} else {
- // target was provided, we extend into it
- jQuery.extend( true, target, jQuery.ajaxSettings, settings );
- }
- // Flatten fields we don't want deep extended
- for( var field in { context: 1, url: 1 } ) {
- if ( field in settings ) {
- target[ field ] = settings[ field ];
- } else if( field in jQuery.ajaxSettings ) {
- target[ field ] = jQuery.ajaxSettings[ field ];
- }
+ // Extending ajaxSettings
+ settings = target;
+ target = jQuery.ajaxSettings;
}
+ ajaxExtend( target, settings );
return target;
},
@@ -352,6 +361,15 @@ jQuery.extend({
// Parse text as xml
"text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ context: true,
+ url: true
}
},
@@ -563,7 +581,7 @@ jQuery.extend({
completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
// Handle the global AJAX counter
if ( !( --jQuery.active ) ) {
jQuery.event.trigger( "ajaxStop" );
View
@@ -2076,6 +2076,22 @@ test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
ok( success, "document.location did not generate exception" );
});
+test( "jQuery.ajax - Context with circular references (#9887)", 2, function () {
+ var success = false,
+ context = {};
+ context.field = context;
+ try {
+ success = !jQuery.ajax( "non-existing", {
+ context: context,
+ beforeSend: function() {
+ ok( this === context, "context was not deep extended" );
+ return false;
+ }
+ });
+ } catch (e) { console.log( e ); }
+ ok( success, "context with circular reference did not generate an exception" );
+});
+
test( "jQuery.ajax - statusCode" , function() {
var count = 12;

0 comments on commit e6a99fd

Please sign in to comment.