Bug 703836 MsgComposeCommands.js Code cleanup: Use Services more, reuse code, and remove commented dumps r=IanN moa=Mnyromyr.
authorPhilip Chee <philip.chee@gmail.com>
Thu, 22 Dec 2011 18:25:06 +0800
changeset 10272 525cf03902bc0d7b0143c7289bf25728e8a80452
parent 10271 07d03fadd4ea351085f583ef916662343f4e2332
child 10273 84ba7b2c99f6f34a6925388f61f9b8d18c8f16cd
push id402
push userbugzilla@standard8.plus.com
push dateTue, 13 Mar 2012 21:17:18 +0000
treeherdercomm-beta@d080a8ebf16a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN
bugs703836
Bug 703836 MsgComposeCommands.js Code cleanup: Use Services more, reuse code, and remove commented dumps r=IanN moa=Mnyromyr.
suite/mailnews/compose/MsgComposeCommands.js
--- a/suite/mailnews/compose/MsgComposeCommands.js
+++ b/suite/mailnews/compose/MsgComposeCommands.js
@@ -42,36 +42,33 @@
  */
 const nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
 const nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
 const nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
 const nsIMsgCompType = Components.interfaces.nsIMsgCompType;
 const nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
 const nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
 const nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
-const nsISupportsString = Components.interfaces.nsISupportsString;
 const mozISpellCheckingEngine = Components.interfaces.mozISpellCheckingEngine;
 
 /**
  * In order to distinguish clearly globals that are initialized once when js load (static globals) and those that need to be
  * initialize every time a compose window open (globals), I (ducarroz) have decided to prefix by s... the static one and
  * by g... the other one. Please try to continue and repect this rule in the future. Thanks.
  */
 /**
  * static globals, need to be initialized only once
  */
 var sMsgComposeService = Components.classes["@mozilla.org/messengercompose;1"].getService(Components.interfaces.nsIMsgComposeService);
 var sComposeMsgsBundle;
 var sBrandBundle;
 
 var sPrefs = null;
 var sPrefBranchInternal = null;
-var sOther_headers = "";
-
-var sAccountManagerDataSource = null;
+
 var sRDF = null;
 var sNameProperty = null;
 var sDictCount = 0;
 
 /* Create message window object. This is use by mail-offline.js and therefore should not be renamed. We need to avoid doing
    this kind of cross file global stuff in the future and instead pass this object as parameter when needed by function
    in the other js file.
 */
@@ -195,17 +192,17 @@ var gComposeRecyclingListener = {
     ReleaseAutoCompleteState();
     awResetAllRows();
     RemoveAllAttachments();
 
     // We need to clear the identity popup menu in case the user will change them. It will be rebuilded later in ComposeStartup
     ClearIdentityListPopup(document.getElementById("msgIdentityPopup"));
 
     //Clear the subject
-    document.getElementById("msgSubject").value = "";
+    GetMsgSubjectElement().value = "";
     SetComposeWindowTitle();
 
     SetContentAndBodyAsUnmodified();
     disableEditableFields();
     ReleaseGlobalVariables();
 
     // Clear the focus
     awGetInputElement(1).removeAttribute('focused');
@@ -421,17 +418,16 @@ var defaultController =
 
       //Options Menu
       case "cmd_selectAddress":
       case "cmd_outputFormat":
       case "cmd_quoteMessage":
         return true;
 
       default:
-//        dump("##MsgCompose: command " + command + "no supported!\n");
         return false;
     }
   },
   isCommandEnabled: function(command)
   {
     var composeHTML = gMsgCompose && gMsgCompose.composeHTML;
 
     switch (command)
@@ -475,17 +471,16 @@ var defaultController =
         return composeHTML;
       case "cmd_quoteMessage":
         var selectedURIs = GetSelectedMessages();
         if (selectedURIs && selectedURIs.length > 0)
           return true;
         return false;
 
       default:
-//        dump("##MsgCompose: command " + command + " disabled!\n");
         return false;
     }
   },
 
   doCommand: function(command)
   {
     switch (command)
     {
@@ -505,38 +500,36 @@ var defaultController =
           else
             SendMessage();
         }
         break;
       case "cmd_sendNow"            : if (defaultController.isCommandEnabled(command)) SendMessage();          break;
       case "cmd_sendWithCheck"   : if (defaultController.isCommandEnabled(command)) SendMessageWithCheck();          break;
       case "cmd_sendLater"          : if (defaultController.isCommandEnabled(command)) SendMessageLater();     break;
       case "cmd_printSetup"         : PrintUtils.showPageSetup(); break;
-      case "cmd_print"              : DoCommandPrint(); break;
+      case "cmd_print"              : PrintUtils.print(); break;
 
       //Edit Menu
       case "cmd_delete"             : if (MessageGetNumSelectedAttachments() > 0) RemoveSelectedAttachment();  break;
       case "cmd_renameAttachment"   : if (MessageGetNumSelectedAttachments() == 1) RenameSelectedAttachment(); break;
       case "cmd_selectAll"          : if (MessageHasAttachments()) SelectAllAttachments();                     break;
       case "cmd_openAttachment"     : if (MessageGetNumSelectedAttachments() == 1) OpenSelectedAttachment();   break;
       case "cmd_account"            : MsgAccountManager(null); break;
       case "cmd_preferences"        : DoCommandPreferences(); break;
 
       //Options Menu
       case "cmd_selectAddress"      : if (defaultController.isCommandEnabled(command)) SelectAddress();         break;
       case "cmd_quoteMessage"       : if (defaultController.isCommandEnabled(command)) QuoteSelectedMessage();  break;
       default:
-//        dump("##MsgCompose: don't know what to do with command " + command + "!\n");
         return;
     }
   },
 
   onEvent: function(event)
   {
-//    dump("DefaultController:onEvent\n");
   }
 }
 
 function QuoteSelectedMessage()
 {
   var selectedURIs = GetSelectedMessages();
   if (selectedURIs)
     for (let i = 0; i < selectedURIs.length; i++)
@@ -572,24 +565,21 @@ function UnloadCommandUpdateHandlers()
 }
 
 function CommandUpdate_MsgCompose()
 {
   var focusedWindow = top.document.commandDispatcher.focusedWindow;
 
   // we're just setting focus to where it was before
   if (focusedWindow == gLastWindowToHaveFocus) {
-    //dump("XXX skip\n");
     return;
   }
 
   gLastWindowToHaveFocus = focusedWindow;
 
-  //dump("XXX update, focus on " + focusedWindow + "\n");
-
   updateComposeItems();
 }
 
 function updateComposeItems()
 {
   try {
     // Edit Menu
     goUpdateCommand("cmd_rewrap");
@@ -1058,23 +1048,16 @@ function DoCommandClose()
 
     // note: if we're not caching this window, this destroys it for us
     MsgComposeCloseWindow(true);
   }
 
   return false;
 }
 
-function DoCommandPrint()
-{
-  try {
-    PrintUtils.print();
-  } catch(ex) {dump("#PRINT ERROR: " + ex + "\n");}
-}
-
 function DoCommandPreferences()
 {
   goPreferences('composing_messages_pane');
 }
 
 function ToggleWindowLock()
 {
   gWindowLocked = !gWindowLocked;
@@ -1122,32 +1105,31 @@ function GetArgs(originalData)
       else
         data += aChar
     }
     else
       data += aChar
   }
 
   var pairs = data.split(separator);
-//  dump("Compose: argument: {" + data + "}\n");
 
   for (let i = pairs.length - 1; i >= 0; i--)
   {
     var pos = pairs[i].indexOf('=');
     if (pos == -1)
       continue;
     var argname = pairs[i].substring(0, pos);
     var argvalue = pairs[i].substring(pos + 1);
     if (argvalue.charAt(0) == "'" && argvalue.charAt(argvalue.length - 1) == "'")
       args[argname] = argvalue.substring(1, argvalue.length - 1);
     else
       try {
         args[argname] = decodeURIComponent(argvalue);
       } catch (e) {args[argname] = argvalue;}
-    dump("[" + argname + "=" + args[argname] + "]\n");
+    // dump("[" + argname + "=" + args[argname] + "]\n");
   }
   return args;
 }
 
 function ComposeFieldsReady()
 {
   //If we are in plain text, we need to set the wrap column
   if (! gMsgCompose.composeHTML) {
@@ -1200,17 +1182,17 @@ function ComposeStartup(recycled, aParam
     // if still no dice, try and see if the params is an old fashioned list of string attributes
     // XXX can we get rid of this yet?
     if (!params)
     {
       args = GetArgs(window.arguments[0]);
     }
   }
 
-  var identityList = document.getElementById("msgIdentity");
+  var identityList = GetMsgIdentityElement();
 
   if (identityList)
     FillIdentityList(identityList);
 
   if (!params) {
     // This code will go away soon as now arguments are passed to the window using a object of type nsMsgComposeParams instead of a string
 
     params = Components.classes["@mozilla.org/messengercompose/composeparams;1"].createInstance(Components.interfaces.nsIMsgComposeParams);
@@ -1306,22 +1288,22 @@ function ComposeStartup(recycled, aParam
       gMsgCompose.recycledWindow = recycled;
 
       if (!editorElement)
       {
         dump("Failed to get editor element!\n");
         return;
       }
 
-      document.getElementById("returnReceiptMenu").setAttribute('checked',
-                                         gMsgCompose.compFields.returnReceipt);
-      document.getElementById("cmd_attachVCard").setAttribute('checked',
-                                         gMsgCompose.compFields.attachVCard);
-      document.getElementById("menu_inlineSpellCheck").setAttribute('checked',
-                                         sPrefs.getBoolPref("mail.spellcheck.inline"));
+      document.getElementById("returnReceiptMenu")
+              .setAttribute("checked", gMsgCompose.compFields.returnReceipt);
+      document.getElementById("cmd_attachVCard")
+              .setAttribute("checked", gMsgCompose.compFields.attachVCard);
+      document.getElementById("menu_inlineSpellCheck")
+              .setAttribute("checked", getPref("mail.spellcheck.inline"));
 
       // If recycle, editor is already created
       if (!recycled)
       {
         try {
           var editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
           editorElement.makeEditable(editortype, true);
         } catch (e) { dump(" FAILED TO START EDITOR: "+e+"\n"); }
@@ -1361,17 +1343,17 @@ function ComposeStartup(recycled, aParam
             // XXX : need to do html-escaping here !
             msgCompFields.body = "<BR><A HREF=\"" + body + "\">" + cleanBody + "</A><BR>";
           }
           else
             msgCompFields.body = "\n<" + body + ">\n";
         }
 
         var subjectValue = msgCompFields.subject;
-        document.getElementById("msgSubject").value = subjectValue;
+        GetMsgSubjectElement().value = subjectValue;
 
         var attachments = msgCompFields.attachments;
         while (attachments.hasMoreElements()) {
           AddAttachment(attachments.getNext().QueryInterface(Components.interfaces.nsIMsgAttachment));
         }
       }
 
       var event = document.createEvent('Events');
@@ -1425,18 +1407,18 @@ function ComposeStartup(recycled, aParam
                     (folder.flags & nsMsgFolderFlags.Drafts);
   }
   catch (ex) {
     gEditingDraft = false;
   }
 
   gAutoSaveKickedIn = false;
 
-  gAutoSaveInterval = sPrefs.getBoolPref("mail.compose.autosave")
-    ? sPrefs.getIntPref("mail.compose.autosaveinterval") * 60000
+  gAutoSaveInterval = getPref("mail.compose.autosave")
+    ? getPref("mail.compose.autosaveinterval") * 60000
     : 0;
 
   if (gAutoSaveInterval)
     gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
 }
 
 // The new, nice, simple way of getting notified when a new editor has been created
 var gMsgEditorCreationObserver =
@@ -1474,60 +1456,46 @@ function WizCallback(state)
   }
 }
 
 function ComposeLoad()
 {
   sComposeMsgsBundle = document.getElementById("bundle_composeMsgs");
   sBrandBundle = document.getElementById("brandBundle");
 
-  // First get the preferences service
-  try {
-    var prefService = Components.classes["@mozilla.org/preferences-service;1"]
-                              .getService(Components.interfaces.nsIPrefService);
-    sPrefs = prefService.getBranch(null);
-    sPrefBranchInternal = sPrefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
-  }
-  catch (ex) {
-    dump("failed to preferences services\n");
-  }
-
-  try {
-    sOther_headers = sPrefs.getCharPref("mail.compose.other.header");
-  }
-  catch (ex) {
-    dump("failed to get the mail.compose.other.header pref\n");
-  }
-
-  try {
-    sAccountManagerDataSource = Components.classes["@mozilla.org/rdf/datasource;1?name=msgaccountmanager"].getService(Components.interfaces.nsIRDFDataSource);
-    sRDF = Components.classes['@mozilla.org/rdf/rdf-service;1'].getService(Components.interfaces.nsIRDFService);
-    sNameProperty = sRDF.GetResource("http://home.netscape.com/NC-rdf#Name?sort=true");
-  }
-  catch (ex) {
-    dump("failed to get RDF\n");
-  }
+  // XXX: Get the preferences service. Remove this once LDAP autocomplete has
+  // been moved to toolkit interfaces.
+  sPrefs = Components.classes["@mozilla.org/preferences-service;1"]
+                     .getService(Components.interfaces.nsIPrefService)
+                     .QueryInterface(Components.interfaces.nsIPrefBranch2);
+  sPrefBranchInternal = sPrefs;
+
+  var otherHeaders = getPref("mail.compose.other.header");
+
+  sRDF = Components.classes['@mozilla.org/rdf/rdf-service;1']
+                   .getService(Components.interfaces.nsIRDFService);
+  sNameProperty = sRDF.GetResource("http://home.netscape.com/NC-rdf#Name?sort=true");
 
   AddMessageComposeOfflineQuitObserver();
   AddDirectoryServerObserver(true);
 
   if (gLogComposePerformance)
     sMsgComposeService.TimeStamp("Start initializing the compose window (ComposeLoad)", false);
 
   try {
     SetupCommandUpdateHandlers();
     // This will do migration, or create a new account if we need to.
     // We also want to open the account wizard if no identities are found
     var state = verifyAccounts(WizCallback, true);
 
-    if (sOther_headers) {
+    if (otherHeaders) {
       var selectNode = document.getElementById('addressCol1#1');
-      var sOther_headers_Array = sOther_headers.split(",");
-      for (let i = 0; i < sOther_headers_Array.length; i++)
-        selectNode.appendItem(sOther_headers_Array[i] + ":", "addr_other");
+      var otherHeaders_Array = otherHeaders.split(",");
+      for (let i = 0; i < otherHeaders_Array.length; i++)
+        selectNode.appendItem(otherHeaders_Array[i] + ":", "addr_other");
     }
     if (state)
       ComposeStartup(false, null);
   }
   catch (ex) {
     Components.utils.reportError(ex);
     var errorTitle = sComposeMsgsBundle.getString("initErrorDlogTitle");
     var errorMsg = sComposeMsgsBundle.getString("initErrorDlgMessage");
@@ -1543,18 +1511,16 @@ function ComposeLoad()
   var mailToolbox = getMailToolbox();
   mailToolbox.customizeInit = MailToolboxCustomizeInit;
   mailToolbox.customizeDone = MailToolboxCustomizeDone;
   mailToolbox.customizeChange = MailToolboxCustomizeChange;
 }
 
 function ComposeUnload()
 {
-  dump("\nComposeUnload from XUL\n");
-
   UnloadCommandUpdateHandlers();
 
   // Stop InlineSpellCheckerUI so personal dictionary is saved
   EnableInlineSpellCheck(false);
 
   EditorCleanup();
 
   RemoveMessageComposeOfflineQuitObserver();
@@ -1567,19 +1533,16 @@ function ComposeUnload()
   if (gMsgCompose)
     gMsgCompose.UnregisterStateListener(stateListener);
   if (gAutoSaveTimeout)
     clearTimeout(gAutoSaveTimeout);
 }
 
 function SetDocumentCharacterSet(aCharset)
 {
-  dump("SetDocumentCharacterSet Callback!\n");
-  dump(aCharset + "\n");
-
   if (gMsgCompose) {
     gMsgCompose.SetDocumentCharset(aCharset);
     gCharsetTitle = null;
     SetComposeWindowTitle();
   }
   else
     dump("Compose has not been created!\n");
 }
@@ -1667,32 +1630,28 @@ function GetCharsetUIString()
   }
 
   return "";
 }
 
 // Add-ons can override this to customize the behavior.
 function DoSpellCheckBeforeSend()
 {
-  return Services.prefs.getBoolPref("mail.SpellCheckBeforeSend");
+  return getPref("mail.SpellCheckBeforeSend");
 }
 
 function GenericSendMessage( msgType )
 {
-  dump("GenericSendMessage from XUL\n");
-
-  dump("Identity = " + getCurrentIdentity() + "\n");
-
   if (gMsgCompose != null)
   {
     var msgCompFields = gMsgCompose.compFields;
     if (msgCompFields)
     {
       Recipients2CompFields(msgCompFields);
-      var subject = document.getElementById("msgSubject").value;
+      var subject = GetMsgSubjectElement().value;
       msgCompFields.subject = subject;
       Attachments2CompFields(msgCompFields);
 
       if (msgType == nsIMsgCompDeliverMode.Now || msgType == nsIMsgCompDeliverMode.Later)
       {
         //Do we need to check the spelling?
         if (DoSpellCheckBeforeSend())
         {
@@ -1714,17 +1673,17 @@ function GenericSendMessage( msgType )
         {
           var result = {value:sComposeMsgsBundle.getString("defaultSubject")};
           if (Services.prompt.prompt(window,
                   sComposeMsgsBundle.getString("sendMsgTitle"),
                   sComposeMsgsBundle.getString("subjectDlogMessage"),
                   result, null, {value:0}))
           {
             msgCompFields.subject = result.value;
-            var subjectInputElem = document.getElementById("msgSubject");
+            var subjectInputElem = GetMsgSubjectElement();
             subjectInputElem.value = result.value;
           }
           else
             return;
         }
 
         // check if the user tries to send a message to a newsgroup through a mail account
         var currentAccountKey = getCurrentAccountKey();
@@ -1735,41 +1694,32 @@ function GenericSendMessage( msgType )
               "' has no matching account!";
         }
         var servertype = account.incomingServer.type;
 
         if (servertype != "nntp" && msgCompFields.newsgroups != "")
         {
           const kDontAskAgainPref = "mail.compose.dontWarnMail2Newsgroup";
           // default to ask user if the pref is not set
-          var dontAskAgain = false;
-          try {
-            var pref = Components.classes["@mozilla.org/preferences-service;1"]
-                                .getService(Components.interfaces.nsIPrefBranch);
-            dontAskAgain = pref.getBoolPref(kDontAskAgainPref);
-          } catch (ex) {}
-
+          var dontAskAgain = getPref(kDontAskAgainPref);
           if (!dontAskAgain)
           {
             var checkbox = {value:false};
             var okToProceed = Services.prompt.confirmCheck(
                                   window,
                                   sComposeMsgsBundle.getString("sendMsgTitle"),
                                   sComposeMsgsBundle.getString("recipientDlogMessage"),
                                   sComposeMsgsBundle.getString("CheckMsg"),
                                   checkbox);
 
             if (!okToProceed)
               return;
-
-            try {
-              if (checkbox.value)
-                pref.setBoolPref(kDontAskAgainPref, true);
-            } catch (ex) {}
           }
+          if (checkbox.value)
+            Services.prefs.setBoolPref(kDontAskAgainPref, true);
 
           // remove newsgroups to prevent news_p to be set
           // in nsMsgComposeAndSend::DeliverMessage()
           msgCompFields.newsgroups = "";
         }
 
         // Before sending the message, check what to do with HTML message, eventually abort.
         var convert = DetermineConvertibility();
@@ -1833,17 +1783,17 @@ function GenericSendMessage( msgType )
         var fallbackCharset = new Object;
         // 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))
         {
           var disableFallback = false;
           try
           {
-            disableFallback = sPrefs.getBoolPref("mailnews.disable_fallback_to_utf8." + originalCharset);
+            disableFallback = getPref("mailnews.disable_fallback_to_utf8." + originalCharset);
           }
           catch (e) {}
           if (disableFallback)
             msgCompFields.needToCheckCharset = false;
           else
             fallbackCharset.value = "UTF-8";
         }
 
@@ -1919,95 +1869,87 @@ function CheckValidEmailAddress(aTo, aCC
     Services.prompt.alert(window, errorTitle, errorMsg);
     return false;
   }
   return true;
 }
 
 function SendMessage()
 {
-  dump("SendMessage from XUL\n");
   GenericSendMessage(nsIMsgCompDeliverMode.Now);
 }
 
 function SendMessageWithCheck()
 {
-    var warn = sPrefs.getBoolPref("mail.warn_on_send_accel_key");
+    var warn = getPref("mail.warn_on_send_accel_key");
 
     if (warn) {
         var checkValue = {value:false};
         var buttonPressed = Services.prompt.confirmEx(window,
               sComposeMsgsBundle.getString('sendMessageCheckWindowTitle'),
               sComposeMsgsBundle.getString('sendMessageCheckLabel'),
               (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
               (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1),
               sComposeMsgsBundle.getString('sendMessageCheckSendButtonLabel'),
               null, null,
               sComposeMsgsBundle.getString('CheckMsg'),
               checkValue);
         if (buttonPressed != 0) {
             return;
         }
         if (checkValue.value) {
-            sPrefs.setBoolPref("mail.warn_on_send_accel_key", false);
+            Services.prefs.setBoolPref("mail.warn_on_send_accel_key", false);
         }
     }
 
   GenericSendMessage(Services.io.offline ? nsIMsgCompDeliverMode.Later
                                          : nsIMsgCompDeliverMode.Now);
 }
 
 function SendMessageLater()
 {
-  dump("SendMessageLater from XUL\n");
   GenericSendMessage(nsIMsgCompDeliverMode.Later);
 }
 
 function Save()
 {
-  dump("Save from XUL\n");
   switch (defaultSaveOperation)
   {
     case "file"     : SaveAsFile(false);      break;
     case "template" : SaveAsTemplate(false);  break;
     default         : SaveAsDraft(false);     break;
   }
 }
 
 function SaveAsFile(saveAs)
 {
-  dump("SaveAsFile from XUL\n");
-  var subject = document.getElementById('msgSubject').value;
+  var subject = GetMsgSubjectElement().value;
   GetCurrentEditor().setDocumentTitle(subject);
 
   if (gMsgCompose.bodyConvertible() == nsIMsgCompConvertible.Plain)
     SaveDocument(saveAs, false, "text/plain");
   else
     SaveDocument(saveAs, false, "text/html");
   defaultSaveOperation = "file";
 }
 
 function SaveAsDraft()
 {
-  dump("SaveAsDraft from XUL\n");
-
   GenericSendMessage(nsIMsgCompDeliverMode.SaveAsDraft);
   defaultSaveOperation = "draft";
-  
+
   gAutoSaveKickedIn = false;
   gEditingDraft = true;
 }
 
 function SaveAsTemplate()
 {
-  dump("SaveAsTemplate from XUL\n");
-
   GenericSendMessage(nsIMsgCompDeliverMode.SaveAsTemplate);
   defaultSaveOperation = "template";
-  
+
   gAutoSaveKickedIn = false;
   gEditingDraft = false;
 }
 
 // Sets the additional FCC, in addition to the default FCC.
 function MessageFcc(menuItem)
 {
   if (!gMsgCompose)
@@ -2220,17 +2162,17 @@ function ChangeLanguage(event)
   if (spellChecker.GetCurrentDictionary() != event.target.value)
   {
     spellChecker.SetCurrentDictionary(event.target.value);
 
     // now check the document and the subject over again with the new dictionary
     if (InlineSpellCheckerUI.enabled)
     {
       InlineSpellCheckerUI.mInlineSpellChecker.spellCheckRange(null);
-      document.getElementById('msgSubject').inputField.parentNode.spellCheckerUI.mInlineSpellChecker.spellCheckRange(null);
+      GetMsgSubjectElement().inputField.parentNode.spellCheckerUI.mInlineSpellChecker.spellCheckRange(null);
     }
   }
   event.stopPropagation();
 }
 
 function ToggleReturnReceipt(target)
 {
     var msgCompFields = gMsgCompose.compFields;
@@ -2266,33 +2208,35 @@ function ClearIdentityListPopup(popup)
 {
   if (popup)
     while (popup.hasChildNodes())
       popup.removeChild(popup.lastChild);
 }
 
 function compareAccountSortOrder(account1, account2)
 {
+  var ds = Components.classes["@mozilla.org/rdf/datasource;1?name=msgaccountmanager"]
+                     .getService(Components.interfaces.nsIRDFDataSource);
   var sortValue1, sortValue2;
 
   try {
     var res1 = sRDF.GetResource(account1.incomingServer.serverURI);
-    sortValue1 = sAccountManagerDataSource.GetTarget(res1, sNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
+    sortValue1 = ds.GetTarget(res1, sNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
   }
   catch (ex) {
     dump("XXX ex ");
     if (account1 && account1.incomingServer && account1.incomingServer.serverURI)
       dump(account1.incomingServer.serverURI + ",");
     dump(ex + "\n");
     sortValue1 = "";
   }
 
   try {
     var res2 = sRDF.GetResource(account2.incomingServer.serverURI);
-    sortValue2 = sAccountManagerDataSource.GetTarget(res2, sNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
+    sortValue2 = ds.GetTarget(res2, sNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
   }
   catch (ex) {
     dump("XXX ex ");
     if (account2 && account2.incomingServer && account2.incomingServer.serverURI)
       dump(account2.incomingServer.serverURI + ",");
     dump(ex + "\n");
     sortValue2 = "";
   }
@@ -2321,65 +2265,59 @@ function FillIdentityList(menulist)
       item.setAttribute("accountkey", accounts[i].key);
     }
   }
 }
 
 function getCurrentIdentity()
 {
     // fill in Identity combobox
-    var identityList = document.getElementById("msgIdentity");
+    var identityList = GetMsgIdentityElement();
 
     var identityKey = identityList.value;
 
     //dump("Looking for identity " + identityKey + "\n");
     var identity = gAccountManager.getIdentity(identityKey);
 
     return identity;
 }
 
 function getCurrentAccountKey()
 {
     // get the accounts key
-    var identityList = document.getElementById("msgIdentity");
+    var identityList = GetMsgIdentityElement();
     return identityList.selectedItem.getAttribute("accountkey");
 }
 
 function getIdentityForKey(key)
 {
     return gAccountManager.getIdentity(key);
 }
 
 function AdjustFocus()
 {
-  //dump("XXX adjusting focus\n");
   var element = awGetInputElement(awGetNumberOfRecipients());
   if (element.value == "") {
-      //dump("XXX focus on address\n");
       awSetFocus(awGetNumberOfRecipients(), element);
   }
   else
   {
-      element = document.getElementById("msgSubject");
+      element = GetMsgSubjectElement();
       if (element.value == "") {
-        //dump("XXX focus on subject\n");
         element.focus();
       }
       else {
-        //dump("XXX focus on body\n");
         SetMsgBodyFrameFocus();
       }
   }
 }
 
 function SetComposeWindowTitle()
 {
-  var newTitle = document.getElementById('msgSubject').value;
-
-  /* dump("newTitle = " + newTitle + "\n"); */
+  var newTitle = GetMsgSubjectElement().value;
 
   if (newTitle == "" )
     newTitle = sComposeMsgsBundle.getString("defaultSubject");
 
   newTitle += GetCharsetUIString();
   document.title = sComposeMsgsBundle.getString("windowTitlePrefix") + " " + newTitle;
 }
 
@@ -2504,17 +2442,18 @@ function MsgComposeCloseWindow(recycleIt
 
 // attachedLocalFile must be a nsILocalFile
 function SetLastAttachDirectory(attachedLocalFile)
 {
   try {
     var file = attachedLocalFile.QueryInterface(Components.interfaces.nsIFile);
     var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
 
-    sPrefs.setComplexValue(kComposeAttachDirPrefName, Components.interfaces.nsILocalFile, parent);
+    Services.prefs.setComplexValue(kComposeAttachDirPrefName,
+                                   Components.interfaces.nsILocalFile, parent);
   }
   catch (ex) {
     dump("error: SetLastAttachDirectory failed: " + ex + "\n");
   }
 }
 
 function AttachFile()
 {
@@ -2566,17 +2505,17 @@ function AttachFiles(attachments)
   }
   return firstAttachedFile;
 }
 
 function AddAttachment(attachment)
 {
   if (attachment && attachment.url)
   {
-    var bucket = document.getElementById("attachmentBucket");
+    var bucket = GetMsgAttachmentElement();
     var item = document.createElement("listitem");
 
     if (!attachment.name)
       attachment.name = gMsgCompose.AttachmentPrettyName(attachment.url, attachment.urlCharset);
 
     // for security reasons, don't allow *-message:// uris to leak out
     // we don't want to reveal the .slt path (for mailbox://), or the username or hostname
     var messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
@@ -2604,33 +2543,33 @@ function AddAttachment(attachment)
     item.setAttribute("image", "moz-icon:" + attachment.url);
     item.setAttribute("crop", "center");
     bucket.appendChild(item);
   }
 }
 
 function SelectAllAttachments()
 {
-  var bucketList = document.getElementById("attachmentBucket");
+  var bucketList = GetMsgAttachmentElement();
   if (bucketList)
     bucketList.selectAll();
 }
 
 function MessageHasAttachments()
 {
-  var bucketList = document.getElementById("attachmentBucket");
+  var bucketList = GetMsgAttachmentElement();
   if (bucketList) {
     return (bucketList && bucketList.hasChildNodes() && (bucketList == top.document.commandDispatcher.focusedElement));
   }
   return false;
 }
 
 function MessageGetNumSelectedAttachments()
 {
-  var bucketList = document.getElementById("attachmentBucket");
+  var bucketList = GetMsgAttachmentElement();
   return (bucketList) ? bucketList.selectedItems.length : 0;
 }
 
 function AttachPage()
 {
   var params = { action: "4", url: null };
   window.openDialog("chrome://communicator/content/openLocation.xul",
                     "_blank", "chrome,close,titlebar,modal", params);
@@ -2641,75 +2580,75 @@ function AttachPage()
                   .createInstance(Components.interfaces.nsIMsgAttachment);
     attachment.url = params.url;
     AddAttachment(attachment);
   }
 }
 
 function DuplicateFileCheck(FileUrl)
 {
-  var bucket = document.getElementById('attachmentBucket');
+  var bucket = GetMsgAttachmentElement();
   for (let i = 0; i < bucket.childNodes.length; i++)
   {
     let attachment = bucket.childNodes[i].attachment;
     if (attachment)
     {
       if (FileUrl == attachment.url)
          return true;
     }
   }
 
   return false;
 }
 
 function Attachments2CompFields(compFields)
 {
-  var bucket = document.getElementById('attachmentBucket');
+  var bucket = GetMsgAttachmentElement();
 
   //First, we need to clear all attachment in the compose fields
   compFields.removeAttachments();
 
   for (let i = 0; i < bucket.childNodes.length; i++)
   {
     let attachment = bucket.childNodes[i].attachment;
     if (attachment)
       compFields.addAttachment(attachment);
   }
 }
 
 function RemoveAllAttachments()
 {
   var child;
-  var bucket = document.getElementById("attachmentBucket");
+  var bucket = GetMsgAttachmentElement();
   while (bucket.hasChildNodes())
   {
     child = bucket.removeChild(bucket.lastChild);
     // Let's release the attachment object hold by the node else it won't go away until the window is destroyed
     child.attachment = null;
   }
 }
 
 function RemoveSelectedAttachment()
 {
   var child;
-  var bucket = document.getElementById("attachmentBucket");
+  var bucket = GetMsgAttachmentElement();
   if (bucket.selectedItems.length > 0) {
     for (let i = bucket.selectedItems.length - 1; i >= 0; i--)
     {
       child = bucket.removeChild(bucket.selectedItems[i]);
       // Let's release the attachment object hold by the node else it won't go away until the window is destroyed
       child.attachment = null;
     }
     gContentChanged = true;
   }
 }
 
 function RenameSelectedAttachment()
 {
-  var bucket = document.getElementById("attachmentBucket");
+  var bucket = GetMsgAttachmentElement();
   if (bucket.selectedItems.length != 1)
     return; // not one attachment selected
 
   var item = bucket.getSelectedItem(0);
   var attachmentName = {value: item.attachment.name};
   if (Services.prompt.prompt(
                      window,
                      sComposeMsgsBundle.getString("renameAttachmentTitle"),
@@ -2728,31 +2667,31 @@ function RenameSelectedAttachment()
     item.label = nameAndSize;
     item.attachment.name = modifiedAttachmentName;
     gContentChanged = true;
   }
 }
 
 function FocusOnFirstAttachment()
 {
-  var bucketList = document.getElementById("attachmentBucket");
+  var bucketList = GetMsgAttachmentElement();
 
   if (bucketList && bucketList.hasChildNodes())
     bucketList.selectItem(bucketList.firstChild);
 }
 
 function AttachmentElementHasItems()
 {
-  var element = document.getElementById("attachmentBucket");
+  var element = GetMsgAttachmentElement();
   return element ? element.childNodes.length : 0;
 }
 
 function OpenSelectedAttachment()
 {
-  var bucket = document.getElementById("attachmentBucket");
+  var bucket = GetMsgAttachmentElement();
   if (bucket.selectedItems.length == 1)
   {
     var attachmentUrl = bucket.getSelectedItem(0).attachment.url;
 
     var messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
     if (messagePrefix.test(attachmentUrl))
     {
       // we must be dealing with a forwarded attachment, treat this specially
@@ -2805,17 +2744,16 @@ function DetermineHTMLAction(convertible
           preferFormat = gMsgCompose.checkAndPopulateRecipients(true, true, obj);
           noHtmlRecipients = obj.value;
         } catch(ex) {
           dump("gMsgCompose.checkAndPopulateRecipients failed: " + ex + "\n");
           var msgCompFields = gMsgCompose.compFields;
           noHtmlRecipients = msgCompFields.to + "," + msgCompFields.cc + "," + msgCompFields.bcc;
           preferFormat = nsIAbPreferMailFormat.unknown;
         }
-        dump("DetermineHTMLAction: preferFormat = " + preferFormat + ", noHtmlRecipients are " + noHtmlRecipients + "\n");
 
         //Check newsgroups now...
         noHtmlnewsgroups = gMsgCompose.compFields.newsgroups;
 
         if (noHtmlRecipients != "" || noHtmlnewsgroups != "")
         {
             if (convertible == nsIMsgCompConvertible.Plain)
               return nsIMsgCompSendFormat.PlainText;
@@ -2825,17 +2763,17 @@ function DetermineHTMLAction(convertible
                 switch (preferFormat)
                 {
                   case nsIAbPreferMailFormat.plaintext :
                     return nsIMsgCompSendFormat.PlainText;
 
                   default :
                     //See if a preference has been set to tell us what to do. Note that we do not honor that
                     //preference for newsgroups. Only for e-mail addresses.
-                    var action = sPrefs.getIntPref("mail.default_html_action");
+                    var action = getPref("mail.default_html_action");
                     switch (action)
                     {
                         case nsIMsgCompSendFormat.PlainText    :
                         case nsIMsgCompSendFormat.HTML         :
                         case nsIMsgCompSendFormat.Both         :
                             return action;
                     }
                 }
@@ -2866,17 +2804,17 @@ function DetermineConvertibility()
     try {
         return gMsgCompose.bodyConvertible();
     } catch(ex) {}
     return nsIMsgCompConvertible.No;
 }
 
 function LoadIdentity(startup)
 {
-    var identityElement = document.getElementById("msgIdentity");
+    var identityElement = GetMsgIdentityElement();
     var prevIdentity = gCurrentIdentity;
 
     if (identityElement) {
         var idKey = identityElement.value;
         gCurrentIdentity = gAccountManager.getIdentity(idKey);
 
         let maxRecipients = awGetMaxRecipients();
         for (let i = 1; i <= maxRecipients; i++)
@@ -2965,17 +2903,17 @@ function LoadIdentity(startup)
 
           var event = document.createEvent('Events');
           event.initEvent('compose-from-changed', false, true);
           document.getElementById("msgcomposeWindow").dispatchEvent(event);
         }
 
       AddDirectoryServerObserver(false);
       if (!startup) {
-          if (sPrefs.getBoolPref("mail.autoComplete.highlightNonMatches"))
+          if (getPref("mail.autoComplete.highlightNonMatches"))
             document.getElementById('addressCol2#1').highlightNonMatches = true;
 
           try {
               setupLdapAutocompleteSession();
           } catch (ex) {
               // catch the exception and ignore it, so that if LDAP setup
               // fails, the entire compose window doesn't end up horked
           }
@@ -2994,20 +2932,20 @@ function setupAutocomplete()
   if (!gCurrentIdentity.autocompleteToMyDomain)
     autoCompleteWidget.minResultsForPopup = 2;
 
   // if the pref is set to turn on the comment column, honor it here.
   // this element then gets cloned for subsequent rows, so they should
   // honor it as well
   //
   try {
-      if (sPrefs.getBoolPref("mail.autoComplete.highlightNonMatches"))
+      if (getPref("mail.autoComplete.highlightNonMatches"))
         autoCompleteWidget.highlightNonMatches = true;
 
-      if (sPrefs.getIntPref("mail.autoComplete.commentColumn"))
+      if (getPref("mail.autoComplete.commentColumn"))
         autoCompleteWidget.showCommentColumn = true;
   } catch (ex) {
       // if we can't get this pref, then don't show the columns (which is
       // what the XUL defaults to)
   }
   if (!gSetupLdapAutocomplete) {
       try {
           setupLdapAutocompleteSession();
@@ -3126,23 +3064,23 @@ var attachmentBucketObserver = {
             }
           }
         }
       }
     },
 
   onDragOver: function (aEvent, aFlavour, aDragSession)
     {
-      var attachmentBucket = document.getElementById("attachmentBucket");
+      var attachmentBucket = GetMsgAttachmentElement();
       attachmentBucket.setAttribute("dragover", "true");
     },
 
   onDragExit: function (aEvent, aDragSession)
     {
-      var attachmentBucket = document.getElementById("attachmentBucket");
+      var attachmentBucket = GetMsgAttachmentElement();
       attachmentBucket.removeAttribute("dragover");
     },
 
   getSupportedFlavours: function ()
     {
       var flavourSet = new FlavourSet();
       flavourSet.appendFlavour("text/x-moz-message");
       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
@@ -3341,104 +3279,120 @@ function SwitchElementFocus(event)
       SetMsgIdentityElementFocus();
     else
       SetMsgAddressingWidgetElementFocus();
   }
 }
 
 function loadHTMLMsgPrefs()
 {
-  var pref = GetPrefs();
-  var fontFace;
   var fontSize;
   var textColor;
   var bgColor;
 
-  try {
-    fontFace = pref.getCharPref("msgcompose.font_face");
-    doStatefulCommand('cmd_fontFace', fontFace);
-  } catch (e) {}
+  // This version of GetStringPref() comes from editorUtilities.js instead of
+  // utilitiesOverlay.js
+  var fontFace = GetStringPref("msgcompose.font_face");
+  doStatefulCommand("cmd_fontFace", fontFace);
 
   try {
-    fontSize = pref.getCharPref("msgcompose.font_size");
+    fontSize = getPref("msgcompose.font_size");
     EditorSetFontSize(fontSize);
   } catch (e) {}
 
   var bodyElement = GetBodyElement();
 
   try {
-    textColor = pref.getCharPref("msgcompose.text_color");
+    textColor = getPref("msgcompose.text_color");
     if (!bodyElement.hasAttribute("text"))
     {
       bodyElement.setAttribute("text", textColor);
       gDefaultTextColor = textColor;
       document.getElementById("cmd_fontColor").setAttribute("state", textColor);
       onFontColorChange();
     }
   } catch (e) {}
 
   try {
-    bgColor = pref.getCharPref("msgcompose.background_color");
+    bgColor = getPref("msgcompose.background_color");
     if (!bodyElement.hasAttribute("bgcolor"))
     {
       bodyElement.setAttribute("bgcolor", bgColor);
       gDefaultBackgroundColor = bgColor;
       document.getElementById("cmd_backgroundColor").setAttribute("state", bgColor);
       onBackgroundColorChange();
     }
   } catch (e) {}
 }
 
 function AutoSave()
 {
-  dump("in autosave\n");
   if (gMsgCompose.editor && (gContentChanged || gMsgCompose.bodyModified))
   {
     GenericSendMessage(nsIMsgCompDeliverMode.AutoSaveAsDraft);
     gAutoSaveKickedIn = true;
   }
   gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
 }
 
 function InitEditor(editor)
 {
   gMsgCompose.initEditor(editor, window.content);
   InlineSpellCheckerUI.init(editor);
-  EnableInlineSpellCheck(sPrefs.getBoolPref("mail.spellcheck.inline"));
+  EnableInlineSpellCheck(getPref("mail.spellcheck.inline"));
   document.getElementById("menu_inlineSpellCheck").setAttribute("disabled", !InlineSpellCheckerUI.canSpellCheck);
 }
 
 function EnableInlineSpellCheck(aEnableInlineSpellCheck)
 {
   InlineSpellCheckerUI.enabled = aEnableInlineSpellCheck;
-  document.getElementById('msgSubject').setAttribute('spellcheck', aEnableInlineSpellCheck);
+  GetMsgSubjectElement().setAttribute("spellcheck", aEnableInlineSpellCheck);
 }
 
 function getMailToolbox()
 {
   return document.getElementById("compose-toolbox");
 }
 
 function MailToolboxCustomizeInit()
 {
   if (document.commandDispatcher.focusedWindow == content)
     window.focus();
   disableEditableFields();
-  document.getElementById("MsgHeadersToolbar").setAttribute("moz-collapsed", true);
+  GetMsgHeadersToolbarElement().setAttribute("moz-collapsed", true);
   document.getElementById("compose-toolbar-sizer").setAttribute("moz-collapsed", true);
   document.getElementById("content-frame").setAttribute("moz-collapsed", true);
   toolboxCustomizeInit("mail-menubar");
 }
 
 function MailToolboxCustomizeDone(aToolboxChanged)
 {
   toolboxCustomizeDone("mail-menubar", getMailToolbox(), aToolboxChanged);
-  document.getElementById("MsgHeadersToolbar").removeAttribute("moz-collapsed");
+  GetMsgHeadersToolbarElement().removeAttribute("moz-collapsed");
   document.getElementById("compose-toolbar-sizer").removeAttribute("moz-collapsed");
   document.getElementById("content-frame").removeAttribute("moz-collapsed");
   enableEditableFields();
   SetMsgBodyFrameFocus();
 }
 
 function MailToolboxCustomizeChange(aEvent)
 {
   toolboxCustomizeChange(getMailToolbox(), aEvent);
 }
+
+// Thunderbird compatibility function.
+function getPref(aPrefName, aIsComplex)
+{
+  if (aIsComplex)
+      return GetStringPref(aPrefName);
+
+  switch (Services.prefs.getPrefType(aPrefName))
+  {
+    case Components.interfaces.nsIPrefBranch.PREF_BOOL:
+      return Services.prefs.getBoolPref(aPrefName);
+    case Components.interfaces.nsIPrefBranch.PREF_INT:
+      return Services.prefs.getIntPref(aPrefName);
+    case Components.interfaces.nsIPrefBranch.PREF_STRING:
+      return Services.prefs.getCharPref(aPrefName);
+    default: // includes nsIPrefBranch.PREF_INVALID
+      return null;
+  }
+}