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; 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({ jQuery.fn.extend({
load: function( url, params, callback ) { load: function( url, params, callback ) {
if ( typeof url !== "string" && _load ) { if ( typeof url !== "string" && _load ) {
@ -279,22 +295,15 @@ jQuery.extend({
// with both ajaxSettings and settings fields. // with both ajaxSettings and settings fields.
// If target is omitted, writes into ajaxSettings. // If target is omitted, writes into ajaxSettings.
ajaxSetup: function( target, settings ) { ajaxSetup: function( target, settings ) {
if ( !settings ) { if ( settings ) {
// Only one parameter, we extend ajaxSettings // Building a settings object
settings = target; ajaxExtend( target, jQuery.ajaxSettings );
target = jQuery.extend( true, jQuery.ajaxSettings, settings );
} else { } else {
// target was provided, we extend into it // Extending ajaxSettings
jQuery.extend( true, target, jQuery.ajaxSettings, settings ); settings = target;
} target = jQuery.ajaxSettings;
// 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 ];
}
} }
ajaxExtend( target, settings );
return target; return target;
}, },
@ -352,6 +361,15 @@ jQuery.extend({
// Parse text as xml // Parse text as xml
"text xml": jQuery.parseXML "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
} }
}, },

View File

@ -2076,6 +2076,22 @@ test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
ok( success, "document.location did not generate exception" ); 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() { test( "jQuery.ajax - statusCode" , function() {
var count = 12; var count = 12;