Bug 1384045 - Show different contents in sync tour of onboarding for signed-in user.r=flod,mossop
MozReview-Commit-ID: BH2f4ujdHbG
This commit is contained in:
115
browser/extensions/onboarding/bootstrap.js
vendored
115
browser/extensions/onboarding/bootstrap.js
vendored
@@ -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.
|
* Listen and process events from content.
|
||||||
*/
|
*/
|
||||||
@@ -68,58 +130,15 @@ function initContentMessageListener() {
|
|||||||
case "set-prefs":
|
case "set-prefs":
|
||||||
setPrefs(msg.data.params);
|
setPrefs(msg.data.params);
|
||||||
break;
|
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.
|
* onBrowserReady - Continues startup of the add-on after browser is ready.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,7 +61,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#onboarding-overlay-dialog,
|
#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;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,8 +194,11 @@ var onboardingTourset = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
getPage(win, bundle) {
|
getPage(win, bundle) {
|
||||||
|
const STATE_LOGOUT = "logged-out";
|
||||||
|
const STATE_LOGIN = "logged-in";
|
||||||
let div = win.document.createElement("div");
|
let div = win.document.createElement("div");
|
||||||
div.classList.add("onboarding-no-button");
|
div.classList.add("onboarding-no-button");
|
||||||
|
div.dataset.loginState = STATE_LOGOUT;
|
||||||
// The email validation pattern used in the form comes from IETF rfc5321,
|
// The email validation pattern used in the form comes from IETF rfc5321,
|
||||||
// which is identical to server-side checker of Firefox Account. See
|
// which is identical to server-side checker of Firefox Account. See
|
||||||
// discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1378770#c6
|
// 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])?)+$";
|
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 = `
|
div.innerHTML = `
|
||||||
<section class="onboarding-tour-description">
|
<section class="onboarding-tour-description">
|
||||||
<h1 data-l10n-id="onboarding.tour-sync.title2"></h1>
|
<h1 data-l10n-id="onboarding.tour-sync.title2" class="show-on-logged-out"></h1>
|
||||||
<p data-l10n-id="onboarding.tour-sync.description2"></p>
|
<p data-l10n-id="onboarding.tour-sync.description2" class="show-on-logged-out"></p>
|
||||||
|
<h1 data-l10n-id="onboarding.tour-sync.logged-in.title" class="show-on-logged-in"></h1>
|
||||||
|
<p data-l10n-id="onboarding.tour-sync.logged-in.description" class="show-on-logged-in"></p>
|
||||||
</section>
|
</section>
|
||||||
<section class="onboarding-tour-content">
|
<section class="onboarding-tour-content">
|
||||||
<form>
|
<form class="show-on-logged-out">
|
||||||
<h3 data-l10n-id="onboarding.tour-sync.form.title"></h3>
|
<h3 data-l10n-id="onboarding.tour-sync.form.title"></h3>
|
||||||
<p data-l10n-id="onboarding.tour-sync.form.description"></p>
|
<p data-l10n-id="onboarding.tour-sync.form.description"></p>
|
||||||
<input id="onboarding-tour-sync-email-input" type="email" required="true"></input><br />
|
<input id="onboarding-tour-sync-email-input" type="email" required="true"></input><br />
|
||||||
@@ -220,6 +225,16 @@ var onboardingTourset = {
|
|||||||
emailInput.placeholder =
|
emailInput.placeholder =
|
||||||
bundle.GetStringFromName("onboarding.tour-sync.email-input.placeholder");
|
bundle.GetStringFromName("onboarding.tour-sync.email-input.placeholder");
|
||||||
emailInput.pattern = emailRegex;
|
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;
|
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
|
* The script won't be initialized if we turned off onboarding by
|
||||||
* setting "browser.onboarding.enabled" to false.
|
* 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) {
|
handleEvent(evt) {
|
||||||
if (evt.type === "resize") {
|
if (evt.type === "resize") {
|
||||||
this._window.cancelIdleCallback(this._resizeTimerId);
|
this._window.cancelIdleCallback(this._resizeTimerId);
|
||||||
@@ -525,7 +539,12 @@ class Onboarding {
|
|||||||
gotoPage(tourId) {
|
gotoPage(tourId) {
|
||||||
let targetPageId = `${tourId}-page`;
|
let targetPageId = `${tourId}-page`;
|
||||||
for (let page of this._tourPages) {
|
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) {
|
for (let li of this._tourItems) {
|
||||||
if (li.id == tourId) {
|
if (li.id == tourId) {
|
||||||
@@ -551,7 +570,7 @@ class Onboarding {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (params.length > 0) {
|
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.
|
// we try to prompt on the 1st session.
|
||||||
let lastTime = 1000 * Preferences.get("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
let lastTime = 1000 * Preferences.get("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
||||||
if (lastTime <= 0) {
|
if (lastTime <= 0) {
|
||||||
this.sendMessageToChrome("set-prefs", [{
|
sendMessageToChrome("set-prefs", [{
|
||||||
name: "browser.onboarding.notification.last-time-of-changing-tour-sec",
|
name: "browser.onboarding.notification.last-time-of-changing-tour-sec",
|
||||||
value: Math.floor(Date.now() / 1000)
|
value: Math.floor(Date.now() / 1000)
|
||||||
}]);
|
}]);
|
||||||
@@ -619,7 +638,7 @@ class Onboarding {
|
|||||||
name: "browser.onboarding.notification.prompt-count",
|
name: "browser.onboarding.notification.prompt-count",
|
||||||
value: 0
|
value: 0
|
||||||
});
|
});
|
||||||
this.sendMessageToChrome("set-prefs", params);
|
sendMessageToChrome("set-prefs", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getNotificationQueue() {
|
_getNotificationQueue() {
|
||||||
@@ -636,7 +655,7 @@ class Onboarding {
|
|||||||
// until the queue is empty.
|
// until the queue is empty.
|
||||||
let ids = this._tours.map(tour => tour.id).join(",");
|
let ids = this._tours.map(tour => tour.id).join(",");
|
||||||
queue = `${ids},${ids}`;
|
queue = `${ids},${ids}`;
|
||||||
this.sendMessageToChrome("set-prefs", [{
|
sendMessageToChrome("set-prefs", [{
|
||||||
name: "browser.onboarding.notification.tour-ids-queue",
|
name: "browser.onboarding.notification.tour-ids-queue",
|
||||||
value: queue
|
value: queue
|
||||||
}]);
|
}]);
|
||||||
@@ -665,7 +684,7 @@ class Onboarding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (queue.length == 0) {
|
if (queue.length == 0) {
|
||||||
this.sendMessageToChrome("set-prefs", [
|
sendMessageToChrome("set-prefs", [
|
||||||
{
|
{
|
||||||
name: "browser.onboarding.notification.finished",
|
name: "browser.onboarding.notification.finished",
|
||||||
value: true
|
value: true
|
||||||
@@ -716,7 +735,7 @@ class Onboarding {
|
|||||||
value: promptCount + 1
|
value: promptCount + 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.sendMessageToChrome("set-prefs", params);
|
sendMessageToChrome("set-prefs", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideNotification() {
|
hideNotification() {
|
||||||
@@ -756,7 +775,7 @@ class Onboarding {
|
|||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.setToursCompleted(this._tours.map(tour => tour.id));
|
this.setToursCompleted(this._tours.map(tour => tour.id));
|
||||||
this.sendMessageToChrome("set-prefs", [
|
sendMessageToChrome("set-prefs", [
|
||||||
{
|
{
|
||||||
name: "browser.onboarding.hidden",
|
name: "browser.onboarding.hidden",
|
||||||
value: true
|
value: true
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ onboarding.notification.onboarding-tour-default-browser.message=It doesn’t tak
|
|||||||
onboarding.tour-sync2=Sync
|
onboarding.tour-sync2=Sync
|
||||||
onboarding.tour-sync.title2=Pick up where you left off.
|
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.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
|
# LOCALIZATION NOTE(onboarding.tour-sync.form.title): This string is displayed
|
||||||
# as a title and followed by onboarding.tour-sync.form.description.
|
# as a title and followed by onboarding.tour-sync.form.description.
|
||||||
# Your translation should be consistent with the form displayed in
|
# Your translation should be consistent with the form displayed in
|
||||||
|
|||||||
Reference in New Issue
Block a user