I got a JavaScript error when trying to remove an image - some debugging traced the problem to onUserExit, which couldn't split options.internalURLs, because the value was missing:

Drupal.settings.content_lock.internal_urls

The DB table "variable" has a handful of settings, which correspond (e.g. DB field name "content_lock_unload_js_message" corresponds to JS variable "Drupal.settings.content_lock.unload_js_message".

I updated using Drush, and can find no reference to creating the setting "internal_urls" within the latest 1.3 code

Comments

ohnobinki’s picture

Status: Active » Postponed (maintainer needs more info)

What does the jQuery.extend(Drupal.settings, …); line look like in the HTML on that page? What URI were you accessing when this happened?

The code in onUserExit.js only gets initialized when content_lock_init.js is added to a page. Whenever content_lock_init.js is loaded on a page, it should be impossible for Drupal.settings.content_lock.internal_urls to be unset.

I cannot reproduce the problem, please provide details on how to reproduce this bug.

ClaudeS-1’s picture

This is the URL I'm on
admin#overlay=node/627/edit%3Fdestination%3Dadmin/content/node
It's just the standard edit page for a node.

This error occurs when I try to remove an image from an image field:

options.internalURLs.split is not a function
var myInternalURLs = options.internalURLs.split("|");

Here is the relevant part of jQuery.extend(Drupal.settings, …);

"content_lock":{"nid":"627","ajax_key":"960643425","token":"GW2RZBOeyrJHnqRkF0sQdr3FU6X7fwr6kECdtE1ibfg","unload_js_message_enable":1,"internal_urls":"node\/627\/edit","internal_forms":"form.node-form","unload_js_message":"If you proceed, ALL of your changes will be lost."}
"internal_urls":"node\/627\/edit"

Using firebug, I can see that there is an object internalURLs which is an array with 2 items:
["node/627/edit", "node/627/edit"]

Has the internalURLs variable changed from a pipe-separated string to an array in the latest release? I've cleared all caches in case the problem is stale JS, but it didn't help.

intu.cz’s picture

I confirm I also have the same problem, preventing me from adding more values to a field with multiple values.

The same message appears in Firebug:

options.internalURLs.split is not a function
var myInternalURLs = options.internalURLs.split("|");

connected with the file sites/all/modules/content_lock/js/onUserExit.js?m2dqkl line 111.

ohnobinki’s picture

Status: Postponed (maintainer needs more info) » Active

OK, I'm able to reproduce it.

I think it has to do with how Drupal updates the Drupal.settings javascript variable with new data from AJAX requests, such as those it makes when uploading an image to an image field.

liam morland’s picture

Status: Active » Needs work
StatusFileSize
new584 bytes

I have been working on this for some time and have not found anything in core which would cause this problem. However, the attached patch fixes the problem by patching content_lock_init.js.

liam morland’s picture

Status: Needs work » Needs review
vurt’s picture

The version 6.x-2.8 is also affected (6.x-2.6 is still working).

The patch (#5) fixes the problem for 6.x-2.8

mpotter’s picture

Status: Needs review » Reviewed & tested by the community

This also fixed the issue in 7.x-1.3 for us. Without this patch a lot of ajax stuff was broken (removing images, adding new items to multivalue fields, etc). This patch really needs to be committed.

mikefyfer’s picture

Also fixed in 7.x-1.3 for me. Hope the patch gets committed. thanks!

julien.reulos’s picture

Hi,
No matter if I apply the patch or not, with the module activated I am not able to add a new item to a multivalue field of textareas anymore. the bug only occurs when I check "Use javascript to detect leaving the node form".

Firebug for Firefox debugging:

cache[id] is undefined
[Break On This Error] 	

cache[ id ].toJSON = jQuery.noop;

in jquery.js?v=1.5.1 (line 1387)

Firebug for Chromium debugging:

Uncaught TypeError: Cannot set property 'toJSON' of undefined jquery.js:1387
jQuery.extend.data jquery.js:1387
jQuery.extend._data jquery.js:1515
jQuery.event.add jquery.js:2181
jQuery.each.jQuery.fn.(anonymous function) jquery.js:3037
jQuery.each.jQuery.fn.(anonymous function) jquery.js:3287
Drupal.behaviors.content_lock.attach content_lock_init.js:26
Drupal.attachBehaviors drupal.js:55
jQuery.extend.each jquery.js:633
Drupal.attachBehaviors drupal.js:53
Drupal.ajax.commands.insert ajax.js:542
Drupal.ajax.success ajax.js:400
Drupal.ajax.ajax.options.success ajax.js:164
$.fn.ajaxSubmit.options.success jquery.form.js:150
cb jquery.form.js:401

Line 26 of content_lock_init.js has this:

/* Prevent submitting the node form from being interpreted as "leaving the page" */
  jQuery(Drupal.settings.content_lock.internal_forms).submit(function () {
liam morland’s picture

@#10 That looks like a different problem and should have its own issue.

julien.reulos’s picture

Yep, sorry, testing with a fresh Drupal 7.14 instalation, I could check that Content Lock and this patch are working well. It seems that my problem is related to a incompatibility between jQuery Update module and CKeditor module.

ohnobinki’s picture

Title: Drupal.settings.content_lock.internal_urls missing - causes errors » Drupal.settings.content_lock.internal_urls is array instead of string, breaks JavaScript when used with file.module's AJAX
Assigned: Unassigned » ohnobinki
Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.41 KB

The error is in file.module line 286 where array_merge_recursive() is used instead of drupal_array_merge_deep_array(). The latter function is the standard Drupal way of performing JavaScript Drupal.settings serialization; it is used in drupal_pre_render_scripts() (for D7 this code is in drupal_get_js()). When drupal_array_merge_deep_array() merges arrays, it replaces existing settings with more recently-added settings. In contrast, array_merge_recursive() will create an array containing both the original setting's value and the newer definitions.

Now that we know why this bug is experienced for the file field and not for a normal page load, we can better look at seeing the limitations in content_lock.module and possible workarounds. Somehow, there are two settings for Drupal.settings.content_lock.internal_urls; this means that content_lock called drupal_add_js() with the same argument twice. Adding code into _content_lock_add_unload_js() to avoid calling drupal_add_js() a second time results in fixing the particular error discussed in this bug. Also, after some more debugging, it appears that _content_lock_add_unload_js() is only called twice for the AJAX image upload -- not on a normal page load. It does make sense to avoid such redundant calls to drupal_add_js(), so I think I'll add a workaround which protects against that. But the core bug (to be filed/found) does need fixing and I should do some investigation into why _content_lock_add_unload_js() is being called multiple when it is on a form that is being submitted.

ohnobinki’s picture

Title: Drupal.settings.content_lock.internal_urls is array instead of string, breaks JavaScript when used with file.module's AJAX » Drupal.settings.content_lock.internal_urls is array instead of string, breaks file.module's JavaScript
ohnobinki’s picture

ohnobinki’s picture

The workaround was committed to the 6.x-2.x branch after being made drupal-6 compatible at 7faf1b2. Releases with this fix for all versions coming "soon" ;-).

ohnobinki’s picture

Status: Needs review » Fixed

Fixed in 6.x-2.9 and 7.x-1.4.

Sorry for taking so long on this. Don't forget to help get the core issue, #1356170: Remove all uses of array_merge_recursive, or document why they are being used instead of NestedArray::mergeDeep(), fixed.

Status: Fixed » Closed (fixed)

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

mrconnerton’s picture

Version: 7.x-1.3 » 7.x-2.0
Issue summary: View changes

@ohnobinki can you clarify if this should be working on it's own in 7.x-1.4 or if a backport patch from #1356170: Remove all uses of array_merge_recursive, or document why they are being used instead of NestedArray::mergeDeep() is required?

edit: Version changed on it's own btw