diff --git a/includes/common.inc b/includes/common.inc index 72fcf76..8792d34 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -3959,36 +3959,41 @@ function drupal_add_js($data = NULL, $options = NULL) { $options['weight'] += count($javascript) / 1000; if (isset($data)) { - // Add jquery.js and drupal.js, as well as the basePath setting, the - // first time a JavaScript file is added. + // Set options for JavaScript settings. if (empty($javascript)) { + $javascript['settings'] = array( + 'data' => array(), + 'type' => 'setting', + 'scope' => 'header', + 'group' => JS_LIBRARY, + 'every_page' => TRUE, + 'weight' => 0, + ); + } + + // Add jquery.js, jquery.once.js and drupal.js, as well as basic settings + // such (basePath and pathPrefix), the first time JavaScript code is added. + // (Don't add these if only JavaScript settings have been added.) + if ($options['type'] != 'setting' && !isset($javascript['misc/drupal.js'])) { // url() generates the prefix using hook_url_outbound_alter(). Instead of // running the hook_url_outbound_alter() again here, extract the prefix // from url(). url('', array('prefix' => &$prefix)); - $javascript = array( - 'settings' => array( - 'data' => array( - array('basePath' => base_path()), - array('pathPrefix' => empty($prefix) ? '' : $prefix), - ), - 'type' => 'setting', - 'scope' => 'header', - 'group' => JS_LIBRARY, - 'every_page' => TRUE, - 'weight' => 0, - ), - 'misc/drupal.js' => array( - 'data' => 'misc/drupal.js', - 'type' => 'file', - 'scope' => 'header', - 'group' => JS_LIBRARY, - 'every_page' => TRUE, - 'weight' => -1, - 'preprocess' => TRUE, - 'cache' => TRUE, - 'defer' => FALSE, - ), + $basic_settings = array( + array('basePath' => base_path()), + array('pathPrefix' => empty($prefix) ? '' : $prefix), + ); + $javascript['settings']['data'] = array_merge($basic_settings, $javascript['settings']['data']); + $javascript['misc/drupal.js'] = array( + 'data' => 'misc/drupal.js', + 'type' => 'file', + 'scope' => 'header', + 'group' => JS_LIBRARY, + 'every_page' => TRUE, + 'weight' => -1, + 'preprocess' => TRUE, + 'cache' => TRUE, + 'defer' => FALSE, ); // Register all required libraries. drupal_add_library('system', 'jquery', TRUE); diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index 5f69673..5681e70 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -1202,6 +1202,12 @@ class JavaScriptTestCase extends DrupalWebTestCase { */ function testAddSetting() { $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); + $this->assertEqual(280342800, $javascript['settings']['data'][0]['dries'], t('JavaScript setting is set correctly.')); + $this->assertEqual('rocks', $javascript['settings']['data'][0]['drupal'], t('The other JavaScript setting is set correctly.')); + + // When JavaScript code is added, the basePath and pathPrefix settings + // are prepended. + $javascript = drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline'); $this->assertEqual(280342800, $javascript['settings']['data'][2]['dries'], t('JavaScript setting is set correctly.')); $this->assertEqual('rocks', $javascript['settings']['data'][2]['drupal'], t('The other JavaScript setting is set correctly.')); } @@ -1231,26 +1237,75 @@ class JavaScriptTestCase extends DrupalWebTestCase { drupal_add_js(array('commonTestArray' => array('key' => 'commonTestNewValue')), 'setting'); $javascript = drupal_get_js('header'); - $this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header returns basePath setting.')); - $this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header includes jQuery.')); - $this->assertTrue(strpos($javascript, 'pathPrefix') > 0, t('Rendered JavaScript header returns pathPrefix setting.')); - // Test whether drupal_add_js can be used to override a previous setting. + // When adding only settings through drupal_add_js(), none of the basic + // JavaScript settings or basic JavaScript files should be added. + $this->assertTrue(strpos($javascript, 'basePath') === FALSE, t('Rendered JavaScript header does not return basePath setting.')); + $this->assertTrue(strpos($javascript, 'pathPrefix') === FALSE, t('Rendered JavaScript header does not return pathPrefix setting.')); + $this->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, t('Rendered JavaScript header does not include Drupal\'s JavaScript library.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, t('Rendered JavaScript header does not include jQuery.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.once.js') === FALSE, t('Rendered JavaScript header does not include jQuery Once.')); + + // Test whether drupal_add_js() can be used to override a previous setting. $this->assertTrue(strpos($javascript, 'commonTestShouldAppear') > 0, t('Rendered JavaScript header returns custom setting.')); $this->assertTrue(strpos($javascript, 'commonTestShouldNotAppear') === FALSE, t('drupal_add_js() correctly overrides a custom setting.')); - // Test whether drupal_add_js can be used to add numerically indexed values - // to an array. + // Test whether drupal_add_js() can be used to add numerically indexed + // values to an array. $array_values_appear = strpos($javascript, 'commonTestValue0') > 0 && strpos($javascript, 'commonTestValue1') > 0 && strpos($javascript, 'commonTestValue2') > 0; $this->assertTrue($array_values_appear, t('drupal_add_js() correctly adds settings to the end of an indexed array.')); - // Test whether drupal_add_js can be used to override the entry for an + // Test whether drupal_add_js() can be used to override the entry for an // existing key in an associative array. $associative_array_override = strpos($javascript, 'commonTestNewValue') > 0 && strpos($javascript, 'commonTestOldValue') === FALSE; $this->assertTrue($associative_array_override, t('drupal_add_js() correctly overrides settings within an associative array.')); } /** + * Test drupal_add_js()'s behavior of adding the basic JavaScript only when + * code has been added (just adding settings should not trigger the addition + * of JavaScript files). + */ + function testBasicJS() { + // When adding only settings through drupal_add_js(), none of the basic + // JavaScript settings or basic JavaScript files should be added. + drupal_add_js(array('foo' => 'bar'), 'setting'); + $javascript = drupal_get_js('header'); + $this->assertTrue(strpos($javascript, 'basePath') === FALSE, t('Rendered JavaScript header does not return basePath setting.')); + $this->assertTrue(strpos($javascript, 'pathPrefix') === FALSE, t('Rendered JavaScript header does not return pathPrefix setting.')); + $this->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, t('Rendered JavaScript header does not include Drupal\'s JavaScript library.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, t('Rendered JavaScript header does not include jQuery.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.once.js') === FALSE, t('Rendered JavaScript header does not include jQuery Once.')); + + // When adding at least one piece of JavaScript code (either 'inline', + // 'file' or 'external'), add the basic JavaScript settings and basic + // JavaScript files. + // Case: 'file'. + drupal_static_reset('drupal_add_js'); + drupal_static_reset('drupal_add_library'); + drupal_add_js('misc/collapse.js'); + $javascript = drupal_get_js('header'); + $this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header does not return basePath setting.')); + $this->assertTrue(strpos($javascript, 'pathPrefix') > 0, t('Rendered JavaScript header does not return pathPrefix setting.')); + $this->assertTrue(strpos($javascript, 'misc/drupal.js') > 0, t('Rendered JavaScript header does not include Drupal\'s JavaScript library.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header does not include jQuery.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.once.js') > 0, t('Rendered JavaScript header does not include jQuery Once.')); + // Case: 'inline'. + drupal_static_reset('drupal_add_js'); + drupal_static_reset('drupal_add_library'); + drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline'); + $javascript = drupal_get_js('header'); + $this->assertTrue(strpos($javascript, 'basePath') > 0, t('Rendered JavaScript header does not return basePath setting.')); + $this->assertTrue(strpos($javascript, 'pathPrefix') > 0, t('Rendered JavaScript header does not return pathPrefix setting.')); + $this->assertTrue(strpos($javascript, 'misc/drupal.js') > 0, t('Rendered JavaScript header does not include Drupal\'s JavaScript library.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header does not include jQuery.')); + $this->assertTrue(strpos($javascript, 'misc/jquery.once.js') > 0, t('Rendered JavaScript header does not include jQuery Once.')); + file_put_contents('/htdocs/test.txt', print_r($javascript, TRUE)); + // Case: 'external'. + // Not tested due to possible unavailability of internet connection. + } + + /** * Test to see if resetting the JavaScript empties the cache. */ function testReset() {