Bug 1361286 - add in-page messages support for Automigration module; r=gijs
MozReview-Commit-ID: I4xK2PkuHp3
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1592,16 +1592,17 @@ pref("dom.ipc.processPrelaunch.enabled",
pref("browser.migrate.automigrate.enabled", true);
#else
pref("browser.migrate.automigrate.enabled", false);
#endif
// 4 here means the suggestion notification will be automatically
// hidden the 4th day, so it will actually be shown on 3 different days.
pref("browser.migrate.automigrate.daysToOfferUndo", 4);
pref("browser.migrate.automigrate.ui.enabled", true);
+pref("browser.migrate.automigrate.inpage.ui.enabled", false);
// See comments in bug 1340115 on how we got to these numbers.
pref("browser.migrate.chrome.history.limit", 2000);
pref("browser.migrate.chrome.history.maxAgeInDays", 180);
// Enable browser frames for use on desktop. Only exposed to chrome callers.
pref("dom.mozBrowserFramesEnabled", true);
--- a/browser/base/content/newtab/page.js
+++ b/browser/base/content/newtab/page.js
@@ -246,15 +246,11 @@ var gPage = {
this.onPageVisibleAndLoaded();
} else {
addEventListener("load", this);
}
},
onPageVisibleAndLoaded() {
// Maybe tell the user they can undo an initial automigration
- this.maybeShowAutoMigrationUndoNotification();
- },
-
- maybeShowAutoMigrationUndoNotification() {
- sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification");
+ sendAsyncMessage("NewTab:MaybeShowMigrateMessage");
},
};
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -155,17 +155,17 @@ var AboutHomeListener = {
docElt.setAttribute("snippetsVersion", aData.snippetsVersion);
},
onPageLoad() {
addMessageListener("AboutHome:Update", this);
addEventListener("click", this, true);
addEventListener("pagehide", this, true);
- sendAsyncMessage("AboutHome:MaybeShowAutoMigrationUndoNotification");
+ sendAsyncMessage("AboutHome:MaybeShowMigrateMessage");
sendAsyncMessage("AboutHome:RequestUpdate");
},
onClick(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
@@ -6,31 +6,34 @@
this.EXPORTED_SYMBOLS = ["AutoMigrate"];
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
const kAutoMigrateEnabledPref = "browser.migrate.automigrate.enabled";
const kUndoUIEnabledPref = "browser.migrate.automigrate.ui.enabled";
+const kInPageUIEnabledPref = "browser.migrate.automigrate.inpage.ui.enabled";
+
const kAutoMigrateBrowserPref = "browser.migrate.automigrate.browser";
const kAutoMigrateImportedItemIds = "browser.migrate.automigrate.imported-items";
const kAutoMigrateLastUndoPromptDateMsPref = "browser.migrate.automigrate.lastUndoPromptDateMs";
const kAutoMigrateDaysToOfferUndoPref = "browser.migrate.automigrate.daysToOfferUndo";
const kAutoMigrateUndoSurveyPref = "browser.migrate.automigrate.undo-survey";
const kAutoMigrateUndoSurveyLocalePref = "browser.migrate.automigrate.undo-survey-locales";
const kNotificationId = "automigration-undo";
Cu.import("resource:///modules/MigrationUtils.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
"resource://gre/modules/AsyncShutdown.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
"resource://gre/modules/LoginHelper.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
"resource://gre/modules/NewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
@@ -309,102 +312,125 @@ const AutoMigrate = {
let browserId = Services.prefs.getCharPref(kAutoMigrateBrowserPref);
if (browserId) {
return MigrationUtils.getBrowserName(browserId);
}
return null;
},
/**
- * Show the user a notification bar indicating we automatically imported
- * their data and offering them the possibility of removing it.
+ * Decide if we need to show [the user] a prompt indicating we automatically
+ * imported their data.
* @param target (xul:browser)
* The browser in which we should show the notification.
+ * @returns {Boolean} return true when need to show the prompt.
*/
- async maybeShowUndoNotification(target) {
+ async shouldShowMigratePrompt(target) {
if (!(await this.canUndo())) {
- return;
+ return false;
}
// The tab might have navigated since we requested the undo state:
let canUndoFromThisPage = ["about:home", "about:newtab"].includes(target.currentURI.spec);
if (!canUndoFromThisPage ||
!Preferences.get(kUndoUIEnabledPref, false)) {
- return;
- }
-
- let win = target.ownerGlobal;
- let notificationBox = win.gBrowser.getNotificationBox(target);
- if (!notificationBox || notificationBox.getNotificationWithValue(kNotificationId)) {
- return;
+ return false;
}
// At this stage we're committed to show the prompt - unless we shouldn't,
// in which case we remove the undo prefs (which will cause canUndo() to
// return false from now on.):
- if (!this.shouldStillShowUndoPrompt()) {
+ if (this.isMigratePromptExpired()) {
this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_EXPIRED);
this._removeNotificationBars();
- return;
+ return false;
}
+ let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 0);
+ Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_UNDO_OFFERED").add(4 - remainingDays);
+
+ return true;
+ },
+
+ /**
+ * Return the message that denotes the user data is migrated from the other browser.
+ * @returns {String} imported message with the brand and the browser name
+ */
+ getUndoMigrationMessage() {
let browserName = this.getBrowserUsedForMigration();
if (!browserName) {
browserName = MigrationUtils.getLocalizedString("automigration.undo.unknownbrowser");
}
- const kMessageId = "automigration.undo.message." +
+ const kMessageId = "automigration.undo.message2." +
Preferences.get(kAutoMigrateImportedItemIds, "all");
const kBrandShortName = gBrandBundle.GetStringFromName("brandShortName");
- let message = MigrationUtils.getLocalizedString(kMessageId,
- [browserName, kBrandShortName]);
+ return MigrationUtils.getLocalizedString(kMessageId,
+ [kBrandShortName, browserName]);
+ },
+ /**
+ * Show the user a notification bar indicating we automatically imported
+ * their data and offering them the possibility of removing it.
+ * @param target (xul:browser)
+ * The browser in which we should show the notification.
+ */
+ showUndoNotificationBar(target) {
+ let isInPage = Preferences.get(kInPageUIEnabledPref, false);
+ let win = target.ownerGlobal;
+ let notificationBox = win.gBrowser.getNotificationBox(target);
+ if (isInPage || !notificationBox || notificationBox.getNotificationWithValue(kNotificationId)) {
+ return;
+ }
+ let message = this.getUndoMigrationMessage();
let buttons = [
{
label: MigrationUtils.getLocalizedString("automigration.undo.keep2.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.keep2.accesskey"),
callback: () => {
- this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_REJECTED);
+ this.keepAutoMigration();
this._removeNotificationBars();
},
},
{
label: MigrationUtils.getLocalizedString("automigration.undo.dontkeep2.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.dontkeep2.accesskey"),
callback: () => {
- this._maybeOpenUndoSurveyTab(win);
- this.undo();
+ this.undoAutoMigration(win);
},
},
];
notificationBox.appendNotification(
message, kNotificationId, null, notificationBox.PRIORITY_INFO_HIGH, buttons
);
- let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 0);
- Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_UNDO_OFFERED").add(4 - remainingDays);
},
- shouldStillShowUndoPrompt() {
+
+ /**
+ * Return true if we have shown the prompt to user several days.
+ * (defined in kAutoMigrateDaysToOfferUndoPref)
+ */
+ isMigratePromptExpired() {
let today = new Date();
// Round down to midnight:
today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
// We store the unix timestamp corresponding to midnight on the last day
// on which we prompted. Fetch that and compare it to today's date.
// (NB: stored as a string because int prefs are too small for unix
// timestamps.)
let previousPromptDateMsStr = Preferences.get(kAutoMigrateLastUndoPromptDateMsPref, "0");
let previousPromptDate = new Date(parseInt(previousPromptDateMsStr, 10));
if (previousPromptDate < today) {
let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 4) - 1;
Preferences.set(kAutoMigrateDaysToOfferUndoPref, remainingDays);
Preferences.set(kAutoMigrateLastUndoPromptDateMsPref, today.valueOf().toString());
if (remainingDays <= 0) {
- return false;
+ return true;
}
}
- return true;
+ return false;
},
UNDO_REMOVED_REASON_UNDO_USED: 0,
UNDO_REMOVED_REASON_SYNC_SIGNIN: 1,
UNDO_REMOVED_REASON_PASSWORD_CHANGE: 2,
UNDO_REMOVED_REASON_BOOKMARK_CHANGE: 3,
UNDO_REMOVED_REASON_OFFER_EXPIRED: 4,
UNDO_REMOVED_REASON_OFFER_REJECTED: 5,
@@ -651,11 +677,27 @@ const AutoMigrate = {
let url = Services.urlFormatter.formatURL(rawURL);
url = url.replace("%IMPORTEDBROWSER%", encodeURIComponent(migrationBrowser));
chromeWindow.openUILinkIn(url, "tab");
},
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIObserver, Ci.nsINavBookmarkObserver, Ci.nsISupportsWeakReference]
),
+
+ /**
+ * Undo action called by the UndoNotification or by the newtab
+ * @param chromeWindow A reference to the window in which to open a link.
+ */
+ undoAutoMigration(chromeWindow) {
+ this._maybeOpenUndoSurveyTab(chromeWindow);
+ this.undo();
+ },
+
+ /**
+ * Keep the automigration result and not prompt anymore
+ */
+ keepAutoMigration() {
+ this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_REJECTED);
+ },
};
AutoMigrate.init();
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -1105,16 +1105,17 @@ this.MigrationUtils = Object.freeze({
gAvailableMigratorKeys,
MIGRATION_ENTRYPOINT_UNKNOWN: 0,
MIGRATION_ENTRYPOINT_FIRSTRUN: 1,
MIGRATION_ENTRYPOINT_FXREFRESH: 2,
MIGRATION_ENTRYPOINT_PLACES: 3,
MIGRATION_ENTRYPOINT_PASSWORDS: 4,
+ MIGRATION_ENTRYPOINT_NEWTAB: 5,
_sourceNameToIdMapping: {
"nothing": 1,
"firefox": 2,
"edge": 3,
"ie": 4,
"chrome": 5,
"chromium": 6,
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -144,17 +144,17 @@ const listeners = {
// PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN ContentPrefServiceParent.init
"FeedConverter:addLiveBookmark": ["Feeds"],
"WCCR:setAutoHandler": ["Feeds"],
"webrtc:UpdateGlobalIndicators": ["webrtcUI"],
"webrtc:UpdatingIndicators": ["webrtcUI"],
},
mm: {
- "AboutHome:MaybeShowAutoMigrationUndoNotification": ["AboutHome"],
+ "AboutHome:MaybeShowMigrateMessage": ["AboutHome"],
"AboutHome:RequestUpdate": ["AboutHome"],
"Content:Click": ["ContentClick"],
"ContentSearch": ["ContentSearch"],
"FormValidation:ShowPopup": ["FormValidationHandler"],
"FormValidation:HidePopup": ["FormValidationHandler"],
"Prompt:Open": ["RemotePrompt"],
"Reader:ArticleGet": ["ReaderParent"],
"Reader:FaviconRequest": ["ReaderParent"],
--- a/browser/locales/en-US/chrome/browser/migration/migration.properties
+++ b/browser/locales/en-US/chrome/browser/migration/migration.properties
@@ -67,21 +67,21 @@ 64_edge=Other Data
64_safari=Other Data
64_chrome=Other Data
64_firefox_other=Other Data
64_360se=Other Data
128_firefox=Windows and Tabs
# Automigration undo notification.
-# %1$S will be replaced with the name of the browser we imported from, %2$S will be replaced with brandShortName
-automigration.undo.message.all = Pick up where you left off. We’ve imported these sites and your bookmarks, history and passwords from %1$S into %2$S.
-automigration.undo.message.bookmarks = Pick up where you left off. We’ve imported these sites and your bookmarks from %1$S into %2$S.
-automigration.undo.message.bookmarks.logins = Pick up where you left off. We’ve imported these sites and your bookmarks and passwords from %1$S into %2$S.
-automigration.undo.message.bookmarks.visits = Pick up where you left off. We’ve imported these sites and your bookmarks and history from %1$S into %2$S.
-automigration.undo.message.logins = Pick up where you left off. We’ve imported your passwords from %1$S into %2$S.
-automigration.undo.message.logins.visits = Pick up where you left off. We’ve imported these sites and your history and passwords from %1$S into %2$S.
-automigration.undo.message.visits = Pick up where you left off. We’ve imported these sites and your history from %1$S into %2$S.
+# %1$S will be replaced with brandShortName, %2$S will be replaced with the name of the browser we imported from
+automigration.undo.message2.all = Dive right into %1$S! Import your favorite sites, bookmarks, history and passwords from %2$S.
+automigration.undo.message2.bookmarks = Dive right into %1$S! Import your favorite sites and bookmarks from %2$S.
+automigration.undo.message2.bookmarks.logins = Dive right into %1$S! Import your favorite sites, bookmarks and passwords from %2$S.
+automigration.undo.message2.bookmarks.visits = Dive right into %1$S! Import your favorite sites, bookmarks and history from %2$S.
+automigration.undo.message2.logins = Dive right into %1$S! Import your passwords from %2$S.
+automigration.undo.message2.logins.visits = Dive right into %1$S! Import your favorite sites, history and passwords from %2$S.
+automigration.undo.message2.visits = Dive right into %1$S! Import your favorite sites and history from %2$S.
automigration.undo.keep2.label = OK, Got it
automigration.undo.keep2.accesskey = O
automigration.undo.dontkeep2.label = No Thanks
automigration.undo.dontkeep2.accesskey = N
automigration.undo.unknownbrowser = Unknown Browser
--- a/browser/modules/AboutHome.jsm
+++ b/browser/modules/AboutHome.jsm
@@ -5,18 +5,18 @@
"use strict";
var Cc = Components.classes;
var Ci = Components.interfaces;
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");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.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",
@@ -144,18 +144,22 @@ var AboutHome = {
case "AboutHome:Settings":
window.openPreferences(undefined, {origin: "aboutHome"} );
break;
case "AboutHome:RequestUpdate":
this.sendAboutHomeData(aMessage.target);
break;
- case "AboutHome:MaybeShowAutoMigrationUndoNotification":
- AutoMigrate.maybeShowUndoNotification(aMessage.target);
+ case "AboutHome:MaybeShowMigrateMessage":
+ AutoMigrate.shouldShowMigratePrompt(aMessage.target).then((prompt) => {
+ if (prompt) {
+ AutoMigrate.showUndoNotificationBar(aMessage.target);
+ }
+ });
break;
}
},
// Send all the chrome-privileged data needed by about:home. This
// gets re-sent when the search engine changes.
sendAboutHomeData(target) {
let wrapper = {};
--- a/browser/modules/AboutNewTab.jsm
+++ b/browser/modules/AboutNewTab.jsm
@@ -27,18 +27,26 @@ var AboutNewTab = {
isOverridden: false,
init() {
if (this.isOverridden) {
return;
}
this.pageListener = new RemotePages("about:newtab");
this.pageListener.addMessageListener("NewTab:Customize", this.customize.bind(this));
- this.pageListener.addMessageListener("NewTab:MaybeShowAutoMigrationUndoNotification",
- (msg) => AutoMigrate.maybeShowUndoNotification(msg.target.browser));
+ this.pageListener.addMessageListener("NewTab:MaybeShowMigrateMessage",
+ this.maybeShowMigrateMessage.bind(this));
+ },
+
+ maybeShowMigrateMessage({ target }) {
+ AutoMigrate.shouldShowMigratePrompt(target.browser).then((prompt) => {
+ if (prompt) {
+ AutoMigrate.showUndoNotificationBar(target.browser);
+ }
+ });
},
customize(message) {
NewTabUtils.allPages.enabled = message.data.enabled;
NewTabUtils.allPages.enhanced = message.data.enhanced;
},
uninit() {