Bug 1241319 - Clarify synced tabs menu when not logged in. r=markh
authorEdouard Oger <eoger@fastmail.com>
Fri, 08 Apr 2016 10:46:00 -0400
changeset 292360 0611a1fb8d39387fe479c4689ef9825d73e31298
parent 292359 870df3ae98535fdd19b0097667b5a0b3c1186cd1
child 292361 a1880ae30781727384eeaa86dbff2288f24a969e
push id30158
push userryanvm@gmail.com
push dateSat, 09 Apr 2016 19:22:30 +0000
treeherdermozilla-central@d62963756d9a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs1241319
milestone48.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 1241319 - Clarify synced tabs menu when not logged in. r=markh
browser/base/content/browser-syncui.js
browser/components/customizableui/CustomizableWidgets.jsm
browser/components/customizableui/content/panelUI.inc.xul
browser/components/syncedtabs/SyncedTabsDeckView.js
browser/components/syncedtabs/sidebar.xhtml
browser/locales/en-US/chrome/browser/browser.dtd
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/shared/customizableui/panelUIOverlay.inc.css
--- a/browser/base/content/browser-syncui.js
+++ b/browser/base/content/browser-syncui.js
@@ -23,16 +23,17 @@ var gSyncUI = {
          "weave:service:login:error",
          "weave:service:logout:finish",
          "weave:service:start-over",
          "weave:service:start-over:finish",
          "weave:ui:login:error",
          "weave:ui:sync:error",
          "weave:ui:sync:finish",
          "weave:ui:clear-error",
+         "weave:engine:sync:finish"
   ],
 
   _unloaded: false,
   // The number of "active" syncs - while this is non-zero, our button will spin
   _numActiveSyncTasks: 0,
 
   init: function () {
     Cu.import("resource://services-common/stringbundle.js");
@@ -412,16 +413,27 @@ var gSyncUI = {
       }
     }
   }),
 
   onSyncFinish: function SUI_onSyncFinish() {
     let title = this._stringBundle.GetStringFromName("error.sync.title");
   },
 
+  onClientsSynced: function() {
+    let broadcaster = document.getElementById("sync-syncnow-state");
+    if (broadcaster) {
+      if (Weave.Service.clientsEngine.stats.numClients > 1) {
+        broadcaster.setAttribute("devices-status", "multi");
+      } else {
+        broadcaster.setAttribute("devices-status", "single");
+      }
+    }
+  },
+
   observe: function SUI_observe(subject, topic, data) {
     this.log.debug("observed", topic);
     if (this._unloaded) {
       Cu.reportError("SyncUI observer called after unload: " + topic);
       return;
     }
 
     // Unwrap, just like Svc.Obs, but without pulling in that dependency.
@@ -465,16 +477,22 @@ var gSyncUI = {
         this.updateUI();
         break;
       case "weave:service:ready":
         this.initUI();
         break;
       case "weave:notification:added":
         this.initNotifications();
         break;
+      case "weave:engine:sync:finish":
+        if (data != "clients") {
+          return;
+        }
+        this.onClientsSynced();
+        break;
     }
   },
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIObserver,
     Ci.nsISupportsWeakReference
   ])
 };
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -311,19 +311,21 @@ const CustomizableWidgets = [
       let bundle = doc.getElementById("bundle_browser");
       let formatArgs = ["android", "ios"].map(os => {
         let link = doc.createElement("label");
         link.textContent = bundle.getString(`appMenuRemoteTabs.mobilePromo.${os}`)
         link.setAttribute("mobile-promo-os", os);
         link.className = "text-link remotetabs-promo-link";
         return link.outerHTML;
       });
+      let promoParentElt = doc.getElementById("PanelUI-remotetabs-mobile-promo");
+      let fxAccountsBrand = promoParentElt.getAttribute("fxAccountsBrand");
+      formatArgs.push(fxAccountsBrand);
       // Put it all together...
-      let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo", formatArgs);
-      let promoParentElt = doc.getElementById("PanelUI-remotetabs-mobile-promo");
+      let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo.text", formatArgs);
       promoParentElt.innerHTML = contents;
       // We manually manage the "click" event to open the promo links because
       // allowing the "text-link" widget handle it has 2 problems: (1) it only
       // supports button 0 and (2) it's tricky to intercept when it does the
       // open and auto-close the panel. (1) can probably be fixed, but (2) is
       // trickier without hard-coding here the knowledge of exactly what buttons
       // it does support.
       // So we allow left and middle clicks to open the link in a new tab and
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -103,26 +103,28 @@
     </panelview>
 
     <panelview id="PanelUI-remotetabs" flex="1" class="PanelUI-subView">
       <label value="&appMenuRemoteTabs.label;" class="panel-subview-header"/>
       <vbox class="panel-subview-body">
         <!-- this widget has 3 boxes in the body, but only 1 is ever visible -->
         <!-- When Sync is ready to sync -->
         <vbox id="PanelUI-remotetabs-main" observes="sync-syncnow-state">
-          <toolbarbutton id="PanelUI-remotetabs-view-sidebar"
-                         class="subviewbutton"
-                         observes="viewTabsSidebar"
-                         label="&appMenuRemoteTabs.sidebar.label;"/>
-          <toolbarbutton id="PanelUI-remotetabs-syncnow"
-                         observes="sync-status"
-                         class="subviewbutton"
-                         oncommand="gSyncUI.doSync();"
-                         closemenu="none"/>
-          <menuseparator id="PanelUI-remotetabs-separator"/>
+          <vbox id="PanelUI-remotetabs-buttons">
+            <toolbarbutton id="PanelUI-remotetabs-view-sidebar"
+                           class="subviewbutton"
+                           observes="viewTabsSidebar"
+                           label="&appMenuRemoteTabs.sidebar.label;"/>
+            <toolbarbutton id="PanelUI-remotetabs-syncnow"
+                           observes="sync-status"
+                           class="subviewbutton"
+                           oncommand="gSyncUI.doSync();"
+                           closemenu="none"/>
+            <menuseparator id="PanelUI-remotetabs-separator"/>
+          </vbox>
           <deck id="PanelUI-remotetabs-deck">
             <!-- Sync is ready to Sync and the "tabs" engine is enabled -->
             <vbox id="PanelUI-remotetabs-tabspane">
               <vbox id="PanelUI-remotetabs-tabslist"
                     notabsforclientlabel="&appMenuRemoteTabs.notabs.label;"
                     />
             </vbox>
             <!-- Sync is ready to Sync but the "tabs" engine isn't enabled-->
@@ -144,19 +146,20 @@
               <!-- Show intentionally blank panel, see bug 1239845 -->
             </vbox>
             <!-- Sync has only 1 (ie, this) device connected -->
             <hbox id="PanelUI-remotetabs-nodevicespane" pack="center" flex="1">
               <vbox class="PanelUI-remotetabs-instruction-box">
                 <hbox pack="center">
                   <image class="fxaSyncIllustration" alt=""/>
                 </hbox>
-                <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.noclients.label;</label>
+                <label class="PanelUI-remotetabs-instruction-title">&appMenuRemoteTabs.noclients.title;</label>
+                <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.noclients.subtitle;</label>
                 <!-- The inner HTML for PanelUI-remotetabs-mobile-promo is built at runtime -->
-                <label id="PanelUI-remotetabs-mobile-promo"/>
+                <label id="PanelUI-remotetabs-mobile-promo" fxAccountsBrand="&syncBrand.fxAccount.label;"/>
               </vbox>
             </hbox>
           </deck>
         </vbox>
         <!-- a box to ensure contained boxes are centered horizonally -->
         <hbox pack="center" flex="1">
           <!-- When Sync is not configured -->
           <vbox id="PanelUI-remotetabs-setupsync"
--- a/browser/components/syncedtabs/SyncedTabsDeckView.js
+++ b/browser/components/syncedtabs/SyncedTabsDeckView.js
@@ -68,19 +68,22 @@ SyncedTabsDeckView.prototype = {
     let bundle = this._getBrowserBundle();
     let formatArgs = ["android", "ios"].map(os => {
       let link = this._doc.createElement("a");
       link.textContent = bundle.getString(`appMenuRemoteTabs.mobilePromo.${os}`)
       link.className = `${os}-link text-link`;
       link.setAttribute("href", "#");
       return link.outerHTML;
     });
+    let promoParentElt = this.container.querySelector(".device-promo");
+    let fxAccountsBrand = promoParentElt.getAttribute("fxAccountsBrand");
+    formatArgs.push(fxAccountsBrand);
     // Put it all together...
-    let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo", formatArgs);
-    this.container.querySelector(".device-promo").innerHTML = contents;
+    let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo.text", formatArgs);
+    promoParentElt.innerHTML = contents;
   },
 
   destroy() {
     this._tabListComponent.uninit();
     this.container.remove();
   },
 
   update(state) {
--- a/browser/components/syncedtabs/sidebar.xhtml
+++ b/browser/components/syncedtabs/sidebar.xhtml
@@ -5,16 +5,19 @@
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [
   <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
   %browserDTD;
   <!ENTITY % globalDTD
     SYSTEM "chrome://global/locale/global.dtd">
   %globalDTD;
+  <!ENTITY % syncBrandDTD
+    SYSTEM "chrome://browser/locale/syncBrand.dtd">
+  %syncBrandDTD;
 ]>
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <head>
     <script src="chrome://browser/content/syncedtabs/sidebar.js" type="application/javascript;version=1.8"></script>
     <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
 
     <link rel="stylesheet" type="text/css" media="all" href="chrome://browser/skin/syncedtabs/sidebar.css"/>
@@ -72,18 +75,19 @@
         <div class="tabs-fetching sync-state">
           <!-- Show intentionally blank panel, see bug 1239845 -->
         </div>
         <div class="notAuthedInfo sync-state">
           <p>&syncedTabs.sidebar.notsignedin.label;</p>
           <p><a href="#" class="sync-prefs text-link">&fxaSignIn.label;</a></p>
         </div>
         <div class="singleDeviceInfo sync-state">
-          <p>&syncedTabs.sidebar.noclients.label;</p>
-          <p class="device-promo"></p>
+          <p>&syncedTabs.sidebar.noclients.title;</p>
+          <p>&syncedTabs.sidebar.noclients.subtitle;</p>
+          <p class="device-promo" fxAccountsBrand="&syncBrand.fxAccount.label;"></p>
         </div>
         <div class="tabs-disabled sync-state">
           <p>&syncedTabs.sidebar.tabsnotsyncing.label;</p>
           <p><a href="#" class="sync-prefs text-link">&syncedTabs.sidebar.openprefs.label;</a></p>
         </div>
       </div>
     </template>
 
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -343,17 +343,18 @@ These should match what Safari and other
      the name of a device when that device has no open tabs -->
 <!ENTITY appMenuRemoteTabs.notabs.label "No open tabs">
 <!-- LOCALIZATION NOTE (appMenuRemoteTabs.tabsnotsyncing.label): This is shown
      when Sync is configured but syncing tabs is disabled. -->
 <!ENTITY appMenuRemoteTabs.tabsnotsyncing.label "Turn on tab syncing to view a list of tabs from your other devices.">
 <!-- LOCALIZATION NOTE (appMenuRemoteTabs.noclients.label): This is shown
      when Sync is configured but this appears to be the only device attached to
      the account. We also show links to download Firefox for android/ios. -->
-<!ENTITY appMenuRemoteTabs.noclients.label "Sign in to Firefox from your other devices to view their tabs here.">
+<!ENTITY appMenuRemoteTabs.noclients.title "No synced tabs… yet!">
+<!ENTITY appMenuRemoteTabs.noclients.subtitle "Want to see your tabs from other devices here?">
 <!ENTITY appMenuRemoteTabs.openprefs.label "Sync Preferences">
 <!ENTITY appMenuRemoteTabs.notsignedin.label "Sign in to view a list of tabs from your other devices.">
 <!ENTITY appMenuRemoteTabs.signin.label "Sign in to Sync">
 <!ENTITY appMenuRemoteTabs.sidebar.label "View Synced Tabs Sidebar">
 
 <!ENTITY customizeMenu.addToToolbar.label "Add to Toolbar">
 <!ENTITY customizeMenu.addToToolbar.accesskey "A">
 <!ENTITY customizeMenu.addToPanel.label "Add to Menu">
@@ -719,16 +720,18 @@ you can use these alternative items. Oth
      The word "toolbar" is appended automatically and should not be contained below! -->
 <!ENTITY tabsToolbar.label "Browser tabs">
 
 <!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu -->
 <!ENTITY syncTabsMenu3.label     "Synced Tabs">
 
 <!ENTITY syncedTabs.sidebar.label              "Synced Tabs">
 <!ENTITY syncedTabs.sidebar.noclients.label    "Sign in to Firefox from your other devices to view their tabs here.">
+<!ENTITY syncedTabs.sidebar.noclients.title    "No synced tabs… yet!">
+<!ENTITY syncedTabs.sidebar.noclients.subtitle "Want to see your tabs from other devices here?">
 <!ENTITY syncedTabs.sidebar.notsignedin.label  "Sign in to view a list of tabs from your other devices.">
 <!ENTITY syncedTabs.sidebar.notabs.label       "No open tabs">
 <!ENTITY syncedTabs.sidebar.openprefs.label    "Open &syncBrand.shortName.label; Preferences">
 <!-- LOCALIZATION NOTE (syncedTabs.sidebar.tabsnotsyncing.label): This is shown
      when Sync is configured but syncing tabs is disabled. -->
 <!ENTITY syncedTabs.sidebar.tabsnotsyncing.label       "Turn on tab syncing to view a list of tabs from your other devices.">
 
 <!ENTITY syncedTabs.context.open.label                       "Open">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -689,24 +689,25 @@ appmenu.updateFailed.description = Backg
 appmenu.restartBrowserButton.label = Restart %S
 appmenu.downloadUpdateButton.label = Download Update
 
 # LOCALIZATION NOTE : FILE Reader View is a feature name and therefore typically used as a proper noun.
 
 readingList.promo.firstUse.readerView.title = Reader View
 readingList.promo.firstUse.readerView.body = Remove clutter so you can focus exactly on what you want to read.
 
-# LOCALIZATION NOTE (appMenuRemoteTabs.mobilePromo):
+# LOCALIZATION NOTE (appMenuRemoteTabs.mobilePromo.text):
 # %1$S will be replaced with a link, the text of which is
 # appMenuRemoteTabs.mobilePromo.android and the link will be to
 # https://www.mozilla.org/firefox/android/.
 # %2$S will be replaced with a link, the text of which is
 # appMenuRemoteTabs.mobilePromo.ios
 # and the link will be to https://www.mozilla.org/firefox/ios/.
-appMenuRemoteTabs.mobilePromo = Get %1$S or %2$S.
+# %3$S will be replace by the content of syncBrand.fxAccount.label (Firefox Account)
+appMenuRemoteTabs.mobilePromo.text = Download %1$S or %2$S and connect them to your %3$S.
 appMenuRemoteTabs.mobilePromo.android = Firefox for Android
 appMenuRemoteTabs.mobilePromo.ios = Firefox for iOS
 
 # LOCALIZATION NOTE (e10s.offerPopup.mainMessage
 #                    e10s.offerPopup.highlight1
 #                    e10s.offerPopup.highlight2
 #                    e10s.offerPopup.enableAndRestart.label
 #                    e10s.offerPopup.enableAndRestart.accesskey
--- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css
+++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css
@@ -674,28 +674,33 @@ toolbarpaletteitem[place="palette"] > to
 #PanelUI-fxa-icon {
   list-style-image: url(chrome://browser/skin/sync-horizontalbar.png);
 }
 
 #PanelUI-remotetabs {
   --panel-ui-sync-illustration-height: 157.5px;
 }
 
+.PanelUI-remotetabs-instruction-title,
 .PanelUI-remotetabs-instruction-label,
 #PanelUI-remotetabs-mobile-promo {
   /* If you change the margin here, the min-height of the synced tabs panel
     (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
     need adjusting (see bug 1248506) */
   margin: 15px;
   text-align: center;
   text-shadow: none;
   max-width: 15em;
   color: GrayText;
 }
 
+.PanelUI-remotetabs-instruction-title {
+  font-size: 1.3em;
+}
+
 /* The boxes with "instructions" get extra top and bottom padding for space
    around the illustration and buttons */
 .PanelUI-remotetabs-instruction-box {
   /* If you change the padding here, the min-height of the synced tabs panel
     (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
     need adjusting (see bug 1248506) */
   padding-bottom: 30px;
   padding-top: 15px;
@@ -770,16 +775,20 @@ toolbarpaletteitem[place="palette"] > to
 /* Collapse the non-active vboxes in the remotetabs deck to use only the
    height the active box needs */
 #PanelUI-remotetabs-deck:not([selectedIndex="1"]) > #PanelUI-remotetabs-tabsdisabledpane,
 #PanelUI-remotetabs-deck:not([selectedIndex="2"]) > #PanelUI-remotetabs-fetching,
 #PanelUI-remotetabs-deck:not([selectedIndex="3"]) > #PanelUI-remotetabs-nodevicespane {
   visibility: collapse;
 }
 
+#PanelUI-remotetabs-main[devices-status="single"] > #PanelUI-remotetabs-buttons {
+  display: none;
+}
+
 #PanelUI-fxa-icon[syncstatus="active"] {
   list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar.png);
 }
 
 #PanelUI-footer-fxa[fxastatus="migrate-signup"] > #PanelUI-fxa-status > #PanelUI-fxa-label,
 #PanelUI-footer-fxa[fxastatus="migrate-verify"] > #PanelUI-fxa-status > #PanelUI-fxa-label {
   list-style-image: url(chrome://browser/skin/warning.svg);
   -moz-image-region: auto;