Bug 1377470 - run onboarding scripts after browser UI is ready;r=mossop

MozReview-Commit-ID: BRxWc962EW2

--HG--
extra : rebase_source : f64af8d463b9475d3871b8e031cb9e37349cf0bc
This commit is contained in:
gasolin 2017-07-06 11:40:26 +08:00
Родитель c493aa2154
Коммит 0b11bf9e92
2 изменённых файлов: 67 добавлений и 12 удалений

Просмотреть файл

@ -1,18 +1,32 @@
# Onboarding
System addon to provide the onboarding overlay for user friendly tours.
System addon to provide the onboarding overlay for user-friendly tours.
## How to show the onboarding tour
Open `about:config` page and filter with `onboarding` keyword. Then set following preferences:
```
browser.onboarding.disabled = false
browser.onboarding.hidden = false
browser.onboarding.tour-set = "new" // for new user tour, or "update" for update user tour
```
And make sure the value of `browser.onboarding.tourset-verion` and `browser.onboarding.seen-tourset-verion` are the same.
## Architecture
Everytime `about:home` or `about:newtab` page is opened, onboarding overlay is injected into that page (if `browser.onboarding.enabled` preference is `true`).
Everytime `about:home` or `about:newtab` page is opened, onboarding overlay is injected into that page.
`OnboardingTourType.jsm` will check the onboarding tour type (currently support `new` and `update`). Then in `onboarding.js`, All tours are defined inside of `onboardingTourset` dictionary. `getTourIDList` function will load tours from proper preferences. (Check `How to change the order of tours` section for more detail).
When user clicks the action button in each tour, We use [UITour](http://bedrock.readthedocs.io/en/latest/uitour.html) to highlight the correspondent browser UI element.
## Landing rules
We would apply some rules:
* Avoid `chrome://` in `onbaording.js` since onboarding is intented to be injected into a normal content process page.
* All styles and ids should be formated as `onboarding-*` to avoid conflict with the origin page.
* All strings in `locales` should be formated as `onboarding.*` for consistency.
* All styles and ids should be formatted as `onboarding-*` to avoid conflict with the origin page.
* All strings in `locales` should be formatted as `onboarding.*` for consistency.
## How to change the order of tours
@ -22,8 +36,8 @@ Edit `browser/app/profile/firefox.js` and modify `browser.onboarding.newtour` fo
The tourset version is used to track the last major tourset change version. The `tourset-version` pref store the major tourset version (ex: `1`) but not the current browser version. When browser update to the next version (ex: 58, 59) the tourset pref is still `1` if we didn't do any major tourset update.
Once the tour set version is updated (ex: `2`), onboarding overlay should show the update tour to the updated user (ex: update from v56 -> v57), even when user have watched the previous tours or preferred to hide the previous tours.
Once the tour set version is updated (ex: `2`), onboarding overlay should show the update tour to the updated user (ex: update from v56 -> v57), even when user has watched the previous tours or preferred to hide the previous tours.
Edit `browser/app/profile/firefox.js` and set `browser.onboarding.tourset-version` as `[tourset version]` (in integer format).
For example if we update the tourset in v60 and decide to show all update users the tour, we set `browser.onboarding.tourset-version` as `3`.
For example, if we update the tourset in v60 and decide to show all update users the tour, we set `browser.onboarding.tourset-version` as `3`.

51
browser/extensions/onboarding/bootstrap.js поставляемый
Просмотреть файл

@ -2,6 +2,7 @@
/* 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/. */
/* globals APP_STARTUP, ADDON_INSTALL */
"use strict";
const {utils: Cu} = Components;
@ -12,7 +13,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
"resource://gre/modules/Timer.jsm");
const BROWSER_READY_NOTIFICATION = "final-ui-startup";
const PREF_WHITELIST = [
"browser.onboarding.enabled",
"browser.onboarding.hidden",
@ -29,6 +33,8 @@ const PREF_WHITELIST = [
"onboarding-tour-sync",
].forEach(tourId => PREF_WHITELIST.push(`browser.onboarding.tour.${tourId}.completed`));
let waitingForBrowserReady = true;
/**
* Set pref. Why no `getPrefs` function is due to the priviledge level.
* We cannot set prefs inside a framescript but can read.
@ -47,6 +53,9 @@ function setPrefs(prefs) {
});
}
/**
* Listen and process events from content.
*/
function initContentMessageListener() {
Services.mm.addMessageListener("Onboarding:OnContentMessage", msg => {
switch (msg.data.action) {
@ -57,14 +66,46 @@ function initContentMessageListener() {
});
}
function install(aData, aReason) {}
/**
* onBrowserReady - Continues startup of the add-on after browser is ready.
*/
function onBrowserReady() {
waitingForBrowserReady = false;
function uninstall(aData, aReason) {}
function startup(aData, reason) {
OnboardingTourType.check();
Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true);
initContentMessageListener();
}
function shutdown(aData, reason) {}
/**
* observe - nsIObserver callback to handle various browser notifications.
*/
function observe(subject, topic, data) {
switch (topic) {
case BROWSER_READY_NOTIFICATION:
Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
// Avoid running synchronously during this event that's used for timing
setTimeout(() => onBrowserReady());
break;
}
}
function install(aData, aReason) {}
function uninstall(aData, aReason) {}
function startup(aData, aReason) {
// Only start Onboarding when the browser UI is ready
if (aReason === APP_STARTUP || aReason === ADDON_INSTALL) {
Services.obs.addObserver(observe, BROWSER_READY_NOTIFICATION);
} else {
onBrowserReady();
}
}
function shutdown(aData, aReason) {
// Stop waiting for browser to be ready
if (waitingForBrowserReady) {
Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
}
}