diff --git a/browser/extensions/onboarding/bootstrap.js b/browser/extensions/onboarding/bootstrap.js index cabf6b855848..5d47b0b8ef4b 100644 --- a/browser/extensions/onboarding/bootstrap.js +++ b/browser/extensions/onboarding/bootstrap.js @@ -59,6 +59,68 @@ function setPrefs(prefs) { }); } +/** + * syncTourChecker listens to and maintains the login status inside, and can be + * queried at any time once initialized. + */ +let syncTourChecker = { + _registered: false, + _loggedIn: false, + + isLoggedIn() { + return this._loggedIn; + }, + + observe(subject, topic) { + switch (topic) { + case "fxaccounts:onlogin": + this.setComplete(); + break; + case "fxaccounts:onlogout": + this._loggedIn = false; + break; + } + }, + + init() { + // Check if we've already logged in at startup. + fxAccounts.getSignedInUser().then(user => { + if (user) { + this.setComplete(); + } + // Observe for login action if we haven't logged in yet. + this.register(); + }); + }, + + register() { + if (this._registered) { + return; + } + Services.obs.addObserver(this, "fxaccounts:onlogin"); + Services.obs.addObserver(this, "fxaccounts:onlogout"); + this._registered = true; + }, + + setComplete() { + this._loggedIn = true; + Services.prefs.setBoolPref("browser.onboarding.tour.onboarding-tour-sync.completed", true); + }, + + unregister() { + if (!this._registered) { + return; + } + Services.obs.removeObserver(this, "fxaccounts:onlogin"); + Services.obs.removeObserver(this, "fxaccounts:onlogout"); + this._registered = false; + }, + + uninit() { + this.unregister(); + }, +} + /** * Listen and process events from content. */ @@ -68,58 +130,15 @@ function initContentMessageListener() { case "set-prefs": setPrefs(msg.data.params); break; + case "get-login-status": + msg.target.messageManager.sendAsyncMessage("Onboarding:ResponseLoginStatus", { + isLoggedIn: syncTourChecker.isLoggedIn() + }); + break; } }); } -let syncTourChecker = { - registered: false, - - observe() { - this.setComplete(); - }, - - init() { - if (Services.prefs.getBoolPref("browser.onboarding.tour.onboarding-tour-sync.completed", false)) { - return; - } - // Check if we've already logged in at startup. - fxAccounts.getSignedInUser().then(user => { - if (user) { - this.setComplete(); - return; - } - // Observe for login action if we haven't logged in yet. - this.register(); - }); - }, - - register() { - if (this.registered) { - return; - } - Services.obs.addObserver(this, "fxaccounts:onverified"); - this.registered = true; - }, - - setComplete() { - Services.prefs.setBoolPref("browser.onboarding.tour.onboarding-tour-sync.completed", true); - this.unregister(); - }, - - unregister() { - if (!this.registered) { - return; - } - Services.obs.removeObserver(this, "fxaccounts:onverified"); - this.registered = false; - }, - - uninit() { - this.unregister(); - }, -} - /** * onBrowserReady - Continues startup of the add-on after browser is ready. */ diff --git a/browser/extensions/onboarding/content/onboarding.css b/browser/extensions/onboarding/content/onboarding.css index daa3fd3d97d4..f5c9b46d6d8a 100644 --- a/browser/extensions/onboarding/content/onboarding.css +++ b/browser/extensions/onboarding/content/onboarding.css @@ -61,7 +61,9 @@ } #onboarding-overlay-dialog, -.onboarding-hidden { +.onboarding-hidden, +#onboarding-tour-sync-page[data-login-state=logged-in] .show-on-logged-out, +#onboarding-tour-sync-page[data-login-state=logged-out] .show-on-logged-in { display: none; } diff --git a/browser/extensions/onboarding/content/onboarding.js b/browser/extensions/onboarding/content/onboarding.js index f202d148ada2..a7c1eef164d1 100644 --- a/browser/extensions/onboarding/content/onboarding.js +++ b/browser/extensions/onboarding/content/onboarding.js @@ -194,8 +194,11 @@ var onboardingTourset = { }; }, getPage(win, bundle) { + const STATE_LOGOUT = "logged-out"; + const STATE_LOGIN = "logged-in"; let div = win.document.createElement("div"); div.classList.add("onboarding-no-button"); + div.dataset.loginState = STATE_LOGOUT; // The email validation pattern used in the form comes from IETF rfc5321, // which is identical to server-side checker of Firefox Account. See // discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1378770#c6 @@ -203,11 +206,13 @@ var onboardingTourset = { let emailRegex = "^[\\w.!#$%&’*+\\/=?^`{|}~-]{1,64}@[a-z\\d](?:[a-z\\d-]{0,253}[a-z\\d])?(?:\\.[a-z\\d](?:[a-z\\d-]{0,253}[a-z\\d])?)+$"; div.innerHTML = `
-

-

+

+

+

+

-
+


@@ -220,6 +225,16 @@ var onboardingTourset = { emailInput.placeholder = bundle.GetStringFromName("onboarding.tour-sync.email-input.placeholder"); emailInput.pattern = emailRegex; + + div.addEventListener("beforeshow", () => { + function loginStatusListener(msg) { + removeMessageListener("Onboarding:ResponseLoginStatus", loginStatusListener); + div.dataset.loginState = msg.data.isLoggedIn ? STATE_LOGIN : STATE_LOGOUT; + } + sendMessageToChrome("get-login-status"); + addMessageListener("Onboarding:ResponseLoginStatus", loginStatusListener); + }); + return div; }, }, @@ -305,6 +320,15 @@ var onboardingTourset = { }, }; +/** + * @param {String} action the action to ask the chrome to do + * @param {Array} params the parameters for the action + */ +function sendMessageToChrome(action, params) { + sendAsyncMessage("Onboarding:OnContentMessage", { + action, params + }); +} /** * The script won't be initialized if we turned off onboarding by * setting "browser.onboarding.enabled" to false. @@ -434,16 +458,6 @@ class Onboarding { } } - /** - * @param {String} action the action to ask the chrome to do - * @param {Array} params the parameters for the action - */ - sendMessageToChrome(action, params) { - sendAsyncMessage("Onboarding:OnContentMessage", { - action, params - }); - } - handleEvent(evt) { if (evt.type === "resize") { this._window.cancelIdleCallback(this._resizeTimerId); @@ -525,7 +539,12 @@ class Onboarding { gotoPage(tourId) { let targetPageId = `${tourId}-page`; for (let page of this._tourPages) { - page.style.display = page.id != targetPageId ? "none" : ""; + if (page.id === targetPageId) { + page.style.display = ""; + page.dispatchEvent(new this._window.CustomEvent("beforeshow")); + } else { + page.style.display = "none"; + } } for (let li of this._tourItems) { if (li.id == tourId) { @@ -551,7 +570,7 @@ class Onboarding { } }); if (params.length > 0) { - this.sendMessageToChrome("set-prefs", params); + sendMessageToChrome("set-prefs", params); } } @@ -579,7 +598,7 @@ class Onboarding { // we try to prompt on the 1st session. let lastTime = 1000 * Preferences.get("browser.onboarding.notification.last-time-of-changing-tour-sec", 0); if (lastTime <= 0) { - this.sendMessageToChrome("set-prefs", [{ + sendMessageToChrome("set-prefs", [{ name: "browser.onboarding.notification.last-time-of-changing-tour-sec", value: Math.floor(Date.now() / 1000) }]); @@ -619,7 +638,7 @@ class Onboarding { name: "browser.onboarding.notification.prompt-count", value: 0 }); - this.sendMessageToChrome("set-prefs", params); + sendMessageToChrome("set-prefs", params); } _getNotificationQueue() { @@ -636,7 +655,7 @@ class Onboarding { // until the queue is empty. let ids = this._tours.map(tour => tour.id).join(","); queue = `${ids},${ids}`; - this.sendMessageToChrome("set-prefs", [{ + sendMessageToChrome("set-prefs", [{ name: "browser.onboarding.notification.tour-ids-queue", value: queue }]); @@ -665,7 +684,7 @@ class Onboarding { } if (queue.length == 0) { - this.sendMessageToChrome("set-prefs", [ + sendMessageToChrome("set-prefs", [ { name: "browser.onboarding.notification.finished", value: true @@ -716,7 +735,7 @@ class Onboarding { value: promptCount + 1 }); } - this.sendMessageToChrome("set-prefs", params); + sendMessageToChrome("set-prefs", params); } hideNotification() { @@ -756,7 +775,7 @@ class Onboarding { hide() { this.setToursCompleted(this._tours.map(tour => tour.id)); - this.sendMessageToChrome("set-prefs", [ + sendMessageToChrome("set-prefs", [ { name: "browser.onboarding.hidden", value: true diff --git a/browser/extensions/onboarding/locales/en-US/onboarding.properties b/browser/extensions/onboarding/locales/en-US/onboarding.properties index f6fbd477ae74..470b08432efe 100644 --- a/browser/extensions/onboarding/locales/en-US/onboarding.properties +++ b/browser/extensions/onboarding/locales/en-US/onboarding.properties @@ -77,6 +77,9 @@ onboarding.notification.onboarding-tour-default-browser.message=It doesn’t tak onboarding.tour-sync2=Sync onboarding.tour-sync.title2=Pick up where you left off. onboarding.tour-sync.description2=Sync makes it easy to access bookmarks, passwords, and even open tabs on all your devices. Sync also gives you control of the types of information you want, and don’t want, to share. +onboarding.tour-sync.logged-in.title=You’re signed in to Sync! +# LOCALIZATION NOTE(onboarding.tour-sync.logged-in.description): %1$S is brandShortName. +onboarding.tour-sync.logged-in.description=Sync works when you’re signed in to %1$S on more than one device. Have a mobile device? Install the %1$S app and sign in to get your bookmarks, history, and passwords on the go. # LOCALIZATION NOTE(onboarding.tour-sync.form.title): This string is displayed # as a title and followed by onboarding.tour-sync.form.description. # Your translation should be consistent with the form displayed in