]> source.dussan.org Git - jquery.git/commitdiff
Fixes #9887: ajax now supports circular references into objects passed as context...
authorjaubourg <j@ubourg.net>
Sat, 23 Jul 2011 00:10:17 +0000 (02:10 +0200)
committerjaubourg <j@ubourg.net>
Sat, 23 Jul 2011 00:10:17 +0000 (02:10 +0200)
src/ajax.js
test/unit/ajax.js

index 087f2febfb9ff856ddbfccba02fb051a871f52b9..77659e11873f43b856cfbaac507fee7ef145160e 100644 (file)
@@ -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" );
index 334339227ab6432e5082d10a8eeec54d8dc94cdd..6af56db4fa52057fa8479b4f7de4290a55402d2d 100644 (file)
@@ -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;