Bug 1275927 - Replace custom Sync success doorhanger with platform notification. r?markh draft
authorEdouard Oger <eoger@fastmail.com>
Thu, 02 Jun 2016 10:36:53 -0700
changeset 374515 236839f36a0400f6d4dae29009f12ef508cbd1f3
parent 374514 91879ebba4d61fde72af13223708faa01109a4d9
child 522658 99b1c6b4e813c135cce0f94a3f8e2f001f1a8df3
push id20049
push userbmo:edouard.oger@gmail.com
push dateThu, 02 Jun 2016 17:45:10 +0000
reviewersmarkh
bugs1275927
milestone49.0a1
Bug 1275927 - Replace custom Sync success doorhanger with platform notification. r?markh MozReview-Commit-ID: 1GJRcB6mnEI
browser/base/content/browser-fxaccounts.js
browser/base/content/browser.xul
browser/components/nsBrowserGlue.js
browser/locales/en-US/chrome/browser/accounts.properties
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/linux/browser.css
browser/themes/osx/browser.css
browser/themes/windows/browser.css
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -1,16 +1,14 @@
 /* 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/. */
 
 var gFxAccounts = {
 
-  PREF_SYNC_START_DOORHANGER: "services.sync.ui.showSyncStartDoorhanger",
-  DOORHANGER_ACTIVATE_DELAY_MS: 5000,
   SYNC_MIGRATION_NOTIFICATION_TITLE: "fxa-migration",
 
   _initialized: false,
   _inCustomizationMode: false,
 
   get weave() {
     delete this.weave;
     return this.weave = Cc["@mozilla.org/weave/service;1"]
@@ -18,23 +16,21 @@ var gFxAccounts = {
                           .wrappedJSObject;
   },
 
   get topics() {
     // Do all this dance to lazy-load FxAccountsCommon.
     delete this.topics;
     return this.topics = [
       "weave:service:ready",
-      "weave:service:sync:start",
       "weave:service:login:error",
       "weave:service:setup-complete",
       "weave:ui:login:error",
       "fxa-migration:state-changed",
       this.FxAccountsCommon.ONLOGIN_NOTIFICATION,
-      this.FxAccountsCommon.ONVERIFIED_NOTIFICATION,
       this.FxAccountsCommon.ONLOGOUT_NOTIFICATION,
       this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
     ];
   },
 
   get panelUIFooter() {
     delete this.panelUIFooter;
     return this.panelUIFooter = document.getElementById("PanelUI-footer-fxa");
@@ -77,32 +73,26 @@ var gFxAccounts = {
       return false;
     }
     // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
     // All other login failures are assumed to be transient and should go
     // away by themselves, so aren't reflected here.
     return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
   },
 
-  get isActiveWindow() {
-    let fm = Services.focus;
-    return fm.activeWindow == window;
-  },
-
   init: function () {
     // Bail out if we're already initialized and for pop-up windows.
     if (this._initialized || !window.toolbar.visible) {
       return;
     }
 
     for (let topic of this.topics) {
       Services.obs.addObserver(this, topic, false);
     }
 
-    addEventListener("activate", this);
     gNavToolbox.addEventListener("customizationstarting", this);
     gNavToolbox.addEventListener("customizationending", this);
 
     EnsureFxAccountsWebChannel();
     this._initialized = true;
 
     this.updateUI();
   },
@@ -116,51 +106,28 @@ var gFxAccounts = {
       Services.obs.removeObserver(this, topic);
     }
 
     this._initialized = false;
   },
 
   observe: function (subject, topic, data) {
     switch (topic) {
-      case this.FxAccountsCommon.ONVERIFIED_NOTIFICATION:
-        Services.prefs.setBoolPref(this.PREF_SYNC_START_DOORHANGER, true);
-        break;
-      case "weave:service:sync:start":
-        this.onSyncStart();
-        break;
       case "fxa-migration:state-changed":
         this.onMigrationStateChanged(data, subject);
         break;
       case this.FxAccountsCommon.ONPROFILE_IMAGE_CHANGE_NOTIFICATION:
         this.updateUI();
         break;
       default:
         this.updateUI();
         break;
     }
   },
 
-  onSyncStart: function () {
-    if (!this.isActiveWindow) {
-      return;
-    }
-
-    let showDoorhanger = false;
-
-    try {
-      showDoorhanger = Services.prefs.getBoolPref(this.PREF_SYNC_START_DOORHANGER);
-    } catch (e) { /* The pref might not exist. */ }
-
-    if (showDoorhanger) {
-      Services.prefs.clearUserPref(this.PREF_SYNC_START_DOORHANGER);
-      this.showSyncStartedDoorhanger();
-    }
-  },
-
   onMigrationStateChanged: function () {
     // Since we nuked most of the migration code, this notification will fire
     // once after legacy Sync has been disconnected (and should never fire
     // again)
     let nb = window.document.getElementById("global-notificationbox");
 
     let msg = this.strings.GetStringFromName("autoDisconnectDescription")
     let signInLabel = this.strings.GetStringFromName("autoDisconnectSignIn.label");
@@ -194,43 +161,18 @@ var gFxAccounts = {
                           nb.PRIORITY_WARNING_LOW,
                           buttons);
 
     // ensure the hamburger menu reflects the newly disconnected state.
     this.updateAppMenuItem();
   },
 
   handleEvent: function (event) {
-    if (event.type == "activate") {
-      // Our window might have been in the background while we received the
-      // sync:start notification. If still needed, show the doorhanger after
-      // a short delay. Without this delay the doorhanger would not show up
-      // or with a too small delay show up while we're still animating the
-      // window.
-      setTimeout(() => this.onSyncStart(), this.DOORHANGER_ACTIVATE_DELAY_MS);
-    } else {
-      this._inCustomizationMode = event.type == "customizationstarting";
-      this.updateAppMenuItem();
-    }
-  },
-
-  showDoorhanger: function (id) {
-    let panel = document.getElementById(id);
-    let anchor = document.getElementById("PanelUI-menu-button");
-
-    let iconAnchor =
-      document.getAnonymousElementByAttribute(anchor, "class",
-                                              "toolbarbutton-icon");
-
-    panel.hidden = false;
-    panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
-  },
-
-  showSyncStartedDoorhanger: function () {
-    this.showDoorhanger("sync-start-panel");
+    this._inCustomizationMode = event.type == "customizationstarting";
+    this.updateAppMenuItem();
   },
 
   updateUI: function () {
     // It's possible someone signed in to FxA after seeing our notification
     // about "Legacy Sync migration" (which now is actually "Legacy Sync
     // auto-disconnect") so kill that notification if it still exists.
     let nb = window.document.getElementById("global-notificationbox");
     let n = nb.getNotificationWithValue(this.SYNC_MIGRATION_NOTIFICATION_TITLE);
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -416,31 +416,16 @@
         <button class="ctrlTab-preview" flex="1"/>
         <button class="ctrlTab-preview" flex="1"/>
       </hbox>
       <hbox pack="center">
         <button id="ctrlTab-showAll" class="ctrlTab-preview" noicon="true"/>
       </hbox>
     </panel>
 
-    <!-- Sync Panel -->
-    <panel id="sync-start-panel" class="sync-panel" type="arrow" hidden="true"
-           noautofocus="true" onclick="this.hidePopup();"
-           flip="slide">
-      <hbox class="sync-panel-outer">
-        <image class="sync-panel-icon"/>
-        <vbox class="sync-panel-inner">
-          <description id="sync-start-panel-title"
-                       value="&syncStartPanel2.heading;"/>
-          <description id="sync-start-panel-subtitle"
-                       value="&syncStartPanel2.subTitle;"/>
-        </vbox>
-      </hbox>
-    </panel>
-
     <!-- Bookmarks and history tooltip -->
     <tooltip id="bhTooltip"/>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
 
     <tooltip id="back-button-tooltip">
       <label class="tooltip-label" value="&backButton.tooltip;"/>
 #ifdef XP_MACOSX
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -304,16 +304,19 @@ BrowserGlue.prototype = {
       case "browser-lastwindow-close-granted":
         if (OBSERVE_LASTWINDOW_CLOSE_TOPICS) {
           this._setPrefToSaveSession();
         }
         break;
       case "weave:service:ready":
         this._setSyncAutoconnectDelay();
         break;
+      case "fxaccounts:onverified":
+        this._showSyncStartedDoorhanger();
+        break;
       case "weave:engine:clients:display-uri":
         this._onDisplaySyncURI(subject);
         break;
       case "session-save":
         this._setPrefToSaveSession(true);
         subject.QueryInterface(Ci.nsISupportsPRBool);
         subject.data = true;
         break;
@@ -521,16 +524,17 @@ BrowserGlue.prototype = {
     os.addObserver(this, "browser:purge-session-history", false);
     os.addObserver(this, "quit-application-requested", false);
     os.addObserver(this, "quit-application-granted", false);
     if (OBSERVE_LASTWINDOW_CLOSE_TOPICS) {
       os.addObserver(this, "browser-lastwindow-close-requested", false);
       os.addObserver(this, "browser-lastwindow-close-granted", false);
     }
     os.addObserver(this, "weave:service:ready", false);
+    os.addObserver(this, "fxaccounts:onverified", false);
     os.addObserver(this, "weave:engine:clients:display-uri", false);
     os.addObserver(this, "session-save", false);
     os.addObserver(this, "places-init-complete", false);
     this._isPlacesInitObserver = true;
     os.addObserver(this, "places-database-locked", false);
     this._isPlacesLockedObserver = true;
     os.addObserver(this, "distribution-customization-complete", false);
     os.addObserver(this, "places-shutdown", false);
@@ -586,16 +590,17 @@ BrowserGlue.prototype = {
     os.removeObserver(this, "quit-application-requested");
     os.removeObserver(this, "quit-application-granted");
     os.removeObserver(this, "restart-in-safe-mode");
     if (OBSERVE_LASTWINDOW_CLOSE_TOPICS) {
       os.removeObserver(this, "browser-lastwindow-close-requested");
       os.removeObserver(this, "browser-lastwindow-close-granted");
     }
     os.removeObserver(this, "weave:service:ready");
+    os.removeObserver(this, "fxaccounts:onverified");
     os.removeObserver(this, "weave:engine:clients:display-uri");
     os.removeObserver(this, "session-save");
     if (this._bookmarksBackupIdleTime) {
       this._idleService.removeIdleObserver(this, this._bookmarksBackupIdleTime);
       delete this._bookmarksBackupIdleTime;
     }
     if (this._isPlacesInitObserver)
       os.removeObserver(this, "places-init-complete");
@@ -1890,16 +1895,29 @@ BrowserGlue.prototype = {
 
     var notifyBox = win.gBrowser.getNotificationBox();
     var notification = notifyBox.appendNotification(text, title, null,
                                                     notifyBox.PRIORITY_CRITICAL_MEDIUM,
                                                     buttons);
     notification.persistence = -1; // Until user closes it
   },
 
+  _showSyncStartedDoorhanger: function () {
+    let bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties");
+    let title = bundle.GetStringFromName("syncStartNotification.title");
+    let body = bundle.GetStringFromName("syncStartNotification.body");
+
+    let clickCallback = (subject, topic, data) => {
+      if (topic != "alertclickcallback")
+        return;
+      this._openPreferences("sync");
+    }
+    AlertsService.showAlertNotification(null, title, body, true, null, clickCallback);
+  },
+
   _migrateUI: function BG__migrateUI() {
     const UI_VERSION = 38;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
--- a/browser/locales/en-US/chrome/browser/accounts.properties
+++ b/browser/locales/en-US/chrome/browser/accounts.properties
@@ -18,8 +18,13 @@ verifyDescription = Verify %S
 
 # These strings are shown in a desktop notification after the
 # user requests we resend a verification email.
 verificationSentTitle = Verification Sent
 # LOCALIZATION NOTE (verificationSentBody) - %S = Email address of user's Firefox Account
 verificationSentBody = A verification link has been sent to %S.
 verificationNotSentTitle = Unable to Send Verification
 verificationNotSentBody = We are unable to send a verification mail at this time, please try again later.
+
+# LOCALIZATION NOTE (syncStartNotification.title, syncStartNotification.body)
+# These strings are used in a notification shown after Sync is connected.
+syncStartNotification.title = Sync enabled
+syncStartNotification.body = Firefox will begin syncing momentarily.
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -105,18 +105,16 @@ These should match what Safari and other
 <!ENTITY fullScreenCmd.macCommandKey "f">
 <!ENTITY showAllTabsCmd.label "Show All Tabs">
 <!ENTITY showAllTabsCmd.accesskey "A">
 
 <!ENTITY fxaSignIn.label "Sign in to &syncBrand.shortName.label;">
 <!ENTITY fxaSignedIn.tooltip "Open &syncBrand.shortName.label; preferences">
 <!ENTITY fxaSignInError.label "Reconnect to &syncBrand.shortName.label;">
 <!ENTITY fxaUnverified.label "Verify Your Account">
-<!ENTITY syncStartPanel2.heading "&syncBrand.shortName.label; enabled">
-<!ENTITY syncStartPanel2.subTitle "&brandShortName; will begin syncing momentarily.">
 
 
 <!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">
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1742,43 +1742,16 @@ toolbarbutton.chevron > .toolbarbutton-i
 
 #ctrlTab-showAll {
   -moz-appearance: button;
   color: ButtonText;
   padding: 0 3px;
   margin-top: 10px;
 }
 
-/* Sync Panel */
-
-.sync-panel-icon {
-  height:32px;
-  width: 32px;
-  background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
-}
-
-.sync-panel-inner {
-  width: 0;
-  padding-left: 10px;
-}
-
-.sync-panel-button-box {
-  margin-top: 1em;
-}
-
-#sync-start-panel-title {
-  font-size: 120%;
-  font-weight: bold;
-  margin-bottom: 5px;
-}
-
-#sync-start-panel-subtitle {
-  margin-bottom: 0;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: linear-gradient(#fff, #ddd);
   border: 1px none #ccc;
   border-top-style: solid;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3255,65 +3255,16 @@ menulist.translate-infobar-element > .me
 .ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
   margin: -10px -10px 0;
 }
 
 #ctrlTab-showAll {
   margin-top: .5em;
 }
 
-/* Sync Panels */
-
-.sync-panel-icon {
-  height:32px;
-  width: 32px;
-  background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
-}
-
-@media (min-resolution: 2dppx) {
-  .sync-panel-icon {
-    background: url("chrome://browser/content/abouthome/sync@2x.png") top left no-repeat;
-    background-size: 32px 32px;
-  }
-}
-
-.sync-panel-inner {
-  width: 0;
-  padding-left: 10px;
-}
-
-.sync-panel-button-box {
-  margin-top: 1em;
-}
-
-.sync-panel-button {
-  @hudButton@
-  margin: 0;
-  min-width: 72px;
-  min-height: 22px;
-}
-
-.sync-panel-button:hover:active {
-  @hudButtonPressed@
-}
-
-.sync-panel-button:-moz-focusring {
-  @hudButtonFocused@
-}
-
-#sync-start-panel-title {
-  font-size: 120%;
-  font-weight: bold;
-  margin-bottom: 5px;
-}
-
-#sync-start-panel-subtitle {
-  margin-bottom: 0;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: linear-gradient(#fff, #ddd);
   border: 1px none #ccc;
   border-top-style: solid;
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2420,43 +2420,16 @@ notification[value="translation"] {
 .ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
   margin: -10px -10px 0;
 }
 
 #ctrlTab-showAll {
   margin-top: .5em;
 }
 
-/* Sync Panel */
-
-.sync-panel-icon {
-  height:32px;
-  width: 32px;
-  background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
-}
-
-.sync-panel-inner {
-  width: 0;
-  padding-left: 10px;
-}
-
-.sync-panel-button-box {
-  margin-top: 1em;
-}
-
-#sync-start-panel-title {
-  font-size: 120%;
-  font-weight: bold;
-  margin-bottom: 5px;
-}
-
-#sync-start-panel-subtitle {
-  margin-bottom: 0;
-}
-
 /* Status panel */
 
 .statuspanel-label {
   margin: 0;
   padding: 2px 4px;
   background: linear-gradient(#fff, #ddd);
   border: 1px none #ccc;
   border-top-style: solid;