We can add javascript or javascript settings in drupal by calling drupal_add_js(), in some cases you may want to remove some javascript you add earlier.
There is no built in function like drupal_remove_js() to do that.
The same applies to javascript settings which are stored Drupal.settings, what if we want to remove some settings that are added in previous processes? Adding a setting multiple times might have some unexpected consequences.
Javascript settings are used when you want to pass server data to javascript in the front end. For example if I want to pass a pair of geo coordinates from database to map initialization function in javascript, I would like to save coordinates in Drupal.settings then in behavior attach function to use them.
Adding server data to javascript settings:
// set the central point $lonlat = array( 'lon' => $lon, 'lat' => $lat, ); // add it to Drupal.settings drupal_add_js(array(‘mySetting’ => array('center'=> $lonlat)), array('type' => 'setting'));
All javascripts and settings of a request are stored in a static data store($javascript), here is what happens when a javascript setting is added by drupal_add_js(),
case 'setting': // All JavaScript settings are placed in the header of the page with // the library weight so that inline scripts appear afterwards. $javascript['settings']['data'][] = $data; break;
As you can see drupal_add_js() does not check if the same settings has already existed, it just simply appends it to $javascript['settings']['data'] array, adding a setting multiple times will end up copies of settings in static javascript array $javascript.
This only happens to settings, for javascripts it is keyed by javascript name, it will not have multiple copies.
When javascript is finally output to page in drupal_get_js():
case 'setting': $js_element = $element; $js_element['#value_prefix'] = $embed_prefix; $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");"; $js_element['#value_suffix'] = $embed_suffix; $output .= theme('html_tag', array('element' => $js_element)); break;
It does do some array merging, so you will not get two copies in Drupal.settings, but it is hard to predict which version of setting in $javascript actually made its way to Drupal.settings. and it is not an ideal situation to have multiple copies in $javascript in the first place.
Ideally drupal_add_js() would have prevented this by checking the existence of a settings before it is added.
Also We cannot find any built in functions that allow us to modify static $javascript. Here I want to share with you a function that I did to remove a customer setting from $javascript.
function _remove_js_settings($settingKey) { $javascript = &drupal_static('drupal_add_js'); foreach ($javascript['settings']['data'] as $key => $item) { if (array_key_exists($settingKey, $item)) { unset($javascript['settings']['data'][$key]); } } return $javascript; }
The only trick is calling &drupal_static() rather than calling drupal_add_js() as the former gives you a pointer and later is giving same list as a copy, the list you get from drupal_add_js() is a copy of static data, so changes to the copy are not persisted to static data store.
I am sure from this example you can work out how to remove javascript or even change css settings from its static cache, bearing in mind that css is stored at ‘drupal_add_css’