Bug 448842 - solution for bug 410333 introducing regression for Japanese users; r=mnyromyr sr=bienvenu
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Mon, 02 Feb 2009 00:47:21 +0100
changeset 1824 b7615869fd7b419fc2720ae0077e232340a0a839
parent 1823 c215a361c0dfbf6d69f22da98b539c7ea81fc3e0
child 1825 8c79d2928abdd45d4707ccbef7d84ba2c8fe994b
push idunknown
push userunknown
push dateunknown
reviewersmnyromyr, bienvenu
bugs448842, 410333
Bug 448842 - solution for bug 410333 introducing regression for Japanese users; r=mnyromyr sr=bienvenu
mail/components/compose/content/MsgComposeCommands.js
mailnews/compose/resources/content/MsgComposeCommands.js
mailnews/compose/src/nsMsgCompose.cpp
mailnews/compose/src/nsMsgSend.cpp
mailnews/mailnews.js
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -85,17 +85,16 @@ var gSendFormat;
 
 var gMsgIdentityElement;
 var gMsgAddressingWidgetTreeElement;
 var gMsgSubjectElement;
 var gMsgAttachmentElement;
 var gMsgHeadersToolbarElement;
 
 // i18n globals
-var gCurrentMailSendCharset;
 var gSendDefaultCharset;
 var gCharsetTitle;
 var gCharsetConvertManager;
 
 var gLastWindowToHaveFocus;
 var gReceiptOptionChanged;
 var gDSNOptionChanged;
 var gAttachVCardOptionChanged;
@@ -124,17 +123,16 @@ function InitializeGlobalVariables()
   gCloseWindowAfterSave = false;
   gIsOffline = gIOService.offline;
   gSessionAdded = false;
   gCurrentAutocompleteDirectory = null;
   gSetupLdapAutocomplete = false;
   gLDAPSession = null;
   gSavedSendNowKey = null;
   gSendFormat = nsIMsgCompSendFormat.AskUser;
-  gCurrentMailSendCharset = null;
   gSendDefaultCharset = null;
   gCharsetTitle = null;
   gCharsetConvertManager = Components.classes['@mozilla.org/charset-converter-manager;1'].getService(Components.interfaces.nsICharsetConverterManager);
   gMailSession = Components.classes["@mozilla.org/messenger/services/session;1"].getService(Components.interfaces.nsIMsgMailSession);
   gHideMenus = false;
 
   gLastWindowToHaveFocus = null;
   gReceiptOptionChanged = false;
@@ -1515,17 +1513,16 @@ function ComposeUnload()
 
 function SetDocumentCharacterSet(aCharset)
 {
   dump("SetDocumentCharacterSet Callback!\n");
   dump(aCharset + "\n");
 
   if (gMsgCompose) {
     gMsgCompose.SetDocumentCharset(aCharset);
-    gCurrentMailSendCharset = aCharset;
     gCharsetTitle = null;
     SetComposeWindowTitle();
   }
   else
     dump("Compose has not been created!\n");
 }
 
 function UpdateMailEditCharset()
@@ -1551,22 +1548,16 @@ function UpdateMailEditCharset()
 
   // Set a document charset to a default mail send charset.
   if (send_default_charset == compFieldsCharset)
     SetDocumentCharacterSet(send_default_charset);
 }
 
 function InitCharsetMenuCheckMark()
 {
-  // return if the charset is already set explitily
-  if (gCurrentMailSendCharset != null) {
-    dump("already set to " + gCurrentMailSendCharset + "\n");
-    return;
-  }
-
   // Check the menu
   UpdateMailEditCharset();
   // use setTimeout workaround to delay checkmark the menu
   // when onmenucomplete is ready then use it instead of oncreate
   // see bug #78290 for the details
   setTimeout(UpdateMailEditCharset, 0);
 
 }
@@ -1766,28 +1757,41 @@ function GenericSendMessage( msgType )
            default: dump("\###SendMessage Error: invalid action value\n"); return;
         }
       }
 
       // hook for extra compose pre-processing
       var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
       observerService.notifyObservers(window, "mail:composeOnSend", null);
 
+      var originalCharset = gMsgCompose.compFields.characterSet;
       // Check if the headers of composing mail can be converted to a mail charset.
       if (msgType == nsIMsgCompDeliverMode.Now || 
         msgType == nsIMsgCompDeliverMode.Later ||
         msgType == nsIMsgCompDeliverMode.Save || 
         msgType == nsIMsgCompDeliverMode.SaveAsDraft || 
         msgType == nsIMsgCompDeliverMode.AutoSaveAsDraft || 
         msgType == nsIMsgCompDeliverMode.SaveAsTemplate) 
       {
         var fallbackCharset = new Object;
-        // Check encoding, switch to UTF-8 if the default encoding doesn't fit.
+        // Check encoding, switch to UTF-8 if the default encoding doesn't fit
+        // and disable_fallback_to_utf8 isn't set for this encoding.
         if (!gMsgCompose.checkCharsetConversion(getCurrentIdentity(), fallbackCharset))
-          fallbackCharset.value = "UTF-8";
+        {
+          var disableFallback = false;
+          try
+          {
+            disableFallback = getPref("mailnews.disable_fallback_to_utf8." + originalCharset);
+          }
+          catch (e) {}
+          if (disableFallback)
+            msgCompFields.needToCheckCharset = false;
+          else
+            fallbackCharset.value = "UTF-8";
+        }
 
         if (fallbackCharset && 
             fallbackCharset.value && fallbackCharset.value != "")
           gMsgCompose.SetDocumentCharset(fallbackCharset.value);
       }
       try {
 
         // just before we try to send the message, fire off the compose-send-message event for listeners
@@ -1825,16 +1829,18 @@ function GenericSendMessage( msgType )
         gMsgCompose.SendMsg(msgType, getCurrentIdentity(), currentAccountKey, msgWindow, progress);
       }
       catch (ex) {
         dump("failed to SendMsg: " + ex + "\n");
         gWindowLocked = false;
         enableEditableFields();
         updateComposeItems();
       }
+      if (gMsgCompose && originalCharset != gMsgCompose.compFields.characterSet)
+        SetDocumentCharacterSet(gMsgCompose.compFields.characterSet);
     }
   }
   else
     dump("###SendMessage Error: composeAppCore is null!\n");
 }
 
 function CheckValidEmailAddress(to, cc, bcc)
 {
--- a/mailnews/compose/resources/content/MsgComposeCommands.js
+++ b/mailnews/compose/resources/content/MsgComposeCommands.js
@@ -105,17 +105,16 @@ var gLogComposePerformance;
 
 var gMsgIdentityElement;
 var gMsgAddressingWidgetElement;
 var gMsgSubjectElement;
 var gMsgAttachmentElement;
 var gMsgHeadersToolbarElement;
 
 // i18n globals
-var gCurrentMailSendCharset;
 var gSendDefaultCharset;
 var gCharsetTitle;
 var gCharsetConvertManager;
 
 var gLastWindowToHaveFocus;
 var gReceiptOptionChanged;
 var gAttachVCardOptionChanged;
 
@@ -143,17 +142,16 @@ function InitializeGlobalVariables()
   gCloseWindowAfterSave = false;
   gIsOffline = gIOService.offline;
   gSessionAdded = false;
   gCurrentAutocompleteDirectory = null;
   gSetupLdapAutocomplete = false;
   gLDAPSession = null;
   gSavedSendNowKey = null;
   gSendFormat = nsIMsgCompSendFormat.AskUser;
-  gCurrentMailSendCharset = null;
   gSendDefaultCharset = null;
   gCharsetTitle = null;
   gCharsetConvertManager = Components.classes['@mozilla.org/charset-converter-manager;1'].getService(Components.interfaces.nsICharsetConverterManager);
   gMailSession = Components.classes["@mozilla.org/messenger/services/session;1"].getService(Components.interfaces.nsIMsgMailSession);
   gHideMenus = false;
   // We are storing the value of the bool logComposePerformance inorder to avoid logging unnecessarily.
   if (sMsgComposeService)
     gLogComposePerformance = sMsgComposeService.logComposePerformance;
@@ -1537,17 +1535,16 @@ function ComposeUnload()
 
 function SetDocumentCharacterSet(aCharset)
 {
   dump("SetDocumentCharacterSet Callback!\n");
   dump(aCharset + "\n");
 
   if (gMsgCompose) {
     gMsgCompose.SetDocumentCharset(aCharset);
-    gCurrentMailSendCharset = aCharset;
     gCharsetTitle = null;
     SetComposeWindowTitle();
   }
   else
     dump("Compose has not been created!\n");
 }
 
 function UpdateMailEditCharset()
@@ -1573,22 +1570,16 @@ function UpdateMailEditCharset()
 
   // Set a document charset to a default mail send charset.
   if (send_default_charset == compFieldsCharset)
     SetDocumentCharacterSet(send_default_charset);
 }
 
 function InitCharsetMenuCheckMark()
 {
-  // return if the charset is already set explitily
-  if (gCurrentMailSendCharset != null) {
-    dump("already set to " + gCurrentMailSendCharset + "\n");
-    return;
-  }
-
   // Check the menu
   UpdateMailEditCharset();
   // use setTimeout workaround to delay checkmark the menu
   // when onmenucomplete is ready then use it instead of oncreate
   // see bug #78290 for the details
   setTimeout("UpdateMailEditCharset()", 0);
 
 }
@@ -1789,28 +1780,41 @@ function GenericSendMessage( msgType )
            default: dump("\###SendMessage Error: invalid action value\n"); return;
         }
       }
 
       // hook for extra compose pre-processing
       var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
       observerService.notifyObservers(window, "mail:composeOnSend", null);
 
+      var originalCharset = gMsgCompose.compFields.characterSet;
       // Check if the headers of composing mail can be converted to a mail charset.
       if (msgType == nsIMsgCompDeliverMode.Now ||
         msgType == nsIMsgCompDeliverMode.Later ||
         msgType == nsIMsgCompDeliverMode.Save ||
         msgType == nsIMsgCompDeliverMode.SaveAsDraft ||
         msgType == nsIMsgCompDeliverMode.AutoSaveAsDraft ||
         msgType == nsIMsgCompDeliverMode.SaveAsTemplate)
       {
         var fallbackCharset = new Object;
-        // Check encoding, switch to UTF-8 if the default encoding doesn't fit.
+        // Check encoding, switch to UTF-8 if the default encoding doesn't fit
+        // and disable_fallback_to_utf8 isn't set for this encoding.
         if (!gMsgCompose.checkCharsetConversion(getCurrentIdentity(), fallbackCharset))
-          fallbackCharset.value = "UTF-8";
+        {
+          var disableFallback = false;
+          try
+          {
+            disableFallback = sPrefs.getBoolPref("mailnews.disable_fallback_to_utf8." + originalCharset);
+          }
+          catch (e) {}
+          if (disableFallback)
+            msgCompFields.needToCheckCharset = false;
+          else
+            fallbackCharset.value = "UTF-8";
+        }
 
         if (fallbackCharset &&
             fallbackCharset.value && fallbackCharset.value != "")
           gMsgCompose.SetDocumentCharset(fallbackCharset.value);
       }
       try {
         // just before we try to send the message, fire off the compose-send-message event for listeners
         // such as smime so they can do any pre-security work such as fetching certificates before sending
@@ -1848,16 +1852,18 @@ function GenericSendMessage( msgType )
         gMsgCompose.SendMsg(msgType, getCurrentIdentity(), currentAccountKey, msgWindow, progress);
       }
       catch (ex) {
         dump("failed to SendMsg: " + ex + "\n");
         gWindowLocked = false;
         enableEditableFields();
         updateComposeItems();
       }
+      if (gMsgCompose && originalCharset != gMsgCompose.compFields.characterSet)
+        SetDocumentCharacterSet(gMsgCompose.compFields.characterSet);
     }
   }
   else
     dump("###SendMessage Error: composeAppCore is null!\n");
 }
 
 function CheckValidEmailAddress(aTo, aCC, aBCC)
 {
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -1093,28 +1093,44 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
       rv = nsMsgI18NSaveAsCharset(contentType, m_compFields->GetCharacterSet(),
                                   msgBody.get(), getter_Copies(outCString),
                                   getter_Copies(fallbackCharset), &isAsciiOnly);
       if (m_compFields->GetForceMsgEncoding())
         isAsciiOnly = PR_FALSE;
       if (NS_SUCCEEDED(rv) && !outCString.IsEmpty())
       {
         // If the body contains characters outside the repertoire of the current
-        // charset, just convert to UTF-8 and be done with it.
-        if (NS_ERROR_UENC_NOMAPPING == rv && m_editor) {
+        // charset, just convert to UTF-8 and be done with it
+        // unless disable_fallback_to_utf8 is set for this charset.
+        if (NS_ERROR_UENC_NOMAPPING == rv && m_editor)
+        {
           PRBool needToCheckCharset;
           m_compFields->GetNeedToCheckCharset(&needToCheckCharset);
-          if (needToCheckCharset) {
-            CopyUTF16toUTF8(msgBody.get(), outCString);
-            m_compFields->SetCharacterSet("UTF-8");
+          if (needToCheckCharset)
+          {
+            PRBool disableFallback = PR_FALSE;
+            nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+            if (prefBranch)
+            {
+              nsCString prefName("mailnews.disable_fallback_to_utf8.");
+              prefName.Append(m_compFields->GetCharacterSet());
+              prefBranch->GetBoolPref(prefName.get(), &disableFallback);
+            }
+            if (!disableFallback)
+            {
+              CopyUTF16toUTF8(msgBody.get(), outCString);
+              m_compFields->SetCharacterSet("UTF-8");
+            }
           }
         }
-        // re-label to the fallback charset
         else if (!fallbackCharset.IsEmpty())
+        {
+          // re-label to the fallback charset
           m_compFields->SetCharacterSet(fallbackCharset.get());
+        }
         m_compFields->SetBodyIsAsciiOnly(isAsciiOnly);
         m_compFields->SetBody(outCString.get());
         entityConversionDone = PR_TRUE;
       }
       else
         m_compFields->SetBody(NS_LossyConvertUTF16toASCII(msgBody).get());
     }
   }
--- a/mailnews/compose/src/nsMsgSend.cpp
+++ b/mailnews/compose/src/nsMsgSend.cpp
@@ -1788,28 +1788,44 @@ nsMsgComposeAndSend::GetBodyFromEditor()
           *bodyTextPtr = 0x0020;
         bodyTextPtr++;
       }
 
       nsCString fallbackCharset;
       rv = nsMsgI18NSaveAsCharset(TEXT_PLAIN, aCharset, bodyText,
            getter_Copies(outCString), getter_Copies(fallbackCharset));
 
-      if (NS_ERROR_UENC_NOMAPPING == rv) {
+      if (NS_ERROR_UENC_NOMAPPING == rv)
+      {
         PRBool needToCheckCharset;
         mCompFields->GetNeedToCheckCharset(&needToCheckCharset);
-        if (needToCheckCharset) {
-          // Just use UTF-8 and be done with it.
-          CopyUTF16toUTF8(bodyText, outCString);
-          mCompFields->SetCharacterSet("UTF-8");
+        if (needToCheckCharset)
+        {
+          // Just use UTF-8 and be done with it
+          // unless disable_fallback_to_utf8 is set for this charset.
+          PRBool disableFallback = PR_FALSE;
+          nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+          if (prefBranch)
+          {
+            nsCString prefName("mailnews.disable_fallback_to_utf8.");
+            prefName.Append(aCharset);
+            prefBranch->GetBoolPref(prefName.get(), &disableFallback);
+          }
+          if (!disableFallback)
+          {
+            CopyUTF16toUTF8(bodyText, outCString);
+            mCompFields->SetCharacterSet("UTF-8");
+          }
         }
       }
-      // re-label to the fallback charset
       else if (!fallbackCharset.IsEmpty())
+      {
+        // re-label to the fallback charset
         mCompFields->SetCharacterSet(fallbackCharset.get());
+      }
     }
 
     if (NS_SUCCEEDED(rv))
       attachment1_body = outCString;
 
     // If we have an origHTMLBody that is not null, this means that it is
     // different than the bodyText because of formatting conversions. Because of
     // this we need to do the charset conversion on this part separately
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -297,16 +297,20 @@ pref("mailnews.offline_sync_news",      
 pref("mailnews.offline_sync_send_unsent",  true);
 pref("mailnews.offline_sync_work_offline", false);
 pref("mailnews.force_ascii_search",        false);
 
 pref("mailnews.send_default_charset",       "chrome://messenger/locale/messenger.properties");
 pref("mailnews.view_default_charset",       "chrome://messenger/locale/messenger.properties");
 pref("mailnews.force_charset_override",     false); // ignore specified MIME encoding and use the default encoding for display
 pref("mailnews.reply_in_default_charset",   false);
+// mailnews.disable_fallback_to_utf8.<charset>
+// don't fallback from <charset> to UTF-8 even if some characters are not found in <charset>.
+// those characters will be crippled.
+pref("mailnews.disable_fallback_to_utf8.ISO-2022-JP", false);
 pref("mailnews.localizedRe",                "chrome://messenger-region/locale/region.properties");
 
 pref("mailnews.search_date_format",        "chrome://messenger/locale/messenger.properties");
 pref("mailnews.search_date_separator",     "chrome://messenger/locale/messenger.properties");
 pref("mailnews.search_date_leading_zeros", "chrome://messenger/locale/messenger.properties");
 
 pref("mailnews.quotingPrefs.version",       0);  // used to decide whether to migrate global quoting prefs