Fixes #9887: ajax now supports circular references into objects passed as context. Prefilter and transport developpers should add their own custom option into flatOptions when needed. Unit test added.

This commit is contained in:
jaubourg 2011-07-23 02:10:17 +02:00
parent 28b470d7d3
commit e6a99fdb0e
2 changed files with 50 additions and 16 deletions

View 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" );

View 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;