forked from mirrors/gecko-dev
Depends on D193120 Differential Revision: https://phabricator.services.mozilla.com/D193121
3810 lines
143 KiB
JavaScript
3810 lines
143 KiB
JavaScript
/*!
|
|
*
|
|
* NOTE: This file is generated by webpack from aboutwelcome.jsx
|
|
* using the npm bundle task.
|
|
*
|
|
*/
|
|
/******/ (() => {
|
|
// webpackBootstrap
|
|
/******/ "use strict";
|
|
/******/ let __webpack_modules__ = [
|
|
,
|
|
/* 0 */ /* 1 */
|
|
/***/ module => {
|
|
module.exports = React;
|
|
|
|
/***/
|
|
},
|
|
/* 2 */
|
|
/***/ module => {
|
|
module.exports = ReactDOM;
|
|
|
|
/***/
|
|
},
|
|
/* 3 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ AboutWelcomeUtils: () =>
|
|
/* binding */ AboutWelcomeUtils,
|
|
/* harmony export */ DEFAULT_RTAMO_CONTENT: () =>
|
|
/* binding */ DEFAULT_RTAMO_CONTENT,
|
|
/* harmony export */
|
|
});
|
|
let _document$querySelect;
|
|
/* 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/. */
|
|
|
|
// If the container has a "page" data attribute, then this is
|
|
// a Spotlight modal or Feature Callout. Otherwise, this is
|
|
// about:welcome and we should return the current page.
|
|
const page =
|
|
((_document$querySelect = document.querySelector(
|
|
"#multi-stage-message-root.onboardingContainer[data-page]"
|
|
)) === null || _document$querySelect === void 0
|
|
? void 0
|
|
: _document$querySelect.dataset.page) || document.location.href;
|
|
const AboutWelcomeUtils = {
|
|
handleUserAction(action) {
|
|
return window.AWSendToParent("SPECIAL_ACTION", action);
|
|
},
|
|
sendImpressionTelemetry(messageId, context) {
|
|
let _window;
|
|
let _window$AWSendEventTe;
|
|
(_window$AWSendEventTe = (_window = window).AWSendEventTelemetry) ===
|
|
null || _window$AWSendEventTe === void 0
|
|
? void 0
|
|
: _window$AWSendEventTe.call(_window, {
|
|
event: "IMPRESSION",
|
|
event_context: {
|
|
...context,
|
|
page,
|
|
},
|
|
message_id: messageId,
|
|
});
|
|
},
|
|
sendActionTelemetry(messageId, elementId, eventName = "CLICK_BUTTON") {
|
|
let _window$AWSendEventTe2;
|
|
let _window2;
|
|
const ping = {
|
|
event: eventName,
|
|
event_context: {
|
|
source: elementId,
|
|
page,
|
|
},
|
|
message_id: messageId,
|
|
};
|
|
(_window$AWSendEventTe2 = (_window2 = window)
|
|
.AWSendEventTelemetry) === null || _window$AWSendEventTe2 === void 0
|
|
? void 0
|
|
: _window$AWSendEventTe2.call(_window2, ping);
|
|
},
|
|
sendDismissTelemetry(messageId, elementId) {
|
|
// Don't send DISMISS telemetry in spotlight modals since they already send
|
|
// their own equivalent telemetry.
|
|
if (page !== "spotlight") {
|
|
this.sendActionTelemetry(messageId, elementId, "DISMISS");
|
|
}
|
|
},
|
|
async fetchFlowParams(metricsFlowUri) {
|
|
let flowParams;
|
|
try {
|
|
const response = await fetch(metricsFlowUri, {
|
|
credentials: "omit",
|
|
});
|
|
if (response.status === 200) {
|
|
const { deviceId, flowId, flowBeginTime } = await response.json();
|
|
flowParams = {
|
|
deviceId,
|
|
flowId,
|
|
flowBeginTime,
|
|
};
|
|
} else {
|
|
console.error("Non-200 response", response);
|
|
}
|
|
} catch (e) {
|
|
flowParams = null;
|
|
}
|
|
return flowParams;
|
|
},
|
|
sendEvent(type, detail) {
|
|
document.dispatchEvent(
|
|
new CustomEvent(`AWPage:${type}`, {
|
|
bubbles: true,
|
|
detail,
|
|
})
|
|
);
|
|
},
|
|
getLoadingStrategyFor(url) {
|
|
return url !== null && url !== void 0 && url.startsWith("http")
|
|
? "lazy"
|
|
: "eager";
|
|
},
|
|
};
|
|
const DEFAULT_RTAMO_CONTENT = {
|
|
template: "return_to_amo",
|
|
utm_term: "rtamo",
|
|
content: {
|
|
position: "split",
|
|
title: {
|
|
string_id: "mr1-return-to-amo-subtitle",
|
|
},
|
|
has_noodles: false,
|
|
subtitle: {
|
|
string_id: "mr1-return-to-amo-addon-title",
|
|
},
|
|
backdrop:
|
|
"var(--mr-welcome-background-color) var(--mr-welcome-background-gradient)",
|
|
background:
|
|
"url('chrome://activity-stream/content/data/content/assets/mr-rtamo-background-image.svg') no-repeat center",
|
|
progress_bar: true,
|
|
primary_button: {
|
|
label: {
|
|
string_id: "mr1-return-to-amo-add-extension-label",
|
|
},
|
|
source_id: "ADD_EXTENSION_BUTTON",
|
|
action: {
|
|
type: "INSTALL_ADDON_FROM_URL",
|
|
data: {
|
|
url: null,
|
|
telemetrySource: "rtamo",
|
|
},
|
|
},
|
|
},
|
|
secondary_button: {
|
|
label: {
|
|
string_id: "onboarding-not-now-button-label",
|
|
},
|
|
source_id: "RTAMO_START_BROWSING_BUTTON",
|
|
action: {
|
|
type: "OPEN_AWESOME_BAR",
|
|
},
|
|
},
|
|
secondary_button_top: {
|
|
label: {
|
|
string_id: "mr1-onboarding-sign-in-button-label",
|
|
},
|
|
source_id: "RTAMO_FXA_SIGNIN_BUTTON",
|
|
action: {
|
|
data: {
|
|
entrypoint: "activity-stream-firstrun",
|
|
where: "tab",
|
|
},
|
|
type: "SHOW_FIREFOX_ACCOUNTS",
|
|
addFlowParams: true,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 4 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ MultiStageAboutWelcome: () =>
|
|
/* binding */ MultiStageAboutWelcome,
|
|
/* harmony export */ SecondaryCTA: () => /* binding */ SecondaryCTA,
|
|
/* harmony export */ StepsIndicator: () => /* binding */ StepsIndicator,
|
|
/* harmony export */ ProgressBar: () => /* binding */ ProgressBar,
|
|
/* harmony export */ WelcomeScreen: () => /* binding */ WelcomeScreen,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(3);
|
|
/* harmony import */ let _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_3__ =
|
|
__webpack_require__(6);
|
|
/* harmony import */ let _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_4__ =
|
|
__webpack_require__(10);
|
|
/* harmony import */ let _newtab_content_src_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ =
|
|
__webpack_require__(18);
|
|
/* 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/. */
|
|
|
|
// Amount of milliseconds for all transitions to complete (including delays).
|
|
const TRANSITION_OUT_TIME = 1000;
|
|
const LANGUAGE_MISMATCH_SCREEN_ID = "AW_LANGUAGE_MISMATCH";
|
|
const MultiStageAboutWelcome = props => {
|
|
let { defaultScreens } = props;
|
|
const didFilter = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
|
|
const [didMount, setDidMount] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
const [screens, setScreens] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(defaultScreens);
|
|
const [index, setScreenIndex] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(props.startScreen);
|
|
const [previousOrder, setPreviousOrder] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(props.startScreen - 1);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
(async () => {
|
|
// If we want to load index from history state, we don't want to send impression yet
|
|
if (!didMount) {
|
|
return;
|
|
}
|
|
// On about:welcome first load, screensVisited should be empty
|
|
let screensVisited = didFilter.current
|
|
? screens.slice(0, index)
|
|
: [];
|
|
let upcomingScreens = defaultScreens
|
|
.filter(s => !screensVisited.find(v => v.id === s.id))
|
|
// Filter out Language Mismatch screen from upcoming
|
|
// screens if screens set from useLanguageSwitcher hook
|
|
// has filtered language screen
|
|
.filter(
|
|
upcomingScreen =>
|
|
!(
|
|
!screens.find(s => s.id === LANGUAGE_MISMATCH_SCREEN_ID) &&
|
|
upcomingScreen.id === LANGUAGE_MISMATCH_SCREEN_ID
|
|
)
|
|
);
|
|
let filteredScreens = screensVisited.concat(
|
|
(await window.AWEvaluateScreenTargeting(upcomingScreens)) ??
|
|
upcomingScreens
|
|
);
|
|
|
|
// Use existing screen for the filtered screen to carry over any modification
|
|
// e.g. if AW_LANGUAGE_MISMATCH exists, use it from existing screens
|
|
setScreens(
|
|
filteredScreens.map(
|
|
filtered => screens.find(s => s.id === filtered.id) ?? filtered
|
|
)
|
|
);
|
|
didFilter.current = true;
|
|
const screenInitials = filteredScreens
|
|
.map(({ id }) => {
|
|
let _id$split$;
|
|
return id === null || id === void 0
|
|
? void 0
|
|
: (_id$split$ = id.split("_")[1]) === null ||
|
|
_id$split$ === void 0
|
|
? void 0
|
|
: _id$split$[0];
|
|
})
|
|
.join("");
|
|
// Send impression ping when respective screen first renders
|
|
filteredScreens.forEach((screen, order) => {
|
|
if (index === order) {
|
|
let _window;
|
|
let _window$AWAddScreenIm;
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendImpressionTelemetry(
|
|
`${props.message_id}_${order}_${screen.id}_${screenInitials}`
|
|
);
|
|
(_window$AWAddScreenIm = (_window = window)
|
|
.AWAddScreenImpression) === null ||
|
|
_window$AWAddScreenIm === void 0
|
|
? void 0
|
|
: _window$AWAddScreenIm.call(_window, screen);
|
|
}
|
|
});
|
|
|
|
// Remember that a new screen has loaded for browser navigation
|
|
if (props.updateHistory && index > window.history.state) {
|
|
window.history.pushState(index, "");
|
|
}
|
|
|
|
// Remember the previous screen index so we can animate the transition
|
|
setPreviousOrder(index);
|
|
})();
|
|
}, [index, didMount]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const [flowParams, setFlowParams] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
const { metricsFlowUri } = props;
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
(async () => {
|
|
if (metricsFlowUri) {
|
|
setFlowParams(
|
|
await _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.fetchFlowParams(
|
|
metricsFlowUri
|
|
)
|
|
);
|
|
}
|
|
})();
|
|
}, [metricsFlowUri]);
|
|
|
|
// Allow "in" style to render to actually transition towards regular state,
|
|
// which also makes using browser back/forward navigation skip transitions.
|
|
const [transition, setTransition] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(
|
|
props.transitions ? "in" : ""
|
|
);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
if (transition === "in") {
|
|
requestAnimationFrame(() =>
|
|
requestAnimationFrame(() => setTransition(""))
|
|
);
|
|
}
|
|
}, [transition]);
|
|
|
|
// Transition to next screen, opening about:home on last screen button CTA
|
|
const handleTransition = () => {
|
|
// Only handle transitioning out from a screen once.
|
|
if (transition === "out") {
|
|
return;
|
|
}
|
|
|
|
// Start transitioning things "out" immediately when moving forwards.
|
|
setTransition(props.transitions ? "out" : "");
|
|
|
|
// Actually move forwards after all transitions finish.
|
|
setTimeout(
|
|
() => {
|
|
if (index < screens.length - 1) {
|
|
setTransition(props.transitions ? "in" : "");
|
|
setScreenIndex(prevState => prevState + 1);
|
|
} else {
|
|
window.AWFinish();
|
|
}
|
|
},
|
|
props.transitions ? TRANSITION_OUT_TIME : 0
|
|
);
|
|
};
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
// When about:welcome loads (on refresh or pressing back button
|
|
// from about:home), ensure history state usEffect runs before
|
|
// useEffect hook that send impression telemetry
|
|
setDidMount(true);
|
|
if (props.updateHistory) {
|
|
// Switch to the screen tracked in state (null for initial state)
|
|
// or last screen index if a user navigates by pressing back
|
|
// button from about:home
|
|
const handler = ({ state }) => {
|
|
if (transition === "out") {
|
|
return;
|
|
}
|
|
setTransition(props.transitions ? "out" : "");
|
|
setTimeout(
|
|
() => {
|
|
setTransition(props.transitions ? "in" : "");
|
|
setScreenIndex(Math.min(state, screens.length - 1));
|
|
},
|
|
props.transitions ? TRANSITION_OUT_TIME : 0
|
|
);
|
|
};
|
|
|
|
// Handle page load, e.g., going back to about:welcome from about:home
|
|
const { state } = window.history;
|
|
if (state) {
|
|
setScreenIndex(Math.min(state, screens.length - 1));
|
|
setPreviousOrder(Math.min(state, screens.length - 1));
|
|
}
|
|
|
|
// Watch for browser back/forward button navigation events
|
|
window.addEventListener("popstate", handler);
|
|
return () => window.removeEventListener("popstate", handler);
|
|
}
|
|
return false;
|
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
// Save the active multi select state for each screen as an object keyed by
|
|
// screen id. Each screen id has an array containing checkbox ids used in
|
|
// handleAction to update MULTI_ACTION data. This allows us to remember the
|
|
// state of each screen's multi select checkboxes when navigating back and
|
|
// forth between screens, while also allowing a message to have more than one
|
|
// multi select screen.
|
|
const [activeMultiSelects, setActiveMultiSelects] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
|
|
|
|
// Get the active theme so the rendering code can make it selected
|
|
// by default.
|
|
const [activeTheme, setActiveTheme] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
const [initialTheme, setInitialTheme] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
(async () => {
|
|
let theme = await window.AWGetSelectedTheme();
|
|
setInitialTheme(theme);
|
|
setActiveTheme(theme);
|
|
})();
|
|
}, []);
|
|
const {
|
|
negotiatedLanguage,
|
|
langPackInstallPhase,
|
|
languageFilteredScreens,
|
|
} = (0,
|
|
_LanguageSwitcher__WEBPACK_IMPORTED_MODULE_4__.useLanguageSwitcher)(
|
|
props.appAndSystemLocaleInfo,
|
|
screens,
|
|
index,
|
|
setScreenIndex
|
|
);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
setScreens(languageFilteredScreens);
|
|
}, [languageFilteredScreens]);
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().Fragment,
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `outer-wrapper onboardingContainer proton transition-${transition}`,
|
|
style: props.backdrop
|
|
? {
|
|
background: props.backdrop,
|
|
}
|
|
: {},
|
|
},
|
|
screens.map((screen, order) => {
|
|
const isFirstScreen = screen === screens[0];
|
|
const isLastScreen = screen === screens[screens.length - 1];
|
|
const totalNumberOfScreens = screens.length;
|
|
const isSingleScreen = totalNumberOfScreens === 1;
|
|
const setActiveMultiSelect = valueOrFn =>
|
|
setActiveMultiSelects(prevState => ({
|
|
...prevState,
|
|
[screen.id]:
|
|
typeof valueOrFn === "function"
|
|
? valueOrFn(prevState[screen.id])
|
|
: valueOrFn,
|
|
}));
|
|
return index === order
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
WelcomeScreen,
|
|
{
|
|
key: screen.id + order,
|
|
id: screen.id,
|
|
totalNumberOfScreens,
|
|
isFirstScreen,
|
|
isLastScreen,
|
|
isSingleScreen,
|
|
order,
|
|
previousOrder,
|
|
content: screen.content,
|
|
navigate: handleTransition,
|
|
messageId: `${props.message_id}_${order}_${screen.id}`,
|
|
UTMTerm: props.utm_term,
|
|
flowParams,
|
|
activeTheme,
|
|
initialTheme,
|
|
setActiveTheme,
|
|
setInitialTheme,
|
|
activeMultiSelect: activeMultiSelects[screen.id],
|
|
setActiveMultiSelect,
|
|
autoAdvance: screen.auto_advance,
|
|
negotiatedLanguage,
|
|
langPackInstallPhase,
|
|
forceHideStepsIndicator:
|
|
screen.force_hide_steps_indicator,
|
|
ariaRole: props.ariaRole,
|
|
aboveButtonStepsIndicator:
|
|
screen.above_button_steps_indicator,
|
|
}
|
|
)
|
|
: null;
|
|
})
|
|
)
|
|
);
|
|
};
|
|
const SecondaryCTA = props => {
|
|
let _props$content$second;
|
|
let _props$content$second2;
|
|
let _props$content$tiles;
|
|
const targetElement = props.position
|
|
? `secondary_button_${props.position}`
|
|
: `secondary_button`;
|
|
let buttonStyling =
|
|
(_props$content$second = props.content.secondary_button) !== null &&
|
|
_props$content$second !== void 0 &&
|
|
_props$content$second.has_arrow_icon
|
|
? `secondary arrow-icon`
|
|
: `secondary`;
|
|
const isTextLink =
|
|
!["split", "callout"].includes(props.content.position) &&
|
|
((_props$content$tiles = props.content.tiles) === null ||
|
|
_props$content$tiles === void 0
|
|
? void 0
|
|
: _props$content$tiles.type) !== "addons-picker";
|
|
const isPrimary =
|
|
((_props$content$second2 = props.content.secondary_button) === null ||
|
|
_props$content$second2 === void 0
|
|
? void 0
|
|
: _props$content$second2.style) === "primary";
|
|
if (isTextLink) {
|
|
buttonStyling += " text-link";
|
|
}
|
|
if (isPrimary) {
|
|
let _props$content$second3;
|
|
buttonStyling =
|
|
(_props$content$second3 = props.content.secondary_button) !==
|
|
null &&
|
|
_props$content$second3 !== void 0 &&
|
|
_props$content$second3.has_arrow_icon
|
|
? `primary arrow-icon`
|
|
: `primary`;
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: props.position
|
|
? `secondary-cta ${props.position}`
|
|
: "secondary-cta",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: props.content[targetElement].text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"span",
|
|
null
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: props.content[targetElement].label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: buttonStyling,
|
|
value: targetElement,
|
|
onClick: props.handleAction,
|
|
}
|
|
)
|
|
)
|
|
);
|
|
};
|
|
const StepsIndicator = props => {
|
|
let steps = [];
|
|
for (let i = 0; i < props.totalNumberOfScreens; i++) {
|
|
let className = `${i === props.order ? "current" : ""} ${
|
|
i < props.order ? "complete" : ""
|
|
}`;
|
|
steps.push(
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
key: i,
|
|
className: `indicator ${className}`,
|
|
role: "presentation",
|
|
}
|
|
)
|
|
);
|
|
}
|
|
return steps;
|
|
};
|
|
const ProgressBar = ({ step, previousStep, totalNumberOfScreens }) => {
|
|
const [progress, setProgress] =
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().useState(
|
|
previousStep / totalNumberOfScreens
|
|
);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
// We don't need to hook any dependencies because any time the step changes,
|
|
// the screen's entire DOM tree will be re-rendered.
|
|
setProgress(step / totalNumberOfScreens);
|
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "indicator",
|
|
role: "presentation",
|
|
style: {
|
|
"--progress-bar-progress": `${progress * 100}%`,
|
|
},
|
|
}
|
|
);
|
|
};
|
|
class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default()
|
|
.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.handleAction = this.handleAction.bind(this);
|
|
}
|
|
|
|
handleOpenURL(action, flowParams, UTMTerm) {
|
|
let { type, data } = action;
|
|
if (type === "SHOW_FIREFOX_ACCOUNTS") {
|
|
let params = {
|
|
..._newtab_content_src_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__.BASE_PARAMS,
|
|
utm_term: `${UTMTerm}-screen`,
|
|
};
|
|
if (action.addFlowParams && flowParams) {
|
|
params = {
|
|
...params,
|
|
...flowParams,
|
|
};
|
|
}
|
|
data = {
|
|
...data,
|
|
extraParams: params,
|
|
};
|
|
} else if (type === "OPEN_URL") {
|
|
let url = new URL(data.args);
|
|
(0,
|
|
_newtab_content_src_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__.addUtmParams)(
|
|
url,
|
|
`${UTMTerm}-screen`
|
|
);
|
|
if (action.addFlowParams && flowParams) {
|
|
url.searchParams.append("device_id", flowParams.deviceId);
|
|
url.searchParams.append("flow_id", flowParams.flowId);
|
|
url.searchParams.append(
|
|
"flow_begin_time",
|
|
flowParams.flowBeginTime
|
|
);
|
|
}
|
|
data = {
|
|
...data,
|
|
args: url.toString(),
|
|
};
|
|
}
|
|
return _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.handleUserAction(
|
|
{
|
|
type,
|
|
data,
|
|
}
|
|
);
|
|
}
|
|
|
|
async handleAction(event) {
|
|
let { props } = this;
|
|
const value =
|
|
event.currentTarget.value ??
|
|
event.currentTarget.getAttribute("value");
|
|
const source = event.source || value;
|
|
let targetContent =
|
|
props.content[value] ||
|
|
props.content.tiles ||
|
|
props.content.languageSwitcher;
|
|
if (!(targetContent && targetContent.action)) {
|
|
return;
|
|
}
|
|
// Send telemetry before waiting on actions
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(
|
|
props.messageId,
|
|
source,
|
|
event.name
|
|
);
|
|
|
|
// Send additional telemetry if a messaging surface like feature callout is
|
|
// dismissed via the dismiss button. Other causes of dismissal will be
|
|
// handled separately by the messaging surface's own code.
|
|
if (value === "dismiss_button" && !event.name) {
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendDismissTelemetry(
|
|
props.messageId,
|
|
source
|
|
);
|
|
}
|
|
let { action } = targetContent;
|
|
action = JSON.parse(JSON.stringify(action));
|
|
if (action.collectSelect) {
|
|
let _action$data;
|
|
// Populate MULTI_ACTION data actions property with selected checkbox
|
|
// actions from tiles data
|
|
if (action.type !== "MULTI_ACTION") {
|
|
console.error(
|
|
"collectSelect is only supported for MULTI_ACTION type actions"
|
|
);
|
|
action.type = "MULTI_ACTION";
|
|
}
|
|
if (
|
|
!Array.isArray(
|
|
(_action$data = action.data) === null || _action$data === void 0
|
|
? void 0
|
|
: _action$data.actions
|
|
)
|
|
) {
|
|
console.error(
|
|
"collectSelect is only supported for MULTI_ACTION type actions with an array of actions"
|
|
);
|
|
action.data = {
|
|
actions: [],
|
|
};
|
|
}
|
|
|
|
// Prepend the multi-select actions to the CTA's actions array, but keep
|
|
// the actions in the same order they appear in. This way the CTA action
|
|
// can go last, after the multi-select actions are processed. For example,
|
|
// 1. checkbox action 1
|
|
// 2. checkbox action 2
|
|
// 3. radio action
|
|
// 4. CTA action (which perhaps depends on the radio action)
|
|
let multiSelectActions = [];
|
|
for (const checkbox of ((_props$content = props.content) === null ||
|
|
_props$content === void 0
|
|
? void 0
|
|
: (_props$content$tiles2 = _props$content.tiles) === null ||
|
|
_props$content$tiles2 === void 0
|
|
? void 0
|
|
: _props$content$tiles2.data) ?? []) {
|
|
var _props$content;
|
|
var _props$content$tiles2;
|
|
var _this$props$activeMul;
|
|
let checkboxAction;
|
|
if (
|
|
(_this$props$activeMul = this.props.activeMultiSelect) !==
|
|
null &&
|
|
_this$props$activeMul !== void 0 &&
|
|
_this$props$activeMul.includes(checkbox.id)
|
|
) {
|
|
checkboxAction = checkbox.checkedAction ?? checkbox.action;
|
|
} else {
|
|
checkboxAction = checkbox.uncheckedAction;
|
|
}
|
|
if (checkboxAction) {
|
|
multiSelectActions.push(checkboxAction);
|
|
}
|
|
}
|
|
action.data.actions.unshift(...multiSelectActions);
|
|
|
|
// Send telemetry with selected checkbox ids
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(
|
|
props.messageId,
|
|
props.activeMultiSelect,
|
|
"SELECT_CHECKBOX"
|
|
);
|
|
}
|
|
let actionResult;
|
|
if (["OPEN_URL", "SHOW_FIREFOX_ACCOUNTS"].includes(action.type)) {
|
|
actionResult = await this.handleOpenURL(
|
|
action,
|
|
props.flowParams,
|
|
props.UTMTerm
|
|
);
|
|
} else if (action.type) {
|
|
actionResult =
|
|
await _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.handleUserAction(
|
|
action
|
|
);
|
|
if (action.type === "FXA_SIGNIN_FLOW") {
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(
|
|
props.messageId,
|
|
actionResult ? "sign_in" : "sign_in_cancel",
|
|
"FXA_SIGNIN_FLOW"
|
|
);
|
|
}
|
|
// Wait until migration closes to complete the action
|
|
const hasMigrate = a => {
|
|
let _a$data;
|
|
let _a$data$actions;
|
|
return (
|
|
a.type === "SHOW_MIGRATION_WIZARD" ||
|
|
(a.type === "MULTI_ACTION" &&
|
|
((_a$data = a.data) === null || _a$data === void 0
|
|
? void 0
|
|
: (_a$data$actions = _a$data.actions) === null ||
|
|
_a$data$actions === void 0
|
|
? void 0
|
|
: _a$data$actions.some(hasMigrate)))
|
|
);
|
|
};
|
|
if (hasMigrate(action)) {
|
|
await window.AWWaitForMigrationClose();
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(
|
|
props.messageId,
|
|
"migrate_close"
|
|
);
|
|
}
|
|
}
|
|
|
|
// A special tiles.action.theme value indicates we should use the event's value vs provided value.
|
|
if (action.theme) {
|
|
let themeToUse =
|
|
action.theme === "<event>"
|
|
? event.currentTarget.value
|
|
: this.props.initialTheme || action.theme;
|
|
this.props.setActiveTheme(themeToUse);
|
|
window.AWSelectTheme(themeToUse);
|
|
}
|
|
|
|
// If the action has persistActiveTheme: true, we set the initial theme to the currently active theme
|
|
// so that it can be reverted to in the event that the user navigates away from the screen
|
|
if (action.persistActiveTheme) {
|
|
this.props.setInitialTheme(this.props.activeTheme);
|
|
}
|
|
|
|
// `navigate` and `dismiss` can be true/false/undefined, or they can be a
|
|
// string "actionResult" in which case we should use the actionResult
|
|
// (boolean resolved by handleUserAction)
|
|
const shouldDoBehavior = behavior =>
|
|
behavior === "actionResult" ? actionResult : behavior;
|
|
if (shouldDoBehavior(action.navigate)) {
|
|
props.navigate();
|
|
}
|
|
if (shouldDoBehavior(action.dismiss)) {
|
|
window.AWFinish();
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_3__.MultiStageProtonScreen,
|
|
{
|
|
content: this.props.content,
|
|
id: this.props.id,
|
|
order: this.props.order,
|
|
previousOrder: this.props.previousOrder,
|
|
activeTheme: this.props.activeTheme,
|
|
activeMultiSelect: this.props.activeMultiSelect,
|
|
setActiveMultiSelect: this.props.setActiveMultiSelect,
|
|
totalNumberOfScreens: this.props.totalNumberOfScreens,
|
|
appAndSystemLocaleInfo: this.props.appAndSystemLocaleInfo,
|
|
negotiatedLanguage: this.props.negotiatedLanguage,
|
|
langPackInstallPhase: this.props.langPackInstallPhase,
|
|
handleAction: this.handleAction,
|
|
messageId: this.props.messageId,
|
|
isFirstScreen: this.props.isFirstScreen,
|
|
isLastScreen: this.props.isLastScreen,
|
|
isSingleScreen: this.props.isSingleScreen,
|
|
startsWithCorner: this.props.startsWithCorner,
|
|
autoAdvance: this.props.autoAdvance,
|
|
forceHideStepsIndicator: this.props.forceHideStepsIndicator,
|
|
ariaRole: this.props.ariaRole,
|
|
aboveButtonStepsIndicator: this.props.aboveButtonStepsIndicator,
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
/***/
|
|
},
|
|
/* 5 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ CONFIGURABLE_STYLES: () =>
|
|
/* binding */ CONFIGURABLE_STYLES,
|
|
/* harmony export */ Localized: () => /* binding */ Localized,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* 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 CONFIGURABLE_STYLES = [
|
|
"color",
|
|
"fontSize",
|
|
"fontWeight",
|
|
"letterSpacing",
|
|
"lineHeight",
|
|
"marginBlock",
|
|
"marginInline",
|
|
"paddingBlock",
|
|
"paddingInline",
|
|
"whiteSpace",
|
|
];
|
|
const ZAP_SIZE_THRESHOLD = 160;
|
|
|
|
/**
|
|
* Based on the .text prop, localizes an inner element if a string_id
|
|
* is provided, OR renders plain text, OR hides it if nothing is provided.
|
|
* Allows configuring of some styles including zap underline and color.
|
|
*
|
|
* Examples:
|
|
*
|
|
* Localized text
|
|
* ftl:
|
|
* title = Welcome
|
|
* jsx:
|
|
* <Localized text={{string_id: "title"}}><h1 /></Localized>
|
|
* output:
|
|
* <h1 data-l10n-id="title">Welcome</h1>
|
|
*
|
|
* Unlocalized text
|
|
* jsx:
|
|
* <Localized text="Welcome"><h1 /></Localized>
|
|
* <Localized text={{raw: "Welcome"}}><h1 /></Localized>
|
|
* output:
|
|
* <h1>Welcome</h1>
|
|
*/
|
|
|
|
const Localized = ({ text, children }) => {
|
|
// Dynamically determine the size of the zap style.
|
|
const zapRef =
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createRef();
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
const { current } = zapRef;
|
|
if (current) {
|
|
requestAnimationFrame(() =>
|
|
current === null || current === void 0
|
|
? void 0
|
|
: current.classList.replace(
|
|
"short",
|
|
current.getBoundingClientRect().width > ZAP_SIZE_THRESHOLD
|
|
? "long"
|
|
: "short"
|
|
)
|
|
);
|
|
}
|
|
});
|
|
|
|
// Skip rendering of children with no text.
|
|
if (!text) {
|
|
return null;
|
|
}
|
|
|
|
// Allow augmenting existing child container properties.
|
|
const props = {
|
|
children: [],
|
|
className: "",
|
|
style: {},
|
|
...(children === null || children === void 0
|
|
? void 0
|
|
: children.props),
|
|
};
|
|
// Support nested Localized by starting with their children.
|
|
const textNodes = Array.isArray(props.children)
|
|
? props.children
|
|
: [props.children];
|
|
|
|
// Pick desired fluent or raw/plain text to render.
|
|
if (text.string_id) {
|
|
// Set the key so React knows not to reuse when switching to plain text.
|
|
props.key = text.string_id;
|
|
props["data-l10n-id"] = text.string_id;
|
|
if (text.args) {
|
|
props["data-l10n-args"] = JSON.stringify(text.args);
|
|
}
|
|
} else if (text.raw) {
|
|
textNodes.push(text.raw);
|
|
} else if (typeof text === "string") {
|
|
textNodes.push(text);
|
|
}
|
|
|
|
// Add zap style and content in a way that allows fluent to insert too.
|
|
if (text.zap) {
|
|
props.className += " welcomeZap";
|
|
textNodes.push(
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"span",
|
|
{
|
|
className: "short zap",
|
|
"data-l10n-name": "zap",
|
|
ref: zapRef,
|
|
},
|
|
text.zap
|
|
)
|
|
);
|
|
}
|
|
if (text.aria_label) {
|
|
props["aria-label"] = text.aria_label;
|
|
}
|
|
|
|
// Apply certain configurable styles.
|
|
CONFIGURABLE_STYLES.forEach(style => {
|
|
if (text[style] !== undefined) {
|
|
props.style[style] = text[style];
|
|
}
|
|
});
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().cloneElement(
|
|
// Provide a default container for the text if necessary.
|
|
children ??
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"span",
|
|
null
|
|
),
|
|
props,
|
|
// Conditionally pass in as void elements can't accept empty array.
|
|
textNodes.length ? textNodes : null
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 6 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ MultiStageProtonScreen: () =>
|
|
/* binding */ MultiStageProtonScreen,
|
|
/* harmony export */ ProtonScreenActionButtons: () =>
|
|
/* binding */ ProtonScreenActionButtons,
|
|
/* harmony export */ ProtonScreen: () => /* binding */ ProtonScreen,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(3);
|
|
/* harmony import */ let _MobileDownloads__WEBPACK_IMPORTED_MODULE_3__ =
|
|
__webpack_require__(7);
|
|
/* harmony import */ let _MultiSelect__WEBPACK_IMPORTED_MODULE_4__ =
|
|
__webpack_require__(8);
|
|
/* harmony import */ let _Themes__WEBPACK_IMPORTED_MODULE_5__ =
|
|
__webpack_require__(9);
|
|
/* harmony import */ let _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__ =
|
|
__webpack_require__(4);
|
|
/* harmony import */ let _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_7__ =
|
|
__webpack_require__(10);
|
|
/* harmony import */ let _CTAParagraph__WEBPACK_IMPORTED_MODULE_8__ =
|
|
__webpack_require__(11);
|
|
/* harmony import */ let _HeroImage__WEBPACK_IMPORTED_MODULE_9__ =
|
|
__webpack_require__(12);
|
|
/* harmony import */ let _OnboardingVideo__WEBPACK_IMPORTED_MODULE_10__ =
|
|
__webpack_require__(13);
|
|
/* harmony import */ let _AdditionalCTA__WEBPACK_IMPORTED_MODULE_11__ =
|
|
__webpack_require__(14);
|
|
/* harmony import */ let _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__ =
|
|
__webpack_require__(15);
|
|
/* harmony import */ let _AddonsPicker__WEBPACK_IMPORTED_MODULE_13__ =
|
|
__webpack_require__(16);
|
|
/* harmony import */ let _LinkParagraph__WEBPACK_IMPORTED_MODULE_14__ =
|
|
__webpack_require__(17);
|
|
/* 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 MultiStageProtonScreen = props => {
|
|
const { autoAdvance, handleAction, order } = props;
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
if (autoAdvance) {
|
|
const timer = setTimeout(() => {
|
|
handleAction({
|
|
currentTarget: {
|
|
value: autoAdvance,
|
|
},
|
|
name: "AUTO_ADVANCE",
|
|
});
|
|
}, 20000);
|
|
return () => clearTimeout(timer);
|
|
}
|
|
return () => {};
|
|
}, [autoAdvance, handleAction, order]);
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
ProtonScreen,
|
|
{
|
|
content: props.content,
|
|
id: props.id,
|
|
order: props.order,
|
|
activeTheme: props.activeTheme,
|
|
activeMultiSelect: props.activeMultiSelect,
|
|
setActiveMultiSelect: props.setActiveMultiSelect,
|
|
totalNumberOfScreens: props.totalNumberOfScreens,
|
|
handleAction: props.handleAction,
|
|
isFirstScreen: props.isFirstScreen,
|
|
isLastScreen: props.isLastScreen,
|
|
isSingleScreen: props.isSingleScreen,
|
|
previousOrder: props.previousOrder,
|
|
autoAdvance: props.autoAdvance,
|
|
isRtamo: props.isRtamo,
|
|
addonName: props.addonName,
|
|
isTheme: props.isTheme,
|
|
iconURL: props.iconURL,
|
|
messageId: props.messageId,
|
|
negotiatedLanguage: props.negotiatedLanguage,
|
|
langPackInstallPhase: props.langPackInstallPhase,
|
|
forceHideStepsIndicator: props.forceHideStepsIndicator,
|
|
ariaRole: props.ariaRole,
|
|
aboveButtonStepsIndicator: props.aboveButtonStepsIndicator,
|
|
}
|
|
);
|
|
};
|
|
const ProtonScreenActionButtons = props => {
|
|
let _content$additional_b;
|
|
let _content$checkbox;
|
|
let _content$primary_butt;
|
|
let _content$primary_butt2;
|
|
let _content$primary_butt3;
|
|
let _content$primary_butt4;
|
|
let _content$primary_butt5;
|
|
const { content, addonName, activeMultiSelect } = props;
|
|
const defaultValue =
|
|
(_content$checkbox = content.checkbox) === null ||
|
|
_content$checkbox === void 0
|
|
? void 0
|
|
: _content$checkbox.defaultValue;
|
|
const [isChecked, setIsChecked] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(defaultValue || false);
|
|
const buttonRef =
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().useRef(null);
|
|
const shouldFocusButton =
|
|
content === null || content === void 0
|
|
? void 0
|
|
: (_content$primary_butt = content.primary_button) === null ||
|
|
_content$primary_butt === void 0
|
|
? void 0
|
|
: _content$primary_butt.should_focus_button;
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
if (shouldFocusButton) {
|
|
let _buttonRef$current;
|
|
(_buttonRef$current = buttonRef.current) === null ||
|
|
_buttonRef$current === void 0
|
|
? void 0
|
|
: _buttonRef$current.focus();
|
|
}
|
|
}, [shouldFocusButton]);
|
|
if (
|
|
!content.primary_button &&
|
|
!content.secondary_button &&
|
|
!content.additional_button
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
// If we have a multi-select screen, we want to disable the primary button
|
|
// until the user has selected at least one item.
|
|
const isPrimaryDisabled = primaryDisabledValue =>
|
|
primaryDisabledValue === "hasActiveMultiSelect"
|
|
? !(
|
|
(activeMultiSelect === null || activeMultiSelect === void 0
|
|
? void 0
|
|
: activeMultiSelect.length) > 0
|
|
)
|
|
: primaryDisabledValue;
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `action-buttons ${
|
|
content.additional_button ? "additional-cta-container" : ""
|
|
}`,
|
|
flow:
|
|
(_content$additional_b = content.additional_button) === null ||
|
|
_content$additional_b === void 0
|
|
? void 0
|
|
: _content$additional_b.flow,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text:
|
|
(_content$primary_butt2 = content.primary_button) === null ||
|
|
_content$primary_butt2 === void 0
|
|
? void 0
|
|
: _content$primary_butt2.label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
ref: buttonRef,
|
|
className: `${
|
|
((_content$primary_butt3 = content.primary_button) === null ||
|
|
_content$primary_butt3 === void 0
|
|
? void 0
|
|
: _content$primary_butt3.style) ?? "primary"
|
|
}${
|
|
(_content$primary_butt4 = content.primary_button) !== null &&
|
|
_content$primary_butt4 !== void 0 &&
|
|
_content$primary_butt4.has_arrow_icon
|
|
? " arrow-icon"
|
|
: ""
|
|
}`,
|
|
// Whether or not the checkbox is checked determines which action
|
|
// should be handled. By setting value here, we indicate to
|
|
// this.handleAction() where in the content tree it should take
|
|
// the action to execute from.
|
|
value: isChecked ? "checkbox" : "primary_button",
|
|
disabled: isPrimaryDisabled(
|
|
(_content$primary_butt5 = content.primary_button) === null ||
|
|
_content$primary_butt5 === void 0
|
|
? void 0
|
|
: _content$primary_butt5.disabled
|
|
),
|
|
onClick: props.handleAction,
|
|
"data-l10n-args": addonName
|
|
? JSON.stringify({
|
|
"addon-name": addonName,
|
|
})
|
|
: "",
|
|
}
|
|
)
|
|
),
|
|
content.additional_button
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_AdditionalCTA__WEBPACK_IMPORTED_MODULE_11__.AdditionalCTA,
|
|
{
|
|
content,
|
|
handleAction: props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.checkbox
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "checkbox-container",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"input",
|
|
{
|
|
type: "checkbox",
|
|
id: "action-checkbox",
|
|
checked: isChecked,
|
|
onChange: () => {
|
|
setIsChecked(!isChecked);
|
|
},
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.checkbox.label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"label",
|
|
{
|
|
htmlFor: "action-checkbox",
|
|
}
|
|
)
|
|
)
|
|
)
|
|
: null,
|
|
content.secondary_button
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.SecondaryCTA,
|
|
{
|
|
content,
|
|
handleAction: props.handleAction,
|
|
}
|
|
)
|
|
: null
|
|
);
|
|
};
|
|
class ProtonScreen extends react__WEBPACK_IMPORTED_MODULE_0___default()
|
|
.PureComponent {
|
|
componentDidMount() {
|
|
this.mainContentHeader.focus();
|
|
}
|
|
|
|
getScreenClassName(
|
|
isFirstScreen,
|
|
isLastScreen,
|
|
includeNoodles,
|
|
isVideoOnboarding,
|
|
isAddonsPicker
|
|
) {
|
|
const screenClass = `screen-${this.props.order % 2 !== 0 ? 1 : 2}`;
|
|
if (isVideoOnboarding) {
|
|
return "with-video";
|
|
}
|
|
if (isAddonsPicker) {
|
|
return "addons-picker";
|
|
}
|
|
return `${isFirstScreen ? `dialog-initial` : ``} ${
|
|
isLastScreen ? `dialog-last` : ``
|
|
} ${includeNoodles ? `with-noodles` : ``} ${screenClass}`;
|
|
}
|
|
|
|
renderTitle({ title, title_logo }) {
|
|
if (title_logo) {
|
|
const { alignment, ...rest } = title_logo;
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "inline-icon-container",
|
|
alignment: alignment ?? "center",
|
|
},
|
|
this.renderPicture({
|
|
...rest,
|
|
}),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: title,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"h1",
|
|
{
|
|
id: "mainContentHeader",
|
|
}
|
|
)
|
|
)
|
|
);
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: title,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"h1",
|
|
{
|
|
id: "mainContentHeader",
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
renderPicture({
|
|
imageURL = "chrome://branding/content/about-logo.svg",
|
|
darkModeImageURL,
|
|
reducedMotionImageURL,
|
|
darkModeReducedMotionImageURL,
|
|
alt = "",
|
|
width,
|
|
height,
|
|
marginBlock,
|
|
marginInline,
|
|
className = "logo-container",
|
|
}) {
|
|
function getLoadingStrategy() {
|
|
for (let url of [
|
|
imageURL,
|
|
darkModeImageURL,
|
|
reducedMotionImageURL,
|
|
darkModeReducedMotionImageURL,
|
|
]) {
|
|
if (
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.getLoadingStrategyFor(
|
|
url
|
|
) === "lazy"
|
|
) {
|
|
return "lazy";
|
|
}
|
|
}
|
|
return "eager";
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"picture",
|
|
{
|
|
className,
|
|
style: {
|
|
marginInline,
|
|
marginBlock,
|
|
},
|
|
},
|
|
darkModeReducedMotionImageURL
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"source",
|
|
{
|
|
srcSet: darkModeReducedMotionImageURL,
|
|
media:
|
|
"(prefers-color-scheme: dark) and (prefers-reduced-motion: reduce)",
|
|
}
|
|
)
|
|
: null,
|
|
darkModeImageURL
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"source",
|
|
{
|
|
srcSet: darkModeImageURL,
|
|
media: "(prefers-color-scheme: dark)",
|
|
}
|
|
)
|
|
: null,
|
|
reducedMotionImageURL
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"source",
|
|
{
|
|
srcSet: reducedMotionImageURL,
|
|
media: "(prefers-reduced-motion: reduce)",
|
|
}
|
|
)
|
|
: null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: alt,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "sr-only logo-alt",
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
className: "brand-logo",
|
|
style: {
|
|
height,
|
|
width,
|
|
},
|
|
src: imageURL,
|
|
alt: "",
|
|
loading: getLoadingStrategy(),
|
|
role: alt ? null : "presentation",
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
renderContentTiles() {
|
|
const { content } = this.props;
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().Fragment,
|
|
null,
|
|
content.tiles &&
|
|
content.tiles.type === "addons-picker" &&
|
|
content.tiles.data
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_AddonsPicker__WEBPACK_IMPORTED_MODULE_13__.AddonsPicker,
|
|
{
|
|
content,
|
|
message_id: this.props.messageId,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.tiles &&
|
|
content.tiles.type === "theme" &&
|
|
content.tiles.data
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_Themes__WEBPACK_IMPORTED_MODULE_5__.Themes,
|
|
{
|
|
content,
|
|
activeTheme: this.props.activeTheme,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.tiles &&
|
|
content.tiles.type === "mobile_downloads" &&
|
|
content.tiles.data
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MobileDownloads__WEBPACK_IMPORTED_MODULE_3__.MobileDownloads,
|
|
{
|
|
data: content.tiles.data,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.tiles &&
|
|
content.tiles.type === "multiselect" &&
|
|
content.tiles.data
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiSelect__WEBPACK_IMPORTED_MODULE_4__.MultiSelect,
|
|
{
|
|
content,
|
|
activeMultiSelect: this.props.activeMultiSelect,
|
|
setActiveMultiSelect: this.props.setActiveMultiSelect,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.tiles && content.tiles.type === "migration-wizard"
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__.EmbeddedMigrationWizard,
|
|
{
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null
|
|
);
|
|
}
|
|
|
|
renderNoodles() {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().Fragment,
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "noodle orange-L",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "noodle purple-C",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "noodle solid-L",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "noodle outline-L",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "noodle yellow-circle",
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
renderLanguageSwitcher() {
|
|
return this.props.content.languageSwitcher
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_LanguageSwitcher__WEBPACK_IMPORTED_MODULE_7__.LanguageSwitcher,
|
|
{
|
|
content: this.props.content,
|
|
handleAction: this.props.handleAction,
|
|
negotiatedLanguage: this.props.negotiatedLanguage,
|
|
langPackInstallPhase: this.props.langPackInstallPhase,
|
|
messageId: this.props.messageId,
|
|
}
|
|
)
|
|
: null;
|
|
}
|
|
|
|
renderDismissButton() {
|
|
const { size, marginBlock, marginInline, label } =
|
|
this.props.content.dismiss_button;
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: "dismiss-button",
|
|
onClick: this.props.handleAction,
|
|
value: "dismiss_button",
|
|
"data-l10n-id":
|
|
(label === null || label === void 0
|
|
? void 0
|
|
: label.string_id) || "spotlight-dialog-close-button",
|
|
"button-size": size,
|
|
style: {
|
|
marginBlock,
|
|
marginInline,
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
renderStepsIndicator() {
|
|
let _content$steps_indica;
|
|
const currentStep = (this.props.order ?? 0) + 1;
|
|
const previousStep = (this.props.previousOrder ?? -1) + 1;
|
|
const { content, totalNumberOfScreens: total } = this.props;
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
id: "steps",
|
|
className: `steps${content.progress_bar ? " progress-bar" : ""}`,
|
|
"data-l10n-id":
|
|
((_content$steps_indica = content.steps_indicator) === null ||
|
|
_content$steps_indica === void 0
|
|
? void 0
|
|
: _content$steps_indica.string_id) ||
|
|
"onboarding-welcome-steps-indicator-label",
|
|
"data-l10n-args": JSON.stringify({
|
|
current: currentStep,
|
|
total: total ?? 0,
|
|
}),
|
|
"data-l10n-attrs": "aria-label",
|
|
role: "progressbar",
|
|
"aria-valuenow": currentStep,
|
|
"aria-valuemin": 1,
|
|
"aria-valuemax": total,
|
|
},
|
|
content.progress_bar
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.ProgressBar,
|
|
{
|
|
step: currentStep,
|
|
previousStep,
|
|
totalNumberOfScreens: total,
|
|
}
|
|
)
|
|
: /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.StepsIndicator,
|
|
{
|
|
order: this.props.order,
|
|
totalNumberOfScreens: total,
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
renderSecondarySection(content) {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `section-secondary ${
|
|
content.hide_secondary_section
|
|
? "with-secondary-section-hidden"
|
|
: ""
|
|
}`,
|
|
style: content.background
|
|
? {
|
|
background: content.background,
|
|
"--mr-secondary-background-position-y":
|
|
content.split_narrow_bkg_position,
|
|
}
|
|
: {},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.image_alt_text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "sr-only image-alt",
|
|
role: "img",
|
|
}
|
|
)
|
|
),
|
|
content.hero_image
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_HeroImage__WEBPACK_IMPORTED_MODULE_9__.HeroImage,
|
|
{
|
|
url: content.hero_image.url,
|
|
}
|
|
)
|
|
: /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().Fragment,
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "message-text",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "spacer-top",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.hero_text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"h1",
|
|
null
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "spacer-bottom",
|
|
}
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
renderOrderedContent(content) {
|
|
const elements = [];
|
|
for (const item of content) {
|
|
switch (item.type) {
|
|
case "text":
|
|
elements.push(
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_LinkParagraph__WEBPACK_IMPORTED_MODULE_14__.LinkParagraph,
|
|
{
|
|
text_content: item,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
);
|
|
break;
|
|
case "image":
|
|
elements.push(
|
|
this.renderPicture({
|
|
imageURL: item.url,
|
|
darkModeImageURL: item.darkModeImageURL,
|
|
height: item.height,
|
|
width: item.width,
|
|
alt: item.alt_text,
|
|
marginInline: item.marginInline,
|
|
className: "inline-image",
|
|
})
|
|
);
|
|
}
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
react__WEBPACK_IMPORTED_MODULE_0___default().Fragment,
|
|
null,
|
|
elements
|
|
);
|
|
}
|
|
|
|
render() {
|
|
let _content$tiles;
|
|
let _content$tiles2;
|
|
let _this$props$appAndSys;
|
|
let _this$props$messageId;
|
|
const {
|
|
autoAdvance,
|
|
content,
|
|
isRtamo,
|
|
isTheme,
|
|
isFirstScreen,
|
|
isLastScreen,
|
|
isSingleScreen,
|
|
forceHideStepsIndicator,
|
|
ariaRole,
|
|
aboveButtonStepsIndicator,
|
|
} = this.props;
|
|
const includeNoodles = content.has_noodles;
|
|
// The default screen position is "center"
|
|
const isCenterPosition =
|
|
content.position === "center" || !content.position;
|
|
const hideStepsIndicator =
|
|
autoAdvance ||
|
|
(content === null || content === void 0
|
|
? void 0
|
|
: content.video_container) ||
|
|
isSingleScreen ||
|
|
forceHideStepsIndicator;
|
|
const textColorClass = content.text_color
|
|
? `${content.text_color}-text`
|
|
: "";
|
|
// Assign proton screen style 'screen-1' or 'screen-2' to centered screens
|
|
// by checking if screen order is even or odd.
|
|
const screenClassName = isCenterPosition
|
|
? this.getScreenClassName(
|
|
isFirstScreen,
|
|
isLastScreen,
|
|
includeNoodles,
|
|
content === null || content === void 0
|
|
? void 0
|
|
: content.video_container,
|
|
((_content$tiles = content.tiles) === null ||
|
|
_content$tiles === void 0
|
|
? void 0
|
|
: _content$tiles.type) === "addons-picker"
|
|
)
|
|
: "";
|
|
const isEmbeddedMigration =
|
|
((_content$tiles2 = content.tiles) === null ||
|
|
_content$tiles2 === void 0
|
|
? void 0
|
|
: _content$tiles2.type) === "migration-wizard";
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"main",
|
|
{
|
|
className: `screen ${this.props.id || ""}
|
|
${screenClassName} ${textColorClass}`,
|
|
role: ariaRole ?? "alertdialog",
|
|
layout: content.layout,
|
|
pos: content.position || "center",
|
|
tabIndex: "-1",
|
|
"aria-labelledby": "mainContentHeader",
|
|
ref: input => {
|
|
this.mainContentHeader = input;
|
|
},
|
|
},
|
|
isCenterPosition ? null : this.renderSecondarySection(content),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `section-main ${
|
|
isEmbeddedMigration ? "embedded-migration" : ""
|
|
}`,
|
|
"hide-secondary-section": content.hide_secondary_section
|
|
? String(content.hide_secondary_section)
|
|
: null,
|
|
role: "document",
|
|
},
|
|
content.secondary_button_top
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.SecondaryCTA,
|
|
{
|
|
content,
|
|
handleAction: this.props.handleAction,
|
|
position: "top",
|
|
}
|
|
)
|
|
: null,
|
|
includeNoodles ? this.renderNoodles() : null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `main-content ${
|
|
hideStepsIndicator ? "no-steps" : ""
|
|
}`,
|
|
style: {
|
|
background:
|
|
content.background && isCenterPosition
|
|
? content.background
|
|
: null,
|
|
width:
|
|
content.width && content.position !== "split"
|
|
? content.width
|
|
: null,
|
|
},
|
|
},
|
|
content.logo ? this.renderPicture(content.logo) : null,
|
|
isRtamo
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "rtamo-icon",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
className: `${
|
|
isTheme ? "rtamo-theme-icon" : "brand-logo"
|
|
}`,
|
|
src: this.props.iconURL,
|
|
loading:
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.getLoadingStrategyFor(
|
|
this.props.iconURL
|
|
),
|
|
alt: "",
|
|
role: "presentation",
|
|
}
|
|
)
|
|
)
|
|
: null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "main-content-inner",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `welcome-text ${content.title_style || ""}`,
|
|
},
|
|
content.title ? this.renderTitle(content) : null,
|
|
content.subtitle
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.subtitle,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"h2",
|
|
{
|
|
"data-l10n-args": JSON.stringify({
|
|
"addon-name": this.props.addonName,
|
|
...((_this$props$appAndSys =
|
|
this.props.appAndSystemLocaleInfo) === null ||
|
|
_this$props$appAndSys === void 0
|
|
? void 0
|
|
: _this$props$appAndSys.displayNames),
|
|
}),
|
|
"aria-flowto":
|
|
(_this$props$messageId =
|
|
this.props.messageId) !== null &&
|
|
_this$props$messageId !== void 0 &&
|
|
_this$props$messageId.includes("FEATURE_TOUR")
|
|
? "steps"
|
|
: "",
|
|
}
|
|
)
|
|
)
|
|
: null,
|
|
content.cta_paragraph
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_CTAParagraph__WEBPACK_IMPORTED_MODULE_8__.CTAParagraph,
|
|
{
|
|
content: content.cta_paragraph,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null
|
|
),
|
|
content.video_container
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_OnboardingVideo__WEBPACK_IMPORTED_MODULE_10__.OnboardingVideo,
|
|
{
|
|
content: content.video_container,
|
|
handleAction: this.props.handleAction,
|
|
}
|
|
)
|
|
: null,
|
|
content.above_button_content
|
|
? this.renderOrderedContent(content.above_button_content)
|
|
: null,
|
|
this.renderContentTiles(),
|
|
this.renderLanguageSwitcher(),
|
|
!hideStepsIndicator && aboveButtonStepsIndicator
|
|
? this.renderStepsIndicator()
|
|
: null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
ProtonScreenActionButtons,
|
|
{
|
|
content,
|
|
addonName: this.props.addonName,
|
|
handleAction: this.props.handleAction,
|
|
activeMultiSelect: this.props.activeMultiSelect,
|
|
}
|
|
)
|
|
),
|
|
!hideStepsIndicator && !aboveButtonStepsIndicator
|
|
? this.renderStepsIndicator()
|
|
: null
|
|
),
|
|
content.dismiss_button ? this.renderDismissButton() : null
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.info_text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"span",
|
|
{
|
|
className: "info-text",
|
|
}
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/***/
|
|
},
|
|
/* 7 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ MarketplaceButtons: () =>
|
|
/* binding */ MarketplaceButtons,
|
|
/* harmony export */ MobileDownloads: () =>
|
|
/* binding */ MobileDownloads,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(3);
|
|
/* 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 MarketplaceButtons = props => {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"ul",
|
|
{
|
|
className: "mobile-download-buttons",
|
|
},
|
|
props.buttons.includes("ios")
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"li",
|
|
{
|
|
className: "ios",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
"data-l10n-id": "spotlight-ios-marketplace-button",
|
|
value: "ios",
|
|
onClick: props.handleAction,
|
|
}
|
|
)
|
|
)
|
|
: null,
|
|
props.buttons.includes("android")
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"li",
|
|
{
|
|
className: "android",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
"data-l10n-id": "spotlight-android-marketplace-button",
|
|
value: "android",
|
|
onClick: props.handleAction,
|
|
}
|
|
)
|
|
)
|
|
: null
|
|
);
|
|
};
|
|
const MobileDownloads = props => {
|
|
const { QR_code: QRCode } = props.data;
|
|
const showEmailLink =
|
|
props.data.email && window.AWSendToDeviceEmailsSupported();
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "mobile-downloads",
|
|
},
|
|
QRCode
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
"data-l10n-id": QRCode.alt_text.string_id
|
|
? QRCode.alt_text.string_id
|
|
: null,
|
|
className: "qr-code-image",
|
|
alt:
|
|
typeof QRCode.alt_text === "string" ? QRCode.alt_text : "",
|
|
src: QRCode.image_url,
|
|
loading:
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.getLoadingStrategyFor(
|
|
QRCode.image_url
|
|
),
|
|
}
|
|
)
|
|
: null,
|
|
showEmailLink
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: props.data.email.link_text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: "email-link",
|
|
value: "email_link",
|
|
onClick: props.handleAction,
|
|
}
|
|
)
|
|
)
|
|
)
|
|
: null,
|
|
props.data.marketplace_buttons
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
MarketplaceButtons,
|
|
{
|
|
buttons: props.data.marketplace_buttons,
|
|
handleAction: props.handleAction,
|
|
}
|
|
)
|
|
: null
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 8 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ MultiSelect: () => /* binding */ MultiSelect,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* 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 MULTI_SELECT_STYLES = [
|
|
..._MSLocalized__WEBPACK_IMPORTED_MODULE_1__.CONFIGURABLE_STYLES,
|
|
"flexDirection",
|
|
"flexWrap",
|
|
"flexFlow",
|
|
"flexGrow",
|
|
"flexShrink",
|
|
"justifyContent",
|
|
"alignItems",
|
|
"gap",
|
|
];
|
|
const MULTI_SELECT_ICON_STYLES = [
|
|
..._MSLocalized__WEBPACK_IMPORTED_MODULE_1__.CONFIGURABLE_STYLES,
|
|
"width",
|
|
"height",
|
|
"background",
|
|
"backgroundColor",
|
|
"backgroundImage",
|
|
"backgroundSize",
|
|
"backgroundPosition",
|
|
"backgroundRepeat",
|
|
"backgroundOrigin",
|
|
"backgroundClip",
|
|
"border",
|
|
"borderRadius",
|
|
"appearance",
|
|
"fill",
|
|
"stroke",
|
|
"outline",
|
|
"outlineOffset",
|
|
"boxShadow",
|
|
];
|
|
function getValidStyle(style, validStyles, allowVars) {
|
|
if (!style) {
|
|
return null;
|
|
}
|
|
return Object.keys(style)
|
|
.filter(
|
|
key =>
|
|
validStyles.includes(key) || (allowVars && key.startsWith("--"))
|
|
)
|
|
.reduce((obj, key) => {
|
|
obj[key] = style[key];
|
|
return obj;
|
|
}, {});
|
|
}
|
|
const MultiSelect = ({
|
|
content,
|
|
activeMultiSelect,
|
|
setActiveMultiSelect,
|
|
}) => {
|
|
const { data } = content.tiles;
|
|
const refs = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)({});
|
|
const handleChange = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
|
|
const newActiveMultiSelect = [];
|
|
Object.keys(refs.current).forEach(key => {
|
|
let _refs$current$key;
|
|
if (
|
|
(_refs$current$key = refs.current[key]) !== null &&
|
|
_refs$current$key !== void 0 &&
|
|
_refs$current$key.checked
|
|
) {
|
|
newActiveMultiSelect.push(key);
|
|
}
|
|
});
|
|
setActiveMultiSelect(newActiveMultiSelect);
|
|
}, [setActiveMultiSelect]);
|
|
const containerStyle = (0, react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(
|
|
() => getValidStyle(content.tiles.style, MULTI_SELECT_STYLES, true),
|
|
[content.tiles.style]
|
|
);
|
|
|
|
// When screen renders for first time, update state
|
|
// with checkbox ids that has defaultvalue true
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
if (!activeMultiSelect) {
|
|
let newActiveMultiSelect = [];
|
|
data.forEach(({ id, defaultValue }) => {
|
|
if (defaultValue && id) {
|
|
newActiveMultiSelect.push(id);
|
|
}
|
|
});
|
|
setActiveMultiSelect(newActiveMultiSelect);
|
|
}
|
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "multi-select-container",
|
|
style: containerStyle,
|
|
},
|
|
data.map(({ id, label, icon, type = "checkbox", group, style }) =>
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
key: id + label,
|
|
className: "checkbox-container multi-select-item",
|
|
style: getValidStyle(style, MULTI_SELECT_STYLES),
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"input",
|
|
{
|
|
type, // checkbox or radio
|
|
id,
|
|
value: id,
|
|
name: group,
|
|
checked:
|
|
activeMultiSelect === null || activeMultiSelect === void 0
|
|
? void 0
|
|
: activeMultiSelect.includes(id),
|
|
style: getValidStyle(
|
|
icon === null || icon === void 0 ? void 0 : icon.style,
|
|
MULTI_SELECT_ICON_STYLES
|
|
),
|
|
onChange: handleChange,
|
|
ref: el => (refs.current[id] = el),
|
|
}
|
|
),
|
|
label
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"label",
|
|
{
|
|
htmlFor: id,
|
|
}
|
|
)
|
|
)
|
|
: null
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 9 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ Themes: () => /* binding */ Themes,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* 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 Themes = props => {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "tiles-theme-container",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"fieldset",
|
|
{
|
|
className: "tiles-theme-section",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: props.content.subtitle,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"legend",
|
|
{
|
|
className: "sr-only",
|
|
}
|
|
)
|
|
),
|
|
props.content.tiles.data.map(
|
|
({ theme, label, tooltip, description }) =>
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
key: theme + label,
|
|
text: typeof tooltip === "object" ? tooltip : {},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"label",
|
|
{
|
|
className: "theme",
|
|
title: theme + label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text:
|
|
typeof description === "object" ? description : {},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"input",
|
|
{
|
|
type: "radio",
|
|
value: theme,
|
|
name: "theme",
|
|
checked: theme === props.activeTheme,
|
|
className: "sr-only input",
|
|
onClick: props.handleAction,
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: `icon ${
|
|
theme === props.activeTheme ? " selected" : ""
|
|
} ${theme}`,
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "text",
|
|
}
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 10 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ useLanguageSwitcher: () =>
|
|
/* binding */ useLanguageSwitcher,
|
|
/* harmony export */ LanguageSwitcher: () =>
|
|
/* binding */ LanguageSwitcher,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(3);
|
|
/* 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/. */
|
|
|
|
/**
|
|
* The language switcher implements a hook that should be placed at a higher level
|
|
* than the actual language switcher component, as it needs to preemptively fetch
|
|
* and install langpacks for the user if there is a language mismatch screen.
|
|
*/
|
|
function useLanguageSwitcher(
|
|
appAndSystemLocaleInfo,
|
|
screens,
|
|
screenIndex,
|
|
setScreenIndex
|
|
) {
|
|
const languageMismatchScreenIndex = screens.findIndex(
|
|
({ id }) => id === "AW_LANGUAGE_MISMATCH"
|
|
);
|
|
const screen = screens[languageMismatchScreenIndex];
|
|
|
|
// Ensure fluent messages have the negotiatedLanguage args set, as they are rendered
|
|
// before the negotiatedLanguage is known. If the arg isn't present then Firefox will
|
|
// crash in development mode.
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
let _screen$content;
|
|
if (
|
|
screen !== null &&
|
|
screen !== void 0 &&
|
|
(_screen$content = screen.content) !== null &&
|
|
_screen$content !== void 0 &&
|
|
_screen$content.languageSwitcher
|
|
) {
|
|
for (const text of Object.values(screen.content.languageSwitcher)) {
|
|
if (
|
|
text !== null &&
|
|
text !== void 0 &&
|
|
text.args &&
|
|
text.args.negotiatedLanguage === undefined
|
|
) {
|
|
text.args.negotiatedLanguage = "";
|
|
}
|
|
}
|
|
}
|
|
}, [screen]);
|
|
|
|
// If there is a mismatch, then Firefox can negotiate a better langpack to offer
|
|
// the user.
|
|
const [negotiatedLanguage, setNegotiatedLanguage] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(
|
|
function getNegotiatedLanguage() {
|
|
if (!appAndSystemLocaleInfo) {
|
|
return;
|
|
}
|
|
if (appAndSystemLocaleInfo.matchType !== "language-mismatch") {
|
|
// There is no language mismatch, so there is no need to negotiate a langpack.
|
|
return;
|
|
}
|
|
(async () => {
|
|
const { langPack, langPackDisplayName } =
|
|
await window.AWNegotiateLangPackForLanguageMismatch(
|
|
appAndSystemLocaleInfo
|
|
);
|
|
if (langPack) {
|
|
setNegotiatedLanguage({
|
|
langPackDisplayName,
|
|
appDisplayName:
|
|
appAndSystemLocaleInfo.displayNames.appLanguage,
|
|
langPack,
|
|
requestSystemLocales: [
|
|
langPack.target_locale,
|
|
appAndSystemLocaleInfo.appLocaleRaw,
|
|
],
|
|
originalAppLocales: [appAndSystemLocaleInfo.appLocaleRaw],
|
|
});
|
|
} else {
|
|
setNegotiatedLanguage({
|
|
langPackDisplayName: null,
|
|
appDisplayName: null,
|
|
langPack: null,
|
|
requestSystemLocales: null,
|
|
});
|
|
}
|
|
})();
|
|
},
|
|
[appAndSystemLocaleInfo]
|
|
);
|
|
|
|
/**
|
|
* @type {
|
|
* "before-installation"
|
|
* | "installing"
|
|
* | "installed"
|
|
* | "installation-error"
|
|
* | "none-available"
|
|
* }
|
|
*/
|
|
const [langPackInstallPhase, setLangPackInstallPhase] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)("before-installation");
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(
|
|
function ensureLangPackInstalled() {
|
|
if (!negotiatedLanguage) {
|
|
// There are no negotiated languages to download yet.
|
|
return;
|
|
}
|
|
setLangPackInstallPhase("installing");
|
|
window
|
|
.AWEnsureLangPackInstalled(
|
|
negotiatedLanguage,
|
|
screen === null || screen === void 0 ? void 0 : screen.content
|
|
)
|
|
.then(
|
|
content => {
|
|
// Update screen content with strings that might have changed.
|
|
screen.content = content;
|
|
setLangPackInstallPhase("installed");
|
|
},
|
|
error => {
|
|
console.error(error);
|
|
setLangPackInstallPhase("installation-error");
|
|
}
|
|
);
|
|
},
|
|
[negotiatedLanguage, screen]
|
|
);
|
|
const [languageFilteredScreens, setLanguageFilteredScreens] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(screens);
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(
|
|
function filterScreen() {
|
|
// Remove the language screen if it exists (already removed for no live
|
|
// reload) and we either don't-need-to or can't switch.
|
|
if (
|
|
screen &&
|
|
((appAndSystemLocaleInfo === null ||
|
|
appAndSystemLocaleInfo === void 0
|
|
? void 0
|
|
: appAndSystemLocaleInfo.matchType) !== "language-mismatch" ||
|
|
(negotiatedLanguage === null || negotiatedLanguage === void 0
|
|
? void 0
|
|
: negotiatedLanguage.langPack) === null)
|
|
) {
|
|
if (screenIndex > languageMismatchScreenIndex) {
|
|
setScreenIndex(screenIndex - 1);
|
|
}
|
|
setLanguageFilteredScreens(
|
|
screens.filter(s => s.id !== "AW_LANGUAGE_MISMATCH")
|
|
);
|
|
} else {
|
|
setLanguageFilteredScreens(screens);
|
|
}
|
|
},
|
|
[
|
|
appAndSystemLocaleInfo === null || appAndSystemLocaleInfo === void 0
|
|
? void 0
|
|
: appAndSystemLocaleInfo.matchType,
|
|
languageMismatchScreenIndex,
|
|
negotiatedLanguage,
|
|
screen,
|
|
screenIndex,
|
|
screens,
|
|
setScreenIndex,
|
|
]
|
|
);
|
|
return {
|
|
negotiatedLanguage,
|
|
langPackInstallPhase,
|
|
languageFilteredScreens,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The language switcher is a separate component as it needs to perform some asynchronous
|
|
* network actions such as retrieving the list of langpacks available, and downloading
|
|
* a new langpack. On a fast connection, this won't be noticeable, but on slow or unreliable
|
|
* internet this may fail for a user.
|
|
*/
|
|
function LanguageSwitcher(props) {
|
|
const {
|
|
content,
|
|
handleAction,
|
|
negotiatedLanguage,
|
|
langPackInstallPhase,
|
|
messageId,
|
|
} = props;
|
|
const [isAwaitingLangpack, setIsAwaitingLangpack] = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
|
|
// Determine the status of the langpack installation.
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
if (isAwaitingLangpack && langPackInstallPhase !== "installing") {
|
|
window.AWSetRequestedLocales(
|
|
negotiatedLanguage.requestSystemLocales
|
|
);
|
|
requestAnimationFrame(() => {
|
|
handleAction(
|
|
// Simulate the click event.
|
|
{
|
|
currentTarget: {
|
|
value: "download_complete",
|
|
},
|
|
}
|
|
);
|
|
});
|
|
}
|
|
}, [
|
|
handleAction,
|
|
isAwaitingLangpack,
|
|
langPackInstallPhase,
|
|
negotiatedLanguage === null || negotiatedLanguage === void 0
|
|
? void 0
|
|
: negotiatedLanguage.requestSystemLocales,
|
|
]);
|
|
let showWaitingScreen = false;
|
|
let showPreloadingScreen = false;
|
|
let showReadyScreen = false;
|
|
if (isAwaitingLangpack && langPackInstallPhase !== "installed") {
|
|
showWaitingScreen = true;
|
|
} else if (langPackInstallPhase === "before-installation") {
|
|
showPreloadingScreen = true;
|
|
} else {
|
|
showReadyScreen = true;
|
|
}
|
|
|
|
// Use {display: "none"} rather than if statements to prevent layout thrashing with
|
|
// the localized text elements rendering as blank, then filling in the text.
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "action-buttons language-switcher-container",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
style: {
|
|
display: showPreloadingScreen ? "block" : "none",
|
|
},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: "primary",
|
|
value: "primary_button",
|
|
disabled: true,
|
|
type: "button",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
className: "language-loader",
|
|
src: "chrome://browser/skin/tabbrowser/tab-connecting.png",
|
|
alt: "",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.waiting,
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "secondary-cta",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.skip,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
value: "decline_waiting",
|
|
type: "button",
|
|
className: "secondary text-link arrow-icon",
|
|
onClick: handleAction,
|
|
}
|
|
)
|
|
)
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
style: {
|
|
display: showWaitingScreen ? "block" : "none",
|
|
},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: "primary",
|
|
value: "primary_button",
|
|
disabled: true,
|
|
type: "button",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
className: "language-loader",
|
|
src: "chrome://browser/skin/tabbrowser/tab-connecting.png",
|
|
alt: "",
|
|
}
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.downloading,
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "secondary-cta",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.cancel,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
type: "button",
|
|
className: "secondary text-link",
|
|
onClick: () => {
|
|
setIsAwaitingLangpack(false);
|
|
handleAction({
|
|
currentTarget: {
|
|
value: "cancel_waiting",
|
|
},
|
|
});
|
|
},
|
|
}
|
|
)
|
|
)
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
style: {
|
|
display: showReadyScreen ? "block" : "none",
|
|
},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: "primary",
|
|
value: "primary_button",
|
|
onClick: () => {
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(
|
|
messageId,
|
|
"download_langpack"
|
|
);
|
|
setIsAwaitingLangpack(true);
|
|
},
|
|
},
|
|
content.languageSwitcher.switch
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.switch,
|
|
}
|
|
) // This is the localized name from the Intl.DisplayNames API.
|
|
: negotiatedLanguage === null || negotiatedLanguage === void 0
|
|
? void 0
|
|
: negotiatedLanguage.langPackDisplayName
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
type: "button",
|
|
className: "primary",
|
|
value: "decline",
|
|
onClick: event => {
|
|
window.AWSetRequestedLocales(
|
|
negotiatedLanguage.originalAppLocales
|
|
);
|
|
handleAction(event);
|
|
},
|
|
},
|
|
content.languageSwitcher.continue
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.languageSwitcher.continue,
|
|
}
|
|
) // This is the localized name from the Intl.DisplayNames API.
|
|
: negotiatedLanguage === null || negotiatedLanguage === void 0
|
|
? void 0
|
|
: negotiatedLanguage.appDisplayName
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
/***/
|
|
},
|
|
/* 11 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ CTAParagraph: () => /* binding */ CTAParagraph,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* 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 CTAParagraph = props => {
|
|
const { content, handleAction } = props;
|
|
if (!(content !== null && content !== void 0 && content.text)) {
|
|
return null;
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"h2",
|
|
{
|
|
className: "cta-paragraph",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: content.text,
|
|
},
|
|
content.text.string_name && typeof handleAction === "function"
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"span",
|
|
{
|
|
"data-l10n-id": content.text.string_id,
|
|
onClick: handleAction,
|
|
onKeyUp: event =>
|
|
["Enter", " "].includes(event.key)
|
|
? handleAction(event)
|
|
: null,
|
|
value: "cta_paragraph",
|
|
role: "button",
|
|
tabIndex: "0",
|
|
},
|
|
" ",
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"a",
|
|
{
|
|
role: "button",
|
|
tabIndex: "0",
|
|
"data-l10n-name": content.text.string_name,
|
|
},
|
|
" "
|
|
)
|
|
)
|
|
: null
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 12 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ HeroImage: () => /* binding */ HeroImage,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(3);
|
|
/* 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 HeroImage = props => {
|
|
const { height, url, alt } = props;
|
|
if (!url) {
|
|
return null;
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "hero-image",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
style: height
|
|
? {
|
|
height,
|
|
}
|
|
: null,
|
|
src: url,
|
|
loading:
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.getLoadingStrategyFor(
|
|
url
|
|
),
|
|
alt: alt || "",
|
|
role: alt ? null : "presentation",
|
|
}
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 13 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ OnboardingVideo: () =>
|
|
/* binding */ OnboardingVideo,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* 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 OnboardingVideo = props => {
|
|
const vidUrl = props.content.video_url;
|
|
const autoplay = props.content.autoPlay;
|
|
const handleVideoAction = event => {
|
|
props.handleAction({
|
|
currentTarget: {
|
|
value: event,
|
|
},
|
|
});
|
|
};
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
null,
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"video",
|
|
{
|
|
// eslint-disable-line jsx-a11y/media-has-caption
|
|
controls: true,
|
|
autoPlay: autoplay,
|
|
src: vidUrl,
|
|
width: "604px",
|
|
height: "340px",
|
|
onPlay: () => handleVideoAction("video_start"),
|
|
onEnded: () => handleVideoAction("video_end"),
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"source",
|
|
{
|
|
src: vidUrl,
|
|
}
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 14 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ AdditionalCTA: () => /* binding */ AdditionalCTA,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* 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 AdditionalCTA = ({ content, handleAction }) => {
|
|
let _content$additional_b;
|
|
let _content$additional_b4;
|
|
let _content$additional_b5;
|
|
let buttonStyle = "";
|
|
if (
|
|
!(
|
|
(_content$additional_b = content.additional_button) !== null &&
|
|
_content$additional_b !== void 0 &&
|
|
_content$additional_b.style
|
|
)
|
|
) {
|
|
buttonStyle = "primary";
|
|
} else {
|
|
let _content$additional_b2;
|
|
let _content$additional_b3;
|
|
buttonStyle =
|
|
((_content$additional_b2 = content.additional_button) === null ||
|
|
_content$additional_b2 === void 0
|
|
? void 0
|
|
: _content$additional_b2.style) === "link"
|
|
? "cta-link"
|
|
: (_content$additional_b3 = content.additional_button) === null ||
|
|
_content$additional_b3 === void 0
|
|
? void 0
|
|
: _content$additional_b3.style;
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text:
|
|
(_content$additional_b4 = content.additional_button) === null ||
|
|
_content$additional_b4 === void 0
|
|
? void 0
|
|
: _content$additional_b4.label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
className: `${buttonStyle} additional-cta`,
|
|
onClick: handleAction,
|
|
value: "additional_button",
|
|
disabled:
|
|
((_content$additional_b5 = content.additional_button) ===
|
|
null || _content$additional_b5 === void 0
|
|
? void 0
|
|
: _content$additional_b5.disabled) === true,
|
|
}
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 15 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ EmbeddedMigrationWizard: () =>
|
|
/* binding */ EmbeddedMigrationWizard,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* 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 EmbeddedMigrationWizard = ({ handleAction }) => {
|
|
const ref = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
|
|
(0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
const handleBeginMigration = () => {
|
|
handleAction({
|
|
currentTarget: {
|
|
value: "migrate_start",
|
|
},
|
|
source: "primary_button",
|
|
});
|
|
};
|
|
const handleClose = () => {
|
|
handleAction({
|
|
currentTarget: {
|
|
value: "migrate_close",
|
|
},
|
|
});
|
|
};
|
|
const { current } = ref;
|
|
current === null || current === void 0
|
|
? void 0
|
|
: current.addEventListener(
|
|
"MigrationWizard:BeginMigration",
|
|
handleBeginMigration
|
|
);
|
|
current === null || current === void 0
|
|
? void 0
|
|
: current.addEventListener("MigrationWizard:Close", handleClose);
|
|
return () => {
|
|
current === null || current === void 0
|
|
? void 0
|
|
: current.removeEventListener(
|
|
"MigrationWizard:BeginMigration",
|
|
handleBeginMigration
|
|
);
|
|
current === null || current === void 0
|
|
? void 0
|
|
: current.removeEventListener(
|
|
"MigrationWizard:Close",
|
|
handleClose
|
|
);
|
|
};
|
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"migration-wizard",
|
|
{
|
|
"force-show-import-all": "false",
|
|
"auto-request-state": "",
|
|
ref,
|
|
}
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 16 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ AddonsPicker: () => /* binding */ AddonsPicker,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(3);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(5);
|
|
/* 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 AddonsPicker = props => {
|
|
const { content } = props;
|
|
if (!content) {
|
|
return null;
|
|
}
|
|
function handleAction(event) {
|
|
const { message_id } = props;
|
|
let { action, source_id } =
|
|
content.tiles.data[event.currentTarget.value];
|
|
let { type, data } = action;
|
|
if (type === "INSTALL_ADDON_FROM_URL") {
|
|
if (!data) {
|
|
return;
|
|
}
|
|
}
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.handleUserAction(
|
|
{
|
|
type,
|
|
data,
|
|
}
|
|
);
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.sendActionTelemetry(
|
|
message_id,
|
|
source_id
|
|
);
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "addons-picker-container",
|
|
},
|
|
content.tiles.data.map(
|
|
({ id, install_label, name, type, description, icon }, index) =>
|
|
name
|
|
? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
key: id,
|
|
className: "addon-container",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "rtamo-icon",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"img",
|
|
{
|
|
className: `${
|
|
type === "theme" ? "rtamo-theme-icon" : "brand-logo"
|
|
}`,
|
|
src: icon,
|
|
role: "presentation",
|
|
alt: "",
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "addon-details",
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_2__.Localized,
|
|
{
|
|
text: name,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "addon-title",
|
|
}
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_2__.Localized,
|
|
{
|
|
text: description,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "addon-description",
|
|
}
|
|
)
|
|
)
|
|
),
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_2__.Localized,
|
|
{
|
|
text: install_label,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"button",
|
|
{
|
|
id: name,
|
|
value: index,
|
|
onClick: handleAction,
|
|
className: "primary",
|
|
}
|
|
)
|
|
)
|
|
)
|
|
: null
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 17 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ LinkParagraph: () => /* binding */ LinkParagraph,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(5);
|
|
/* 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 LinkParagraph = props => {
|
|
let _text_content$link_ke;
|
|
const { text_content, handleAction } = props;
|
|
const handleParagraphAction = (0,
|
|
react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(
|
|
event => {
|
|
if (event.target.closest("a")) {
|
|
handleAction({
|
|
...event,
|
|
currentTarget: event.target,
|
|
});
|
|
}
|
|
},
|
|
[handleAction]
|
|
);
|
|
const onKeyPress = (0, react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(
|
|
event => {
|
|
if (event.key === "Enter" && !event.repeat) {
|
|
handleParagraphAction(event);
|
|
}
|
|
},
|
|
[handleParagraphAction]
|
|
);
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized,
|
|
{
|
|
text: text_content.text,
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"p",
|
|
{
|
|
className:
|
|
text_content.font_styles === "legal"
|
|
? "legal-paragraph"
|
|
: "link-paragraph",
|
|
onClick: handleParagraphAction,
|
|
value: "link_paragraph",
|
|
onKeyPress,
|
|
},
|
|
(_text_content$link_ke = text_content.link_keys) === null ||
|
|
_text_content$link_ke === void 0
|
|
? void 0
|
|
: _text_content$link_ke.map(link =>
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"a",
|
|
{
|
|
key: link,
|
|
value: link,
|
|
role: "link",
|
|
className: "text-link",
|
|
"data-l10n-name": link,
|
|
// must pass in tabIndex when no href is provided
|
|
tabIndex: "0",
|
|
},
|
|
" "
|
|
)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
/***/
|
|
},
|
|
/* 18 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ BASE_PARAMS: () => /* binding */ BASE_PARAMS,
|
|
/* harmony export */ addUtmParams: () => /* binding */ addUtmParams,
|
|
/* harmony export */
|
|
});
|
|
/* 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/. */
|
|
|
|
/**
|
|
* BASE_PARAMS keys/values can be modified from outside this file
|
|
*/
|
|
const BASE_PARAMS = {
|
|
utm_source: "activity-stream",
|
|
utm_campaign: "firstrun",
|
|
utm_medium: "referral",
|
|
};
|
|
|
|
/**
|
|
* Takes in a url as a string or URL object and returns a URL object with the
|
|
* utm_* parameters added to it. If a URL object is passed in, the paraemeters
|
|
* are added to it (the return value can be ignored in that case as it's the
|
|
* same object).
|
|
*/
|
|
function addUtmParams(url, utmTerm) {
|
|
let returnUrl = url;
|
|
if (typeof returnUrl === "string") {
|
|
returnUrl = new URL(url);
|
|
}
|
|
for (let [key, value] of Object.entries(BASE_PARAMS)) {
|
|
if (!returnUrl.searchParams.has(key)) {
|
|
returnUrl.searchParams.append(key, value);
|
|
}
|
|
}
|
|
returnUrl.searchParams.append("utm_term", utmTerm);
|
|
return returnUrl;
|
|
}
|
|
|
|
/***/
|
|
},
|
|
/* 19 */
|
|
/***/ (
|
|
__unused_webpack_module,
|
|
__webpack_exports__,
|
|
__webpack_require__
|
|
) => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ ReturnToAMO: () => /* binding */ ReturnToAMO,
|
|
/* harmony export */
|
|
});
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(3);
|
|
/* harmony import */ let _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(6);
|
|
/* harmony import */ let _newtab_content_src_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__ =
|
|
__webpack_require__(18);
|
|
/* 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/. */
|
|
|
|
class ReturnToAMO extends react__WEBPACK_IMPORTED_MODULE_0___default()
|
|
.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.fetchFlowParams = this.fetchFlowParams.bind(this);
|
|
this.handleAction = this.handleAction.bind(this);
|
|
}
|
|
|
|
async fetchFlowParams() {
|
|
if (this.props.metricsFlowUri) {
|
|
this.setState({
|
|
flowParams:
|
|
await _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.fetchFlowParams(
|
|
this.props.metricsFlowUri
|
|
),
|
|
});
|
|
}
|
|
}
|
|
|
|
componentDidUpdate() {
|
|
this.fetchFlowParams();
|
|
}
|
|
|
|
handleAction(event) {
|
|
const { content, message_id, url, utm_term } = this.props;
|
|
let { action, source_id } = content[event.currentTarget.value];
|
|
let { type, data } = action;
|
|
if (type === "INSTALL_ADDON_FROM_URL") {
|
|
if (!data) {
|
|
return;
|
|
}
|
|
// Set add-on url in action.data.url property from JSON
|
|
data = {
|
|
...data,
|
|
url,
|
|
};
|
|
} else if (type === "SHOW_FIREFOX_ACCOUNTS") {
|
|
let params = {
|
|
..._newtab_content_src_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__.BASE_PARAMS,
|
|
utm_term: `aboutwelcome-${utm_term}-screen`,
|
|
};
|
|
if (action.addFlowParams && this.state.flowParams) {
|
|
params = {
|
|
...params,
|
|
...this.state.flowParams,
|
|
};
|
|
}
|
|
data = {
|
|
...data,
|
|
extraParams: params,
|
|
};
|
|
}
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.handleUserAction(
|
|
{
|
|
type,
|
|
data,
|
|
}
|
|
);
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.sendActionTelemetry(
|
|
message_id,
|
|
source_id
|
|
);
|
|
}
|
|
|
|
render() {
|
|
let _this$props$themeScre;
|
|
const { content, type } = this.props;
|
|
if (!content) {
|
|
return null;
|
|
}
|
|
if (
|
|
content !== null &&
|
|
content !== void 0 &&
|
|
content.primary_button.label
|
|
) {
|
|
content.primary_button.label.string_id = type.includes("theme")
|
|
? "return-to-amo-add-theme-label"
|
|
: "mr1-return-to-amo-add-extension-label";
|
|
}
|
|
|
|
// For experiments, when needed below rendered UI allows settings hard coded strings
|
|
// directly inside JSON except for ReturnToAMOText which picks add-on name and icon from fluent string
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
"div",
|
|
{
|
|
className: "outer-wrapper onboardingContainer proton",
|
|
style: content.backdrop
|
|
? {
|
|
background: content.backdrop,
|
|
}
|
|
: {},
|
|
},
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__.MultiStageProtonScreen,
|
|
{
|
|
content,
|
|
isRtamo: true,
|
|
isTheme: type.includes("theme"),
|
|
id: this.props.message_id,
|
|
order: this.props.order || 0,
|
|
totalNumberOfScreens: 1,
|
|
isSingleScreen: true,
|
|
autoAdvance: this.props.auto_advance,
|
|
iconURL: type.includes("theme")
|
|
? (_this$props$themeScre = this.props.themeScreenshots[0]) ===
|
|
null || _this$props$themeScre === void 0
|
|
? void 0
|
|
: _this$props$themeScre.url
|
|
: this.props.iconURL,
|
|
addonName: this.props.name,
|
|
handleAction: this.handleAction,
|
|
}
|
|
)
|
|
);
|
|
}
|
|
}
|
|
ReturnToAMO.defaultProps =
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_RTAMO_CONTENT;
|
|
|
|
/***/
|
|
},
|
|
/******/
|
|
];
|
|
/************************************************************************/
|
|
/******/ // The module cache
|
|
/******/ let __webpack_module_cache__ = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/ // Check if module is in cache
|
|
/******/ let cachedModule = __webpack_module_cache__[moduleId];
|
|
/******/ if (cachedModule !== undefined) {
|
|
/******/ return cachedModule.exports;
|
|
/******/
|
|
}
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ let module = (__webpack_module_cache__[moduleId] = {
|
|
/******/ // no module.id needed
|
|
/******/ // no module.loaded needed
|
|
/******/ exports: {},
|
|
/******/
|
|
});
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ __webpack_modules__[moduleId](
|
|
module,
|
|
module.exports,
|
|
__webpack_require__
|
|
);
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/
|
|
}
|
|
/******/
|
|
/************************************************************************/
|
|
/******/ /* webpack/runtime/compat get default export */
|
|
/******/ (() => {
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
/******/ __webpack_require__.n = module => {
|
|
/******/ let getter =
|
|
module && module.__esModule
|
|
? /******/ () => module.default
|
|
: /******/ () => module;
|
|
/******/ __webpack_require__.d(getter, { a: getter });
|
|
/******/ return getter;
|
|
/******/
|
|
};
|
|
/******/
|
|
})();
|
|
/******/
|
|
/******/ /* webpack/runtime/define property getters */
|
|
/******/ (() => {
|
|
/******/ // define getter functions for harmony exports
|
|
/******/ __webpack_require__.d = (exports, definition) => {
|
|
/******/ for (let key in definition) {
|
|
/******/ if (
|
|
__webpack_require__.o(definition, key) &&
|
|
!__webpack_require__.o(exports, key)
|
|
) {
|
|
/******/ Object.defineProperty(exports, key, {
|
|
enumerable: true,
|
|
get: definition[key],
|
|
});
|
|
/******/
|
|
}
|
|
/******/
|
|
}
|
|
/******/
|
|
};
|
|
/******/
|
|
})();
|
|
/******/
|
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
/******/ (() => {
|
|
/******/ __webpack_require__.o = (obj, prop) =>
|
|
Object.prototype.hasOwnProperty.call(obj, prop);
|
|
/******/
|
|
})();
|
|
/******/
|
|
/******/ /* webpack/runtime/make namespace object */
|
|
/******/ (() => {
|
|
/******/ // define __esModule on exports
|
|
/******/ __webpack_require__.r = exports => {
|
|
/******/ if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
|
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, {
|
|
value: "Module",
|
|
});
|
|
/******/
|
|
}
|
|
/******/ Object.defineProperty(exports, "__esModule", { value: true });
|
|
/******/
|
|
};
|
|
/******/
|
|
})();
|
|
/******/
|
|
/************************************************************************/
|
|
let __webpack_exports__ = {};
|
|
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
|
(() => {
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0__ =
|
|
__webpack_require__(1);
|
|
/* harmony import */ let react__WEBPACK_IMPORTED_MODULE_0___default =
|
|
/*#__PURE__*/ __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ let react_dom__WEBPACK_IMPORTED_MODULE_1__ =
|
|
__webpack_require__(2);
|
|
/* harmony import */ let react_dom__WEBPACK_IMPORTED_MODULE_1___default =
|
|
/*#__PURE__*/ __webpack_require__.n(
|
|
react_dom__WEBPACK_IMPORTED_MODULE_1__
|
|
);
|
|
/* harmony import */ let _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ =
|
|
__webpack_require__(3);
|
|
/* harmony import */ let _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__ =
|
|
__webpack_require__(4);
|
|
/* harmony import */ let _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__ =
|
|
__webpack_require__(19);
|
|
function _extends() {
|
|
_extends = Object.assign
|
|
? Object.assign.bind()
|
|
: function (target) {
|
|
for (let i = 1; i < arguments.length; i++) {
|
|
let source = arguments[i];
|
|
for (let 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
|
|
* 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/. */
|
|
|
|
class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default()
|
|
.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
metricsFlowUri: null,
|
|
};
|
|
this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this);
|
|
}
|
|
|
|
async fetchFxAFlowUri() {
|
|
let _window;
|
|
let _window$AWGetFxAMetri;
|
|
this.setState({
|
|
metricsFlowUri: await ((_window$AWGetFxAMetri = (_window = window)
|
|
.AWGetFxAMetricsFlowURI) === null ||
|
|
_window$AWGetFxAMetri === void 0
|
|
? void 0
|
|
: _window$AWGetFxAMetri.call(_window)),
|
|
});
|
|
}
|
|
|
|
componentDidMount() {
|
|
if (!this.props.skipFxA) {
|
|
this.fetchFxAFlowUri();
|
|
}
|
|
if (document.location.href === "about:welcome") {
|
|
// Record impression with performance data after allowing the page to load
|
|
const recordImpression = domState => {
|
|
const { domComplete, domInteractive } = performance
|
|
.getEntriesByType("navigation")
|
|
.pop();
|
|
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendImpressionTelemetry(
|
|
this.props.messageId,
|
|
{
|
|
domComplete,
|
|
domInteractive,
|
|
mountStart: performance.getEntriesByName("mount").pop()
|
|
.startTime,
|
|
domState,
|
|
source: this.props.UTMTerm,
|
|
}
|
|
);
|
|
};
|
|
if (document.readyState === "complete") {
|
|
// Page might have already triggered a load event because it waited for async data,
|
|
// e.g., attribution, so the dom load timing could be of a empty content
|
|
// with domState in telemetry captured as 'complete'
|
|
recordImpression(document.readyState);
|
|
} else {
|
|
window.addEventListener("load", () => recordImpression("load"), {
|
|
once: true,
|
|
});
|
|
}
|
|
|
|
// Captures user has seen about:welcome by setting
|
|
// firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId
|
|
window.AWSendToParent(
|
|
"SET_WELCOME_MESSAGE_SEEN",
|
|
this.props.messageId
|
|
);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const { props } = this;
|
|
if (props.template === "return_to_amo") {
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__.ReturnToAMO,
|
|
{
|
|
message_id: props.messageId,
|
|
type: props.type,
|
|
name: props.name,
|
|
url: props.url,
|
|
iconURL: props.iconURL,
|
|
themeScreenshots: props.screenshots,
|
|
metricsFlowUri: this.state.metricsFlowUri,
|
|
}
|
|
);
|
|
}
|
|
return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
_components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__.MultiStageAboutWelcome,
|
|
{
|
|
message_id: props.messageId,
|
|
defaultScreens: props.screens,
|
|
updateHistory: !props.disableHistoryUpdates,
|
|
metricsFlowUri: this.state.metricsFlowUri,
|
|
utm_term: props.UTMTerm,
|
|
transitions: props.transitions,
|
|
backdrop: props.backdrop,
|
|
startScreen: props.startScreen || 0,
|
|
appAndSystemLocaleInfo: props.appAndSystemLocaleInfo,
|
|
ariaRole: props.aria_role,
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
// Computes messageId and UTMTerm info used in telemetry
|
|
function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) {
|
|
let messageId =
|
|
welcomeContent.template === "return_to_amo"
|
|
? `RTAMO_DEFAULT_WELCOME_${welcomeContent.type.toUpperCase()}`
|
|
: "DEFAULT_ID";
|
|
let UTMTerm = "aboutwelcome-default";
|
|
if (welcomeContent.id) {
|
|
messageId = welcomeContent.id.toUpperCase();
|
|
}
|
|
if (experimentId && branchId) {
|
|
UTMTerm = `aboutwelcome-${experimentId}-${branchId}`.toLowerCase();
|
|
}
|
|
return {
|
|
messageId,
|
|
UTMTerm,
|
|
};
|
|
}
|
|
async function retrieveRenderContent() {
|
|
// Feature config includes RTAMO attribution data if exists
|
|
// else below data in order specified
|
|
// user prefs
|
|
// experiment data
|
|
// defaults
|
|
let featureConfig = await window.AWGetFeatureConfig();
|
|
let { messageId, UTMTerm } = ComputeTelemetryInfo(
|
|
featureConfig,
|
|
featureConfig.slug,
|
|
featureConfig.branch && featureConfig.branch.slug
|
|
);
|
|
return {
|
|
featureConfig,
|
|
messageId,
|
|
UTMTerm,
|
|
};
|
|
}
|
|
async function mount() {
|
|
let {
|
|
featureConfig: aboutWelcomeProps,
|
|
messageId,
|
|
UTMTerm,
|
|
} = await retrieveRenderContent();
|
|
react_dom__WEBPACK_IMPORTED_MODULE_1___default().render(
|
|
/*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
AboutWelcome,
|
|
_extends(
|
|
{
|
|
messageId,
|
|
UTMTerm,
|
|
},
|
|
aboutWelcomeProps
|
|
)
|
|
),
|
|
document.getElementById("multi-stage-message-root")
|
|
);
|
|
}
|
|
performance.mark("mount");
|
|
mount();
|
|
})();
|
|
|
|
/******/
|
|
})();
|