bug 935640 part 1 Australis, update social sidebar with new ux, r=markh
authorShane Caraveo <scaraveo@mozilla.com>
Mon, 16 Dec 2013 21:37:30 -0800
changeset 160781 d3ef31b50bf953a2567c2b278c695283d2fe85d9
parent 160780 07f6abdf6cd71cc2e9b1b59330d6c94b84618784
child 160782 45d47db0c321cbc1d916c524531ec97c9ff8c1a7
push id25849
push usercbook@mozilla.com
push dateTue, 17 Dec 2013 11:47:53 +0000
treeherdermozilla-central@e5b49dc699c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs935640
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 935640 part 1 Australis, update social sidebar with new ux, r=markh
browser/base/content/browser-menubar.inc
browser/base/content/browser-sets.inc
browser/base/content/browser-social.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/test/social/head.js
browser/components/customizableui/src/CustomizableUI.jsm
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/linux/jar.mn
browser/themes/osx/browser.css
browser/themes/osx/jar.mn
browser/themes/shared/social/chat.inc.css
browser/themes/shared/social/gear_clicked.png
browser/themes/shared/social/gear_default.png
browser/themes/windows/browser-aero.css
browser/themes/windows/jar.mn
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -197,20 +197,19 @@
                   <menupopup id="viewSidebarMenu">
                     <menuitem id="menu_bookmarksSidebar"
                               key="viewBookmarksSidebarKb"
                               observes="viewBookmarksSidebar"/>
                     <menuitem id="menu_historySidebar"
                               key="key_gotoHistory"
                               observes="viewHistorySidebar"
                               label="&historyButton.label;"/>
-                    <menuitem id="menu_socialSidebar"
-                              type="checkbox"
-                              autocheck="false"
-                              command="Social:ToggleSidebar"/>
+                    <!-- Service providers with sidebars are inserted between these two menuseperators -->
+                    <menuseparator hidden="true"/>
+                    <menuseparator class="social-provider-menu" hidden="true"/>
                   </menupopup>
                 </menu>
                 <menuseparator/>
                 <menu id="viewFullZoomMenu" label="&fullZoom.label;"
                       accesskey="&fullZoom.accesskey;"
                       onpopupshowing="FullZoom.updateMenu();">
                   <menupopup>
                     <menuitem id="menu_zoomEnlarge"
@@ -442,59 +441,16 @@
                         accesskey="&downloads.accesskey;"
                         key="key_openDownloads"
                         command="Tools:Downloads"/>
               <menuitem id="menu_openAddons"
                         label="&addons.label;"
                         accesskey="&addons.accesskey;"
                         key="key_openAddons"
                         command="Tools:Addons"/>
-              <menu id="menu_socialAmbientMenu"
-                    observes="socialActiveBroadcaster">
-                <menupopup id="menu_social-statusarea-popup">
-                  <menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center"
-                            observes="socialBroadcaster_userDetails"
-                            oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();">
-                    <image class="social-statusarea-user-portrait"
-                           observes="socialBroadcaster_userDetails"/>
-                    <vbox>
-                      <label class="social-statusarea-loggedInStatus"
-                             observes="socialBroadcaster_userDetails"/>
-                    </vbox>
-                  </menuitem>
-#ifndef XP_WIN
-                  <menuseparator class="social-statusarea-separator"/>
-#endif
-                  <menuseparator id="socialAmbientMenuSeparator"
-                                 hidden="true"/>
-                  <menuitem class="social-toggle-sidebar-menuitem"
-                            type="checkbox"
-                            autocheck="false"
-                            command="Social:ToggleSidebar"
-                            label="&social.toggleSidebar.label;"
-                            accesskey="&social.toggleSidebar.accesskey;"/>
-                  <menuitem class="social-toggle-notifications-menuitem"
-                            type="checkbox"
-                            autocheck="false"
-                            command="Social:ToggleNotifications"
-                            label="&social.toggleNotifications.label;"
-                            accesskey="&social.toggleNotifications.accesskey;"/>
-                  <menuitem id="menu_focusChatBar"
-                            label="&social.chatBar.label;"
-                            accesskey="&social.chatBar.accesskey;"
-                            key="focusChatBar"
-                            command="Social:FocusChat"
-                            class="show-only-for-keyboard"/>
-                  <menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
-                  <menuseparator class="social-statusarea-separator"/>
-                  <menuseparator class="social-provider-menu" hidden="true"/>
-                  <menuitem class="social-addons-menuitem" command="Social:Addons"
-                            label="&social.addons.label;"/>
-                </menupopup>
-              </menu>
 #ifdef MOZ_SERVICES_SYNC
               <!-- only one of sync-setup or sync-menu will be showing at once -->
               <menuitem id="sync-setup"
                         label="&syncSetup.label;"
                         accesskey="&syncSetup.accesskey;"
                         observes="sync-setup-state"
                         oncommand="gSyncUI.openSetup()"/>
               <menuitem id="sync-syncnowitem"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -164,17 +164,16 @@
     <broadcaster id="multipleFeedsMenuState" hidden="true"/>
     <broadcaster id="tabviewGroupsNumber" groups="1"/>
 #ifdef MOZ_SERVICES_SYNC
     <broadcaster id="sync-setup-state"/>
     <broadcaster id="sync-syncnow-state"/>
 #endif
     <broadcaster id="workOfflineMenuitemState"/>
     <broadcaster id="socialSidebarBroadcaster" hidden="true"/>
-    <broadcaster id="socialActiveBroadcaster" hidden="true"/>
 
     <!-- DevTools broadcasters -->
     <broadcaster id="devtoolsMenuBroadcaster_DevToolbox"
                  label="&devToolboxMenuItem.label;"
                  type="checkbox" autocheck="false"
                  command="Tools:DevToolbox"
                  key="key_devToolboxMenuItem"/>
     <broadcaster id="devtoolsMenuBroadcaster_DevToolbar"
@@ -209,20 +208,16 @@
                  label="&errorConsoleCmd.label;"
                  command="Tools:ErrorConsole"/>
     <broadcaster id="devtoolsMenuBroadcaster_GetMoreTools"
                  label="&getMoreDevtoolsCmd.label;"
                  oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/>
     <broadcaster id="devtoolsMenuBroadcaster_connect"
                  label="&devtoolsConnect.label;"
                  command="Tools:DevToolsConnect"/>
-
-    <!-- SocialAPI broadcasters -->
-    <broadcaster id="socialBroadcaster_userDetails"
-                 notLoggedInLabel="&social.notLoggedIn.label;"/>
   </broadcasterset>
 
   <keyset id="mainKeyset">
     <key id="key_newNavigator"
          key="&newNavigatorCmd.key;"
          command="cmd_newNavigator"
          modifiers="accel"/>
     <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTab"/>
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -3,18 +3,16 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 // the "exported" symbols
 let SocialUI,
     SocialChatBar,
     SocialFlyout,
     SocialMarks,
     SocialShare,
-    SocialMenu,
-    SocialToolbar,
     SocialSidebar,
     SocialStatus;
 
 (function() {
 
 // The minimum sizes for the auto-resize panel code.
 const PANEL_MIN_HEIGHT = 100;
 const PANEL_MIN_WIDTH = 330;
@@ -65,16 +63,21 @@ SocialUI = {
     Services.obs.addObserver(this, "social:provider-disabled", false);
 
     Services.prefs.addObserver("social.sidebar.open", this, false);
     Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
 
     gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
     document.getElementById("PanelUI-popup").addEventListener("popupshown", SocialMarks.updatePanelButtons, true);
 
+    // menupopups that list social providers. we only populate them when shown,
+    // and if it has not been done already.
+    document.getElementById("viewSidebarMenu").addEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
+    document.getElementById("social-statusarea-popup").addEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
+
     if (!Social.initialized) {
       Social.init();
     } else if (Social.providers.length > 0) {
       // Social was initialized during startup in a previous window. If we have
       // providers enabled initialize the UI for this window.
       this.observe(null, "social:providers-changed", null);
       this.observe(null, "social:provider-set", Social.provider ? Social.provider.origin : null);
     }
@@ -90,16 +93,18 @@ SocialUI = {
     Services.obs.removeObserver(this, "social:provider-reload");
     Services.obs.removeObserver(this, "social:provider-enabled");
     Services.obs.removeObserver(this, "social:provider-disabled");
 
     Services.prefs.removeObserver("social.sidebar.open", this);
     Services.prefs.removeObserver("social.toast-notifications.enabled", this);
 
     document.getElementById("PanelUI-popup").removeEventListener("popupshown", SocialMarks.updatePanelButtons, true);
+    document.getElementById("viewSidebarMenu").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
+    document.getElementById("social-statusarea-popup").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
   },
 
   _matchesCurrentProvider: function (origin) {
     return Social.provider && Social.provider.origin == origin;
   },
 
   observe: function SocialUI_observe(subject, topic, data) {
     // Exceptions here sometimes don't get reported properly, report them
@@ -124,98 +129,69 @@ SocialUI = {
           // has not changed, it will be loaded in provider-set below. Other
           // panels will be unloaded or handle reload.
           SocialSidebar.unloadSidebar();
           // fall through to social:provider-set
         case "social:provider-set":
           // Social.provider has changed (possibly to null), update any state
           // which depends on it.
           this._updateActiveUI();
-          this._updateMenuItems();
 
           SocialFlyout.unload();
           SocialChatBar.update();
           SocialShare.update();
           SocialSidebar.update();
-          SocialToolbar.update();
           SocialStatus.populateToolbarPalette();
           SocialMarks.populateToolbarPalette();
-          SocialMenu.populate();
           break;
         case "social:providers-changed":
           // the list of providers changed - this may impact the "active" UI.
           this._updateActiveUI();
           // and the multi-provider menu
-          SocialToolbar.populateProviderMenus();
+          SocialSidebar.clearProviderMenus();
           SocialShare.populateProviderMenu();
           SocialStatus.populateToolbarPalette();
           SocialMarks.populateToolbarPalette();
           break;
 
         // Provider-specific notifications
         case "social:ambient-notification-changed":
           SocialStatus.updateButton(data);
-          if (this._matchesCurrentProvider(data)) {
-            SocialToolbar.updateButton();
-            SocialMenu.populate();
-          }
           break;
         case "social:profile-changed":
           // make sure anything that happens here only affects the provider for
           // which the profile is changing, and that anything we call actually
           // needs to change based on profile data.
           SocialStatus.updateButton(data);
-          if (this._matchesCurrentProvider(data)) {
-            SocialToolbar.updateProvider();
-          }
-          // Refresh the provider menus, as the icons may have changed.
-          SocialToolbar.populateProviderMenus();
           break;
         case "social:frameworker-error":
           if (this.enabled && Social.provider.origin == data) {
             SocialSidebar.setSidebarErrorMessage();
           }
           break;
 
         case "nsPref:changed":
           if (data == "social.sidebar.open") {
             SocialSidebar.update();
           } else if (data == "social.toast-notifications.enabled") {
-            SocialToolbar.updateButton();
+            SocialSidebar.updateToggleNotifications();
           }
           break;
       }
     } catch (e) {
       Components.utils.reportError(e + "\n" + e.stack);
       throw e;
     }
   },
 
-  nonBrowserWindowInit: function SocialUI_nonBrowserInit() {
-    // Disable the social menu item in non-browser windows
-    document.getElementById("menu_socialAmbientMenu").hidden = true;
-  },
-
-  // Miscellaneous helpers
-  showProfile: function SocialUI_showProfile() {
-    if (Social.provider.haveLoggedInUser())
-      openUILinkIn(Social.provider.profile.profileURL, "tab");
-    else {
-      // XXX Bug 789585 will implement an API for provider-specified login pages.
-      openUILinkIn(Social.provider.origin, "tab");
-    }
-  },
-
   _updateActiveUI: function SocialUI_updateActiveUI() {
     // The "active" UI isn't dependent on there being a provider, just on
     // social being "active" (but also chromeless/PB)
     let enabled = Social.providers.length > 0 && !this._chromeless &&
                   !PrivateBrowsingUtils.isWindowPrivate(window);
-    let broadcaster = document.getElementById("socialActiveBroadcaster");
-    broadcaster.hidden = !enabled;
 
     let toggleCommand = document.getElementById("Social:Toggle");
     toggleCommand.setAttribute("hidden", enabled ? "false" : "true");
 
     if (enabled) {
       // enabled == true means we at least have a defaultProvider
       let provider = Social.provider || Social.defaultProvider;
       // We only need to update the command itself - all our menu items use it.
@@ -233,25 +209,16 @@ SocialUI = {
       let accesskey = gNavigatorBundle.getString(Social.provider
                                                  ? "social.turnOff.accesskey"
                                                  : "social.turnOn.accesskey");
       toggleCommand.setAttribute("label", label);
       toggleCommand.setAttribute("accesskey", accesskey);
     }
   },
 
-  _updateMenuItems: function () {
-    let provider = Social.provider || Social.defaultProvider;
-    if (!provider)
-      return;
-    // The View->Sidebar and Menubar->Tools menu.
-    for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
-      document.getElementById(id).setAttribute("label", provider.name);
-  },
-
   // This handles "ActivateSocialFeature" events fired against content documents
   // in this window.
   _activationEventHandler: function SocialUI_activationHandler(e) {
     let targetDoc;
     let node;
     if (e.target instanceof HTMLDocument) {
       // version 0 support
       targetDoc = e.target;
@@ -328,19 +295,20 @@ SocialUI = {
 
       let notificationPanel = SocialUI.activationPanel;
       // Set the origin being activated and the previously active one, to allow undo
       notificationPanel.setAttribute("origin", provider.origin);
       notificationPanel.setAttribute("oldorigin", oldOrigin);
 
       // Show the panel
       notificationPanel.hidden = false;
-      setTimeout(function () {
-        notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
-      }, 0);
+      // XXX addressed in patch part 2
+      //setTimeout(function () {
+      //  notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
+      //}, 0);
     });
   },
 
   undoActivation: function SocialUI_undoActivation() {
     let origin = this.activationPanel.getAttribute("origin");
     let oldOrigin = this.activationPanel.getAttribute("oldorigin");
     Social.deactivateFromOrigin(origin, oldOrigin);
     this.activationPanel.hidePopup();
@@ -799,408 +767,22 @@ SocialShare = {
 
     let navBar = document.getElementById("nav-bar");
     let anchor = document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
     this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
     Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
   }
 };
 
-SocialMenu = {
-  populate: function SocialMenu_populate() {
-    let submenu = document.getElementById("menu_social-statusarea-popup");
-    let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
-    while (ambientMenuItems.length)
-      submenu.removeChild(ambientMenuItems.item(0));
-
-    let separator = document.getElementById("socialAmbientMenuSeparator");
-    separator.hidden = true;
-    let provider = SocialUI.enabled ? Social.provider : null;
-    if (!provider)
-      return;
-
-    let iconNames = Object.keys(provider.ambientNotificationIcons);
-    for (let name of iconNames) {
-      let icon = provider.ambientNotificationIcons[name];
-      if (!icon.label || !icon.menuURL)
-        continue;
-      separator.hidden = false;
-      let menuitem = document.createElement("menuitem");
-      menuitem.setAttribute("label", icon.label);
-      menuitem.classList.add("ambient-menuitem");
-      menuitem.addEventListener("command", function() {
-        openUILinkIn(icon.menuURL, "tab");
-      }, false);
-      submenu.insertBefore(menuitem, separator);
-    }
-  }
-};
-
-// XXX Need to audit that this is being initialized correctly
-SocialToolbar = {
-  // Called once, after window load, when the Social.provider object is
-  // initialized.
-  get _dynamicResizer() {
-    delete this._dynamicResizer;
-    this._dynamicResizer = new DynamicResizeWatcher();
-    return this._dynamicResizer;
-  },
-
-  update: function() {
-    this._updateButtonHiddenState();
-    this.updateProvider();
-    this.populateProviderMenus();
-  },
-
-  // Called when the Social.provider changes
-  updateProvider: function () {
-    let provider = Social.provider;
-    // If the provider uses the new SocialStatus button, then they do
-    // not get to customize the old toolbar button.  Since the status
-    // button depends on multiple workers, if not enabled we will
-    // ignore this limitation.  That allows a provider to migrate to
-    // the new functionality once we enable multiple workers.
-    if (provider && (!provider.statusURL || !Social.allowMultipleWorkers)) {
-      this.button.setAttribute("label", provider.name);
-      this.button.setAttribute("tooltiptext", provider.name);
-      this.button.style.listStyleImage = "url(" + provider.iconURL + ")";
-    } else {
-      this.button.setAttribute("label", gNavigatorBundle.getString("service.toolbarbutton.label"));
-      this.button.setAttribute("tooltiptext", gNavigatorBundle.getString("service.toolbarbutton.tooltiptext"));
-      this.button.style.removeProperty("list-style-image");
-    }
-    if (provider)
-      this.updateProfile();
-    this.updateButton();
-  },
-
-  get button() {
-    return document.getElementById("social-provider-button");
-  },
-
-  // Note: this doesn't actually handle hiding the toolbar button,
-  // socialActiveBroadcaster is responsible for that.
-  _updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
-    let socialEnabled = SocialUI.enabled;
-    for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
-      for (let element of document.getElementsByClassName(className))
-        element.hidden = !socialEnabled;
-    }
-    let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
-    toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
-
-    // we need to remove buttons and frames if !socialEnabled or the provider
-    // has changed (frame origin does not match current provider). We only
-    // remove frames that are "attached" to buttons in this toolbar button since
-    // other buttons may also be using grouped frames.
-    let tbi = document.getElementById("social-provider-button");
-    if (tbi) {
-      // buttons after social-provider-button are ambient icons
-      let next = tbi.nextSibling;
-      let currentOrigin = Social.provider ? Social.provider.origin : null;
-
-      while (next) {
-        let button = next;
-        next = next.nextSibling;
-        // get the frame for this button
-        let frameId = button.getAttribute("notificationFrameId");
-        let frame = document.getElementById(frameId);
-        if (!socialEnabled || frame.getAttribute("origin") != currentOrigin) {
-          SharedFrame.forgetGroup(frame.id);
-          frame.parentNode.removeChild(frame);
-          button.parentNode.removeChild(button);
-        }
-      }
-    }
-  },
-
-  updateProfile: function SocialToolbar_updateProfile() {
-    // Profile may not have been initialized yet, since it depends on a worker
-    // response. In that case we'll be called again when it's available, via
-    // social:profile-changed
-    if (!Social.provider)
-      return;
-    let profile = Social.provider.profile || {};
-    let userPortrait = profile.portrait;
-
-    let userDetailsBroadcaster = document.getElementById("socialBroadcaster_userDetails");
-    let loggedInStatusValue = profile.userName ||
-                              userDetailsBroadcaster.getAttribute("notLoggedInLabel");
-
-    // "image" and "label" are used by Mac's native menus that do not render the menuitem's children
-    // elements. "src" and "value" are used by the image/label children on the other platforms.
-    if (userPortrait) {
-      userDetailsBroadcaster.setAttribute("src", userPortrait);
-      userDetailsBroadcaster.setAttribute("image", userPortrait);
-    } else {
-      userDetailsBroadcaster.removeAttribute("src");
-      userDetailsBroadcaster.removeAttribute("image");
-    }
-
-    userDetailsBroadcaster.setAttribute("value", loggedInStatusValue);
-    userDetailsBroadcaster.setAttribute("label", loggedInStatusValue);
-  },
-
-  updateButton: function SocialToolbar_updateButton() {
-    this._updateButtonHiddenState();
-    let panel = document.getElementById("social-notification-panel");
-    panel.hidden = !SocialUI.enabled;
-
-    let command = document.getElementById("Social:ToggleNotifications");
-    command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
-
-    const CACHE_PREF_NAME = "social.cached.ambientNotificationIcons";
-    // provider.profile == undefined means no response yet from the provider
-    // to tell us whether the user is logged in or not.
-    if (!SocialUI.enabled ||
-        (!Social.provider.haveLoggedInUser() && Social.provider.profile !== undefined)) {
-      // Either no enabled provider, or there is a provider and it has
-      // responded with a profile and the user isn't loggedin.  The icons
-      // etc have already been removed by updateButtonHiddenState, so we want
-      // to nuke any cached icons we have and get out of here!
-      Services.prefs.clearUserPref(CACHE_PREF_NAME);
-      return;
-    }
-
-    // If the provider uses the new SocialStatus button, then they do not get
-    // to use the ambient icons in the old toolbar button.  Since the status
-    // button depends on multiple workers, if not enabled we will ignore this
-    // limitation.  That allows a provider to migrate to the new functionality
-    // once we enable multiple workers.
-    if (Social.provider.statusURL && Social.allowMultipleWorkers)
-      return;
-
-    let icons = Social.provider.ambientNotificationIcons;
-    let iconNames = Object.keys(icons);
-
-    if (Social.provider.profile === undefined) {
-      // provider has not told us about the login state yet - see if we have
-      // a cached version for this provider.
-      let cached;
-      try {
-        cached = JSON.parse(Services.prefs.getComplexValue(CACHE_PREF_NAME,
-                                                           Ci.nsISupportsString).data);
-      } catch (ex) {}
-      if (cached && cached.provider == Social.provider.origin && cached.data) {
-        icons = cached.data;
-        iconNames = Object.keys(icons);
-        // delete the counter data as it is almost certainly stale.
-        for each(let name in iconNames) {
-          icons[name].counter = '';
-        }
-      }
-    } else {
-      // We have a logged in user - save the current set of icons back to the
-      // "cache" so we can use them next startup.
-      let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
-      str.data = JSON.stringify({provider: Social.provider.origin, data: icons});
-      Services.prefs.setComplexValue(CACHE_PREF_NAME,
-                                     Ci.nsISupportsString,
-                                     str);
-    }
-
-    let toolbarButtons = document.createDocumentFragment();
-
-    let createdFrames = [];
-
-    for each(let name in iconNames) {
-      let icon = icons[name];
-
-      let notificationFrameId = "social-status-" + icon.name;
-      let notificationFrame = document.getElementById(notificationFrameId);
-
-      if (!notificationFrame) {
-        notificationFrame = SharedFrame.createFrame(
-          notificationFrameId, /* frame name */
-          panel, /* parent */
-          {
-            "type": "content",
-            "mozbrowser": "true",
-            "class": "social-panel-frame",
-            "id": notificationFrameId,
-            "tooltip": "aHTMLTooltip",
-
-            // work around bug 793057 - by making the panel roughly the final size
-            // we are more likely to have the anchor in the correct position.
-            "style": "width: " + PANEL_MIN_WIDTH + "px;",
-
-            "origin": Social.provider.origin,
-            "src": icon.contentPanel
-          }
-        );
-
-        createdFrames.push(notificationFrame);
-      } else {
-        notificationFrame.setAttribute("origin", Social.provider.origin);
-        SharedFrame.updateURL(notificationFrameId, icon.contentPanel);
-      }
-
-      let toolbarButtonId = "social-notification-icon-" + icon.name;
-      let toolbarButton = document.getElementById(toolbarButtonId);
-      if (!toolbarButton) {
-        toolbarButton = document.createElement("toolbarbutton");
-        toolbarButton.setAttribute("type", "badged");
-        toolbarButton.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
-        toolbarButton.setAttribute("id", toolbarButtonId);
-        toolbarButton.setAttribute("notificationFrameId", notificationFrameId);
-        toolbarButton.addEventListener("mousedown", function (event) {
-          if (event.button == 0 && panel.state == "closed")
-            SocialToolbar.showAmbientPopup(toolbarButton);
-        });
-
-        toolbarButtons.appendChild(toolbarButton);
-      }
-
-      toolbarButton.style.listStyleImage = "url(" + icon.iconURL + ")";
-      toolbarButton.setAttribute("label", icon.label);
-      toolbarButton.setAttribute("tooltiptext", icon.label);
-
-      let badge = icon.counter || "";
-      toolbarButton.setAttribute("badge", badge);
-      let ariaLabel = icon.label;
-      // if there is a badge value, we must use a localizable string to insert it.
-      if (badge)
-        ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
-                                                        [ariaLabel, badge]);
-      toolbarButton.setAttribute("aria-label", ariaLabel);
-    }
-    let socialToolbarItem = document.getElementById("social-toolbar-item");
-    socialToolbarItem.appendChild(toolbarButtons);
-
-    for (let frame of createdFrames) {
-      if (frame.socialErrorListener)
-        frame.socialErrorListener.remove();
-      if (frame.docShell) {
-        frame.docShell.isActive = false;
-        Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
-      }
-    }
-  },
-
-  showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButton) {
-    // Hide any other social panels that may be open.
-    SocialFlyout.panel.hidePopup();
-
-    let panel = document.getElementById("social-notification-panel");
-    let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
-    let notificationFrame = document.getElementById(notificationFrameId);
-
-    let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
-    SharedFrame.setOwner(notificationFrameId, notificationFrame);
-
-    // Clear dimensions on all browsers so the panel size will
-    // only use the selected browser.
-    let frameIter = panel.firstElementChild;
-    while (frameIter) {
-      frameIter.collapsed = (frameIter != notificationFrame);
-      frameIter = frameIter.nextElementSibling;
-    }
-
-    function dispatchPanelEvent(name) {
-      let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
-      evt.initCustomEvent(name, true, true, {});
-      notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
-    }
-
-    let dynamicResizer = this._dynamicResizer;
-    panel.addEventListener("popuphidden", function onpopuphiding() {
-      panel.removeEventListener("popuphidden", onpopuphiding);
-      aToolbarButton.removeAttribute("open");
-      aToolbarButton.parentNode.removeAttribute("open");
-      dynamicResizer.stop();
-      notificationFrame.docShell.isActive = false;
-      dispatchPanelEvent("socialFrameHide");
-    });
-
-    panel.addEventListener("popupshown", function onpopupshown() {
-      panel.removeEventListener("popupshown", onpopupshown);
-      // The "open" attribute is needed on both the button and the containing
-      // toolbaritem since the buttons on OS X have moz-appearance:none, while
-      // their container gets moz-appearance:toolbarbutton due to the way that
-      // toolbar buttons get combined on OS X.
-      aToolbarButton.setAttribute("open", "true");
-      aToolbarButton.parentNode.setAttribute("open", "true");
-      notificationFrame.docShell.isActive = true;
-      notificationFrame.docShell.isAppTab = true;
-      if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
-        dynamicResizer.start(panel, notificationFrame);
-        dispatchPanelEvent("socialFrameShow");
-      } else {
-        // first time load, wait for load and dispatch after load
-        notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
-          notificationFrame.removeEventListener("load", panelBrowserOnload, true);
-          dynamicResizer.start(panel, notificationFrame);
-          setTimeout(function() {
-            dispatchPanelEvent("socialFrameShow");
-          }, 0);
-        }, true);
-      }
-    });
-
-    let navBar = document.getElementById("nav-bar");
-    let anchor = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
-    // Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
-    // handling from preventing it being opened in some cases.
-    setTimeout(function() {
-      panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
-    }, 0);
-  },
-
-  setPanelErrorMessage: function SocialToolbar_setPanelErrorMessage(aNotificationFrame) {
-    if (!aNotificationFrame)
-      return;
-
-    let src = aNotificationFrame.getAttribute("src");
-    aNotificationFrame.removeAttribute("src");
-    aNotificationFrame.webNavigation.loadURI("about:socialerror?mode=tryAgainOnly&url=" +
-                                             encodeURIComponent(src), null, null, null, null);
-    let panel = aNotificationFrame.parentNode;
-    sizeSocialPanelToContent(panel, aNotificationFrame);
-  },
-
-  populateProviderMenus: function SocialToolbar_renderProviderMenus() {
-    let providerMenuSeps = document.getElementsByClassName("social-provider-menu");
-    for (let providerMenuSep of providerMenuSeps)
-      this._populateProviderMenu(providerMenuSep);
-  },
-
-  _populateProviderMenu: function SocialToolbar_renderProviderMenu(providerMenuSep) {
-    let menu = providerMenuSep.parentNode;
-    // selectable providers are inserted before the provider-menu seperator,
-    // remove any menuitems in that area
-    while (providerMenuSep.previousSibling.nodeName == "menuitem") {
-      menu.removeChild(providerMenuSep.previousSibling);
-    }
-    // only show a selection if enabled and there is more than one
-    let providers = [p for (p of Social.providers) if (p.workerURL || p.sidebarURL)];
-    if (providers.length < 2) {
-      providerMenuSep.hidden = true;
-      return;
-    }
-    for (let provider of providers) {
-      let menuitem = document.createElement("menuitem");
-      menuitem.className = "menuitem-iconic social-provider-menuitem";
-      menuitem.setAttribute("image", provider.iconURL);
-      menuitem.setAttribute("label", provider.name);
-      menuitem.setAttribute("origin", provider.origin);
-      if (provider == Social.provider) {
-        menuitem.setAttribute("checked", "true");
-      } else {
-        menuitem.setAttribute("oncommand", "Social.setProviderByOrigin(this.getAttribute('origin'));");
-      }
-      menu.insertBefore(menuitem, providerMenuSep);
-    }
-    providerMenuSep.hidden = false;
-  }
-}
-
 SocialSidebar = {
   // Whether the sidebar can be shown for this window.
   get canShow() {
-    return SocialUI.enabled && Social.provider.sidebarURL;
+    if (PrivateBrowsingUtils.isWindowPrivate(window))
+      return false;
+    return [p for (p of Social.providers) if (p.enabled && p.sidebarURL)].length > 0;
   },
 
   // Whether the user has toggled the sidebar on (for windows where it can appear)
   get opened() {
     return Services.prefs.getBoolPref("social.sidebar.open") && !document.mozFullScreen;
   },
 
   setSidebarVisibilityState: function(aEnabled) {
@@ -1210,17 +792,25 @@ SocialSidebar = {
     if (aEnabled == sbrowser.docShellIsActive)
       return;
     sbrowser.docShellIsActive = aEnabled;
     let evt = sbrowser.contentDocument.createEvent("CustomEvent");
     evt.initCustomEvent(aEnabled ? "socialFrameShow" : "socialFrameHide", true, true, {});
     sbrowser.contentDocument.documentElement.dispatchEvent(evt);
   },
 
+  updateToggleNotifications: function() {
+    let command = document.getElementById("Social:ToggleNotifications");
+    command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
+    command.setAttribute("hidden", !SocialUI.enabled);
+  },
+
   update: function SocialSidebar_update() {
+    this.updateToggleNotifications();
+    this._updateHeader();
     clearTimeout(this._unloadTimeoutId);
     // Hide the toggle menu item if the sidebar cannot appear
     let command = document.getElementById("Social:ToggleSidebar");
     command.setAttribute("hidden", this.canShow ? "false" : "true");
 
     // Hide the sidebar if it cannot appear, or has been toggled off.
     // Also set the command "checked" state accordingly.
     let hideSidebar = !this.canShow || !this.opened;
@@ -1248,35 +838,41 @@ SocialSidebar = {
       sbrowser.setAttribute("origin", Social.provider.origin);
       if (Social.provider.errorState == "frameworker-error") {
         SocialSidebar.setSidebarErrorMessage();
         return;
       }
 
       // Make sure the right sidebar URL is loaded
       if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
+        // we check readyState right after setting src, we need a new content
+        // viewer to ensure we are checking against the correct document.
+        sbrowser.docShell.createAboutBlankContentViewer(null);
         Social.setErrorListener(sbrowser, this.setSidebarErrorMessage.bind(this));
         // setting isAppTab causes clicks on untargeted links to open new tabs
         sbrowser.docShell.isAppTab = true;
         sbrowser.setAttribute("src", Social.provider.sidebarURL);
         PopupNotifications.locationChange(sbrowser);
       }
 
       // if the document has not loaded, delay until it is
       if (sbrowser.contentDocument.readyState != "complete") {
+        document.getElementById("social-sidebar-button").setAttribute("loading", "true");
         sbrowser.addEventListener("load", SocialSidebar._loadListener, true);
       } else {
         this.setSidebarVisibilityState(true);
       }
     }
+    this._updateCheckedMenuItems(this.opened && this.provider ? this.provider.origin : null);
   },
 
   _loadListener: function SocialSidebar_loadListener() {
     let sbrowser = document.getElementById("social-sidebar-browser");
     sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
+    document.getElementById("social-sidebar-button").removeAttribute("loading");
     SocialSidebar.setSidebarVisibilityState(true);
   },
 
   unloadSidebar: function SocialSidebar_unloadSidebar() {
     let sbrowser = document.getElementById("social-sidebar-browser");
     if (!sbrowser.hasAttribute("origin"))
       return;
 
@@ -1296,16 +892,118 @@ SocialSidebar = {
     let sbrowser = document.getElementById("social-sidebar-browser");
     // a frameworker error "trumps" a sidebar error.
     if (Social.provider.errorState == "frameworker-error") {
       sbrowser.setAttribute("src", "about:socialerror?mode=workerFailure");
     } else {
       let url = encodeURIComponent(Social.provider.sidebarURL);
       sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
     }
+  },
+
+  // provider will move to a sidebar specific member in bug 894806
+  get provider() {
+    return Social.provider;
+  },
+
+  setProvider: function(origin) {
+    Social.setProviderByOrigin(origin);
+    this._updateHeader();
+    this._updateCheckedMenuItems(origin);
+  },
+
+  _updateHeader: function() {
+    let provider = this.provider;
+    let image, title;
+    if (provider) {
+      image = "url(" + (provider.icon32URL || provider.iconURL) + ")";
+      title = provider.name;
+    }
+    document.getElementById("social-sidebar-favico").style.listStyleImage = image;
+    document.getElementById("social-sidebar-title").value = title;
+  },
+
+  _updateCheckedMenuItems: function(origin) {
+    // update selected menuitems
+    let menuitems = document.getElementsByClassName("social-provider-menuitem");
+    for (let mi of menuitems) {
+      if (origin && mi.getAttribute("origin") == origin) {
+        mi.setAttribute("checked", "true");
+        mi.setAttribute("oncommand", "SocialSidebar.hide();");
+      } else if (mi.getAttribute("checked")) {
+        mi.removeAttribute("checked");
+        mi.setAttribute("oncommand", "SocialSidebar.show(this.getAttribute('origin'));");
+      }
+    }
+  },
+
+  show: function(origin) {
+    // always show the sidebar, and set the provider
+    this.setProvider(origin);
+    Services.prefs.setBoolPref("social.sidebar.open", true);
+  },
+
+  hide: function() {
+    Services.prefs.setBoolPref("social.sidebar.open", false);
+    this._updateCheckedMenuItems();
+  },
+
+  populateSidebarMenu: function(event) {
+    // Providers are removed from the view->sidebar menu when there is a change
+    // in providers, so we only have to populate onshowing if there are no
+    // provider menus. We populate this menu so long as there are enabled
+    // providers with sidebars.
+    let popup = event.target;
+    let providerMenuSeps = popup.getElementsByClassName("social-provider-menu");
+    if (providerMenuSeps[0].previousSibling.nodeName == "menuseparator")
+      SocialSidebar._populateProviderMenu(providerMenuSeps[0]);
+  },
+
+  clearProviderMenus: function() {
+    // called when there is a change in the provider list we clear all menus,
+    // they will be repopulated when the menu is shown
+    let providerMenuSeps = document.getElementsByClassName("social-provider-menu");
+    for (let providerMenuSep of providerMenuSeps) {
+      while (providerMenuSep.previousSibling.nodeName == "menuitem") {
+        let menu = providerMenuSep.parentNode;
+        menu.removeChild(providerMenuSep.previousSibling);
+      }
+    }
+  },
+
+  _populateProviderMenu: function(providerMenuSep) {
+    let menu = providerMenuSep.parentNode;
+    // selectable providers are inserted before the provider-menu seperator,
+    // remove any menuitems in that area
+    while (providerMenuSep.previousSibling.nodeName == "menuitem") {
+      menu.removeChild(providerMenuSep.previousSibling);
+    }
+    // only show a selection in the sidebar header menu if there is more than one
+    let providers = [p for (p of Social.providers) if (p.sidebarURL)];
+    if (providers.length < 2 && menu.id != "viewSidebarMenu") {
+      providerMenuSep.hidden = true;
+      return;
+    }
+    let topSep = providerMenuSep.previousSibling;
+    for (let provider of providers) {
+      let menuitem = document.createElement("menuitem");
+      menuitem.className = "menuitem-iconic social-provider-menuitem";
+      menuitem.setAttribute("image", provider.iconURL);
+      menuitem.setAttribute("label", provider.name);
+      menuitem.setAttribute("origin", provider.origin);
+      if (this.opened && provider == this.provider) {
+        menuitem.setAttribute("checked", "true");
+        menuitem.setAttribute("oncommand", "SocialSidebar.hide();");
+      } else {
+        menuitem.setAttribute("oncommand", "SocialSidebar.show(this.getAttribute('origin'));");
+      }
+      menu.insertBefore(menuitem, providerMenuSep);
+    }
+    topSep.hidden = topSep.nextSibling == providerMenuSep;
+    providerMenuSep.hidden = !providerMenuSep.nextSibling;
   }
 }
 
 // this helper class is used by removable/customizable buttons to handle
 // widget creation/destruction
 
 // When a provider is installed we show all their UI so the user will see the
 // functionality of what they installed. The user can later customize the UI,
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1347,18 +1347,16 @@ var gBrowserInit = {
                             .getService(Ci.nsIMacDockSupport);
           dockSupport.dockMenu = nativeMenu;
         }
         catch (e) {
         }
       }
     }
 
-    SocialUI.nonBrowserWindowInit();
-
     if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
       document.getElementById("macDockMenuNewWindow").hidden = true;
     }
 
     this._delayedStartupTimeoutId = setTimeout(this.nonBrowserWindowDelayedStartup.bind(this), 0);
   },
 
   nonBrowserWindowDelayedStartup: function() {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -823,68 +823,16 @@
         <toolbarbutton id="social-share-button"
                        class="toolbarbutton-1 chromeclass-toolbar-additional"
                        hidden="true"
                        overflows="false"
                        label="&sharePageCmd.label;"
                        tooltiptext="&sharePageCmd.label;"
                        cui-areatype="toolbar"
                        command="Social:SharePage"/>
-
-        <toolbaritem id="social-toolbar-item"
-                     class="chromeclass-toolbar-additional toolbaritem-with-separator"
-                     removable="false"
-                     title="&socialToolbar.title;"
-                     hidden="true"
-                     overflows="false"
-                     cui-areatype="toolbar"
-                     observes="socialActiveBroadcaster">
-        <toolbarbutton id="social-notification-icon" class="default-notification-icon toolbarbutton-1 notification-anchor-icon"
-                   oncommand="PopupNotifications._reshowNotifications(this,
-                                document.getElementById('social-sidebar-browser'));"/>
-          <toolbarbutton id="social-provider-button"
-                         class="toolbarbutton-1"
-                         type="menu">
-            <menupopup id="social-statusarea-popup">
-              <menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center"
-                        observes="socialBroadcaster_userDetails"
-                        oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();">
-                <image class="social-statusarea-user-portrait"
-                       observes="socialBroadcaster_userDetails"/>
-                <vbox>
-                  <label class="social-statusarea-loggedInStatus"
-                         observes="socialBroadcaster_userDetails"/>
-                </vbox>
-              </menuitem>
-#ifndef XP_WIN
-              <menuseparator class="social-statusarea-separator"/>
-#endif
-              <menuitem class="social-toggle-sidebar-menuitem"
-                        type="checkbox"
-                        autocheck="false"
-                        command="Social:ToggleSidebar"
-                        label="&social.toggleSidebar.label;"
-                        accesskey="&social.toggleSidebar.accesskey;"/>
-              <menuitem class="social-toggle-notifications-menuitem"
-                        type="checkbox"
-                        autocheck="false"
-                        command="Social:ToggleNotifications"
-                        label="&social.toggleNotifications.label;"
-                        accesskey="&social.toggleNotifications.accesskey;"/>
-              <menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
-              <menuseparator/>
-              <menuseparator class="social-provider-menu" hidden="true"/>
-              <menuitem class="social-addons-menuitem" command="Social:Addons"
-                        label="&social.addons.label;"/>
-              <menuitem label="&social.learnMore.label;"
-                        accesskey="&social.learnMore.accesskey;"
-                        oncommand="SocialUI.showLearnMore();"/>
-            </menupopup>
-          </toolbarbutton>
-        </toolbaritem>
       </hbox>
 
       <toolbarbutton id="nav-bar-overflow-button"
                      class="toolbarbutton-1 chromeclass-toolbar-additional overflow-button"
                      skipintoolbarset="true"
                      tooltiptext="&navbarOverflow.label;"/>
 
       <toolbaritem id="PanelUI-button"
@@ -1045,16 +993,47 @@
       </vbox>
       <splitter id="social-sidebar-splitter"
                 class="chromeclass-extrachrome sidebar-splitter"
                 observes="socialSidebarBroadcaster"/>
       <vbox id="social-sidebar-box"
             class="chromeclass-extrachrome"
             observes="socialSidebarBroadcaster"
             persist="width">
+
+        <sidebarheader id="social-sidebar-header" class="sidebar-header" align="center">
+          <image id="social-sidebar-favico"/>
+          <label id="social-sidebar-title" class="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
+          <button id="social-sidebar-button"
+                         type="menu">
+            <menupopup id="social-statusarea-popup" position="after_end">
+              <menuitem class="social-toggle-sidebar-menuitem"
+                        type="checkbox"
+                        autocheck="false"
+                        command="Social:ToggleSidebar"
+                        label="&social.toggleSidebar.label;"
+                        accesskey="&social.toggleSidebar.accesskey;"/>
+              <menuitem class="social-toggle-notifications-menuitem"
+                        type="checkbox"
+                        autocheck="false"
+                        command="Social:ToggleNotifications"
+                        label="&social.toggleNotifications.label;"
+                        accesskey="&social.toggleNotifications.accesskey;"/>
+              <menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
+              <menuseparator/>
+              <menuseparator class="social-provider-menu" hidden="true"/>
+              <menuitem class="social-addons-menuitem" command="Social:Addons"
+                        label="&social.addons.label;"/>
+              <menuitem label="&social.learnMore.label;"
+                        accesskey="&social.learnMore.accesskey;"
+                        oncommand="SocialUI.showLearnMore();"/>
+            </menupopup>
+          </button>
+        </sidebarheader>
+
         <browser id="social-sidebar-browser"
                  type="content"
                  context="contentAreaContextMenu"
                  disableglobalhistory="true"
                  tooltip="aHTMLTooltip"
                popupnotificationanchor="social-notification-icon"
                  flex="1"
                  style="min-width: 14em; width: 18em; max-width: 36em;"/>
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -247,19 +247,16 @@ function checkSocialUI(win) {
     if (!enabled || (Social.defaultProvider.statusURL && Social.allowMultipleWorkers)) {
       _ok(!win.SocialToolbar.button.style.listStyleImage, "toolbar button is default icon");
     } else {
       _is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
     }
   }
   // the menus should always have the provider name
   if (provider) {
-    for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
-      _is(document.getElementById(id).getAttribute("label"), Social.provider.name, "element has the provider name");
-
     let contextMenus = [
       {
         type: "link",
         id: "context-marklinkMenu",
         label: "social.marklinkMenu.label"
       },
       {
         type: "page",
@@ -294,18 +291,16 @@ function checkSocialUI(win) {
 
   // and for good measure, check all the social commands.
   isbool(!doc.getElementById("Social:Toggle").hidden, active, "Social:Toggle visible?");
   isbool(!doc.getElementById("Social:ToggleSidebar").hidden, enabled, "Social:ToggleSidebar visible?");
   isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
   isbool(!doc.getElementById("Social:FocusChat").hidden, enabled, "Social:FocusChat visible?");
   isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
 
-  // broadcasters.
-  isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
   // and report on overall success of failure of the various checks here.
   is(numGoodTests, numTests, "The Social UI tests succeeded.")
 }
 
 function waitForNotification(topic, cb) {
   function observer(subject, topic, data) {
     Services.obs.removeObserver(observer, topic);
     cb();
--- a/browser/components/customizableui/src/CustomizableUI.jsm
+++ b/browser/components/customizableui/src/CustomizableUI.jsm
@@ -179,17 +179,16 @@ let CustomizableUIInternal = {
       defaultPlacements: [
         "urlbar-container",
         "search-container",
         "webrtc-status-button",
         "bookmarks-menu-button",
         "downloads-button",
         "home-button",
         "social-share-button",
-        "social-toolbar-item",
       ]
     });
 #ifndef XP_MACOSX
     this.registerArea(CustomizableUI.AREA_MENUBAR, {
       legacy: true,
       type: CustomizableUI.TYPE_TOOLBAR,
       defaultPlacements: [
         "menubar-items",
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -640,17 +640,16 @@ just addresses the organization to follo
 
 <!ENTITY syncSetup.label              "Set Up &syncBrand.shortName.label;…">
 <!ENTITY syncSetup.accesskey          "Y">
 <!ENTITY syncSyncNowItem.label        "Sync Now">
 <!ENTITY syncSyncNowItem.accesskey    "S">
 <!ENTITY syncToolbarButton.label      "Sync">
 
 <!ENTITY socialToolbar.title        "Social Toolbar Button">
-<!ENTITY social.notLoggedIn.label   "Not logged in">
 
 <!ENTITY social.ok.label       "OK">
 <!ENTITY social.ok.accesskey   "O">
 
 <!ENTITY social.toggleSidebar.label "Show sidebar">
 <!ENTITY social.toggleSidebar.accesskey "s">
 
 <!ENTITY social.addons.label "Manage Services…">
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -118,16 +118,18 @@ browser.jar:
 * skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
   skin/classic/browser/preferences/applications.css   (preferences/applications.css)
   skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
   skin/classic/browser/social/services-16.png         (social/services-16.png)
   skin/classic/browser/social/services-64.png         (social/services-64.png)
   skin/classic/browser/social/share-button.png        (social/share-button.png)
   skin/classic/browser/social/share-button-active.png (social/share-button-active.png)
   skin/classic/browser/social/chat-icons.png          (social/chat-icons.png)
+  skin/classic/browser/social/gear_default.png        (../shared/social/gear_default.png)
+  skin/classic/browser/social/gear_clicked.png        (../shared/social/gear_clicked.png)
   skin/classic/browser/tabbrowser/connecting.png      (tabbrowser/connecting.png)
   skin/classic/browser/tabbrowser/loading.png         (tabbrowser/loading.png)
   skin/classic/browser/tabbrowser/tab.png             (tabbrowser/tab.png)
   skin/classic/browser/tabbrowser/tab-active-middle.png     (tabbrowser/tab-active-middle.png)
   skin/classic/browser/tabbrowser/tab-background-end.png    (tabbrowser/tab-background-end.png)
   skin/classic/browser/tabbrowser/tab-background-middle.png (tabbrowser/tab-background-middle.png)
   skin/classic/browser/tabbrowser/tab-background-start.png  (tabbrowser/tab-background-start.png)
   skin/classic/browser/tabbrowser/tab-overflow-border.png   (tabbrowser/tab-overflow-border.png)
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -2397,21 +2397,23 @@ sidebarheader {
 
 #appcontent ~ .sidebar-splitter {
   -moz-border-start: 1px solid #ccc;
   -moz-border-end: none;
   -moz-margin-start: 0;
   -moz-margin-end: -3px;
 }
 
+.sidebar-title,
 #sidebar-title {
   color: #535f6d;
   font-weight: bold;
 }
 
+.sidebar-throbber[loading="true"],
 #sidebar-throbber[loading="true"] {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
 }
 
 sidebarheader > .tabs-closebutton > .toolbarbutton-text {
   display: none;
 }
 
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -191,16 +191,18 @@ browser.jar:
   skin/classic/browser/preferences/applications.css         (preferences/applications.css)
   skin/classic/browser/preferences/aboutPermissions.css     (preferences/aboutPermissions.css)
   skin/classic/browser/social/services-16.png               (social/services-16.png)
   skin/classic/browser/social/services-16@2x.png            (social/services-16@2x.png)
   skin/classic/browser/social/services-64.png               (social/services-64.png)
   skin/classic/browser/social/services-64@2x.png            (social/services-64@2x.png)
   skin/classic/browser/social/chat-icons.png                             (social/chat-icons.png)
   skin/classic/browser/social/chat-icons@2x.png                          (social/chat-icons@2x.png)
+  skin/classic/browser/social/gear_default.png                           (../shared/social/gear_default.png)
+  skin/classic/browser/social/gear_clicked.png                           (../shared/social/gear_clicked.png)
   skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png             (tabbrowser/alltabs-box-bkgnd-icon.png)
   skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon-inverted.png    (tabbrowser/alltabs-box-bkgnd-icon-inverted.png)
   skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon-inverted@2x.png (tabbrowser/alltabs-box-bkgnd-icon-inverted@2x.png)
   skin/classic/browser/tabbrowser/newtab.png                             (tabbrowser/newtab.png)
   skin/classic/browser/tabbrowser/newtab@2x.png                          (tabbrowser/newtab@2x.png)
   skin/classic/browser/tabbrowser/newtab-inverted.png                    (tabbrowser/newtab-inverted.png)
   skin/classic/browser/tabbrowser/newtab-inverted@2x.png                 (tabbrowser/newtab-inverted@2x.png)
   skin/classic/browser/tabbrowser/connecting.png                         (tabbrowser/connecting.png)
--- a/browser/themes/shared/social/chat.inc.css
+++ b/browser/themes/shared/social/chat.inc.css
@@ -1,14 +1,44 @@
 %if 0
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 %endif
 
+#social-sidebar-header {
+  padding: 3px;
+}
+
+#social-sidebar-button {
+  -moz-appearance: none;
+  list-style-image: url(chrome://browser/skin/social/gear_default.png);
+  min-width: 16px;
+  padding: 0;
+  margin: 2px;
+}
+#social-sidebar-button:hover,
+#social-sidebar-button:hover:active {
+  list-style-image: url(chrome://browser/skin/social/gear_clicked.png);
+}
+#social-sidebar-button > .toolbarbutton-menu-dropmarker {
+  display: none;
+}
+
+#social-sidebar-button[loading="true"] {
+  list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#social-sidebar-favico {
+  max-height: 16px;
+  max-width: 16px;
+  padding: 0;
+  margin: 2px;
+}
+
 .chat-status-icon {
   max-height: 16px;
   max-width: 16px;
   padding: 0;
 }
 
 .chat-toolbarbutton {
   -moz-appearance: none;
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7c93aa767e4b9542ab143f6bf7062514761f7304
GIT binary patch
literal 1262
zc%17D@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%*vS|5hW46K32*3xq68pHF_1f1q>iyV_#8_n4FzjqL7rD
zo|$K>^nUk#C56lsTcvPQUjyF)=hTc$kE){7;3~h6<f`ms%M>MhI|Z8xE1&_nsU?XD
z6}dTi#a0!zN?>!XfNYSkzLEl1NlCV?62wsvz5xo(`9-M;rh2Bj$p(fd3g(u2hNgxl
z7KS<sMh1q)`Ub}OhQ_*vMpg!vR)(euP@n{~ttchUD#*nRY8Q}atCUevQedU8UtV6W
zS8lAAUzDzIXlZGwZ(yWvWTXpJp<7&;SCUwvn^&w1Gr=XbIJqdZpd>RtPXWYFOv*1U
zu~kxnc_Fs|ZfssLG?;(^reBd*pl_&WppT@`*B8Ii++4Wo;*y}$H2kWILn;eW^@CE2
z^Gl18ff1Lc4ANX+<y@4SSdw29lAoUg3&ntp{F40QjQj!xXJ-Ws-^Aq1JP=<KtijjU
z$}_LHBrz{J)zigR2`HkMnVDkcWZ`0AZsh7{V(jE<Xy|HeVeD$+YG&Z%WMXP+VP@n4
z)9aF-T$-DjR|3<Ug3#-PQ!gkjKy;@TWtOF;xE1B+DuDfLm5JLe7P#F4(VK$XEtWX-
z>H{64j~3G~Az<<WG2!VJ$bqN))I4BvF9N3PNq-NRFfcGCdb&7<RNShW<gMY7D02M0
z?ECOF$NEGf{Vy)jIP0`=!_3Hq9aECl>qJ(rQCH!P-fUEvqocEI3hT`kn%t>NTQ+@=
zy8hnhfAsv-HD7oC|2?<*oNfR6&&>)S4oy9oB6PxL&C{Zti*kxRY*RMwZQVEZ-g{GC
z;{-l#7Slzq6RLR37cQ1Rd80YTfpgyj=2;Ks<kaS|+0XU+zL+<lL0RI%zjfs^8iXa9
z_DtQy9s6O`B%9P-O<@`BQa2{=l{}VgWA^YIXH{dIm-nK%8<eZ(Hm%uoyQu%mw4`D!
z_Sr8MUEcon2hX%8J^9V^%+}pn)%7L)?T@PeW$l|6DrZc5D;V_W=d2vDDXo#Un?2<Z
zOkx!?ox|Q?eR$`Uea>dqx4A+?<jzT`JPDW(Y^pL>!Me{ggL${-?~B|9O)`g;|I&Q9
z>#1h#m0TM!$s<!rB#%dJiLT}SeECOx<LV8px3?+&kc(uro~M5Oqk97*gGP5&g2Kzc
QlAsdE)78&qol`;+0DFeR0ssI2
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2a9c8e19895a44c153fb6cc953d7373778befd3a
GIT binary patch
literal 1271
zc%17D@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O`
z&)mfH)S%SFl*+=BsWuD@%*vS|5hW46K32*3xq68pHF_1f1q>iyV_#8_n4FzjqL7rD
zo|$K>^nUk#C56lsTcvPQUjyF)=hTc$kE){7;3~h6<f`ms%M>MhI|Z8xE1&_nsU?XD
z6}dTi#a0!zN?>!XfNYSkzLEl1NlCV?62wsvz5xo(`9-M;rh2Bj$p(fd3g(u2hNgxl
z7KS<sMh1q)`Ub}OhQ_*vMpg!vR)(euP@n{~ttchUD#*nRY8Q}atCUevQedU8UtV6W
zS8lAAUzDzIXlZGwZ(yWvWTXpJp<7&;SCUwvn^&w1Gr=XbIJqdZpd>RtPXWYFOv*1U
zu~kxnc_Fs|ZfssLG?;(^reBd*pl_&WppT@`*B8Ii++4Wo;*y}$H2kWILn;eW^@CE2
z^Gl18ff1Lc4ANX+<y@4SSdw29lAoUg3&ntp{F40QjQj!xXJ-Ws-^Aq1JP=<KtijjU
z$}_LHBrz{J)zigR2`HkMnVDkcV&-aT=4fPYV(jc}Xy|HeVeD$+YG&Z%WMXP+VP@n4
z)9aF-T$-DjR|3<Ug3xP$Q!gkjKy;@TWtOF;xE1B+DuDfLm5IeIP8Kc}=0>j0CdN*#
z*xdrrn}XXdW;orV4|I$^T1>-)fXN5Mgr{2|2cGg%^MJ{{2$-(V^{zX}z`&U0>Eakt
zajRz1d2N?Kk>mGgKm0lOZiM2~<JVf$o=(*f;jU-sx}ovymF~;lKM@g}Cl6gKI+UaH
zWmb?_#7a%>)WdA453g6)rCY6ExBSkpGv)7gKHu~Cahx@evv$<Y9JAgthi5&nblrMZ
zaqEWGx4NI!Zm3%?IfJz@LScnmEc->_9i1|7BaX#AVe<OGDu03DdCF^Z;~V?l^Dih3
zXh<$tyZ^PUnj-(<36q1qFJz9}s^V=N>nOa%NmORVUO_dXKRJiz3Vva#oifewcB21V
zQz@0Hcc)b^*{*1|{FQ=mtjVuwa`PQ0%_%g?czG-&a_Yu^OJt+}*SjBE^4LQ91y{)G
zwZ<GxdtUG2Pno>H_r=A{Y3Fu5j9M0T<)Mw!DT#AS-`&2VRzCYm*Qvvj?OUuwuAFS_
z5mdQu$f~QL|I*+egWE*qA6M$Ue%&eJNj;NeBPe}j%PXP2OU2XoEfBPu^-I4%v@9Xq
mjOD)aX@%>bQ>^}R7%(^<%Dc*2xb`WiDDrgmb6Mw<&;$TplE}~i
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -47,24 +47,26 @@
     border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
   }
 
   #urlbar:not(:-moz-lwtheme)[focused],
   .searchbar-textbox:not(:-moz-lwtheme)[focused] {
     border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
   }
 
+  .sidebar-header,
   #sidebar-header {
     -moz-appearance: none;
     color: black;
     background-color: #EEF3FA;
     border-bottom: none;
     text-shadow: none;
   }
 
+  .sidebar-title,
   #sidebar-title {
     font-weight: bold;
   }
 
   .sidebar-splitter {
     border: 0;
     -moz-border-end: 1px solid #A9B7C9;
     min-width: 0;
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -137,16 +137,18 @@ browser.jar:
         skin/classic/browser/preferences/saveFile.png                (preferences/saveFile.png)
 *       skin/classic/browser/preferences/preferences.css             (preferences/preferences.css)
 *       skin/classic/browser/preferences/in-content/preferences.css  (preferences/in-content/preferences.css)
         skin/classic/browser/preferences/applications.css            (preferences/applications.css)
         skin/classic/browser/preferences/aboutPermissions.css        (preferences/aboutPermissions.css)
         skin/classic/browser/social/services-16.png                  (social/services-16.png)
         skin/classic/browser/social/services-64.png                  (social/services-64.png)
         skin/classic/browser/social/chat-icons.png                   (social/chat-icons.png)
+        skin/classic/browser/social/gear_default.png                 (../shared/social/gear_default.png)
+        skin/classic/browser/social/gear_clicked.png                 (../shared/social/gear_clicked.png)
         skin/classic/browser/tabbrowser/newtab.png                   (tabbrowser/newtab.png)
         skin/classic/browser/tabbrowser/newtab-inverted.png          (tabbrowser/newtab-inverted.png)
         skin/classic/browser/tabbrowser/connecting.png               (tabbrowser/connecting.png)
         skin/classic/browser/tabbrowser/loading.png                  (tabbrowser/loading.png)
         skin/classic/browser/tabbrowser/tab.png                      (tabbrowser/tab.png)
         skin/classic/browser/tabbrowser/tab-active-middle.png        (tabbrowser/tab-active-middle.png)
         skin/classic/browser/tabbrowser/tab-arrow-left.png           (tabbrowser/tab-arrow-left.png)
         skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png  (tabbrowser/tab-arrow-left-inverted.png)
@@ -444,16 +446,18 @@ browser.jar:
         skin/classic/aero/browser/preferences/saveFile.png           (preferences/saveFile-aero.png)
 *       skin/classic/aero/browser/preferences/preferences.css        (preferences/preferences.css)
 *       skin/classic/aero/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
         skin/classic/aero/browser/preferences/applications.css       (preferences/applications.css)
         skin/classic/aero/browser/preferences/aboutPermissions.css   (preferences/aboutPermissions.css)
         skin/classic/aero/browser/social/services-16.png             (social/services-16.png)
         skin/classic/aero/browser/social/services-64.png             (social/services-64.png)
         skin/classic/aero/browser/social/chat-icons.png              (social/chat-icons.png)
+        skin/classic/aero/browser/social/gear_default.png            (../shared/social/gear_default.png)
+        skin/classic/aero/browser/social/gear_clicked.png            (../shared/social/gear_clicked.png)
         skin/classic/aero/browser/tabbrowser/newtab.png              (tabbrowser/newtab.png)
         skin/classic/aero/browser/tabbrowser/newtab-inverted.png     (tabbrowser/newtab-inverted.png)
         skin/classic/aero/browser/tabbrowser/connecting.png          (tabbrowser/connecting.png)
         skin/classic/aero/browser/tabbrowser/loading.png             (tabbrowser/loading.png)
         skin/classic/aero/browser/tabbrowser/tab.png                 (tabbrowser/tab.png)
         skin/classic/aero/browser/tabbrowser/tab-active-middle.png   (tabbrowser/tab-active-middle.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-left.png      (tabbrowser/tab-arrow-left.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)