I had an interesting Drupal bug. One of my forms has some javascript that turns an file field widget into an image gallery. When the form fails validation, the page reloads with the invalid fields highlighted (excellent Drupal feature). Unfortunately the Drupal.settings array is reloaded (using jQuery.extend) without clearing the previous array. This has the affect of changing an array of strings and ints into an array of arrays.


button_remote_url
"Choose something from the URL"

button_remove
"Change picture"

button_upload
"Upload your own"

error_ajax
"Error: unable to communicate with server"

error_noimages
"Error: No images received from server"

image_height
200

image_path
"/legacy/sites/all/modules/iconfetch/images"

- becomes -


button_remote_url
["Choose something from the URL", "Choose something from the URL"]

button_remove
["Change picture", "Change picture"]

button_upload
["Upload your own", "Upload your own"]

error_ajax
["Error: unable to communicate with server", "Error: unable to communicate with server"]

error_noimages
["Error: No images received from server", "Error: No images received from server"]

image_height
[200, 200]

image_path
["/legacy/sites/all/modules/iconfetch/images", "/legacy/sites/all/modules/iconfetch/images"]

image_spinner
["ajaxload-34-0.gif", "ajaxload-34-0.gif"]

status_fetching
["Status: Making icons", "Status: Making icons"]

status_invalid
["Status: awaiting a valid URL", "Status: awaiting a valid URL"]

status_pending
["Status: please enter a URL first", "Status: please enter a URL first"]

which clearly breaks every line of JS looking for an atomic value at say Drupal.settings.iconfetch.icon_height.

The solution is very simple, a 3 line function that hunts for pairs (nested arrays) and strips them back to singletons.


function fixDoubleDrupalSettings() {
for (var key in Drupal.settings.iconfetch) {
// if it's an array (follow double-page load merge)
if (Drupal.settings.iconfetch[key] instanceof Array) {
// take the first key
Drupal.settings.iconfetch[key] = Drupal.settings.iconfetch[key][0];
}
}
}