Bug 957460 - [Australis] Add Firefox Accounts widget for customization panel r=gijs,markh
authorTim Taubert <ttaubert@mozilla.com>
Fri, 10 Jan 2014 19:32:11 +0100
changeset 165641 e6012841cb57f8081d960b394cc59697028e7362
parent 165640 c338f5d414b695c20bf2060d026081a843805722
child 165642 ce50a0cdc32904f2a87413868e4923951a6c431d
push id4630
push userttaubert@mozilla.com
push dateTue, 28 Jan 2014 23:26:26 +0000
treeherderfx-team@e6012841cb57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgijs, markh
bugs957460
milestone29.0a1
Bug 957460 - [Australis] Add Firefox Accounts widget for customization panel r=gijs,markh
browser/base/content/browser-fxaccounts.js
browser/components/customizableui/content/panelUI.inc.xul
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/shared/customizableui/panelUIOverlay.inc.css
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -4,56 +4,130 @@
 
 XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
   return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
 });
 
 let gFxAccounts = {
 
   _initialized: false,
+  _originalLabel: null,
+  _inCustomizationMode: false,
+
+  get weave() {
+    delete this.weave;
+    return this.weave = Cc["@mozilla.org/weave/service;1"]
+                          .getService(Ci.nsISupports)
+                          .wrappedJSObject;
+  },
 
   get topics() {
     delete this.topics;
     return this.topics = [
-      FxAccountsCommon.ONVERIFIED_NOTIFICATION
+      FxAccountsCommon.ONLOGIN_NOTIFICATION,
+      FxAccountsCommon.ONVERIFIED_NOTIFICATION,
+      FxAccountsCommon.ONLOGOUT_NOTIFICATION
     ];
   },
 
+  get button() {
+    delete this.button;
+    return this.button = document.getElementById("PanelUI-fxa-status");
+  },
+
   init: function () {
     if (this._initialized) {
       return;
     }
 
     for (let topic of this.topics) {
       Services.obs.addObserver(this, topic, false);
     }
 
+    gNavToolbox.addEventListener("customizationstarting", this);
+    gNavToolbox.addEventListener("customizationending", this);
+
+    // Save the button's original label so that
+    // we can restore it if overridden later.
+    this._originalLabel = this.button.getAttribute("label");
     this._initialized = true;
+
+    this.updateUI();
   },
 
   uninit: function () {
     if (!this._initialized) {
       return;
     }
 
     for (let topic of this.topics) {
       Services.obs.removeObserver(this, topic);
     }
 
     this._initialized = false;
   },
 
   observe: function (subject, topic) {
-    this.showDoorhanger();
+    if (topic == FxAccountsCommon.ONVERIFIED_NOTIFICATION) {
+      this.showDoorhanger();
+    } else {
+      this.updateUI();
+    }
+  },
+
+  handleEvent: function (event) {
+    this._inCustomizationMode = event.type == "customizationstarting";
+    this.updateUI();
   },
 
   showDoorhanger: function () {
     let panel = document.getElementById("sync-popup");
     let anchor = document.getElementById("PanelUI-menu-button");
 
     let iconAnchor =
       document.getAnonymousElementByAttribute(anchor, "class",
                                               "toolbarbutton-icon");
 
     panel.hidden = false;
     panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
+  },
+
+  updateUI: function () {
+    // Bail out if FxA is disabled.
+    if (!this.weave.fxAccountsEnabled) {
+      return;
+    }
+
+    // FxA is enabled, show the widget.
+    this.button.removeAttribute("hidden");
+
+    // Make sure the button is disabled in customization mode.
+    if (this._inCustomizationMode) {
+      this.button.setAttribute("disabled", "true");
+    } else {
+      this.button.removeAttribute("disabled");
+    }
+
+    // If the user is signed into their Firefox account and we are not
+    // currently in customization mode, show their email address.
+    fxAccounts.getSignedInUser().then(userData => {
+      if (userData && !this._inCustomizationMode) {
+        this.button.setAttribute("signedin", "true");
+        this.button.setAttribute("label", userData.email);
+        this.button.setAttribute("tooltiptext", userData.email);
+      } else {
+        this.button.removeAttribute("signedin");
+        this.button.setAttribute("label", this._originalLabel);
+        this.button.removeAttribute("tooltiptext");
+      }
+    });
+  },
+
+  toggle: function (event) {
+    if (event.originalTarget.hasAttribute("signedin")) {
+      openPreferences("paneSync");
+    } else {
+      switchToTabHavingURI("about:accounts", true);
+    }
+
+    PanelUI.hide();
   }
 };
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -10,35 +10,39 @@
        noautofocus="true">
   <panelmultiview id="PanelUI-multiView" mainViewId="PanelUI-mainView">
     <panelview id="PanelUI-mainView" context="customizationPanelContextMenu">
       <vbox id="PanelUI-contents-scroller">
         <vbox id="PanelUI-contents" class="panelUI-grid"/>
       </vbox>
 
       <footer id="PanelUI-footer">
-        <!-- The parentNode is used so that the footer is presented as the anchor
-             instead of just the button being the anchor. -->
-        <toolbarbutton id="PanelUI-customize" label="&appMenuCustomize.label;"
-                       exitLabel="&appMenuCustomizeExit.label;"
-                       oncommand="gCustomizeMode.toggle();"/>
-        <toolbarseparator/>
-        <toolbarbutton id="PanelUI-help" label="&helpMenu.label;"
-                       tooltiptext="&helpMenu.label;"
-                       oncommand="PanelUI.showHelpView(this.parentNode);"/>
-        <toolbarseparator/>
-        <toolbarbutton id="PanelUI-quit"
+        <toolbarbutton id="PanelUI-fxa-status" label="&fxaSignIn.label;"
+                       oncommand="gFxAccounts.toggle(event);"
+                       hidden="true"/>
+
+        <hbox id="PanelUI-footer-inner">
+          <toolbarbutton id="PanelUI-customize" label="&appMenuCustomize.label;"
+                         exitLabel="&appMenuCustomizeExit.label;"
+                         oncommand="gCustomizeMode.toggle();"/>
+          <toolbarseparator/>
+          <toolbarbutton id="PanelUI-help" label="&helpMenu.label;"
+                         tooltiptext="&helpMenu.label;"
+                         oncommand="PanelUI.showHelpView(this.parentNode);"/>
+          <toolbarseparator/>
+          <toolbarbutton id="PanelUI-quit"
 #ifdef XP_WIN
-                       label="&quitApplicationCmdWin.label;"
-                       tooltiptext="&quitApplicationCmdWin.label;"
+                         label="&quitApplicationCmdWin.label;"
+                         tooltiptext="&quitApplicationCmdWin.label;"
 #else
-                       label="&quitApplicationCmd.label;"
-                       tooltiptext="&quitApplicationCmd.label;"
+                         label="&quitApplicationCmd.label;"
+                         tooltiptext="&quitApplicationCmd.label;"
 #endif
-                       command="cmd_quitApplication"/>
+                         command="cmd_quitApplication"/>
+        </hbox>
       </footer>
     </panelview>
 
     <panelview id="PanelUI-history" flex="1">
       <label value="&appMenuHistory.label;" class="panel-subview-header"/>
       <toolbarbutton id="appMenuViewHistorySidebar"
                      label="&appMenuHistory.viewSidebar.label;"
                      type="checkbox"
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -91,18 +91,19 @@ These should match what Safari and other
 <!ENTITY exitFullScreenCmd.label "Exit Full Screen">
 <!ENTITY exitFullScreenCmd.accesskey "F">
 <!ENTITY fullScreenCmd.label "Full Screen">
 <!ENTITY fullScreenCmd.accesskey "F">
 <!ENTITY fullScreenCmd.macCommandKey "f">
 <!ENTITY showAllTabsCmd.label "Show All Tabs">
 <!ENTITY showAllTabsCmd.accesskey "A">
 
+<!ENTITY fxaSignIn.label "Sign in to Sync">
 <!ENTITY syncPanel.descriptionSyncing "&brandShortName; is now syncing.">
-<!ENTITY syncPanel.descriptionPrefs "You can manage Sync from your browser's Preferences.">
+<!ENTITY syncPanel.descriptionPrefs "You can manage Sync in Preferences.">
 
 <!ENTITY fullScreenMinimize.tooltip "Minimize">
 <!ENTITY fullScreenRestore.tooltip "Restore">
 <!ENTITY fullScreenClose.tooltip "Close">
 <!ENTITY fullScreenAutohide.label "Hide Toolbars">
 <!ENTITY fullScreenAutohide.accesskey "H">
 <!ENTITY fullScreenExit.label "Exit Full Screen Mode">
 <!ENTITY fullScreenExit.accesskey "F">
--- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css
+++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css
@@ -211,83 +211,102 @@ toolbarpaletteitem[place="palette"] > to
 #zoom-in-button > .toolbarbutton-text,
 #zoom-out-button > .toolbarbutton-text,
 #zoom-reset-button > .toolbarbutton-icon {
   display: none;
 }
 
 #PanelUI-footer {
   display: flex;
+  flex-direction: column;
   background-color: rgba(0, 0, 0, 0.05);
   box-shadow: 0 -1px 0 rgba(0,0,0,.15);
   padding: 0;
   margin: 0;
-  min-height: 4em;
+}
+
+#PanelUI-footer-inner {
+  display: flex;
+  box-shadow: 0 -1px 0 rgba(0,0,0,.15);
 }
 
 #PanelUI-footer > toolbarseparator {
   border: 0;
   border-left: 1px solid rgba(0,0,0,0.1);
   margin: 7px 0 7px;
 }
 
 #PanelUI-footer:hover > toolbarseparator {
   margin: 0;
 }
 
 #PanelUI-help,
+#PanelUI-fxa-status,
 #PanelUI-customize,
 #PanelUI-quit {
   margin: 0;
   padding: 10px 0;
+  min-height: 2em;
   -moz-appearance: none;
   box-shadow: none;
   background-image: none;
   border: 1px solid transparent;
   border-bottom-style: none;
   border-radius: 0;
   transition: background-color;
   -moz-box-orient: horizontal;
 }
 
+#PanelUI-fxa-status {
+  width: calc(@menuPanelWidth@ + 20px);
+  border-bottom-style: solid;
+}
+
+#PanelUI-fxa-status[signedin] {
+  font-weight: bold;
+}
+
 #PanelUI-help,
 #PanelUI-quit {
   min-width: 46px;
 }
 
+#PanelUI-fxa-status > .toolbarbutton-text,
 #PanelUI-customize > .toolbarbutton-text {
   text-align: start;
 }
 
 #PanelUI-help > .toolbarbutton-text,
 #PanelUI-quit > .toolbarbutton-text {
   display: none;
 }
 
 #PanelUI-help > .toolbarbutton-icon,
 #PanelUI-quit > .toolbarbutton-icon {
   -moz-margin-end: 0;
 }
 
+#PanelUI-fxa-status,
 #PanelUI-customize {
   flex: 1;
   -moz-padding-start: 15px;
   -moz-border-start-style: none;
   list-style-image: url(chrome://browser/skin/menuPanel-customize.png);
 }
 
 #PanelUI-help {
   list-style-image: url(chrome://browser/skin/menuPanel-help.png);
 }
 
 #PanelUI-quit {
   -moz-border-end-style: none;
   list-style-image: url(chrome://browser/skin/menuPanel-exit.png);
 }
 
+#PanelUI-fxa-status,
 #PanelUI-customize,
 #PanelUI-help,
 #PanelUI-quit {
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 
 #PanelUI-customize:hover,
 #PanelUI-help:not([disabled]):hover,
@@ -309,16 +328,22 @@ toolbarpaletteitem[place="palette"] > to
 #PanelUI-help:not([disabled]):hover,
 #PanelUI-customize:hover,
 #PanelUI-quit:not([disabled]):hover {
   outline: 1px solid rgba(0,0,0,0.1);
   background-color: rgba(0,0,0,0.1);
   box-shadow: none;
 }
 
+#PanelUI-fxa-status:not([disabled]):hover {
+  background-color: rgba(0,0,0,0.1);
+  border-bottom-color: rgba(0,0,0,0.1);
+  box-shadow: 0 -1px 0 rgba(0,0,0,0.2);
+}
+
 #PanelUI-quit:not([disabled]):hover {
   background-color: #d94141;
   outline-color: #c23a3a;
 }
 
 #PanelUI-quit:not([disabled]):hover:active {
   background-color: #ad3434;
 }