diff --git a/includes/batch.inc b/includes/batch.inc index fb13aa58c8fbce0fb81cbfd8c4de36da368df1a5..b65a80452c09a96e26497a5a596181ff63898a0c 100644 --- a/includes/batch.inc +++ b/includes/batch.inc @@ -84,7 +84,7 @@ function _batch_progress_page_js() { // error messages. Only safe strings should be passed in to batch_set(). $current_set = _batch_current_set(); drupal_set_title($current_set['title'], PASS_THROUGH); - drupal_add_js('misc/progress.js', array('type' => 'core', 'cache' => FALSE)); + drupal_add_js('misc/progress.js', array('cache' => FALSE)); $url = url($batch['url'], array('query' => array('id' => $batch['id']))); $js_setting = array( @@ -95,7 +95,7 @@ function _batch_progress_page_js() { ), ); drupal_add_js($js_setting, 'setting'); - drupal_add_js('misc/batch.js', array('type' => 'core', 'cache' => FALSE)); + drupal_add_js('misc/batch.js', array('cache' => FALSE)); $output = '<div id="progress"></div>'; return $output; diff --git a/includes/common.inc b/includes/common.inc index 633ab0f7422bdfdc466aeb00baf6a5054f6dd8c4..5c9cb056923f25b3da08ea799669667a7ef79f6f 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -24,6 +24,22 @@ */ define('SAVED_DELETED', 3); +/** + * The weight of JavaScript libraries, settings or jQuery plugins being + * added to the page. + */ +define('JS_LIBRARY', -100); + +/** + * The default weight of JavaScript being added to the page. + */ +define('JS_DEFAULT', 0); + +/** + * The weight of theme JavaScript code being added to the page. + */ +define('JS_THEME', 100); + /** * Set content for a specified region. * @@ -2085,58 +2101,74 @@ function drupal_clear_css_cache() { * reference to an existing file or as inline code. The following actions can be * performed using this function: * - * - Add a file ('core', 'module' and 'theme'): - * Adds a reference to a JavaScript file to the page. JavaScript files - * are placed in a certain order, from 'core' first, to 'module' and finally - * 'theme' so that files, that are added later, can override previously added - * files with ease. + * - Add a file ('file'): + * Adds a reference to a JavaScript file to the page. * * - Add inline JavaScript code ('inline'): * Executes a piece of JavaScript code on the current page by placing the code * directly in the page. This can, for example, be useful to tell the user that - * a new message arrived, by opening a pop up, alert box etc. + * a new message arrived, by opening a pop up, alert box etc. This should only + * be used for JavaScript which cannot be placed and executed from a file. * * - Add settings ('setting'): * Adds a setting to Drupal's global storage of JavaScript settings. Per-page - * settings are required by some modules to function properly. The settings + * settings are required by some modules to function properly. All settings * will be accessible at Drupal.settings. * * Examples: * @code * drupal_add_js('misc/collapse.js'); - * drupal_add_js('misc/collapse.js', 'module'); + * drupal_add_js('misc/collapse.js', 'file'); + * drupal_add_js('$(document).ready(function(){alert("Hello!");});', 'inline'); * drupal_add_js('$(document).ready(function(){alert("Hello!");});', - * array('type' => 'inline', 'scope' => 'footer') + * array('type' => 'inline', 'scope' => 'footer', 'weight' => 5) * ); * @endcode * * @param $data * (optional) If given, the value depends on the $options parameter: - * - 'core', 'module' or 'theme': Path to the file relative to base_path(). + * - 'file': Path to the file relative to base_path(). * - 'inline': The JavaScript code that should be placed in the given scope. * - 'setting': An array with configuration options as associative array. The - * array is directly placed in Drupal.settings. You might want to wrap your - * actual configuration settings in another variable to prevent the pollution - * of the Drupal.settings namespace. + * array is directly placed in Drupal.settings. All modules should wrap + * their actual configuration settings in another variable to prevent + * the pollution of the Drupal.settings namespace. * @param $options * (optional) A string defining the type of JavaScript that is being added - * in the $data parameter ('core', 'module', 'theme', 'setting', 'inline'), - * or an array which can have any or all of the following keys (these are - * not valid with type => 'setting'): + * in the $data parameter ('file'/'setting'/'inline'), or an array which + * can have any or all of the following keys. JavaScript settings should + * always pass the string 'setting' only. * - type - * The type of JavaScript that should be added to the page. Allowed - * values are 'core', 'module', 'theme', 'inline' and 'setting'. Defaults - * to 'module'. + * The type of JavaScript that is to be added to the page. Allowed + * values are 'file', 'inline' or 'setting'. Defaults to 'file'. * - scope - * The location in which you want to place the script. Possible - * values are 'header' and 'footer'. If your theme implements different - * locations, however, you can also use these. Defaults to 'header'. + * The location in which you want to place the script. Possible values + * are 'header' or 'footer'. If your theme implements different regions, + * however, you can also use these. Defaults to 'header'. + * - weight + * A number defining the order in which the JavaScript is added to the + * page. In some cases, the order in which the JavaScript is presented + * on the page is very important. jQuery, for example, must be added to + * to the page before any jQuery code is run, so jquery.js uses a weight + * of JS_LIBRARY - 2, drupal.js uses a weight of JS_LIBRARY - 1, and all + * following scripts depending on jQuery and Drupal behaviors are simply + * added using the default weight of JS_DEFAULT. + * + * Available constants are: + * - JS_LIBRARY: Any libraries, settings, or jQuery plugins. + * - JS_DEFAULT: Any module-layer JavaScript. + * - JS_THEME: Any theme-layer JavaScript. + * + * If you need to invoke a JavaScript file before any other module's + * JavaScript, for example, you would use JS_DEFAULT - 1. + * Note that inline JavaScripts are simply appended to the end of the + * specified scope (region), so they always come last. * - defer - * If set to TRUE, the defer attribute is set on the <script> tag. - * Defaults to FALSE. This parameter is not used with 'type' => 'setting'. + * If set to TRUE, the defer attribute is set on the <script> tag. + * Defaults to FALSE. * - cache * If set to FALSE, the JavaScript file is loaded anew on every page - * call, that means, it is not cached. Used only when type references + * call, that means, it is not cached. Used only when 'type' references * a JavaScript file. Defaults to TRUE. * - preprocess * Aggregate the JavaScript if the JavaScript optimization setting has @@ -2160,18 +2192,16 @@ function drupal_add_js($data = NULL, $options = NULL, $reset = FALSE) { $options = array(); } $options += array( - 'type' => 'module', - // Default to a header scope only if we're adding some data. - 'scope' => isset($data) ? 'header' : NULL, + 'type' => 'file', + 'weight' => JS_DEFAULT, + 'scope' => 'header', 'cache' => TRUE, 'defer' => FALSE, - 'preprocess' => TRUE + 'preprocess' => TRUE, + 'data' => $data, ); // Preprocess can only be set if caching is enabled. $options['preprocess'] = $options['cache'] ? $options['preprocess'] : FALSE; - $type = $options['type']; - $scope = $options['scope']; - unset($options['type'], $options['scope']); // Request made to reset the JavaScript added so far. if ($reset) { @@ -2183,47 +2213,54 @@ function drupal_add_js($data = NULL, $options = NULL, $reset = FALSE) { // first time a Javascript file is added. if (empty($javascript)) { $javascript = array( - 'header' => array( - 'core' => array( - 'misc/jquery.js' => array('cache' => TRUE, 'defer' => FALSE, 'preprocess' => TRUE), - 'misc/drupal.js' => array('cache' => TRUE, 'defer' => FALSE, 'preprocess' => TRUE), - ), - 'module' => array(), - 'theme' => array(), - 'setting' => array( + 'settings' => array( + 'data' => array( array('basePath' => base_path()), ), - 'inline' => array(), - ) + 'type' => 'setting', + 'scope' => 'header', + 'weight' => JS_LIBRARY, + ), + 'misc/jquery.js' => array( + 'data' => 'misc/jquery.js', + 'type' => 'file', + 'scope' => 'header', + 'weight' => JS_LIBRARY - 2, + 'cache' => TRUE, + 'defer' => FALSE, + 'preprocess' => TRUE, + ), + 'misc/drupal.js' => array( + 'data' => 'misc/drupal.js', + 'type' => 'file', + 'scope' => 'header', + 'weight' => JS_LIBRARY - 1, + 'cache' => TRUE, + 'defer' => FALSE, + 'preprocess' => TRUE, + ), ); } - if (isset($scope) && !isset($javascript[$scope])) { - $javascript[$scope] = array('core' => array(), 'module' => array(), 'theme' => array(), 'setting' => array(), 'inline' => array()); - } - - if (isset($type) && isset($scope) && !isset($javascript[$scope][$type])) { - $javascript[$scope][$type] = array(); - } - - switch ($type) { + switch ($options['type']) { case 'setting': - $javascript[$scope][$type][] = $data; + // 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; + case 'inline': - $javascript[$scope][$type][] = array('code' => $data, 'defer' => $options['defer']); + $javascript[] = $options; break; - default: - $javascript[$scope][$type][$data] = $options; - } - } - if (isset($scope)) { - return isset($javascript[$scope]) ? $javascript[$scope] : array(); - } - else { - return $javascript; + case 'file': + // Files must keep their name as the associative key so the same + // JavaScript files can not be added twice. + $javascript[$options['data']] = $options; + break; + } } + return $javascript; } /** @@ -2248,18 +2285,24 @@ function drupal_get_js($scope = 'header', $javascript = NULL) { if ((!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') && function_exists('locale_update_js_files')) { locale_update_js_files(); } - if (!isset($javascript)) { - $javascript = drupal_add_js(NULL, array('scope' => $scope)); + $javascript = drupal_add_js(); } - if (empty($javascript)) { return ''; } + // Filter out elements of the given scope. + $items = array(); + foreach ($javascript as $item) { + if ($item['scope'] == $scope) { + $items[] = $item; + } + } + $output = ''; $preprocessed = ''; - $no_preprocess = array('core' => '', 'module' => '', 'theme' => ''); + $no_preprocess = ''; $files = array(); $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); $directory = file_directory_path(); @@ -2279,29 +2322,28 @@ function drupal_get_js($scope = 'header', $javascript = NULL) { $embed_prefix = "\n<!--//--><![CDATA[//><!--\n"; $embed_suffix = "\n//--><!]]>\n"; - foreach ($javascript as $type => $data) { - if (!$data) continue; + // Sort the JavaScript by weight so that it appears in the correct order. + uasort($items, 'drupal_sort_weight'); - switch ($type) { + // Loop through the JavaScript to construct the rendered output. + foreach ($items as $item) { + switch ($item['type']) { case 'setting': - $output .= '<script type="text/javascript">' . $embed_prefix . 'jQuery.extend(Drupal.settings, ' . drupal_to_js(call_user_func_array('array_merge_recursive', $data)) . ");" . $embed_suffix . "</script>\n"; + $output .= '<script type="text/javascript">' . $embed_prefix . 'jQuery.extend(Drupal.settings, ' . drupal_to_js(call_user_func_array('array_merge_recursive', $item['data'])) . ");" . $embed_suffix . "</script>\n"; break; + case 'inline': - foreach ($data as $info) { - $output .= '<script type="text/javascript"' . ($info['defer'] ? ' defer="defer"' : '') . '>' . $embed_prefix . $info['code'] . $embed_suffix . "</script>\n"; - } + $output .= '<script type="text/javascript"' . ($item['defer'] ? ' defer="defer"' : '') . '>' . $embed_prefix . $item['data'] . $embed_suffix . "</script>\n"; break; - default: - // If JS preprocessing is off, we still need to output the scripts. - // Additionally, go through any remaining scripts if JS preprocessing is on and output the non-cached ones. - foreach ($data as $path => $info) { - if (!$info['preprocess'] || !$is_writable || !$preprocess_js) { - $no_preprocess[$type] .= '<script type="text/javascript"' . ($info['defer'] ? ' defer="defer"' : '') . ' src="' . base_path() . $path . ($info['cache'] ? $query_string : '?' . REQUEST_TIME) . "\"></script>\n"; - } - else { - $files[$path] = $info; - } + + case 'file': + if (!$item['preprocess'] || !$is_writable || !$preprocess_js) { + $no_preprocess .= '<script type="text/javascript"' . ($item['defer'] ? ' defer="defer"' : '') . ' src="' . base_path() . $item['data'] . ($item['cache'] ? $query_string : '?' . REQUEST_TIME) . "\"></script>\n"; + } + else { + $files[$item['data']] = $item; } + break; } } @@ -2314,9 +2356,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL) { // Keep the order of JS files consistent as some are preprocessed and others are not. // Make sure any inline or JS setting variables appear last after libraries have loaded. - $output = $preprocessed . implode('', $no_preprocess) . $output; - - return $output; + return $preprocessed . $no_preprocess . $output; } /** @@ -2429,7 +2469,10 @@ function drupal_get_js($scope = 'header', $javascript = NULL) { function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgroup = NULL, $source = NULL, $hidden = TRUE, $limit = 0) { static $js_added = FALSE; if (!$js_added) { - drupal_add_js('misc/tabledrag.js', 'core'); + // Add the table drag JavaScript to the page before the module JavaScript + // to ensure that table drag behaviors are registered before any module + // uses it. + drupal_add_js('misc/tabledrag.js', array('weight' => JS_DEFAULT - 1)); $js_added = TRUE; } @@ -3025,6 +3068,18 @@ function element_sort($a, $b) { return ($a_weight < $b_weight) ? -1 : 1; } +/** + * Function used by uasort to sort structured arrays by weight, without the property weight prefix. + */ +function drupal_sort_weight($a, $b) { + $a_weight = (is_array($a) && isset($a['weight'])) ? $a['weight'] : 0; + $b_weight = (is_array($b) && isset($b['weight'])) ? $b['weight'] : 0; + if ($a_weight == $b_weight) { + return 0; + } + return ($a_weight < $b_weight) ? -1 : 1; +} + /** * Check if the key is a property. */ diff --git a/includes/form.inc b/includes/form.inc index 9799aeca00f8eca5426e9d902294826fafe4fdcd..4512fb0add7fe5273cc0e01355a948ab5ed59c15 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -1893,7 +1893,7 @@ function form_process_ahah($element) { // Adding the same javascript settings twice will cause a recursion error, // we avoid the problem by checking if the javascript has already been added. if (isset($element['#ahah']['path']) && isset($element['#ahah']['event']) && !isset($js_added[$element['#id']])) { - drupal_add_js('misc/jquery.form.js'); + drupal_add_js('misc/jquery.form.js', array('weight' => JS_LIBRARY)); drupal_add_js('misc/ahah.js'); $ahah_binding = array( @@ -1919,7 +1919,7 @@ function form_process_ahah($element) { // Add progress.js if we're doing a bar display. if ($ahah_binding['progress']['type'] == 'bar') { - drupal_add_js('misc/progress.js'); + drupal_add_js('misc/progress.js', array('cache' => FALSE)); } drupal_add_js(array('ahah' => array($element['#id'] => $ahah_binding)), 'setting'); diff --git a/includes/theme.inc b/includes/theme.inc index 29d9aa5e09639e131c3faed42e5b6ff8ec3e3c4f..1f7396397e31cebc488565e103ded33aeaf3e186 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -158,7 +158,7 @@ function _init_theme($theme, $base_theme = array(), $registry_callback = '_theme // Add scripts used by this theme. foreach ($final_scripts as $script) { - drupal_add_js($script, 'theme'); + drupal_add_js($script, array('weight' => JS_THEME)); } $theme_engine = NULL; diff --git a/install.php b/install.php index caa5feb3ea0850a1e175d687ffb14288a44dffba..3b6dd1848e77e8761c3217c056ef1d853ab84193 100644 --- a/install.php +++ b/install.php @@ -726,7 +726,7 @@ function install_tasks($profile, $task) { // Add JavaScript validation. _user_password_dynamic_validation(); - drupal_add_js(drupal_get_path('module', 'system') . '/system.js', 'module'); + drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); // We add these strings as settings because JavaScript translation does not // work on install time. drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail')), 'cleanURL' => array('success' => st('Your server has been successfully tested to support this feature.'), 'failure' => st('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.'), 'testing' => st('Testing clean URLs...'))), 'setting'); diff --git a/modules/color/color.module b/modules/color/color.module index 51c894e514dd2975f662146f397c08a6998ea42e..3eb8cca247b243e30a35a659c1ea21cc5009b910 100644 --- a/modules/color/color.module +++ b/modules/color/color.module @@ -154,7 +154,7 @@ function color_scheme_form(&$form_state, $theme) { // Add Farbtastic color picker. drupal_add_css('misc/farbtastic/farbtastic.css', array('preprocess' => FALSE)); - drupal_add_js('misc/farbtastic/farbtastic.js'); + drupal_add_js('misc/farbtastic/farbtastic.js', array('weight' => JS_LIBRARY)); // Add custom CSS and JS. drupal_add_css($base . '/color.css', array('preprocess' => FALSE)); diff --git a/modules/locale/locale.module b/modules/locale/locale.module index b7d862708a34482f69ea4af300b21a4382ae4bb0..15629d3b83a57bd17d30566660582b6b287aafaa 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -522,20 +522,17 @@ function locale_update_js_files() { $javascript = drupal_add_js(); $files = $new_files = FALSE; - foreach ($javascript as $scope) { - foreach ($scope as $type => $data) { - if ($type != 'setting' && $type != 'inline') { - foreach ($data as $filepath => $info) { - $files = TRUE; - if (!in_array($filepath, $parsed)) { - // Don't parse our own translations files. - if (substr($filepath, 0, strlen($dir)) != $dir) { - locale_inc_callback('_locale_parse_js_file', $filepath); - watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath)); - $parsed[] = $filepath; - $new_files = TRUE; - } - } + foreach ($javascript as $item) { + if ($item['type'] == 'file') { + $files = TRUE; + $filepath = $item['data']; + if (!in_array($filepath, $parsed)) { + // Don't parse our own translations files. + if (substr($filepath, 0, strlen($dir)) != $dir) { + locale_inc_callback('_locale_parse_js_file', $filepath); + watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath)); + $parsed[] = $filepath; + $new_files = TRUE; } } } @@ -566,7 +563,7 @@ function locale_update_js_files() { // Add the translation JavaScript file to the page. if ($files && !empty($language->javascript)) { - drupal_add_js($dir . '/' . $language->language . '_' . $language->javascript . '.js', 'core'); + drupal_add_js($dir . '/' . $language->language . '_' . $language->javascript . '.js'); } } diff --git a/modules/node/node.admin.inc b/modules/node/node.admin.inc index 7076e51823a31f57a6d17c5e5cc263314fb77221..02606abd84da4c0aa91e4989af9b6e26ebb14b2a 100644 --- a/modules/node/node.admin.inc +++ b/modules/node/node.admin.inc @@ -250,7 +250,7 @@ function node_filter_form() { $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset')); } - drupal_add_js('misc/form.js', 'core'); + drupal_add_js('misc/form.js'); return $form; } diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module index 5275afb679329a40e51dff4884dde2b2e2ca994d..71225ff5ce1ec0ed091360770c4a7379ac30184e 100644 --- a/modules/simpletest/simpletest.module +++ b/modules/simpletest/simpletest.module @@ -210,7 +210,10 @@ function simpletest_test_form() { function theme_simpletest_test_table($table) { drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css'); - drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', 'module'); + + // Since SimpleTest is a special use case for the table select, stick the + // SimpleTest JavaScript above the table select. + drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => JS_DEFAULT - 1)); // Create header for test selection table. $header = array( diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index b7ebac4ff26d19354667820d88ee9c36bcbb4266..c2eaad4d33ae9fd4d10abdac4692027e484bbd18 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -306,6 +306,11 @@ class DrupalSetContentTestCase extends DrupalWebTestCase { * Tests for the JavaScript system. */ class JavaScriptTestCase extends DrupalWebTestCase { + /** + * Store configured value for JavaScript preprocessing. + */ + var $preprocess_js = NULL; + /** * Implementation of getInfo(). */ @@ -316,45 +321,58 @@ class JavaScriptTestCase extends DrupalWebTestCase { 'group' => t('System') ); } - + /** * Implementation of setUp(). */ function setUp() { - parent::setUp(); + // Enable locale in test environment. + parent::setUp('locale'); + + // Disable preprocessing + $this->preprocess_js = variable_get('preprocess_js', 0); + variable_set('preprocess_js', 0); + // Reset drupal_add_js() before each test. drupal_add_js(NULL, NULL, TRUE); } - + + /** + * Implementation of tearDown(). + */ + function tearDown() { + // Restore configured value for JavaScript preprocessing. + variable_set('preprocess_js', $this->preprocess_js); + parent::tearDown(); + } + /** * Test default JavaScript is empty. */ function testDefault() { $this->assertEqual(array(), drupal_add_js(), t('Default JavaScript is empty.')); } - + /** * Test adding a JavaScript file. */ function testAddFile() { - drupal_add_js('misc/collapse.js'); - $javascript = drupal_add_js(); - $this->assertTrue(array_key_exists('misc/jquery.js', $javascript['header']['core']), t('jQuery is added when a file is added.')); - $this->assertTrue(array_key_exists('misc/drupal.js', $javascript['header']['core']), t('Drupal.js is added when file is added.')); - $this->assertTrue(array_key_exists('misc/collapse.js', $javascript['header']['module']), t('JavaScript files are correctly added.')); - $this->assertEqual(base_path(), $javascript['header']['setting'][0]['basePath'], t('Base path JavaScript setting is correctly set.')); + $javascript = drupal_add_js('misc/collapse.js'); + $this->assertTrue(array_key_exists('misc/jquery.js', $javascript), t('jQuery is added when a file is added.')); + $this->assertTrue(array_key_exists('misc/drupal.js', $javascript), t('Drupal.js is added when file is added.')); + $this->assertTrue(array_key_exists('misc/collapse.js', $javascript), t('JavaScript files are correctly added.')); + $this->assertEqual(base_path(), $javascript['settings']['data'][0]['basePath'], t('Base path JavaScript setting is correctly set.')); } - + /** * Test adding settings. */ function testAddSetting() { - drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); - $javascript = drupal_add_js(); - $this->assertEqual(280342800, $javascript['header']['setting'][1]['dries'], t('JavaScript setting is set correctly.')); - $this->assertEqual('rocks', $javascript['header']['setting'][1]['drupal'], t('The other JavaScript setting is set correctly.')); + $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); + $this->assertEqual(280342800, $javascript['settings']['data'][1]['dries'], t('JavaScript setting is set correctly.')); + $this->assertEqual('rocks', $javascript['settings']['data'][1]['drupal'], t('The other JavaScript setting is set correctly.')); } - + /** * Test drupal_get_js() for JavaScript settings. */ @@ -365,27 +383,27 @@ class JavaScriptTestCase extends DrupalWebTestCase { $this->assertTrue(strpos($javascript, 'testSetting') > 0, t('Rendered JavaScript header returns custom setting.')); $this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, t('Rendered JavaScript header includes jQuery.')); } - + /** * Test to see if resetting the JavaScript empties the cache. */ function testReset() { drupal_add_js('misc/collapse.js'); - drupal_add_js(NULL, NULL, TRUE); + drupal_add_js(NULL, NULL, TRUE); $this->assertEqual(array(), drupal_add_js(), t('Resetting the JavaScript correctly empties the cache.')); } - + /** * Test adding inline scripts. */ function testAddInline() { $inline = '$(document).ready(function(){});'; - drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); - $javascript = drupal_add_js(); - $this->assertTrue(array_key_exists('misc/jquery.js', $javascript['header']['core']), t('jQuery is added when inline scripts are added.')); - $this->assertEqual($inline, $javascript['footer']['inline'][0]['code'], t('Inline JavaScript is correctly added to the footer.')); + $javascript = drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); + $this->assertTrue(array_key_exists('misc/jquery.js', $javascript), t('jQuery is added when inline scripts are added.')); + $data = end($javascript); + $this->assertEqual($inline, $data['data'], t('Inline JavaScript is correctly added to the footer.')); } - + /** * Test drupal_get_js() with a footer scope. */ @@ -395,14 +413,30 @@ class JavaScriptTestCase extends DrupalWebTestCase { $javascript = drupal_get_js('footer'); $this->assertTrue(strpos($javascript, $inline) > 0, t('Rendered JavaScript footer returns the inline code.')); } - + /** * Test drupal_add_js() sets preproccess to false when cache is set to false. */ function testNoCache() { - drupal_add_js('misc/collapse.js', array('cache' => FALSE)); - $javascript = drupal_add_js(); - $this->assertTrue(!$javascript['header']['module']['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); + $javascript = drupal_add_js('misc/collapse.js', array('cache' => FALSE)); + $this->assertFalse($javascript['misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); + } + + /** + * Test adding a JavaScript file with a different weight. + */ + function testDifferentWeight() { + $javascript = drupal_add_js('misc/collapse.js', array('weight' => JS_THEME)); + $this->assertEqual($javascript['misc/collapse.js']['weight'], JS_THEME, t('Adding a JavaScript file with a different weight caches the given weight.')); + } + + /** + * Test rendering the JavaScript with a file's weight above jQuery's. + */ + function testRenderDifferentWeight() { + drupal_add_js('misc/collapse.js', array('weight' => JS_LIBRARY - 10)); + $javascript = drupal_get_js(); + $this->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), t('Rendering a JavaScript file above jQuery.')); } } diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 48c901293e3b77856f0439d11194d8dda43c27b5..03db7b6832e1200b2edf67640c273cd531dd734d 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1528,7 +1528,7 @@ function system_rss_feeds_settings() { * @see system_date_time_settings_submit() */ function system_date_time_settings() { - drupal_add_js(drupal_get_path('module', 'system') . '/system.js', 'module'); + drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); drupal_add_js(array('dateTime' => array('lookup' => url('admin/settings/date-time/lookup'))), 'setting'); // Date settings: @@ -1736,7 +1736,7 @@ function system_clean_url_settings() { if (!variable_get('clean_url', 0)) { if (strpos(request_uri(), '?q=') !== FALSE) { - drupal_add_js(drupal_get_path('module', 'system') . '/system.js', 'module'); + drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); $form['clean_url']['#description'] .= ' <span>' . t('Before enabling clean URLs, you must perform a test to determine if your server is properly configured. If you are able to see this page again after clicking the "Run the clean URL test" link, the test has succeeded and the radio buttons above will be available. If instead you are directed to a "Page not found" error, you will need to change the configuration of your server. The <a href="@handbook">handbook page on Clean URLs</a> has additional troubleshooting information.', array('@handbook' => 'http://drupal.org/node/15365')) . '</span>'; diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc index 33fea1827279cb1bdaba15a7a5e8d16fd985038a..c58cbb6484a4207c40794066ad404b3cbf1b3687 100644 --- a/modules/user/user.admin.inc +++ b/modules/user/user.admin.inc @@ -83,7 +83,7 @@ function user_filter_form() { ); } - drupal_add_js('misc/form.js', 'core'); + drupal_add_js('misc/form.js'); return $form; } diff --git a/modules/user/user.module b/modules/user/user.module index 9a42cfc2148fa3b49177e9ec608572c04ae379a0..84ba50441fd009015b82842b7bfa535a86a8040f 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -2160,7 +2160,7 @@ function _user_password_dynamic_validation() { global $user; // Only need to do once per page. if (!$complete) { - drupal_add_js(drupal_get_path('module', 'user') . '/user.js', 'module'); + drupal_add_js(drupal_get_path('module', 'user') . '/user.js'); drupal_add_js(array( 'password' => array(