Bug 953475 - Command-W Does Not Close Buddy List Window.
authorFlorian Quèze <florian@instantbird.org>
Thu, 17 Mar 2011 17:42:56 +0100
changeset 18182 a1765b4e2e9170c2e4b17903739f5304fdd69375
parent 18181 b1ba8f8385de5ef0b7734bcf5f58d1a39b221b8d
child 18183 b1334d8d641a8c757f3877a3e8d501951c447058
push id1103
push usermbanner@mozilla.com
push dateTue, 18 Mar 2014 07:44:06 +0000
treeherdercomm-beta@50c6279a0af0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs953475
Bug 953475 - Command-W Does Not Close Buddy List Window.
im/app/profile/all-instantbird.js
im/components/Makefile.in
im/components/autoLoginHandler.js
im/components/autoLoginHandler.manifest
im/components/ibCommandLineHandler.js
im/components/ibCommandLineHandler.manifest
im/components/logger.js
im/content/blist.js
im/content/blist.xul
im/content/contact.xml
im/content/core.js
im/content/debug/debug.js
im/content/hiddenWindow.xul
im/content/jar.mn
im/content/menus-mac.xul
im/content/menus.js
im/installer/package-manifest.in
im/locales/en-US/chrome/instantbird/instantbird.dtd
im/modules/Makefile.in
im/modules/ibCore.jsm
im/modules/imWindows.jsm
--- a/im/app/profile/all-instantbird.js
+++ b/im/app/profile/all-instantbird.js
@@ -1,10 +1,13 @@
 pref("toolkit.defaultChromeURI", "chrome://instantbird/content/blist.xul");
 pref("toolkit.singletonWindowType", "Messenger:blist");
+#ifdef XP_MACOSX
+pref("browser.hiddenWindowChromeURL", "chrome://instantbird/content/hiddenWindow.xul");
+#endif
 
 #expand pref("general.useragent.extra.instantbird", "Instantbird/__APP_VERSION__");
 
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 #define UNIX_BUT_NOT_MAC
 #endif
 #endif
--- a/im/components/Makefile.in
+++ b/im/components/Makefile.in
@@ -41,20 +41,23 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= instantbird
 
 XPIDLSRCS	= ibILogger.idl
 
 EXTRA_COMPONENTS = \
+	ibCommandLineHandler.manifest \
+	logger.manifest \
 	smileProtocolHandler.js smileProtocolHandler.manifest \
-	autoLoginHandler.js autoLoginHandler.manifest \
-	logger.manifest \
 	$(NULL)
 
-EXTRA_PP_COMPONENTS = logger.js
+EXTRA_PP_COMPONENTS = \
+	ibCommandLineHandler.js \
+	logger.js \
+	$(NULL)
 
 ifeq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_COMPONENTS += profileMigrator.js profileMigrator.manifest
 endif
 
 include $(topsrcdir)/config/rules.mk
rename from im/components/autoLoginHandler.js
rename to im/components/ibCommandLineHandler.js
--- a/im/components/autoLoginHandler.js
+++ b/im/components/ibCommandLineHandler.js
@@ -31,44 +31,69 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/ibCore.jsm");
 
-function autoLoginHandler() { }
+function ibCommandLineHandler() { }
 
-autoLoginHandler.prototype = {
+ibCommandLineHandler.prototype = {
   handle: function clh_handle(cmdLine) {
     if (cmdLine.handleFlag("preferences", false)) {
-      var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
-      var url = "chrome://instantbird/content/preferences/preferences.xul";
-      Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
-                .getService(Components.interfaces.nsIWindowWatcher)
-                .openWindow(null, url, "_blank", features, null);
+      Core.showPreferences();
       cmdLine.preventDefault = true;
+      return;
+    }
+
+    if (cmdLine.handleFlag("n", false)) {
+      Components.classes["@instantbird.org/purple/core;1"]
+                .getService(Ci.purpleICoreService)
+                .autoLoginStatus = Ci.purpleICoreService.AUTOLOGIN_USER_DISABLED;
     }
 
-    if (!cmdLine.handleFlag("n", false))
-      return;
-
-    Components.classes["@instantbird.org/purple/core;1"]
-              .getService(Ci.purpleICoreService)
-              .autoLoginStatus = Ci.purpleICoreService.AUTOLOGIN_USER_DISABLED;
+    // Initialize the core only at the first real startup,
+    // not when clicking the dock.
+    if (cmdLine.state == cmdLine.STATE_INITIAL_LAUNCH) {
+      // If the core failed to init, don't show the buddy list
+      if (!Core.init())
+        cmdLine.preventDefault = true;
+#ifdef XP_MACOSX
+      else {
+        // If we have no reason to show the account manager and the
+        // buddy list is not shown because of the -silent flag, we
+        // should avoid an early exit.
+        // The code in nsAppStartup::Run won't start the event loop if
+        // we don't have at least one window or one call to
+        // enterLastWindowClosingSurvivalArea.
+        let as = Components.classes["@mozilla.org/toolkit/app-startup;1"]
+                           .getService(Ci.nsIAppStartup);
+        as.enterLastWindowClosingSurvivalArea();
+        // We can exitLastWindowClosingSurvivalArea as soon as the
+        // load of our application provided hiddenWindow has begun.
+        let tm = Components.classes["@mozilla.org/thread-manager;1"]
+                           .getService(Components.interfaces.nsIThreadManager);
+        tm.mainThread.dispatch(function() {
+          as.exitLastWindowClosingSurvivalArea();
+        }, tm.DISPATCH_NORMAL);
+      }
+#endif
+    }
   },
 
   // 3 tabs here because there is a misalignment with only 2
   helpInfo: "  -n                 Disables auto-login.\n" +
-            "  -preferences       Open only the preferences window.",
+            "  -preferences       Open only the preferences window.\n" +
+            "  -silent            Do not open the contacts list.\n",
 
-  classDescription: "AutoLogin Handler",
-  classID: Components.ID("{9e5d5160-d61d-4d57-ae0d-81bee4380269}"),
-  contractID: "@instantbird.org/autologin-handler;1",
+  classDescription: "Instantbird Command Line Handler",
+  classID: Components.ID("{cd6763b7-df9a-4b64-9d06-2b77c755d9c1}"),
+  contractID: "@instantbird.org/command-line-handler;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler])
 };
 
-const NSGetFactory = XPCOMUtils.generateNSGetFactory([autoLoginHandler]);
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([ibCommandLineHandler]);
rename from im/components/autoLoginHandler.manifest
rename to im/components/ibCommandLineHandler.manifest
--- a/im/components/autoLoginHandler.manifest
+++ b/im/components/ibCommandLineHandler.manifest
@@ -1,3 +1,3 @@
-component {9e5d5160-d61d-4d57-ae0d-81bee4380269} autoLoginHandler.js
-contract @instantbird.org/autologin-handler;1 {9e5d5160-d61d-4d57-ae0d-81bee4380269}
-category command-line-handler b-n @instantbird.org/autologin-handler;1
+component {cd6763b7-df9a-4b64-9d06-2b77c755d9c1} ibCommandLineHandler.js
+contract @instantbird.org/command-line-handler;1 {cd6763b7-df9a-4b64-9d06-2b77c755d9c1}
+category command-line-handler b-n @instantbird.org/command-line-handler;1
--- a/im/components/logger.js
+++ b/im/components/logger.js
@@ -128,17 +128,17 @@ ConversationLog.prototype = {
            " on " + account.name +
            " (" + account.protocol.normalizedName + ")@LINE_BREAK@";
   },
   _serialize: function cl_serialize(aString) {
     // TODO cleanup once bug 102699 is fixed
     let doc = Cc["@mozilla.org/appshell/appShellService;1"]
                .getService(Ci.nsIAppShellService)
                .hiddenDOMWindow.document;
-    let div = doc.createElement("div");
+    let div = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
     div.innerHTML = aString.replace(/\r?\n/g, "<br/>");
     const type = "text/plain";
     let encoder =
       Components.classes["@mozilla.org/layout/documentEncoder;1?type=" + type]
                 .createInstance(Components.interfaces.nsIDocumentEncoder);
     encoder.init(doc, type, 0);
     encoder.setContainerNode(div);
     encoder.setNodeFixup({fixupNode: function(aNode, aSerializeKids) {
--- a/im/content/blist.js
+++ b/im/content/blist.js
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 Components.utils.import("resource:///modules/imStatusUtils.jsm");
 
 const events = ["contact-availability-changed",
                 "contact-added",
                 "contact-moved",
-                "account-disconnected",
                 "status-changed",
                 "purple-quit"];
 
 const showOfflineBuddiesPref = "messenger.buddies.showOffline";
 
 var gBuddyListContextMenu = null;
 
 function buddyListContextMenu(aXulMenu) {
@@ -230,24 +229,16 @@ var buddyList = {
             blistBox.removeChild(elt);
         }
       });
       return;
     }
 
     if (aTopic == "status-changed") {
       this.displayCurrentStatus();
-      this.showAccountManagerIfNeeded(false);
-      return;
-    }
-
-    if (aTopic == "account-disconnected") {
-      let account = aSubject.QueryInterface(Ci.purpleIAccount);
-      if (account.reconnectAttempt <= 1)
-        this.showAccountManagerIfNeeded(false);
       return;
     }
 
     // aSubject is an imIContact
     if (aSubject.online || this._showOffline) {
       aSubject.getTags().forEach(function (aTag) {
         if (!document.getElementById("group" + aTag.id)) {
           let groupElt = document.createElement("group");
@@ -399,97 +390,27 @@ var buddyList = {
     if (elt.hasAttribute("usingDefault"))
       elt.setAttribute("value", elt.getAttribute("usingDefault"));
     TextboxSpellChecker.unregisterTextbox(elt);
     elt.removeAttribute("editing");
     elt.removeEventListener("keypress", this.statusMessageKeyPress, false);
     elt.removeEventListener("blur", this.statusMessageBlur, false);
   },
 
-  getAccounts: function bl_getAccounts() getIter(Services.core.getAccounts()),
-
-  /* This function pops up the account manager is no account is
-   * connected or connecting.
-   * When called during startup (aIsStarting == true), it will also
-   * look for crashed accounts.
-   */
-  showAccountManagerIfNeeded: function bl_showAccountManagerIfNeeded(aIsStarting) {
-    // If the current status is offline, we don't need the account manager
-    let isOffline =
-      Services.core.currentStatusType == Ci.imIStatusInfo.STATUS_OFFLINE;
-    if (isOffline && !aIsStarting)
-      return;
-
-    let hasActiveAccount = false;
-    let hasCrashedAccount = false;
-    for (let acc in this.getAccounts()) {
-      if (acc.connected || acc.connecting)
-        hasActiveAccount = true;
-
-      // We only check for crashed accounts on startup.
-      if (aIsStarting && acc.autoLogin &&
-          acc.firstConnectionState == acc.FIRST_CONNECTION_CRASHED)
-        hasCrashedAccount = true;
-    }
-
-    /* We only display the account manager on startup if an account has crashed
-       or if all accounts are disconnected
-       In case of connection failure after an automatic reconnection attempt,
-       we don't want to popup the account manager */
-    if ((!hasActiveAccount && !isOffline) || (aIsStarting && hasCrashedAccount))
-      menus.accounts();
-  },
-
   load: function bl_load() {
     var blistWindows = Services.wm.getEnumerator("Messenger:blist");
     while (blistWindows.hasMoreElements()) {
       var win = blistWindows.getNext();
       if (win != window) {
         win.QueryInterface(Ci.nsIDOMWindowInternal).focus();
         window.close();
         return;
       }
     }
 
-    try {
-      // Set the Vendor for breakpad only
-      if ("nsICrashReporter" in Ci) {
-        Components.classes["@mozilla.org/xre/app-info;1"]
-                  .getService(Ci.nsICrashReporter)
-                  .annotateCrashReport("Vendor", "Instantbird");
-      }
-    } catch(e) {
-      // This can fail if breakpad isn't enabled,
-      // don't worry too much about this exception.
-    }
-
-    if (!initPurpleCore()) {
-      window.close();
-      return;
-    }
-
-    let status = {
-      back: "AVAILABLE",
-      away: "AWAY",
-      busy: "UNAVAILABLE",
-      dnd: "UNAVAILABLE",
-      offline: "OFFLINE"
-    };
-    for (let cmd in status) {
-      let statusValue = Ci.imIStatusInfo["STATUS_" + status[cmd]];
-      Services.cmd.registerCommand({
-        name: cmd,
-        priority: Ci.imICommand.PRIORITY_HIGH,
-        run: function(aMsg) {
-          Services.core.setStatus(statusValue, aMsg);
-          return true;
-        }
-      });
-    }
-
     // TODO remove this once we cleanup the way the menus are inserted
     let menubar = document.getElementById("blistMenubar");
     let statusArea = document.getElementById("statusArea");
     statusArea.parentNode.insertBefore(menubar, statusArea);
 
     buddyList.displayCurrentStatus();
 
     let prefBranch = Services.prefs;
@@ -508,34 +429,23 @@ var buddyList = {
       if (!groupElt.build(aTag))
         blistBox.removeChild(groupElt);
     });
     blistBox.focus();
 
     prefBranch.addObserver(showOfflineBuddiesPref, buddyList, false);
     addObservers(buddyList, events);
 
-    Components.utils.import("resource:///modules/imWindows.jsm");
-    Conversations.init();
-
-    buddyList.showAccountManagerIfNeeded(true);
     this.addEventListener("unload", buddyList.unload, false);
-    this.addEventListener("close", buddyList.close, false);
   },
   unload: function bl_unload() {
     removeObservers(buddyList, events);
     Services.prefs.removeObserver(showOfflineBuddiesPref, buddyList);
-    uninitPurpleCore();
    },
 
-  close: function bl_close(event) {
-    event.preventDefault();
-    goQuitApplication();
-  },
-
   // Handle key pressing
   keyPress: function bl_keyPress(aEvent) {
     var item = document.getElementById("buddylistbox").selectedItem;
     if (!item || !item.parentNode) // empty list or item no longer in the list
       return;
     item.keyPress(aEvent);
   }
 };
--- a/im/content/blist.xul
+++ b/im/content/blist.xul
@@ -51,24 +51,36 @@
 
 <window
   id     = "blistWindow"
   windowtype="Messenger:blist"
   title  = "&blist.title;"
   width  = "200"
   height = "600"
   persist= "width height screenX screenY"
+#ifndef XP_MACOSX
+  onclose= "event.preventDefault(); goQuitApplication();"
+#endif
   xmlns  = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://instantbird/content/utilities.js"/>
-  <script type="application/javascript" src="chrome://instantbird/content/core.js"/>
   <script type="application/javascript" src="chrome://instantbird/content/blist.js"/>
   <script type="application/javascript" src="chrome://instantbird/content/sound.js"/>
 
 #include menus.xul.inc
 
+#ifdef XP_MACOSX
+  <commandset id="blistCommands">
+    <command id="cmd_close" oncommand="window.close();"/>
+  </commandset>
+
+  <keyset id="blistKeys">
+    <key id="key_close" key="w" modifiers="accel" command="cmd_close"/>
+  </keyset>
+
+#endif
   <popupset id="mainPopupSet">
     <tooltip id="buddyTooltip" type="buddy"
              onpopupshowing="if ('_droptarget' in window) return false;"/>
 
     <menupopup id="buddyListContextMenu"
                onpopupshowing="if (event.target != this) return true; gBuddyListContextMenu = new buddyListContextMenu(this); return gBuddyListContextMenu.shouldDisplay;"
                onpopuphiding="if (event.target == this) { gBuddyListContextMenu = null; }">
       <menuitem id="context-openconversation"
--- a/im/content/contact.xml
+++ b/im/content/contact.xml
@@ -307,16 +307,18 @@
          return this.contact.canSendMessage;
        ]]>
       </body>
      </method>
 
      <method name="openConversation">
       <body>
        <![CDATA[
+         if (!("Conversations" in window))
+           Components.utils.import("resource:///modules/imWindows.jsm");
          Conversations.focusConversation(this.contact.createConversation());
        ]]>
       </body>
      </method>
 
      <method name="keyPress">
       <parameter name="aEvent"/>
       <body>this._keyPress(aEvent);</body>
--- a/im/content/debug/debug.js
+++ b/im/content/debug/debug.js
@@ -20,18 +20,18 @@ var debug = {
     start_venkman();
   },
 
   inspector: function debug_inspector() {
     inspectDOMDocument(document);
   },
 
   garbageCollect: function debug_garbageCollect() {
-    window.QueryInterface(Ci.nsIInterfaceRequestor)
-          .getInterface(Ci.nsIDOMWindowUtils)
+    window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+          .getInterface(Components.interfaces.nsIDOMWindowUtils)
           .garbageCollect();
   },
 
   forceOnline: function debug_forceOnline() {
     var ios = Services.io;
     ios.manageOfflineStatus = false;
     ios.offline = false;
   },
new file mode 100644
--- /dev/null
+++ b/im/content/hiddenWindow.xul
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+# -*- Mode: HTML -*-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Communicator client code, released
+# March 31, 1998.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   David Hyatt <hyatt@mozilla.org> (Original Author)
+#   Asaf Romano <mozilla.mano@sent.com>
+#   Florian Queze <florian@instantbird.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#ifdef XP_MACOSX
+<?xul-overlay href="chrome://instantbird/content/menus.xul"?>
+
+<window id="main-window"
+        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+#include menus.xul.inc
+
+<script type="application/javascript">
+  addEventListener("load", function() {
+    // disable the minimize and zoom menu items.
+    ["minimizeWindow", "zoomWindow"].forEach(function(aId) {
+      document.getElementById(aId).setAttribute("disabled", "true");
+    });
+
+    // also hide the window-list separator
+    document.getElementById("sep-window-list").setAttribute("hidden", "true");
+  }, false);
+</script>
+
+</window>
+
+#endif
--- a/im/content/jar.mn
+++ b/im/content/jar.mn
@@ -12,19 +12,18 @@ instantbird.jar:
 	instantbird/account.xul
 	instantbird/addbuddy.js
 	instantbird/addbuddy.xul
 	instantbird/blist.css
 	instantbird/blist.js
 *	instantbird/blist.xul
 	instantbird/buddy.xml
 	instantbird/buddytooltip.xml
-        instantbird/browserRequest.js
-        instantbird/browserRequest.xul
-	instantbird/core.js
+	instantbird/browserRequest.js
+	instantbird/browserRequest.xul
 	instantbird/topicNotification.xml
 	instantbird/contact.xml
 *	instantbird/conversation.xml
 	instantbird/convbrowser.xml
 	instantbird/conv.html
 *	instantbird/credits.xhtml
 *	instantbird/engineManager.js
 *	instantbird/engineManager.xul
@@ -45,16 +44,17 @@ instantbird.jar:
 	instantbird/sound.js
 *	instantbird/tabbrowser.xml
 	instantbird/tabbrowser.css
 	instantbird/utilities.js
 *	instantbird/viewlog.xul
 	instantbird/viewlog.js
 	instantbird/viewlog.css
 #ifdef XP_MACOSX
+*	instantbird/hiddenWindow.xul
 	instantbird/menus-mac.xul
 	instantbird/macgestures.js
 #elifdef XP_WIN
 	instantbird/menus-win.xul
 #else
 	instantbird/menus-unix.xul
 #endif
 *	instantbird/preferences/advanced.xul            (preferences/advanced.xul)
--- a/im/content/menus-mac.xul
+++ b/im/content/menus-mac.xul
@@ -40,16 +40,29 @@
   <!ENTITY % instantbirdDTD SYSTEM "chrome://instantbird/locale/instantbird.dtd">
   %instantbirdDTD;
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
   %brandDTD;
 ]>
 <overlay id="menusOverlayMac"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
+  <commandset id="maincommandset">
+    <command id="cmd_contacts"
+             oncommand="if (window.location.href == 'chrome://instantbird/content/blist.xul')
+                          window.close();
+                        else
+                          Core.showContacts();"/>
+  </commandset>
+
+  <keyset id="mainkeyset">
+    <key id="contactskey" command="cmd_contacts"
+         key="&contacts.commandkey;" modifiers="accel,shift"/>
+  </keyset>
+
   <!-- adds the onpopupshowing attributes -->
   <menupopup id="setStatusMenupopup"
              onpopupshowing="menus.onStatusPopupShowing();"/>
   <menupopup id="toolsMenuPopup"
              onpopupshowing="menus.displayUpdateStatus();"/>
 
   <menuitem id="menu_FileQuitItem"
             label="&quitApplicationCmdMac.label;"
@@ -61,16 +74,19 @@
   <menupopup id="helpMenuPopup" onpopupshowing=""/>
   <menuitem id="updatesMenuItem" removeelement="true"/>
   <menuseparator id="updatesSep" removeelement="true"/>
 
   <!-- bottom of the tools menu -->
   <menuseparator id="prefSep" removeelement="true"/>
   <menuitem id="menu_preferences" removeelement="true"/>
   <menupopup id="toolsMenuPopup">
+    <menuitem id="contactsMenuItem" insertbefore="addonsMenuItem"
+              label="&contacts.label;" accesskey="&contacts.accesskey;"
+              command="cmd_contacts" key="contactskey"/>
     <menuseparator id="updatesSep"/>
     <menuitem id="updatesMenuItem"
               label="&checkForUpdates;"
               oncommand="menus.updates()"/>
   </menupopup>
 
   <menu id="helpMenu" hidden="true"/>
 
--- a/im/content/menus.js
+++ b/im/content/menus.js
@@ -41,71 +41,55 @@ const blistWindow = "chrome://instantbir
 const addBuddyWindow = "chrome://instantbird/content/addbuddy.xul";
 const joinChatWindow = "chrome://instantbird/content/joinchat.xul";
 const aboutWindow = "chrome://instantbird/content/aboutDialog.xul";
 const errorConsoleWindow = "chrome://global/content/console.xul";
 const preferencesWindow = "chrome://instantbird/content/preferences/preferences.xul";
 
 if (!("Services" in window))
   Components.utils.import("resource:///modules/imServices.jsm");
+if (!("Core" in window))
+  Components.utils.import("resource:///modules/ibCore.jsm");
 
 var menus = {
   focus: function menu_focus(aWindowType) {
     var win = Services.wm.getMostRecentWindow(aWindowType);
     if (win)
       win.focus();
     return win;
   },
 
   about: function menu_about() {
     if (!this.focus("Messenger:About"))
       window.open(aboutWindow, "About",
                   "chrome,resizable=no,minimizable=no,centerscreen");
   },
 
   accounts: function menu_accounts() {
-    if (!this.focus("Messenger:Accounts"))
-      window.open(accountManagerWindow, "Accounts",
-                  "chrome,resizable");
+    Core.showAccounts();
   },
 
   preferences: function menu_preferences() {
-    if (!this.focus("Messenger:Preferences"))
-      window.open(preferencesWindow, "Preferences",
-                  "chrome,titlebar,toolbar,centerscreen,dialog=no");
+    Core.showPreferences();
   },
 
   addons: function menu_addons() {
     if (!this.focus("Extension:Manager"))
       window.open(addonManagerWindow, "Addons",
                   "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable");
   },
 
   errors: function debug_errors() {
     if (!menus.focus("global:console"))
       window.open(errorConsoleWindow, "Errors",
                   "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
   },
 
   updates: function menu_updates() {
-    // copied from checkForUpdates in mozilla/browser/base/content/utilityOverlay.js
-    var um =
-      Components.classes["@mozilla.org/updates/update-manager;1"]
-                .getService(Components.interfaces.nsIUpdateManager);
-    var prompter =
-      Components.classes["@mozilla.org/updates/update-prompt;1"]
-                .createInstance(Components.interfaces.nsIUpdatePrompt);
-
-    // If there's an update ready to be applied, show the "Update Downloaded"
-    // UI instead and let the user know they have to restart the browser for
-    // the changes to be applied.
-    if (um.activeUpdate && um.activeUpdate.state == "pending")
-      prompter.showUpdateDownloaded(um.activeUpdate);
-    else
-      prompter.checkForUpdates();
+    Core.showUpdates();
   },
 
   displayUpdateStatus: function menu_displayUpdateStatus() {
     // copied from buildHelpMenu in mozilla/browser/base/content/utilityOverlay.js
     var updates =
       Components.classes["@mozilla.org/updates/update-service;1"]
                 .getService(Components.interfaces.nsIApplicationUpdateService);
     var um =
@@ -154,27 +138,28 @@ var menus = {
     checkForUpdates.accessKey =
       strings.GetStringFromName("updatesItem_" + key + ".accesskey");
     if (um.activeUpdate && updates.isDownloading)
       checkForUpdates.setAttribute("loading", "true");
     else
       checkForUpdates.removeAttribute("loading");
   },
 
-  getAccounts: function bl_getAccounts() {
-    return getIter(Services.core.getAccounts());
-  },
   updateFileMenuitems: function menu_updateFileMenuitems() {
     let hasConnectedAccount = false;
     let canJoinChat = false;
-    for (let acc in this.getAccounts()) {
+    let enumerator = Services.core.getAccounts();
+    while (enumerator.hasMoreElements()) {
+      let acc = enumerator.getNext();
       if (acc.connected) {
         hasConnectedAccount = true;
-        if (acc.canJoinChat)
+        if (acc.canJoinChat) {
           canJoinChat = true;
+          break;
+        }
       }
     }
 
     document.getElementById("addBuddyMenuItem").disabled = !hasConnectedAccount;
     document.getElementById("joinChatMenuItem").disabled = !canJoinChat;
   },
 
   addBuddy: function menu_addBuddy() {
--- a/im/installer/package-manifest.in
+++ b/im/installer/package-manifest.in
@@ -406,18 +406,18 @@
 @BINPATH@/components/imCommands.manifest
 @BINPATH@/components/imContacts.js
 @BINPATH@/components/imContacts.manifest
 
 #ifndef XP_MACOSX
 @BINPATH@/components/profileMigrator.js
 @BINPATH@/components/profileMigrator.manifest
 #endif
-@BINPATH@/components/autoLoginHandler.js
-@BINPATH@/components/autoLoginHandler.manifest
+@BINPATH@/components/ibCommandLineHandler.js
+@BINPATH@/components/ibCommandLineHandler.manifest
 @BINPATH@/components/facebookOverrideProtocol.js
 @BINPATH@/components/gtalkOverrideProtocol.js
 @BINPATH@/components/overrideProtocols.manifest
 @BINPATH@/components/twitter.js
 @BINPATH@/components/twitter.manifest
 @BINPATH@/components/smileProtocolHandler.js
 @BINPATH@/components/smileProtocolHandler.manifest
 @BINPATH@/components/logger.js
--- a/im/locales/en-US/chrome/instantbird/instantbird.dtd
+++ b/im/locales/en-US/chrome/instantbird/instantbird.dtd
@@ -22,16 +22,19 @@
 <!ENTITY available          "Available">
 <!ENTITY unavailable        "Unavailable">
 <!ENTITY offline            "Offline">
 <!ENTITY tools.menu         "Tools">
 <!ENTITY tools.accesskey    "T">
 <!ENTITY accountManager     "Accounts">
 <!ENTITY account.commandkey "a">
 <!ENTITY account.accesskey  "A">
+<!ENTITY contacts.label     "Contacts">
+<!ENTITY contacts.commandkey "c">
+<!ENTITY contacts.accesskey "C">
 <!ENTITY addonManager       "Add-ons">
 <!ENTITY checkForUpdates    "Check for Updates">
 <!ENTITY help.menu          "Help">
 <!ENTITY help.accesskey     "H">
 <!-- LOCALIZATION NOTE (helpWin.menu):
     Some localizations of Windows (e.g. French, German) use "?" for the help
     button in the menubar. -->
 <!ENTITY helpWin.menu       "Help">
--- a/im/modules/Makefile.in
+++ b/im/modules/Makefile.in
@@ -37,16 +37,17 @@
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_JS_MODULES = \
+	ibCore.jsm \
 	imContentSink.jsm \
 	imServices.jsm \
 	imSmileys.jsm \
 	imStatusUtils.jsm \
 	$(NULL)
 
 EXTRA_PP_JS_MODULES = \
 	imThemes.jsm \
rename from im/content/core.js
rename to im/modules/ibCore.jsm
--- a/im/content/core.js
+++ b/im/modules/ibCore.jsm
@@ -31,91 +31,289 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-function initPurpleCore()
-{
-  if (!Ci.purpleICoreService) {
-    promptError("startupFailure.purplexpcomFileError");
-    return false;
-  }
+const EXPORTED_SYMBOLS = ["Core"];
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource:///modules/imServices.jsm");
+Cu.import("resource:///modules/imWindows.jsm");
 
-  if (!Components.classes["@instantbird.org/purple/core;1"]) {
-    promptError("startupFailure.xpcomRegistrationError");
-    return false;
-  }
+var Core = {
+  _events: [
+    "account-connected",
+    "account-disconnected",
+    "browser-request",
+    "quit-application-requested"
+  ],
 
-  try {
-    var pcs = Services.core;
-    pcs.init();
-  }
-  catch (e) {
-    promptError("startupFailure.purplexpcomInitError", e);
-    return false;
-  }
+  init: function() {
+    try {
+      // Set the Vendor for breakpad only
+      if ("nsICrashReporter" in Ci) {
+        Components.classes["@mozilla.org/xre/app-info;1"]
+                  .getService(Ci.nsICrashReporter)
+                  .annotateCrashReport("Vendor", "Instantbird");
+      }
+    } catch(e) {
+      // This can fail if breakpad isn't enabled,
+      // don't worry too much about this exception.
+    }
+
+    if (!Ci.purpleICoreService) {
+      this._promptError("startupFailure.purplexpcomFileError");
+      return false;
+    }
 
-  if (!pcs.version) {
-    promptError("startupFailure.libpurpleError");
-    return false;
-  }
+    if (!Components.classes["@instantbird.org/purple/core;1"]) {
+      this._promptError("startupFailure.xpcomRegistrationError");
+      return false;
+    }
 
-  if (!pcs.getProtocols().hasMoreElements()) {
-    promptError("startupFailure.noProtocolLoaded");
-    uninitPurpleCore();
-    return false;
-  }
+    try {
+      var pcs = Services.core;
+      pcs.init();
+    }
+    catch (e) {
+      this._promptError("startupFailure.purplexpcomInitError", e);
+      return false;
+    }
+
+    if (!pcs.version) {
+      this._promptError("startupFailure.libpurpleError");
+      return false;
+    }
 
-  return true;
-}
+    if (!pcs.getProtocols().hasMoreElements()) {
+      this._promptError("startupFailure.noProtocolLoaded");
+      this.uninitPurpleCore();
+      return false;
+    }
 
-function uninitPurpleCore()
-{
-  try {
-    Services.core.quit();
-  }
-  catch (e) {
-    Services.prompt.alert(null, "Shutdown Error",
-                          "An error occurred while shutting down purplexpcom: " + e);
-  }
-}
+    let status = {
+      back: "AVAILABLE",
+      away: "AWAY",
+      busy: "UNAVAILABLE",
+      dnd: "UNAVAILABLE",
+      offline: "OFFLINE"
+    };
+    for (let cmd in status) {
+      let statusValue = Ci.imIStatusInfo["STATUS_" + status[cmd]];
+      Services.cmd.registerCommand({
+        name: cmd,
+        priority: Ci.imICommand.PRIORITY_HIGH,
+        run: function(aMsg) {
+          Services.core.setStatus(statusValue, aMsg);
+          return true;
+        }
+      });
+    }
+
+    Conversations.init();
+
+    this._events.forEach(function (aTopic) {
+      Services.obs.addObserver(Core, aTopic, false);
+    });
 
-function promptError(aKeyString, aMessage) {
-  var bundle =
-    Services.strings.createBundle("chrome://instantbird/locale/core.properties");
+    this._showAccountManagerIfNeeded(true);
+    return true;
+  },
+
+  showWindow: function(aWindowType, aUrl, aName, aFeatures) {
+    var win = Services.wm.getMostRecentWindow(aWindowType);
+    if (win)
+      win.focus();
+    else
+      win = Services.ww.openWindow(null, aUrl, aName, aFeatures, null);
+    return win;
+  },
 
-  var title = bundle.GetStringFromName("startupFailure.title");
-  var message =
-    bundle.GetStringFromName("startupFailure.apologize") + "\n\n" +
-    (aMessage ? bundle.formatStringFromName(aKeyString, [aMessage], 1)
-              : bundle.GetStringFromName(aKeyString)) + "\n\n" +
-    bundle.GetStringFromName("startupFailure.update");
-  const nsIPromptService = Components.interfaces.nsIPromptService;
-  const flags =
-    nsIPromptService.BUTTON_POS_1 * nsIPromptService.BUTTON_TITLE_IS_STRING +
-    nsIPromptService.BUTTON_POS_0 * nsIPromptService.BUTTON_TITLE_IS_STRING;
-
-  var prompts = Services.prompt;
-  if (!prompts.confirmEx(null, title, message, flags,
-                         bundle.GetStringFromName("startupFailure.buttonUpdate"),
-                         bundle.GetStringFromName("startupFailure.buttonClose"),
-                         null, null, {})) {
+  showAccounts: function() {
+    this.showWindow("Messenger:Accounts",
+                    "chrome://instantbird/content/accounts.xul", "Accounts",
+                    "chrome,resizable");
+  },
+  showContacts: function() {
+    this.showWindow("Messenger:blist",
+                    "chrome://instantbird/content/blist.xul", "Contacts",
+                    "chrome,dialog=no,all");
+  },
+  showPreferences: function() {
+    this.showWindow("Messenger:Preferences",
+                    "chrome://instantbird/content/preferences/preferences.xul",
+                    "Preferences",
+                    "chrome,titlebar,toolbar,centerscreen,dialog=no");
+  },
+  showUpdates: function() {
     // copied from checkForUpdates in mozilla/browser/base/content/utilityOverlay.js
     var um =
       Components.classes["@mozilla.org/updates/update-manager;1"]
                 .getService(Components.interfaces.nsIUpdateManager);
     var prompter =
       Components.classes["@mozilla.org/updates/update-prompt;1"]
                 .createInstance(Components.interfaces.nsIUpdatePrompt);
 
     // If there's an update ready to be applied, show the "Update Downloaded"
     // UI instead and let the user know they have to restart the browser for
     // the changes to be applied.
     if (um.activeUpdate && um.activeUpdate.state == "pending")
       prompter.showUpdateDownloaded(um.activeUpdate);
     else
       prompter.checkForUpdates();
+  },
+
+  getIter: function(aEnumerator) {
+    while (aEnumerator.hasMoreElements())
+      yield aEnumerator.getNext();
+  },
+  getAccounts: function() this.getIter(Services.core.getAccounts()),
+
+  /* This function pops up the account manager if no account is
+   * connected or connecting.
+   * When called during startup (aIsStarting == true), it will also
+   * look for crashed accounts.
+   */
+  _showAccountManagerIfNeeded: function (aIsStarting) {
+    // If the current status is offline, we don't need the account manager
+    let isOffline =
+      Services.core.currentStatusType == Ci.imIStatusInfo.STATUS_OFFLINE;
+    if (isOffline && !aIsStarting)
+      return;
+
+    let hasActiveAccount = false;
+    let hasCrashedAccount = false;
+    for (let acc in this.getAccounts()) {
+      if (acc.connected || acc.connecting)
+        hasActiveAccount = true;
+
+      // We only check for crashed accounts on startup.
+      if (aIsStarting && acc.autoLogin &&
+          acc.firstConnectionState == acc.FIRST_CONNECTION_CRASHED)
+        hasCrashedAccount = true;
+    }
+
+    /* We only display the account manager on startup if an account has crashed
+       or if all accounts are disconnected
+       In case of connection failure after an automatic reconnection attempt,
+       we don't want to popup the account manager */
+    if ((!hasActiveAccount && !isOffline) || (aIsStarting && hasCrashedAccount))
+      this.showAccounts();
+  },
+
+  observe: function(aSubject, aTopic, aMsg) {
+    if (aTopic == "account-connected") {
+      let account = aSubject.QueryInterface(Components.interfaces.purpleIAccount);
+      if (!account.canJoinChat)
+        return;
+
+      let pref = "messenger.account." + account.id + ".autoJoin";
+      if (Services.prefs.prefHasUserValue(pref)) {
+        let autojoin = Services.prefs.getCharPref(pref);
+        if (autojoin) {
+          autojoin = autojoin.split(",");
+          for (let i = 0; i < autojoin.length; ++i) {
+            let values = account.getChatRoomDefaultFieldValues(autojoin[i]);
+            account.joinChat(values);
+          }
+        }
+      }
+      return;
+    }
+
+    if (aTopic == "account-disconnected") {
+      let account = aSubject.QueryInterface(Ci.purpleIAccount);
+      if (account.reconnectAttempt <= 1)
+        this._showAccountManagerIfNeeded(false);
+      return;
+    }
+
+    if (aTopic == "browser-request") {
+      Services.ww.openWindow(null,
+                             "chrome://instantbird/content/browserRequest.xul",
+                             null, "chrome", aSubject);
+      return;
+    }
+
+    if (aTopic == "quit-application-requested") {
+      this._onQuitRequest(aSubject, aMsg);
+      return;
+    }
+  },
+
+  uninit: function() {
+    try {
+      Services.core.quit();
+    }
+    catch (e) {
+      Services.prompt.alert(null, "Shutdown Error",
+                            "An error occurred while shutting down purplexpcom: " + e);
+    }
+  },
+
+  _onQuitRequest: function (aCancelQuit, aQuitType) {
+    // The request has already been canceled somewhere else
+    if ((aCancelQuit instanceof Components.interfaces.nsISupportsPRBool)
+         && aCancelQuit.data)
+      return;
+
+    if (!Services.prefs.getBoolPref("messenger.warnOnQuit"))
+      return;
+
+    let unreadConvsCount = Conversations.unreadConvsCount;
+    if (unreadConvsCount == 0)
+      return;
+
+    let bundle =
+      Services.strings.createBundle("chrome://instantbird/locale/quitDialog.properties");
+    let promptTitle    = bundle.GetStringFromName("dialogTitle");
+    let promptMessage  = bundle.GetStringFromName("message");
+    let promptCheckbox = bundle.GetStringFromName("checkbox");
+    let action         = aQuitType == "restart" ? "restart" : "quit";
+    let button         = bundle.GetStringFromName(action + "Button");
+
+    Components.utils.import("resource://gre/modules/PluralForm.jsm");
+    promptMessage = PluralForm.get(unreadConvsCount, promptMessage)
+                              .replace("#1", unreadConvsCount);
+
+    let prompts = Services.prompt;
+    let flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 +
+                prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1 +
+                prompts.BUTTON_POS_1_DEFAULT;
+    let checkbox = {value: false};
+    let convWindow = Services.wm.getMostRecentWindow("Messenger:convs");
+    if (prompts.confirmEx(convWindow, promptTitle, promptMessage, flags,
+                          button, null, null, promptCheckbox, checkbox)) {
+      aCancelQuit.data = true;
+      return;
+    }
+
+    if (checkbox.value)
+      Services.prefs.setBoolPref("messenger.warnOnQuit", false);
+  },
+
+  _promptError: function(aKeyString, aMessage) {
+    var bundle =
+      Services.strings.createBundle("chrome://instantbird/locale/core.properties");
+
+    var title = bundle.GetStringFromName("startupFailure.title");
+    var message =
+      bundle.GetStringFromName("startupFailure.apologize") + "\n\n" +
+      (aMessage ? bundle.formatStringFromName(aKeyString, [aMessage], 1)
+                : bundle.GetStringFromName(aKeyString)) + "\n\n" +
+      bundle.GetStringFromName("startupFailure.update");
+    const nsIPromptService = Components.interfaces.nsIPromptService;
+    const flags =
+      nsIPromptService.BUTTON_POS_1 * nsIPromptService.BUTTON_TITLE_IS_STRING +
+      nsIPromptService.BUTTON_POS_0 * nsIPromptService.BUTTON_TITLE_IS_STRING;
+
+    var prompts = Services.prompt;
+    if (!prompts.confirmEx(null, title, message, flags,
+                           bundle.GetStringFromName("startupFailure.buttonUpdate"),
+                           bundle.GetStringFromName("startupFailure.buttonClose"),
+                           null, null, {}))
+      this.showUpdates();
   }
-}
+};
--- a/im/modules/imWindows.jsm
+++ b/im/modules/imWindows.jsm
@@ -31,17 +31,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const CONVERSATION_WINDOW_URI = "chrome://instantbird/content/instantbird.xul";
-const BROWSER_REQUEST_WINDOW_URI = "chrome://instantbird/content/browserRequest.xul";
 var EXPORTED_SYMBOLS = ["Conversations"];
 
 Components.utils.import("resource:///modules/imServices.jsm");
 
 var Conversations = {
 #ifdef XP_MACOSX
   _badgeTimeout: null,
   _showDockBadgePrefName: "messenger.options.showUnreadCountInDock",
@@ -145,59 +144,22 @@ var Conversations = {
       let conv = this._purpleConv[id];
       let doc = conv.ownerDocument;
       doc.getElementById("conversations").selectedTab = conv.tab;
       conv.focus();
       doc.defaultView.focus();
     }
   },
 
-  _onQuitRequest: function (aCancelQuit, aQuitType) {
-    // The request has already been canceled somewhere else
-    if ((aCancelQuit instanceof Components.interfaces.nsISupportsPRBool)
-         && aCancelQuit.data)
-      return;
-
-    if (!Services.prefs.getBoolPref("messenger.warnOnQuit"))
-      return;
-
-    let unreadConvsCount = this._conversations.filter(function(conv) {
+  get unreadConvsCount() {
+    return this._conversations.filter(function(conv) {
       let tab = conv.tab;
       return tab.hasAttribute("unread") &&
              (!tab.hasAttribute("chat") || tab.hasAttribute("attention"));
     }).length;
-
-    if (unreadConvsCount == 0)
-      return;
-
-    let bundle =
-      Services.strings.createBundle("chrome://instantbird/locale/quitDialog.properties");
-    let promptTitle    = bundle.GetStringFromName("dialogTitle");
-    let promptMessage  = bundle.GetStringFromName("message");
-    let promptCheckbox = bundle.GetStringFromName("checkbox");
-    let action         = aQuitType == "restart" ? "restart" : "quit";
-    let button         = bundle.GetStringFromName(action + "Button");
-
-    Components.utils.import("resource://gre/modules/PluralForm.jsm");
-    promptMessage = PluralForm.get(unreadConvsCount, promptMessage)
-                              .replace("#1", unreadConvsCount);
-
-    let prompts = Services.prompt;
-    let flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 +
-                prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1 +
-                prompts.BUTTON_POS_1_DEFAULT;
-    let checkbox = {value: false};
-    if (prompts.confirmEx(this._windows[0], promptTitle, promptMessage, flags,
-                          button, null, null, promptCheckbox, checkbox)) {
-      aCancelQuit.data = true;
-      return;
-    }
-
-    if (checkbox.value)
-      Services.prefs.setBoolPref("messenger.warnOnQuit", false);
   },
 
   onWindowFocus: function (aWindow) {
     let position = this._windows.indexOf(aWindow);
     if (position != -1) {
       this._windows.splice(position, 1);
       this._windows.unshift(aWindow);
     }
@@ -261,35 +223,27 @@ var Conversations = {
     Components.classes["@mozilla.org/alerts-service;1"]
               .getService(Components.interfaces.nsIAlertsService)
               .showAlertNotification(icon, aMessage.alias || aMessage.who,
                                      messageText, true, "", observer);
   },
 
   init: function() {
     let os = Services.obs;
-    ["browser-request",
-     "new-text",
+    ["new-text",
      "new-conversation",
-     "account-connected",
-     "purple-quit",
-     "quit-application-requested"].forEach(function (aTopic) {
+     "purple-quit"].forEach(function (aTopic) {
       os.addObserver(Conversations, aTopic, false);
     });
 #ifdef XP_MACOSX
     Services.prefs.addObserver(this._showDockBadgePrefName, this, false);
 #endif
   },
 
   observe: function(aSubject, aTopic, aMsg) {
-    if (aTopic == "quit-application-requested") {
-      this._onQuitRequest(aSubject, aMsg);
-      return;
-    }
-
     if (aTopic == "purple-quit") {
       for (let id in this._purpleConv)
         this._purpleConv[id].unInit();
 #ifdef XP_MACOSX
       Services.prefs.removeObserver(Conversations._showDockBadgePrefName,
                                     Conversations);
 #endif
     }
@@ -301,41 +255,16 @@ var Conversations = {
           this._showUnreadCount();
         else
           this._hideUnreadCountDockBadge();
       }
       return;
     }
 #endif
 
-    if (aTopic == "account-connected") {
-      let account = aSubject.QueryInterface(Components.interfaces.purpleIAccount);
-      if (!account.canJoinChat)
-        return;
-
-      let pref = "messenger.account." + account.id + ".autoJoin";
-      if (Services.prefs.prefHasUserValue(pref)) {
-        let autojoin = Services.prefs.getCharPref(pref);
-        if (autojoin) {
-          autojoin = autojoin.split(",");
-          for (let i = 0; i < autojoin.length; ++i) {
-            let values = account.getChatRoomDefaultFieldValues(autojoin[i]);
-            account.joinChat(values);
-          }
-        }
-      }
-      return;
-    }
-
-    if (aTopic == "browser-request") {
-      Services.ww.openWindow(null, BROWSER_REQUEST_WINDOW_URI, null,
-                             "chrome", aSubject);
-      return;
-    }
-
     if (aTopic != "new-text" && aTopic != "new-conversation")
       return;
 
     let conv = aTopic == "new-conversation" ? aSubject : aSubject.conversation;
     if (!(conv.id in this._purpleConv)) {
       // The conversation is not displayed anywhere yet.
       // First, check if an existing conversation window can accept it.
       for each (let win in this._windows)