Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.238
diff -u -p -r1.238 locale.inc
--- includes/locale.inc	9 Dec 2009 15:35:48 -0000	1.238
+++ includes/locale.inc	18 Dec 2009 10:07:04 -0000
@@ -2908,6 +2908,7 @@ function _locale_rebuild_js($langcode = 
   }
 
   // Construct the JavaScript file, if there are translations.
+  $data_hash = NULL;
   $data = $status = '';
   if (!empty($translations)) {
 
@@ -2926,22 +2927,38 @@ function _locale_rebuild_js($langcode = 
   $dir = 'public://' . variable_get('locale_js_directory', 'languages');
 
   // Delete old file, if we have no translations anymore, or a different file to be saved.
-  if (!empty($language->javascript) && (!$data || $language->javascript != $data_hash)) {
+  $changed_hash = $language->javascript != $data_hash;
+  if (!empty($language->javascript) && (!$data || $changed_hash)) {
     file_unmanaged_delete($dir . '/' . $language->language . '_' . $language->javascript . '.js');
     $language->javascript = '';
     $status = 'deleted';
   }
 
-  // Only create a new file if the content has changed.
-  if ($data && $language->javascript != $data_hash) {
+  // Only create a new file if the content has changed or the original file got
+  // lost.
+  $dest = $dir . '/' . $language->language . '_' . $data_hash . '.js';
+  if ($data && ($changed_hash || !file_exists($dest))) {
     // Ensure that the directory exists and is writable, if possible.
     file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
 
     // Save the file.
-    $dest = $dir . '/' . $language->language . '_' . $data_hash . '.js';
     if (file_unmanaged_save_data($data, $dest)) {
       $language->javascript = $data_hash;
-      $status = ($status == 'deleted') ? 'updated' : 'created';
+      // If we deleted a previous version of the file and we replace it with a
+      // new one we have an update.
+      if ($status == 'deleted') {
+        $status = 'updated';
+      }
+      // If the file did not exist previously and the data has has changed we
+      // have a fresh creation.
+      elseif ($changed_hash) {
+        $status = 'created';
+      }
+      // If the data hash is unchanged the translation was lost and has to be
+      // rebuilt.
+      else {
+        $status = 'rebuilt';
+      }
     }
     else {
       $language->javascript = '';
@@ -2949,9 +2966,10 @@ function _locale_rebuild_js($langcode = 
     }
   }
 
-  // Save the new JavaScript hash (or an empty value if the file
-  // just got deleted). Act only if some operation was executed.
-  if ($status) {
+  // Save the new JavaScript hash (or an empty value if the file just got
+  // deleted). Act only if some operation was executed that changed the hash
+  // code.
+  if ($status && $changed_hash) {
     db_update('languages')
       ->fields(array(
         'javascript' => $language->javascript,
@@ -2974,6 +2992,10 @@ function _locale_rebuild_js($langcode = 
     case 'updated':
       watchdog('locale', 'Updated JavaScript translation file for the language %language.', array('%language' => t($language->name)));
       return TRUE;
+    case 'rebuilt':
+      watchdog('locale', 'JavaScript translation file %file.js was lost.', array('%file' => $language->javascript), WATCHDOG_WARNING);
+      // Proceed to the 'created' case as the JavaScript translation file has
+      // been created again.
     case 'created':
       watchdog('locale', 'Created JavaScript translation file for the language %language.', array('%language' => t($language->name)));
       return TRUE;
Index: modules/locale/locale.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.test,v
retrieving revision 1.55
diff -u -p -r1.55 locale.test
--- modules/locale/locale.test	7 Dec 2009 06:07:19 -0000	1.55
+++ modules/locale/locale.test	18 Dec 2009 09:36:01 -0000
@@ -292,6 +292,62 @@ class LocaleTranslationFunctionalTest ex
     $this->assertNoText($name, t('Search now can not find the name.'));
   }
 
+  /*
+   * Adds a language and checks that the JavaScript translation files are
+   * properly created and rebuilt on deletion.
+   */
+  function testJavaScriptTranslation() {
+    $user = $this->drupalCreateUser(array('translate interface', 'administer languages', 'access administration pages'));
+    $this->drupalLogin($user);
+
+    $langcode = 'xx';
+    // The English name for the language. This will be translated.
+    $name = $this->randomName(16);
+    // The native name for the language.
+    $native = $this->randomName(16);
+    // The domain prefix.
+    $prefix = $langcode;
+
+    // Add custom language.
+    $edit = array(
+      'langcode' => $langcode,
+      'name' => $name,
+      'native' => $native,
+      'prefix' => $prefix,
+      'direction' => '0',
+    );
+    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
+    drupal_static_reset('language_list');
+
+    // Build the JavaScript translation file.
+    $this->drupalGet('admin/config/regional/translate/translate');
+
+    $query = db_select('locales_source', 'l');
+    $query->addExpression('min(l.lid)', 'lid');
+    $result = $query->condition('l.location', '%.js%', 'LIKE')
+      ->condition('l.textgroup', 'default')
+      ->execute();
+    $url = 'admin/config/regional/translate/edit/' . $result->fetchObject()->lid;
+    $edit = array('translations['. $langcode .']' => 'string translation');
+    $this->drupalPost($url, $edit, t('Save translations'));
+
+    locale_inc_callback('_locale_rebuild_js', $langcode);
+    $file = db_select('languages', 'l')
+      ->fields('l', array('javascript'))
+      ->condition('language', $langcode)
+      ->execute()
+      ->fetchObject();
+    $js_file = 'public://' . variable_get('locale_js_directory', 'languages') . '/' . $langcode . '_' . $file->javascript . '.js';
+    $this->assertTrue($result = file_exists($js_file), t('JavaScript file created: %file', array('%file' => $result ? $js_file : t('not found'))));
+
+    // Test JavaScript translation rebuilding.
+    file_unmanaged_delete($js_file);
+    $this->assertTrue($result = !file_exists($js_file), t('JavaScript file deleted: %file', array('%file' => $result ? $js_file : t('found'))));
+    cache_clear_all();
+    locale_inc_callback('_locale_rebuild_js', $langcode);
+    $this->assertTrue($result = file_exists($js_file), t('JavaScript file rebuilt: %file', array('%file' => $result ? $js_file : t('not found'))));
+  }
+
   /**
    * Tests the validation of the translation input.
    */
