Bug 1289231 - Show 'undo' notification bar. r=dolske, a=lizzard
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Sat, 20 Aug 2016 12:15:02 +0100
changeset 347864 468ca2351fe24b9244915e7d2ffde07810849f64
parent 347863 c2aa582a598090ba22e6fd0a6550a06bdc316161
child 347865 656a6b1bdec9749882809999daa4cdc740e7054a
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske, lizzard
bugs1289231
milestone50.0a2
Bug 1289231 - Show 'undo' notification bar. r=dolske, a=lizzard MozReview-Commit-ID: 1qy7GUSaowb
browser/base/content/tab-content.js
browser/components/migration/AutoMigrate.jsm
browser/components/migration/content/automigration.properties
browser/components/migration/jar.mn
browser/modules/AboutHome.jsm
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -154,16 +154,17 @@ var AboutHomeListener = {
     docElt.setAttribute("snippetsVersion", aData.snippetsVersion);
   },
 
   onPageLoad: function() {
     addMessageListener("AboutHome:Update", this);
     addEventListener("click", this, true);
     addEventListener("pagehide", this, true);
 
+    sendAsyncMessage("AboutHome:MaybeShowAutoMigrationUndoNotification");
     sendAsyncMessage("AboutHome:RequestUpdate");
   },
 
   onClick: function(aEvent) {
     if (!aEvent.isTrusted || // Don't trust synthetic events
         aEvent.button == 2 || aEvent.target.localName != "button") {
       return;
     }
--- a/browser/components/migration/AutoMigrate.jsm
+++ b/browser/components/migration/AutoMigrate.jsm
@@ -15,23 +15,35 @@ const kAutoMigrateFinishedPref = "browse
 const kAutoMigrateBrowserPref = "browser.migrate.automigrate.browser";
 
 const kPasswordManagerTopic = "passwordmgr-storage-changed";
 const kPasswordManagerTopicTypes = new Set([
   "addLogin",
   "modifyLogin",
 ]);
 
+const kNotificationId = "abouthome-automigration-undo";
+
 Cu.import("resource:///modules/MigrationUtils.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+let gAutoMigrationBundle;
+
+function getBundle() {
+  if (!gAutoMigrationBundle) {
+    gAutoMigrationBundle = Services.strings.createBundle(
+     "chrome://browser/content/migration/automigration.properties");
+  }
+  return gAutoMigrationBundle;
+}
+
 const AutoMigrate = {
   get resourceTypesToUse() {
     let {BOOKMARKS, HISTORY, PASSWORDS} = Ci.nsIBrowserProfileMigrator;
     return BOOKMARKS | HISTORY | PASSWORDS;
   },
 
   init() {
     this.enabled = Preferences.get(kAutoMigrateEnabledPref, false);
@@ -244,16 +256,88 @@ const AutoMigrate = {
       Services.obs.removeObserver(this, kPasswordManagerTopic);
     } catch (ex) {}
     try {
       PlacesUtils.removeLazyBookmarkObserver(this);
     } catch (ex) {}
     Services.prefs.clearUserPref(kAutoMigrateStartedPref);
     Services.prefs.clearUserPref(kAutoMigrateFinishedPref);
     Services.prefs.clearUserPref(kAutoMigrateBrowserPref);
+
+    let browserWindows = Services.wm.getEnumerator("navigator:browser");
+    while (browserWindows.hasMoreElements()) {
+      let win = browserWindows.getNext();
+      if (!win.closed) {
+        for (let browser of win.gBrowser.browsers) {
+          let nb = win.gBrowser.getNotificationBox(browser);
+          let notification = nb.getNotificationWithValue(kNotificationId);
+          if (notification) {
+            nb.removeNotification(notification);
+          }
+        }
+      }
+    }
+  },
+
+  getBrowserUsedForMigration() {
+    let browserId = Services.prefs.getCharPref(kAutoMigrateBrowserPref);
+    if (browserId) {
+      return MigrationUtils.getBrowserName(browserId);
+    }
+    return null;
+  },
+
+  getLocalizedString(str, args) {
+    if (args === undefined)
+      return getBundle().GetStringFromName(str);
+    return getBundle().formatStringFromName(
+      str, args, args.length);
+  },
+
+  maybeShowUndoNotification(target) {
+    this.canUndo().then(canUndo => {
+      // The tab might have navigated since we requested the undo state:
+      if (!canUndo || target.currentURI.spec != "about:home") {
+        return;
+      }
+      let win = target.ownerGlobal;
+      let notificationBox = win.gBrowser.getNotificationBox(target);
+      if (!notificationBox || notificationBox.getNotificationWithValue("abouthome-automigration-undo")) {
+        return;
+      }
+
+      let browserName = this.getBrowserUsedForMigration();
+      let message;
+      if (browserName) {
+        message = this.getLocalizedString("automigration.undo.message",
+                                                    [browserName]);
+      } else {
+        message = this.getLocalizedString("automigration.undo.unknownBrowserMessage");
+      }
+
+      let buttons = [
+        {
+          label: this.getLocalizedString("automigration.undo.keep.label"),
+          accessKey: this.getLocalizedString("automigration.undo.keep.accesskey"),
+          callback: () => {
+            this.removeUndoOption();
+          },
+        },
+        {
+          label: this.getLocalizedString("automigration.undo.dontkeep.label"),
+          accessKey: this.getLocalizedString("automigration.undo.dontkeep.accesskey"),
+          callback: () => {
+            this.undo();
+          },
+        },
+      ];
+      notificationBox.appendNotification(
+        message, kNotificationId, null, notificationBox.PRIORITY_INFO_HIGH, buttons
+      );
+    });
   },
 
   QueryInterface: XPCOMUtils.generateQI(
     [Ci.nsIObserver, Ci.nsINavBookmarkObserver, Ci.nsISupportsWeakReference]
   ),
 };
 
 AutoMigrate.init();
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/content/automigration.properties
@@ -0,0 +1,7 @@
+# Automigration undo notification.
+automigration.undo.message               = We automatically imported your data from %S. Would you like to keep it?
+automigration.undo.unknownBrowserMessage = We automatically imported your data from another browser. Would you like to keep it?
+automigration.undo.keep.label            = Keep
+automigration.undo.keep.accesskey        = K
+automigration.undo.dontkeep.label        = Don't Keep
+automigration.undo.dontkeep.accesskey    = D
--- a/browser/components/migration/jar.mn
+++ b/browser/components/migration/jar.mn
@@ -1,8 +1,9 @@
 # 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/.
 
 browser.jar:
 *  content/browser/migration/migration.xul                    (content/migration.xul)
    content/browser/migration/migration.js                     (content/migration.js)
+   content/browser/migration/automigration.properties         (content/automigration.properties)
    content/browser/aboutWelcomeBack.xhtml                     (content/aboutWelcomeBack.xhtml)
--- a/browser/modules/AboutHome.jsm
+++ b/browser/modules/AboutHome.jsm
@@ -10,20 +10,22 @@ var Cu = Components.utils;
 
 this.EXPORTED_SYMBOLS = [ "AboutHomeUtils", "AboutHome" ];
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AutoMigrate",
+  "resource:///modules/AutoMigrate.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
+  "resource://gre/modules/FxAccounts.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
-  "resource://gre/modules/FxAccounts.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
   "resource://gre/modules/Promise.jsm");
 
 // Url to fetch snippets, in the urlFormatter service format.
 const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl";
 
 // Should be bumped up if the snippets content format changes.
 const STARTPAGE_VERSION = 4;
@@ -94,16 +96,17 @@ var AboutHome = {
     "AboutHome:RestorePreviousSession",
     "AboutHome:Downloads",
     "AboutHome:Bookmarks",
     "AboutHome:History",
     "AboutHome:Addons",
     "AboutHome:Sync",
     "AboutHome:Settings",
     "AboutHome:RequestUpdate",
+    "AboutHome:MaybeShowAutoMigrationUndoNotification",
   ],
 
   init: function() {
     let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
 
     for (let msg of this.MESSAGES) {
       mm.addMessageListener(msg, this);
     }
@@ -143,16 +146,20 @@ var AboutHome = {
 
       case "AboutHome:Settings":
         window.openPreferences();
         break;
 
       case "AboutHome:RequestUpdate":
         this.sendAboutHomeData(aMessage.target);
         break;
+
+      case "AboutHome:MaybeShowAutoMigrationUndoNotification":
+        AutoMigrate.maybeShowUndoNotification(aMessage.target);
+        break;
     }
   },
 
   // Send all the chrome-privileged data needed by about:home. This
   // gets re-sent when the search engine changes.
   sendAboutHomeData: function(target) {
     let wrapper = {};
     Components.utils.import("resource:///modules/sessionstore/SessionStore.jsm",
@@ -177,10 +184,11 @@ var AboutHome = {
         target.messageManager.sendAsyncMessage("AboutHome:Update", data);
       } else {
         let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
         mm.broadcastAsyncMessage("AboutHome:Update", data);
       }
     }).then(null, function onError(x) {
       Cu.reportError("Error in AboutHome.sendAboutHomeData: " + x);
     });
-  }
+  },
+
 };