зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1637079 - Initial multi stage about:welcome layout r=k88hudson
Differential Revision: https://phabricator.services.mozilla.com/D74811
This commit is contained in:
Родитель
656bed86b0
Коммит
d2bfedea15
|
@ -1327,6 +1327,8 @@ pref("trailhead.firstrun.branches", "join-dynamic");
|
||||||
|
|
||||||
// Separate about welcome
|
// Separate about welcome
|
||||||
pref("browser.aboutwelcome.enabled", true);
|
pref("browser.aboutwelcome.enabled", true);
|
||||||
|
// Used for switching simplified 3 cards welcome to multistage welcome
|
||||||
|
pref("browser.aboutwelcome.overrideContent", "");
|
||||||
|
|
||||||
// The pref that controls if the What's New panel is enabled.
|
// The pref that controls if the What's New panel is enabled.
|
||||||
pref("browser.messaging-system.whatsNewPanel.enabled", true);
|
pref("browser.messaging-system.whatsNewPanel.enabled", true);
|
||||||
|
|
|
@ -39,6 +39,7 @@ module.exports = {
|
||||||
// These files use fluent-dom to insert content
|
// These files use fluent-dom to insert content
|
||||||
files: [
|
files: [
|
||||||
"content-src/aboutwelcome/components/HeroText.jsx",
|
"content-src/aboutwelcome/components/HeroText.jsx",
|
||||||
|
"content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx",
|
||||||
"content-src/asrouter/templates/OnboardingMessage/**",
|
"content-src/asrouter/templates/OnboardingMessage/**",
|
||||||
"content-src/asrouter/templates/FirstRun/**",
|
"content-src/asrouter/templates/FirstRun/**",
|
||||||
"content-src/asrouter/templates/Trailhead/**",
|
"content-src/asrouter/templates/Trailhead/**",
|
||||||
|
|
|
@ -21,6 +21,25 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||||
return new Logger("AboutWelcomeChild");
|
return new Logger("AboutWelcomeChild");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function _parseOverrideContent(value) {
|
||||||
|
let result = {};
|
||||||
|
try {
|
||||||
|
result = value ? JSON.parse(value) : {};
|
||||||
|
} catch (e) {
|
||||||
|
Cu.reportError(e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
this,
|
||||||
|
"multiStageAboutWelcomeContent",
|
||||||
|
"browser.aboutwelcome.overrideContent",
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
_parseOverrideContent
|
||||||
|
);
|
||||||
|
|
||||||
class AboutWelcomeChild extends JSWindowActorChild {
|
class AboutWelcomeChild extends JSWindowActorChild {
|
||||||
actorCreated() {
|
actorCreated() {
|
||||||
this.exportFunctions();
|
this.exportFunctions();
|
||||||
|
@ -73,6 +92,12 @@ class AboutWelcomeChild extends JSWindowActorChild {
|
||||||
defineAs: "AWGetStartupData",
|
defineAs: "AWGetStartupData",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// For local dev, checks for JSON content inside pref browser.aboutwelcome.overrideContent
|
||||||
|
// that is used to override default 3 cards welcome UI with multistage welcome
|
||||||
|
Cu.exportFunction(this.AWGetMultiStageScreens.bind(this), window, {
|
||||||
|
defineAs: "AWGetMultiStageScreens",
|
||||||
|
});
|
||||||
|
|
||||||
Cu.exportFunction(this.AWGetFxAMetricsFlowURI.bind(this), window, {
|
Cu.exportFunction(this.AWGetFxAMetricsFlowURI.bind(this), window, {
|
||||||
defineAs: "AWGetFxAMetricsFlowURI",
|
defineAs: "AWGetFxAMetricsFlowURI",
|
||||||
});
|
});
|
||||||
|
@ -92,6 +117,16 @@ class AboutWelcomeChild extends JSWindowActorChild {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send multistage welcome JSON data read from aboutwelcome.overrideConetent pref to page
|
||||||
|
*/
|
||||||
|
AWGetMultiStageScreens() {
|
||||||
|
return Cu.cloneInto(
|
||||||
|
multiStageAboutWelcomeContent || {},
|
||||||
|
this.contentWindow
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send initial data to page including experiment information
|
* Send initial data to page including experiment information
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -100,10 +100,11 @@ __webpack_require__.r(__webpack_exports__);
|
||||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
|
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
|
||||||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
||||||
/* harmony import */ var _components_HeroText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
/* harmony import */ var _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
||||||
/* harmony import */ var _components_FxCards__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
|
/* harmony import */ var _components_HeroText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
|
||||||
/* harmony import */ var _components_MSLocalized__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4);
|
/* harmony import */ var _components_FxCards__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7);
|
||||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8);
|
/* harmony import */ var _components_MSLocalized__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4);
|
||||||
|
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5);
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
@ -116,6 +117,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
|
class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -136,6 +138,8 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.props.experiment && this.props.branchId) {
|
if (this.props.experiment && this.props.branchId) {
|
||||||
this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
|
this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
|
||||||
|
} else if (this.props.id && this.props.screens) {
|
||||||
|
this.messageId = this.props.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fetchFxAFlowUri();
|
this.fetchFxAFlowUri();
|
||||||
|
@ -149,7 +153,7 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
|
||||||
}
|
}
|
||||||
|
|
||||||
handleStartBtnClick() {
|
handleStartBtnClick() {
|
||||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__["AboutWelcomeUtils"].handleUserAction(this.props.startButton.action);
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_6__["AboutWelcomeUtils"].handleUserAction(this.props.startButton.action);
|
||||||
const ping = {
|
const ping = {
|
||||||
event: "CLICK_BUTTON",
|
event: "CLICK_BUTTON",
|
||||||
event_context: {
|
event_context: {
|
||||||
|
@ -165,21 +169,31 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
props
|
props
|
||||||
} = this;
|
} = this; // TBD: Refactor to redirect based off template value
|
||||||
|
// inside props.template
|
||||||
|
// Create SimpleAboutWelcome that renders default about welcome
|
||||||
|
// See Bug 1638087
|
||||||
|
|
||||||
|
if (props.screens) {
|
||||||
|
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_2__["MultiStageAboutWelcome"], {
|
||||||
|
screens: props.screens
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let UTMTerm = this.props.experiment && this.props.branchId ? `${this.props.experiment}-${this.props.branchId}` : "default";
|
let UTMTerm = this.props.experiment && this.props.branchId ? `${this.props.experiment}-${this.props.branchId}` : "default";
|
||||||
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||||
className: "outer-wrapper welcomeContainer"
|
className: "outer-wrapper welcomeContainer"
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||||
className: "welcomeContainerInner"
|
className: "welcomeContainerInner"
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_HeroText__WEBPACK_IMPORTED_MODULE_2__["HeroText"], {
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_HeroText__WEBPACK_IMPORTED_MODULE_3__["HeroText"], {
|
||||||
title: props.title,
|
title: props.title,
|
||||||
subtitle: props.subtitle
|
subtitle: props.subtitle
|
||||||
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_FxCards__WEBPACK_IMPORTED_MODULE_3__["FxCards"], {
|
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_FxCards__WEBPACK_IMPORTED_MODULE_4__["FxCards"], {
|
||||||
cards: props.cards,
|
cards: props.cards,
|
||||||
metricsFlowUri: this.state.metricsFlowUri,
|
metricsFlowUri: this.state.metricsFlowUri,
|
||||||
sendTelemetry: window.AWSendEventTelemetry,
|
sendTelemetry: window.AWSendEventTelemetry,
|
||||||
utm_term: UTMTerm
|
utm_term: UTMTerm
|
||||||
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MSLocalized__WEBPACK_IMPORTED_MODULE_4__["Localized"], {
|
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MSLocalized__WEBPACK_IMPORTED_MODULE_5__["Localized"], {
|
||||||
text: props.startButton.label
|
text: props.startButton.label
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||||
className: "start-button",
|
className: "start-button",
|
||||||
|
@ -189,14 +203,20 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__["DEFAULT_WELCOME_CONTENT"];
|
AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_6__["DEFAULT_WELCOME_CONTENT"];
|
||||||
|
|
||||||
async function mount() {
|
async function mount() {
|
||||||
const {
|
const {
|
||||||
slug,
|
slug,
|
||||||
branch
|
branch
|
||||||
} = await window.AWGetStartupData();
|
} = await window.AWGetStartupData();
|
||||||
const settings = branch && branch.value ? branch.value : {};
|
let settings = branch && branch.value ? branch.value : {};
|
||||||
|
|
||||||
|
if (!(branch && branch.value)) {
|
||||||
|
// Check for override content in pref browser.aboutwelcome.overrideContent
|
||||||
|
settings = await window.AWGetMultiStageScreens();
|
||||||
|
}
|
||||||
|
|
||||||
react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, _extends({
|
react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, _extends({
|
||||||
experiment: slug,
|
experiment: slug,
|
||||||
branchId: branch && branch.slug
|
branchId: branch && branch.slug
|
||||||
|
@ -223,24 +243,48 @@ module.exports = ReactDOM;
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
__webpack_require__.r(__webpack_exports__);
|
__webpack_require__.r(__webpack_exports__);
|
||||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HeroText", function() { return HeroText; });
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiStageAboutWelcome", function() { return MultiStageAboutWelcome; });
|
||||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||||
|
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
|
||||||
const HeroText = props => {
|
|
||||||
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
const MultiStageAboutWelcome = props => {
|
||||||
text: props.title
|
const [index, setScreenIndex] = Object(react__WEBPACK_IMPORTED_MODULE_0__["useState"])(0); // Transition to next screen, opening about:home on last screen button CTA
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
|
||||||
className: "welcome-title"
|
const handleTransition = index < props.screens.length ? Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(() => setScreenIndex(prevState => prevState + 1), []) : _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].handleUserAction({
|
||||||
})), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
type: "OPEN_ABOUT_PAGE",
|
||||||
text: props.subtitle
|
data: {
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", {
|
args: "home",
|
||||||
className: "welcome-subtitle"
|
where: "current"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||||
|
className: `welcomeCardGrid`
|
||||||
|
}, props.screens.map(screen => {
|
||||||
|
return index === screen.order ? react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(WelcomeScreen, {
|
||||||
|
key: screen.id,
|
||||||
|
id: screen.id,
|
||||||
|
content: screen.content,
|
||||||
|
navigate: handleTransition
|
||||||
|
}) : null;
|
||||||
|
})));
|
||||||
|
};
|
||||||
|
|
||||||
|
const WelcomeScreen = props => {
|
||||||
|
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||||
|
className: `${props.id}`
|
||||||
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||||
|
text: props.content.title
|
||||||
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", null)), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||||
|
text: props.content.primary_button.label
|
||||||
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||||
|
onClick: props.navigate
|
||||||
})));
|
})));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,14 +349,164 @@ const Localized = ({
|
||||||
/* 5 */
|
/* 5 */
|
||||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
__webpack_require__.r(__webpack_exports__);
|
||||||
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AboutWelcomeUtils", function() { return AboutWelcomeUtils; });
|
||||||
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DEFAULT_WELCOME_CONTENT", function() { return DEFAULT_WELCOME_CONTENT; });
|
||||||
|
/* 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/. */
|
||||||
|
const AboutWelcomeUtils = {
|
||||||
|
handleUserAction(action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case "OPEN_ABOUT_PAGE":
|
||||||
|
case "OPEN_AWESOME_BAR":
|
||||||
|
case "OPEN_PRIVATE_BROWSER_WINDOW":
|
||||||
|
case "SHOW_MIGRATION_WIZARD":
|
||||||
|
window.AWSendToParent("SPECIAL_ACTION", action);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "OPEN_URL":
|
||||||
|
window.open(action.data.args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sendEvent(type, detail) {
|
||||||
|
document.dispatchEvent(new CustomEvent(`AWPage:${type}`, {
|
||||||
|
bubbles: true,
|
||||||
|
detail
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
const DEFAULT_WELCOME_CONTENT = {
|
||||||
|
title: {
|
||||||
|
string_id: "onboarding-welcome-header"
|
||||||
|
},
|
||||||
|
startButton: {
|
||||||
|
label: {
|
||||||
|
string_id: "onboarding-start-browsing-button-label"
|
||||||
|
},
|
||||||
|
message_id: "START_BROWSING_BUTTON",
|
||||||
|
action: {
|
||||||
|
type: "OPEN_AWESOME_BAR"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cards: [{
|
||||||
|
content: {
|
||||||
|
title: {
|
||||||
|
string_id: "onboarding-data-sync-title"
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
string_id: "onboarding-data-sync-text2"
|
||||||
|
},
|
||||||
|
icon: "devices",
|
||||||
|
primary_button: {
|
||||||
|
label: {
|
||||||
|
string_id: "onboarding-data-sync-button2"
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: "OPEN_URL",
|
||||||
|
addFlowParams: true,
|
||||||
|
data: {
|
||||||
|
args: "https://accounts.firefox.com/?service=sync&action=email&context=fx_desktop_v3&entrypoint=activity-stream-firstrun&style=trailhead",
|
||||||
|
where: "tabshifted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id: "TRAILHEAD_CARD_2",
|
||||||
|
order: 1,
|
||||||
|
blockOnClick: false
|
||||||
|
}, {
|
||||||
|
content: {
|
||||||
|
title: {
|
||||||
|
string_id: "onboarding-firefox-monitor-title"
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
string_id: "onboarding-firefox-monitor-text2"
|
||||||
|
},
|
||||||
|
icon: "ffmonitor",
|
||||||
|
primary_button: {
|
||||||
|
label: {
|
||||||
|
string_id: "onboarding-firefox-monitor-button"
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: "OPEN_URL",
|
||||||
|
data: {
|
||||||
|
args: "https://monitor.firefox.com/",
|
||||||
|
where: "tabshifted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id: "TRAILHEAD_CARD_3",
|
||||||
|
order: 2,
|
||||||
|
blockOnClick: false
|
||||||
|
}, {
|
||||||
|
content: {
|
||||||
|
title: {
|
||||||
|
string_id: "onboarding-browse-privately-title"
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
string_id: "onboarding-browse-privately-text"
|
||||||
|
},
|
||||||
|
icon: "private",
|
||||||
|
primary_button: {
|
||||||
|
label: {
|
||||||
|
string_id: "onboarding-browse-privately-button"
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: "OPEN_PRIVATE_BROWSER_WINDOW"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
id: "TRAILHEAD_CARD_4",
|
||||||
|
order: 3,
|
||||||
|
blockOnClick: true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 6 */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
__webpack_require__.r(__webpack_exports__);
|
||||||
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HeroText", function() { return HeroText; });
|
||||||
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||||
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
|
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
|
||||||
|
const HeroText = props => {
|
||||||
|
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||||
|
text: props.title
|
||||||
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
||||||
|
className: "welcome-title"
|
||||||
|
})), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||||
|
text: props.subtitle
|
||||||
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", {
|
||||||
|
className: "welcome-subtitle"
|
||||||
|
})));
|
||||||
|
};
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 7 */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
__webpack_require__.r(__webpack_exports__);
|
__webpack_require__.r(__webpack_exports__);
|
||||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FxCards", function() { return FxCards; });
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FxCards", function() { return FxCards; });
|
||||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
|
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
|
||||||
/* harmony import */ var _asrouter_templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
|
/* harmony import */ var _asrouter_templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9);
|
||||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8);
|
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
|
||||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
@ -422,7 +616,7 @@ class FxCards extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 6 */
|
/* 8 */
|
||||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -463,7 +657,7 @@ function addUtmParams(url, utmTerm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 7 */
|
/* 9 */
|
||||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -527,127 +721,5 @@ class OnboardingCard extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 8 */
|
|
||||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
__webpack_require__.r(__webpack_exports__);
|
|
||||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AboutWelcomeUtils", function() { return AboutWelcomeUtils; });
|
|
||||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DEFAULT_WELCOME_CONTENT", function() { return DEFAULT_WELCOME_CONTENT; });
|
|
||||||
/* 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/. */
|
|
||||||
const AboutWelcomeUtils = {
|
|
||||||
handleUserAction(action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case "OPEN_AWESOME_BAR":
|
|
||||||
case "OPEN_PRIVATE_BROWSER_WINDOW":
|
|
||||||
case "SHOW_MIGRATION_WIZARD":
|
|
||||||
window.AWSendToParent("SPECIAL_ACTION", action);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "OPEN_URL":
|
|
||||||
window.open(action.data.args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
sendEvent(type, detail) {
|
|
||||||
document.dispatchEvent(new CustomEvent(`AWPage:${type}`, {
|
|
||||||
bubbles: true,
|
|
||||||
detail
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
const DEFAULT_WELCOME_CONTENT = {
|
|
||||||
title: {
|
|
||||||
string_id: "onboarding-welcome-header"
|
|
||||||
},
|
|
||||||
startButton: {
|
|
||||||
label: {
|
|
||||||
string_id: "onboarding-start-browsing-button-label"
|
|
||||||
},
|
|
||||||
message_id: "START_BROWSING_BUTTON",
|
|
||||||
action: {
|
|
||||||
type: "OPEN_AWESOME_BAR"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cards: [{
|
|
||||||
content: {
|
|
||||||
title: {
|
|
||||||
string_id: "onboarding-data-sync-title"
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
string_id: "onboarding-data-sync-text2"
|
|
||||||
},
|
|
||||||
icon: "devices",
|
|
||||||
primary_button: {
|
|
||||||
label: {
|
|
||||||
string_id: "onboarding-data-sync-button2"
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: "OPEN_URL",
|
|
||||||
addFlowParams: true,
|
|
||||||
data: {
|
|
||||||
args: "https://accounts.firefox.com/?service=sync&action=email&context=fx_desktop_v3&entrypoint=activity-stream-firstrun&style=trailhead",
|
|
||||||
where: "tabshifted"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
id: "TRAILHEAD_CARD_2",
|
|
||||||
order: 1,
|
|
||||||
blockOnClick: false
|
|
||||||
}, {
|
|
||||||
content: {
|
|
||||||
title: {
|
|
||||||
string_id: "onboarding-firefox-monitor-title"
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
string_id: "onboarding-firefox-monitor-text2"
|
|
||||||
},
|
|
||||||
icon: "ffmonitor",
|
|
||||||
primary_button: {
|
|
||||||
label: {
|
|
||||||
string_id: "onboarding-firefox-monitor-button"
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: "OPEN_URL",
|
|
||||||
data: {
|
|
||||||
args: "https://monitor.firefox.com/",
|
|
||||||
where: "tabshifted"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
id: "TRAILHEAD_CARD_3",
|
|
||||||
order: 2,
|
|
||||||
blockOnClick: false
|
|
||||||
}, {
|
|
||||||
content: {
|
|
||||||
title: {
|
|
||||||
string_id: "onboarding-browse-privately-title"
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
string_id: "onboarding-browse-privately-text"
|
|
||||||
},
|
|
||||||
icon: "private",
|
|
||||||
primary_button: {
|
|
||||||
label: {
|
|
||||||
string_id: "onboarding-browse-privately-button"
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: "OPEN_PRIVATE_BROWSER_WINDOW"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
id: "TRAILHEAD_CARD_4",
|
|
||||||
order: 3,
|
|
||||||
blockOnClick: true
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
/******/ ]);
|
/******/ ]);
|
|
@ -121,12 +121,9 @@ body {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 32px;
|
grid-gap: 32px;
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.4s;
|
transition: opacity 0.4s;
|
||||||
transition-delay: 0.1s;
|
transition-delay: 0.1s;
|
||||||
grid-auto-rows: 1fr; }
|
grid-auto-rows: 1fr; }
|
||||||
.welcomeCardGrid.show {
|
|
||||||
opacity: 1; }
|
|
||||||
@media (min-width: 610px) {
|
@media (min-width: 610px) {
|
||||||
.welcomeCardGrid {
|
.welcomeCardGrid {
|
||||||
grid-template-columns: repeat(auto-fit, 224px); } }
|
grid-template-columns: repeat(auto-fit, 224px); } }
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
import { MultiStageAboutWelcome } from "./components/MultiStageAboutWelcome";
|
||||||
import { HeroText } from "./components/HeroText";
|
import { HeroText } from "./components/HeroText";
|
||||||
import { FxCards } from "./components/FxCards";
|
import { FxCards } from "./components/FxCards";
|
||||||
import { Localized } from "./components/MSLocalized";
|
import { Localized } from "./components/MSLocalized";
|
||||||
|
@ -29,6 +30,8 @@ class AboutWelcome extends React.PureComponent {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.props.experiment && this.props.branchId) {
|
if (this.props.experiment && this.props.branchId) {
|
||||||
this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
|
this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
|
||||||
|
} else if (this.props.id && this.props.screens) {
|
||||||
|
this.messageId = this.props.id;
|
||||||
}
|
}
|
||||||
this.fetchFxAFlowUri();
|
this.fetchFxAFlowUri();
|
||||||
window.AWSendEventTelemetry({
|
window.AWSendEventTelemetry({
|
||||||
|
@ -56,6 +59,14 @@ class AboutWelcome extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { props } = this;
|
const { props } = this;
|
||||||
|
// TBD: Refactor to redirect based off template value
|
||||||
|
// inside props.template
|
||||||
|
// Create SimpleAboutWelcome that renders default about welcome
|
||||||
|
// See Bug 1638087
|
||||||
|
if (props.screens) {
|
||||||
|
return <MultiStageAboutWelcome screens={props.screens} />;
|
||||||
|
}
|
||||||
|
|
||||||
let UTMTerm =
|
let UTMTerm =
|
||||||
this.props.experiment && this.props.branchId
|
this.props.experiment && this.props.branchId
|
||||||
? `${this.props.experiment}-${this.props.branchId}`
|
? `${this.props.experiment}-${this.props.branchId}`
|
||||||
|
@ -88,7 +99,12 @@ AboutWelcome.defaultProps = DEFAULT_WELCOME_CONTENT;
|
||||||
|
|
||||||
async function mount() {
|
async function mount() {
|
||||||
const { slug, branch } = await window.AWGetStartupData();
|
const { slug, branch } = await window.AWGetStartupData();
|
||||||
const settings = branch && branch.value ? branch.value : {};
|
let settings = branch && branch.value ? branch.value : {};
|
||||||
|
|
||||||
|
if (!(branch && branch.value)) {
|
||||||
|
// Check for override content in pref browser.aboutwelcome.overrideContent
|
||||||
|
settings = await window.AWGetMultiStageScreens();
|
||||||
|
}
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<AboutWelcome
|
<AboutWelcome
|
||||||
|
|
|
@ -61,15 +61,10 @@ body {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 32px;
|
grid-gap: 32px;
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.4s;
|
transition: opacity 0.4s;
|
||||||
transition-delay: 0.1s;
|
transition-delay: 0.1s;
|
||||||
grid-auto-rows: 1fr;
|
grid-auto-rows: 1fr;
|
||||||
|
|
||||||
&.show {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $break-point-medium) {
|
@media (min-width: $break-point-medium) {
|
||||||
grid-template-columns: repeat(auto-fit, 224px);
|
grid-template-columns: repeat(auto-fit, 224px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
import React, { useState, useCallback } from "react";
|
||||||
|
import { Localized } from "./MSLocalized";
|
||||||
|
import { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
|
||||||
|
|
||||||
|
export const MultiStageAboutWelcome = props => {
|
||||||
|
const [index, setScreenIndex] = useState(0);
|
||||||
|
// Transition to next screen, opening about:home on last screen button CTA
|
||||||
|
const handleTransition =
|
||||||
|
index < props.screens.length
|
||||||
|
? useCallback(() => setScreenIndex(prevState => prevState + 1), [])
|
||||||
|
: AboutWelcomeUtils.handleUserAction({
|
||||||
|
type: "OPEN_ABOUT_PAGE",
|
||||||
|
data: { args: "home", where: "current" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className={`welcomeCardGrid`}>
|
||||||
|
{props.screens.map(screen => {
|
||||||
|
return index === screen.order ? (
|
||||||
|
<WelcomeScreen
|
||||||
|
key={screen.id}
|
||||||
|
id={screen.id}
|
||||||
|
content={screen.content}
|
||||||
|
navigate={handleTransition}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const WelcomeScreen = props => {
|
||||||
|
return (
|
||||||
|
<div className={`${props.id}`}>
|
||||||
|
<Localized text={props.content.title}>
|
||||||
|
<h1 />
|
||||||
|
</Localized>
|
||||||
|
<Localized text={props.content.primary_button.label}>
|
||||||
|
<button onClick={props.navigate} />
|
||||||
|
</Localized>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -5,6 +5,7 @@
|
||||||
export const AboutWelcomeUtils = {
|
export const AboutWelcomeUtils = {
|
||||||
handleUserAction(action) {
|
handleUserAction(action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case "OPEN_ABOUT_PAGE":
|
||||||
case "OPEN_AWESOME_BAR":
|
case "OPEN_AWESOME_BAR":
|
||||||
case "OPEN_PRIVATE_BROWSER_WINDOW":
|
case "OPEN_PRIVATE_BROWSER_WINDOW":
|
||||||
case "SHOW_MIGRATION_WIZARD":
|
case "SHOW_MIGRATION_WIZARD":
|
||||||
|
|
|
@ -16,6 +16,7 @@ prefs =
|
||||||
[browser_aboutwelcome.js]
|
[browser_aboutwelcome.js]
|
||||||
[browser_aboutwelcome_actors.js]
|
[browser_aboutwelcome_actors.js]
|
||||||
[browser_aboutwelcome_simplified.js]
|
[browser_aboutwelcome_simplified.js]
|
||||||
|
[browser_aboutwelcome_multistage.js]
|
||||||
[browser_aboutwelcome_observer.js]
|
[browser_aboutwelcome_observer.js]
|
||||||
[browser_as_load_location.js]
|
[browser_as_load_location.js]
|
||||||
[browser_as_render.js]
|
[browser_as_render.js]
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const SEPARATE_ABOUT_WELCOME_PREF = "browser.aboutwelcome.enabled";
|
||||||
|
const ABOUT_WELCOME_OVERRIDE_CONTENT_PREF =
|
||||||
|
"browser.aboutwelcome.overrideContent";
|
||||||
|
const TEST_MULTISTAGE_JSON =
|
||||||
|
'{"id": "multi-stage-welcome","screens": [{"id": "AW_STEP1","order": 0,"content": {"title": "Step 1","primary_button": {"label": "Next"}}},{"id": "AW_STEP2","order": 1,"content": {"title": "Step 2","primary_button": {"label": "Next"}}},{"id": "AW_STEP3","order": 2,"content": {"title": "Step 3","primary_button": {"label": "Next"}}}]}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the aboutwelcome pref to enabled simplified welcome UI
|
||||||
|
*/
|
||||||
|
async function setAboutWelcomePref(value) {
|
||||||
|
return pushPrefs([SEPARATE_ABOUT_WELCOME_PREF, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setAboutWelcomeMultiStage(value) {
|
||||||
|
return pushPrefs([ABOUT_WELCOME_OVERRIDE_CONTENT_PREF, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openAboutWelcome() {
|
||||||
|
await setAboutWelcomePref(true);
|
||||||
|
await setAboutWelcomeMultiStage(TEST_MULTISTAGE_JSON);
|
||||||
|
|
||||||
|
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||||
|
gBrowser,
|
||||||
|
"about:welcome",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
registerCleanupFunction(() => {
|
||||||
|
BrowserTestUtils.removeTab(tab);
|
||||||
|
});
|
||||||
|
return tab.linkedBrowser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup and test simplified welcome UI
|
||||||
|
*/
|
||||||
|
async function test_about_welcome(
|
||||||
|
browser,
|
||||||
|
experiment,
|
||||||
|
expectedSelectors = [],
|
||||||
|
unexpectedSelectors = []
|
||||||
|
) {
|
||||||
|
await ContentTask.spawn(
|
||||||
|
browser,
|
||||||
|
{ expectedSelectors, experiment, unexpectedSelectors },
|
||||||
|
async ({
|
||||||
|
expectedSelectors: expected,
|
||||||
|
experiment: experimentName,
|
||||||
|
unexpectedSelectors: unexpected,
|
||||||
|
}) => {
|
||||||
|
for (let selector of expected) {
|
||||||
|
await ContentTaskUtils.waitForCondition(
|
||||||
|
() => content.document.querySelector(selector),
|
||||||
|
`Should render ${selector} in ${experimentName}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (let selector of unexpected) {
|
||||||
|
ok(
|
||||||
|
!content.document.querySelector(selector),
|
||||||
|
`Should not render ${selector} in ${experimentName}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onNavigate(browser, message) {
|
||||||
|
await ContentTask.spawn(
|
||||||
|
browser,
|
||||||
|
{ message },
|
||||||
|
async ({ message: messageText }) => {
|
||||||
|
await ContentTaskUtils.waitForCondition(
|
||||||
|
() => content.document.querySelector("button"),
|
||||||
|
messageText
|
||||||
|
);
|
||||||
|
let button = content.document.querySelector("button");
|
||||||
|
button.click();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the multistage welcome UI rendered using TEST_MULTISTAGE_JSON
|
||||||
|
*/
|
||||||
|
add_task(async function test_Separate_About_Welcome_branches() {
|
||||||
|
let browser = await openAboutWelcome();
|
||||||
|
|
||||||
|
await test_about_welcome(
|
||||||
|
browser,
|
||||||
|
"multistage step 1",
|
||||||
|
// Expected selectors:
|
||||||
|
["div.welcomeCardGrid", "div.AW_STEP1"],
|
||||||
|
// Unexpected selectors:
|
||||||
|
["div.AW_STEP2", "div.AW_STEP3"]
|
||||||
|
);
|
||||||
|
|
||||||
|
await onNavigate(browser, "Step 1");
|
||||||
|
await test_about_welcome(
|
||||||
|
browser,
|
||||||
|
"multistage step 2",
|
||||||
|
// Expected selectors:
|
||||||
|
["div.welcomeCardGrid", "div.AW_STEP2"],
|
||||||
|
// Unexpected selectors:
|
||||||
|
["div.AW_STEP1", "div.AW_STEP3"]
|
||||||
|
);
|
||||||
|
await onNavigate(browser, "Step 2");
|
||||||
|
await test_about_welcome(
|
||||||
|
browser,
|
||||||
|
"multistage step 3",
|
||||||
|
// Expected selectors:
|
||||||
|
["div.welcomeCardGrid", "div.AW_STEP3"],
|
||||||
|
// Unexpected selectors:
|
||||||
|
["div.AW_STEP1", "div.AW_STEP2"]
|
||||||
|
);
|
||||||
|
});
|
|
@ -110,7 +110,10 @@ const SpecialMessageActions = {
|
||||||
if (action.data.entrypoint) {
|
if (action.data.entrypoint) {
|
||||||
aboutPageURL.search = action.data.entrypoint;
|
aboutPageURL.search = action.data.entrypoint;
|
||||||
}
|
}
|
||||||
window.openTrustedLinkIn(aboutPageURL.toString(), "tab");
|
window.openTrustedLinkIn(
|
||||||
|
aboutPageURL.toString(),
|
||||||
|
action.data.where || "tab"
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "OPEN_PREFERENCES_PAGE":
|
case "OPEN_PREFERENCES_PAGE":
|
||||||
window.openPreferences(
|
window.openPreferences(
|
||||||
|
|
|
@ -66,6 +66,12 @@ const SpecialMessageActionSchemas = {
|
||||||
description: 'The about page. E.g. "welcome" for about:welcome',
|
description: 'The about page. E.g. "welcome" for about:welcome',
|
||||||
type: "string",
|
type: "string",
|
||||||
},
|
},
|
||||||
|
where: {
|
||||||
|
default: "tab",
|
||||||
|
description: "Where the URL is opened.",
|
||||||
|
enum: ["current", "save", "tab", "tabshifted", "window"],
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
entrypoint: {
|
entrypoint: {
|
||||||
description:
|
description:
|
||||||
'Any optional entrypoint value that will be added to the search. E.g. "foo=bar" would result in about:welcome?foo=bar',
|
'Any optional entrypoint value that will be added to the search. E.g. "foo=bar" would result in about:welcome?foo=bar',
|
||||||
|
|
Загрузка…
Ссылка в новой задаче