Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.823
diff -u -u -p -r1.823 common.inc
--- includes/common.inc	10 Nov 2008 05:22:59 -0000	1.823
+++ includes/common.inc	10 Nov 2008 20:09:37 -0000
@@ -2191,15 +2191,9 @@ function drupal_add_js($data = NULL, $op
   else {
     $options = array();
   }
-  $options += array(
-    'type' => 'file',
-    'weight' => JS_DEFAULT,
-    'scope' => 'header',
-    'cache' => TRUE,
-    'defer' => FALSE,
-    'preprocess' => TRUE,
-    'data' => $data,
-  );
+  $options += drupal_get_js_defaults();
+  $options['data'] = $data;
+
   // Preprocess can only be set if caching is enabled.
   $options['preprocess'] = $options['cache'] ? $options['preprocess'] : FALSE;
 
@@ -2264,6 +2258,19 @@ function drupal_add_js($data = NULL, $op
 }
 
 /**
+ * Default values for JavaScript
+ */
+function drupal_get_js_defaults() {
+  return array(
+    'type' => 'file',
+    'weight' => JS_DEFAULT,
+    'scope' => 'header',
+    'cache' => TRUE,
+    'defer' => FALSE,
+    'preprocess' => TRUE,
+  );
+}
+/**
  * Returns a themed presentation of all JavaScript code for the current page.
  *
  * References to JavaScript files are placed in a certain order: first, all
@@ -2271,6 +2278,11 @@ function drupal_add_js($data = NULL, $op
  * are added to the page. Then, all settings are output, followed by 'inline'
  * JavaScript code. If running update.php, all preprocessing is disabled.
  *
+ * Note that hook_js_alter(&$javascript) is called during this function call
+ * to allow alterations of the JavaScript during its presentation. Calls to
+ * drupal_add_js() from hook_js_alter() will reflect properly on screen as
+ * hook_js_alter() is made for modifying JavaScript, not adding JavaScript.
+ *
  * @param $scope
  *   (optional) The scope for which the JavaScript rules should be returned.
  *   Defaults to 'header'.
@@ -2279,12 +2291,9 @@ function drupal_add_js($data = NULL, $op
  *   JavaScript array for the given scope.
  * @return
  *   All JavaScript code segments and includes for the scope as HTML tags.
- * @see drupal_add_js()
+ * @see drupal_add_js, simpletest_js_alter
  */
 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();
   }
@@ -2292,6 +2301,9 @@ function drupal_get_js($scope = 'header'
     return '';
   }
 
+  // Allow modules to alter the JavaScript.
+  drupal_alter('js', $javascript);
+
   // Filter out elements of the given scope.
   $items = array();
   foreach ($javascript as $item) {
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.231
diff -u -u -p -r1.231 locale.module
--- modules/locale/locale.module	10 Nov 2008 05:22:59 -0000	1.231
+++ modules/locale/locale.module	10 Nov 2008 20:09:37 -0000
@@ -505,33 +505,32 @@ function locale_system_update($component
 }
 
 /**
+ * Implementation of hook_javascript_alter().
+ * 
  * Update JavaScript translation file, if required, and add it to the page.
  *
- * This function checks all JavaScript files currently added via drupal_add_js()
+ * This function checks all JavaScript files that have been added to the page
  * and invokes parsing if they have not yet been parsed for Drupal.t()
  * and Drupal.formatPlural() calls. Also refreshes the JavaScript translation
  * file if necessary, and adds it to the page.
  */
-function locale_update_js_files() {
+function locale_js_alter(&$javascript) {
   global $language;
 
   $dir = file_create_path(variable_get('locale_js_directory', 'languages'));
   $parsed = variable_get('javascript_parsed', array());
-
-  // Get an array of all the JavaScript added so far.
-  $javascript = drupal_add_js();
   $files = $new_files = FALSE;
 
-  foreach ($javascript as $item) {
-    if ($item['type'] == 'file') {
+  foreach ($javascript as $key => $file) {
+    // If we have a javascript file that has not been parsed already, then we need to parse it.
+    if ($file['type'] != 'setting' && $file['type'] != 'inline') {
       $files = TRUE;
-      $filepath = $item['data'];
-      if (!in_array($filepath, $parsed)) {
+      if (!in_array($file['data'], $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;
+        if (substr($file['data'], 0, strlen($dir)) != $dir) {
+          locale_inc_callback('_locale_parse_js_file', $file['data']);
+          watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $file['data']));
+          $parsed[] = $file['data'];
           $new_files = TRUE;
         }
       }
@@ -561,9 +560,11 @@ function locale_update_js_files() {
     variable_set('javascript_parsed', $parsed);
   }
 
-  // Add the translation JavaScript file to the page.
   if ($files && !empty($language->javascript)) {
-    drupal_add_js($dir . '/' . $language->language . '_' . $language->javascript . '.js');
+    // Add the translation JavaScript file to the page.
+    $result = drupal_get_js_defaults();
+    $result['data'] = $dir . '/' . $language->language . '_' . $language->javascript . '.js';
+    $javascript[] = $result;
   }
 }
 
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.27
diff -u -u -p -r1.27 simpletest.module
--- modules/simpletest/simpletest.module	10 Nov 2008 05:23:00 -0000	1.27
+++ modules/simpletest/simpletest.module	10 Nov 2008 20:09:37 -0000
@@ -210,10 +210,7 @@ function simpletest_test_form() {
 
 function theme_simpletest_test_table($table) {
   drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
-
-  // 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));
+  drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js');
 
   // Create header for test selection table.
   $header = array(
@@ -301,6 +298,18 @@ function theme_simpletest_test_table($ta
   }
 }
 
+/**
+ * Implementation of hook_js_alter().
+ */
+function simpletest_js_alter(&$javascript) {
+  // Since SimpleTest is a special use case for the table select, stick the
+  // SimpleTest JavaScript above the table select.
+  $simpletest = drupal_get_path('module', 'simpletest') . '/simpletest.js';
+  if (array_key_exists($simpletest, $javascript)) {
+    $javascript[$simpletest]['weight'] = $javascript['misc/tableselect.js']['weight'] - 1;
+  }
+}
+
 function theme_simpletest_result_summary($form, $text = NULL) {
   return '<div class="simpletest-'. ($form['#ok'] ? 'pass' : 'fail') .'">' . _simpletest_format_summary_line($form) . '</div>';
 }
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.12
diff -u -u -p -r1.12 common.test
--- modules/simpletest/tests/common.test	10 Nov 2008 05:23:00 -0000	1.12
+++ modules/simpletest/tests/common.test	10 Nov 2008 20:09:37 -0000
@@ -327,7 +327,7 @@ class JavaScriptTestCase extends DrupalW
    */
   function setUp() {
     // Enable locale in test environment.
-    parent::setUp('locale');
+    parent::setUp('locale', 'simpletest');
 
     // Disable preprocessing
     $this->preprocess_js = variable_get('preprocess_js', 0);
@@ -438,6 +438,21 @@ class JavaScriptTestCase extends DrupalW
     $javascript = drupal_get_js();
     $this->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), t('Rendering a JavaScript file above jQuery.'));
   }
+
+  /**
+   * Test altering a JavaScript's weight via hook_js_alter().
+   *
+   * @see simpletest_js_alter
+   */
+  function testAlter() {
+    // Add both tableselect.js and simpletest.js, with a larger weight on SimpleTest.
+    drupal_add_js('misc/tableselect.js');
+    drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => JS_THEME));
+
+    // Render the JavaScript, testing if simpletest.js was altered to be before tableselect.js.
+    $javascript = drupal_get_js();
+    $this->assertTrue(strpos($javascript, 'simpletest.js') < strpos($javascript, 'misc/tableselect.js'), t('Altering JavaScript weight through the alter hook.'));
+  }
 }
 
 /**
