When running Drupal.extend twice and supplying an object with string properties that already exists in the page scope (for instance, when ajax-loading a page including a call to drupal_add_js($script, 'setting'), the function attempts to recurse over string properties, thinking they are arrays or objects. This is caused by the following piece of code:

  for (var i in obj) {
    if (this[i]) {
        ...
    }
  }

I've attached a patch which seems to solve this issue without raising any side effect.

CommentFileSizeAuthor
drupal.js_.patch476 byteselectricmonk
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

electricmonk’s picture

Status: Active » Needs review
marcus_clements’s picture

I encountered this problem trying to use lightbox2 to display node edit forms.
The error has disappeared in Firefox and I haven't spotted any side effects.

Thanks for the patch.

Sadly doesn't seem to have solved the problems I'm having with IE7 and node/edit forms in lightbox, which I'd hoped it would...

cheers

Marcus

marcus_clements’s picture

In case this helps someone...

This is a symptom which for me was part of a much larger problem which is making js and css available to modal lightbox forms. I'm using a tpl file to control what gets loaded into the lightbox, but because it is a node/add form, other modules need to add css and js for various functions (taxonomy ajax) etc. Because some of the css and js already exists in the main page "below" I have to be careful only to load those scripts necessary for the node/edit form which *dont* already exist.

With a create content link in a block that can be called from any page - this may be a pit of vipers...

electricmonk’s picture

This may help - I created this function in order to do just that, only load the additional scripts loaded by an AJAX load operation. It's basically a copy of jQuery's $.load() function which, before applying the new scripts to the page, removes all existing ones from the loaded page.

(function($) 
{
	/**
	 * Reimplementation of AJAX load to filter existing scripts
	 */
	$.fn.loadAndProcessScripts = function(url, params, callback)
	{

		var off = url.indexOf(" ");
		if ( off >= 0 ) {
			var selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		callback = callback || function(){};

		// Default to a GET request
		var type = "GET";

		// If the second parameter was provided
		if ( params )
			// If it's a function
			if ( jQuery.isFunction( params ) ) {
				// We assume that it's the callback
				callback = params;
				params = null;

			// Otherwise, build a param string
			} else {
				params = jQuery.param( params );
				type = "POST";
			}

		var self = this;

		// Request the remote document
		$.ajax({
			url: url,
			type: type,
			dataType: "html",
			data: params,
			complete: function(res, status){
				// If successful, inject the HTML into all the matched elements
				if ( status == "success" || status == "notmodified" )
				{
					// See if a selector was specified
					var newContent = jQuery( selector ?
						// Create a dummy div to hold the results
						$("<div/>")
							// inject the contents of the document in, removing the scripts
							// to avoid any 'Permission Denied' errors in IE
							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))

							// Locate the specified elements
							.find(selector) :

						// If not, just inject the full result
						res.responseText );
				
					var removed = [];
					
					// remove all existing scripts from the new content
					$('script[src]').each(function(i, script)
					{
						var src = script.src.toLowerCase().substring(script.src.lastIndexOf('/'));

						var removedScript = newContent.find('script[src*=\'' + src + '\']');
						
						if (removedScript.length > 0)
						{
							removed.push(removedScript[0]);
						}
						
						removedScript.remove();
					});
					
					//window.console.log('removed: ', removed);
					//window.console.log('injecting: ', newContent.find('script[src]'));
					
					try
					{
						self.html(newContent);
					}
					catch (e)
					{
						
					}

				}

				self.each( callback, [res.responseText, status, res] );
			}
		});
		return this;		
	}	
})(jQuery); 
electricmonk’s picture

I would like to apply this patch against the 5.x core. Anyone objects?

drumm’s picture

Status: Needs review » Fixed

Committed to 5.x.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.