зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1404193 - enable customizable logo, speech bubble string, and hide the skip button;r=Fischer
MozReview-Commit-ID: 1cHpXouqNCg --HG-- extra : rebase_source : 4b1a52b2e044f92fed5856a9fc397b6546c11584
This commit is contained in:
Родитель
55703dd1f1
Коммит
abb89f528c
|
@ -49,6 +49,8 @@ Edit `browser/app/profile/firefox.js` and modify `browser.onboarding.newtour` fo
|
|||
|
||||
## How to pump tour set version after update tours
|
||||
|
||||
We only update the tourset version when we have different **update** tourset. Update the new tourset **does not** require update the tourset version.
|
||||
|
||||
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 has watched the previous tours or preferred to hide the previous tours.
|
||||
|
@ -64,3 +66,22 @@ By default, it shows `default` state.
|
|||
When either tours or notifications are all completed, the icon changes to the `watermark` state.
|
||||
The icon state is stored in `browser.onboarding.state`.
|
||||
When `tourset-version` is updated, or when we detect the `tour-type` is changed to `update`, icon state will be changed back to the `default` state.
|
||||
|
||||
## Customizable preferences
|
||||
|
||||
Here are current support preferences that allow to customize the Onboarding's behavior.
|
||||
|
||||
| PREF | DESCRIPTION | DEFAULT |
|
||||
|-----|-------------|:-----:|
|
||||
| `browser.onboarding.enabled` | disable onboarding experience entirely | true
|
||||
| `browser.onboarding.notification.finished` | Decide if we want to hide the notification permanently. | false
|
||||
| `browser.onboarding.notification.mute-duration-on-first-session-ms` |Notification mute duration. It also effect when the speech bubble is hidden and turned into the blue dot | 300000 (5 Min)
|
||||
| `browser.onboarding.notification.max-life-time-all-tours-ms` | Notification tours will all hide after this period | 1209600000 (10 Days)
|
||||
| `browser.onboarding.notification.max-life-time-per-tours-ms` | Per Notification tours will hide and show the next tour after this period | 432000000 (5 Days)
|
||||
| `browser.onboarding.notification.max-prompt-count-per-tour` | Each tour can only show the specific times in notification bar if user didn't interact with the tour notification. | 8
|
||||
| `browser.onboarding.newtour` | The tourset of new user tour. | performance,private,screenshots,addons,customize,default
|
||||
| `browser.onboarding.newtour.tooltip` | The string id which is shown in the new user tour's speech bubble. The preffered length is 2 lines. Should use `%S` to denote Firefox (brand short name) in string, or use `%1$S` if the name shows more than 1 time. | `onboarding.overlay-icon-tooltip2`
|
||||
| `browser.onboarding.updatetour` | The tourset of new user tour. | performance,library,screenshots,singlesearch,customize,sync
|
||||
| `browser.onboarding.updatetour.tooltip` | The string id which is shown in the update user tour's speech bubble. The preffered length is 2 lines. Should use `%S` to denote Firefox (brand short name) in string, or use `%1$S` if the name shows shows more than 1 time. | `onboarding.overlay-icon-tooltip-updated2`
|
||||
| `browser.onboarding.default-icon-src` | The default icon url. Should be svg or at least 64x64 | `chrome://branding/content/icon64.png`
|
||||
| `browser.onboarding.watermark-icon-src` | The watermark icon url. Should be svg or at least 64x64 | `resource://onboarding/img/watermark.svg`
|
||||
|
|
|
@ -22,9 +22,10 @@ const PROMPT_COUNT_PREF = "browser.onboarding.notification.prompt-count";
|
|||
const ONBOARDING_DIALOG_ID = "onboarding-overlay-dialog";
|
||||
const ONBOARDING_MIN_WIDTH_PX = 960;
|
||||
const SPEECH_BUBBLE_MIN_WIDTH_PX = 1130;
|
||||
const SPEECH_BUBBLE_NEWTOUR_STRING_ID = "onboarding.overlay-icon-tooltip2";
|
||||
const SPEECH_BUBBLE_UPDATETOUR_STRING_ID = "onboarding.overlay-icon-tooltip-updated2";
|
||||
const ICON_STATE_WATERMARK = "watermark";
|
||||
const ICON_STATE_DEFAULT = "default";
|
||||
|
||||
/**
|
||||
* Add any number of tours, key is the tourId, value should follow the format below
|
||||
* "tourId": { // The short tour id which could be saved in pref
|
||||
|
@ -1130,6 +1131,11 @@ class Onboarding {
|
|||
_renderOverlay() {
|
||||
let div = this._window.document.createElement("div");
|
||||
div.id = "onboarding-overlay";
|
||||
let skipButtonMarkup = "";
|
||||
if (!Services.prefs.getBoolPref("browser.onboarding.skip-tour-button.hide", false)) {
|
||||
let label = this._bundle.GetStringFromName("onboarding.skip-tour-button-label");
|
||||
skipButtonMarkup = `<button id="onboarding-skip-tour-button" class="onboarding-action-button">${label}</button>`;
|
||||
}
|
||||
// We use `innerHTML` for more friendly reading.
|
||||
// The security should be fine because this is not from an external input.
|
||||
div.innerHTML = `
|
||||
|
@ -1139,7 +1145,7 @@ class Onboarding {
|
|||
<ul id="onboarding-tour-list" role="tablist"></ul>
|
||||
</nav>
|
||||
<footer id="onboarding-footer">
|
||||
<button id="onboarding-skip-tour-button" class="onboarding-action-button"></button>
|
||||
${skipButtonMarkup}
|
||||
</footer>
|
||||
<button id="onboarding-overlay-close-btn" class="onboarding-close-btn"></button>
|
||||
</div>
|
||||
|
@ -1147,9 +1153,6 @@ class Onboarding {
|
|||
|
||||
this._dialog = div.querySelector(`[role="dialog"]`);
|
||||
this._dialog.id = ONBOARDING_DIALOG_ID;
|
||||
|
||||
div.querySelector("#onboarding-skip-tour-button").textContent =
|
||||
this._bundle.GetStringFromName("onboarding.skip-tour-button-label");
|
||||
div.querySelector("#onboarding-header").textContent =
|
||||
this._bundle.GetStringFromName("onboarding.overlay-title2");
|
||||
let closeBtn = div.querySelector("#onboarding-overlay-close-btn");
|
||||
|
@ -1160,9 +1163,25 @@ class Onboarding {
|
|||
|
||||
_renderOverlayButton() {
|
||||
let button = this._window.document.createElement("button");
|
||||
let tooltipStringId = this._tourType === "new" ?
|
||||
"onboarding.overlay-icon-tooltip2" : "onboarding.overlay-icon-tooltip-updated2";
|
||||
let tooltip = this._bundle.formatStringFromName(tooltipStringId, [BRAND_SHORT_NAME], 1);
|
||||
// support customize speech bubble string via pref
|
||||
let tooltipStringPrefId = "";
|
||||
let defaultTourStringId = "";
|
||||
if (this._tourType === "new") {
|
||||
tooltipStringPrefId = "browser.onboarding.newtour.tooltip";
|
||||
defaultTourStringId = SPEECH_BUBBLE_NEWTOUR_STRING_ID;
|
||||
} else {
|
||||
tooltipStringPrefId = "browser.onboarding.updatetour.tooltip";
|
||||
defaultTourStringId = SPEECH_BUBBLE_UPDATETOUR_STRING_ID;
|
||||
}
|
||||
let tooltip = "";
|
||||
try {
|
||||
let tooltipStringId = Services.prefs.getStringPref(tooltipStringPrefId, defaultTourStringId);
|
||||
tooltip = this._bundle.formatStringFromName(tooltipStringId, [BRAND_SHORT_NAME], 1);
|
||||
} catch (e) {
|
||||
Cu.reportError(`the provided ${tooltipStringPrefId} string is in wrong format `, e);
|
||||
// fallback to defaultTourStringId to proceed
|
||||
tooltip = this._bundle.formatStringFromName(defaultTourStringId, [BRAND_SHORT_NAME], 1);
|
||||
}
|
||||
button.setAttribute("aria-label", tooltip);
|
||||
button.id = "onboarding-overlay-button";
|
||||
button.setAttribute("aria-haspopup", true);
|
||||
|
@ -1170,12 +1189,14 @@ class Onboarding {
|
|||
let defaultImg = this._window.document.createElement("img");
|
||||
defaultImg.id = "onboarding-overlay-button-icon";
|
||||
defaultImg.setAttribute("role", "presentation");
|
||||
defaultImg.src = "chrome://branding/content/icon64.png";
|
||||
defaultImg.src = Services.prefs.getStringPref("browser.onboarding.default-icon-src",
|
||||
"chrome://branding/content/icon64.png");
|
||||
button.appendChild(defaultImg);
|
||||
let watermarkImg = this._window.document.createElement("img");
|
||||
watermarkImg.id = "onboarding-overlay-button-watermark-icon";
|
||||
watermarkImg.setAttribute("role", "presentation");
|
||||
watermarkImg.src = "resource://onboarding/img/watermark.svg";
|
||||
watermarkImg.src = Services.prefs.getStringPref("browser.onboarding.watermark-icon-src",
|
||||
"resource://onboarding/img/watermark.svg");
|
||||
button.appendChild(watermarkImg);
|
||||
return button;
|
||||
}
|
||||
|
|
|
@ -26,3 +26,17 @@ add_task(async function test_skip_onboarding_tours() {
|
|||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function test_hide_skip_button_via_perf() {
|
||||
resetOnboardingDefaultState();
|
||||
Preferences.set("browser.onboarding.skip-tour-button.hide", true);
|
||||
|
||||
let tab = await openTab(ABOUT_NEWTAB_URL);
|
||||
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-overlay-button", {}, tab.linkedBrowser);
|
||||
await promiseOnboardingOverlayOpened(tab.linkedBrowser);
|
||||
|
||||
ok(!content.document.querySelector("#onboarding-skip-tour-button"), "should not render the skip button");
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
|
@ -40,6 +40,7 @@ function resetOnboardingDefaultState() {
|
|||
Preferences.reset("browser.onboarding.notification.last-time-of-changing-tour-sec");
|
||||
Preferences.reset("browser.onboarding.notification.prompt-count");
|
||||
Preferences.reset("browser.onboarding.notification.tour-ids-queue");
|
||||
Preferences.reset("browser.onboarding.skip-tour-button.hide");
|
||||
TOUR_IDs.forEach(id => Preferences.reset(`browser.onboarding.tour.${id}.completed`));
|
||||
UPDATE_TOUR_IDs.forEach(id => Preferences.reset(`browser.onboarding.tour.${id}.completed`));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче