/*! * * NOTE: This file is generated by webpack from aboutwelcome.jsx * using the npm bundle task. * */ /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __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 */ }); var _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) { var _window$AWSendEventTe, _window; (_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") { var _window$AWSendEventTe2, _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 })); } }; 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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6); /* harmony import */ var _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11); /* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ = __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/. */ // 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 }) => { var _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) { var _window$AWAddScreenIm, _window; _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 containing array of checkbox ids // used in handleAction to update MULTI_ACTION data const [activeMultiSelect, setActiveMultiSelect] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null); // 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; return index === order ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(WelcomeScreen, { key: screen.id + order, id: screen.id, totalNumberOfScreens: totalNumberOfScreens, isFirstScreen: isFirstScreen, isLastScreen: isLastScreen, isSingleScreen: isSingleScreen, order: order, previousOrder: previousOrder, content: screen.content, navigate: handleTransition, messageId: `${props.message_id}_${order}_${screen.id}`, UTMTerm: props.utm_term, flowParams: flowParams, activeTheme: activeTheme, initialTheme: initialTheme, setActiveTheme: setActiveTheme, setInitialTheme: setInitialTheme, activeMultiSelect: activeMultiSelect, setActiveMultiSelect: setActiveMultiSelect, autoAdvance: screen.auto_advance, negotiatedLanguage: negotiatedLanguage, langPackInstallPhase: langPackInstallPhase }) : null; }))); }; const SecondaryCTA = props => { var _props$content$second; let targetElement = props.position ? `secondary_button_${props.position}` : `secondary_button`; const buttonStyling = (_props$content$second = props.content.secondary_button) !== null && _props$content$second !== void 0 && _props$content$second.has_arrow_icon ? `secondary text-link arrow-icon` : `secondary text-link`; 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 = { ..._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,_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; if (action.collectSelect) { // Populate MULTI_ACTION data actions property with selected checkbox actions from tiles data action.data = { actions: [] }; for (const checkbox of ((_props$content = props.content) === null || _props$content === void 0 ? void 0 : (_props$content$tiles = _props$content.tiles) === null || _props$content$tiles === void 0 ? void 0 : _props$content$tiles.data) ?? []) { var _props$content, _props$content$tiles; let checkboxAction; if (this.props.activeMultiSelect.includes(checkbox.id)) { checkboxAction = checkbox.checkedAction ?? checkbox.action; } else { checkboxAction = checkbox.uncheckedAction; } if (checkboxAction) { action.data.actions.push(checkboxAction); } } // 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 => { var _a$data, _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.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 }); } } /***/ }), /* 5 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Localized": () => (/* binding */ Localized) /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* 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"]; 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: *

* output: *

Welcome

* * Unlocalized text * jsx: *

*

* output: *

Welcome

*/ 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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _MRColorways__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7); /* harmony import */ var _MobileDownloads__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8); /* harmony import */ var _MultiSelect__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9); /* harmony import */ var _Themes__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10); /* harmony import */ var _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4); /* harmony import */ var _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(11); /* harmony import */ var _CTAParagraph__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(12); /* harmony import */ var _HeroImage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(13); /* harmony import */ var _OnboardingVideo__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(14); /* harmony import */ var _AdditionalCTA__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(15); /* harmony import */ var _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(16); /* 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 }); }; const ProtonScreenActionButtons = props => { var _content$checkbox, _content$additional_b, _content$primary_butt, _content$primary_butt2; const { content, addonName } = 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); if (!content.primary_button && !content.secondary_button && !content.additional_button) { return null; } 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_butt = content.primary_button) === null || _content$primary_butt === void 0 ? void 0 : _content$primary_butt.label }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "primary" // 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: ((_content$primary_butt2 = content.primary_button) === null || _content$primary_butt2 === void 0 ? void 0 : _content$primary_butt2.disabled) === true, 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: 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: content, handleAction: props.handleAction }) : null); }; class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { componentDidMount() { this.mainContentHeader.focus(); } getScreenClassName(isFirstScreen, isLastScreen, includeNoodles, isVideoOnboarding) { const screenClass = `screen-${this.props.order % 2 !== 0 ? 1 : 2}`; if (isVideoOnboarding) return "with-video"; return `${isFirstScreen ? `dialog-initial` : ``} ${isLastScreen ? `dialog-last` : ``} ${includeNoodles ? `with-noodles` : ``} ${screenClass}`; } renderLogo({ imageURL = "chrome://branding/content/about-logo.svg", darkModeImageURL, reducedMotionImageURL, darkModeReducedMotionImageURL, alt = "", height }) { return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("picture", { className: "logo-container" }, 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("img", { className: "brand-logo", style: { height }, src: imageURL, alt: alt, 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 === "colorway" && content.tiles.colorways ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MRColorways__WEBPACK_IMPORTED_MODULE_2__.Colorways, { content: content, activeTheme: this.props.activeTheme, 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: 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: 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() { return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { className: "dismiss-button", onClick: this.props.handleAction, value: "dismiss_button", "data-l10n-id": "spotlight-dialog-close-button" }); } renderStepsIndicator() { 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": "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: 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", 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" })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { text: content.help_text }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "attrib-text" })))); } render() { var _content$tiles, _this$props$appAndSys, _this$props$messageId; const { autoAdvance, content, isRtamo, isTheme, isFirstScreen, isLastScreen, isSingleScreen } = 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; 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) : ""; const isEmbeddedMigration = ((_content$tiles = content.tiles) === null || _content$tiles === void 0 ? void 0 : _content$tiles.type) === "migration-wizard"; return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("main", { className: `screen ${this.props.id || ""} ${screenClassName} ${textColorClass}`, role: "alertdialog", 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" : ""}`, role: "document" }, content.secondary_button_top ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.SecondaryCTA, { content: 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: content.background && isCenterPosition ? { background: content.background } : {} }, content.logo ? this.renderLogo(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, role: "presentation", alt: "" })) : 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 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { text: content.title }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("h1", { id: "mainContentHeader" })) : 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, this.renderContentTiles(), this.renderLanguageSwitcher(), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ProtonScreenActionButtons, { content: content, addonName: this.props.addonName, handleAction: this.props.handleAction })), !hideStepsIndicator ? this.renderStepsIndicator() : null), content.dismiss_button ? this.renderDismissButton() : null)); } } /***/ }), /* 7 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ColorwayDescription": () => (/* binding */ ColorwayDescription), /* harmony export */ "computeColorWay": () => (/* binding */ computeColorWay), /* harmony export */ "computeVariationIndex": () => (/* binding */ computeVariationIndex), /* harmony export */ "Colorways": () => (/* binding */ Colorways) /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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 ColorwayDescription = props => { const { colorway } = props; if (!colorway) { return null; } const { label, description } = colorway; return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { text: description }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "colorway-text", "data-l10n-args": JSON.stringify({ colorwayName: label }) })); }; // Return colorway as "default" for default theme variations Automatic, Light, Dark, // Alpenglow theme and legacy colorways which is not supported in Colorway picker. // For themes other then default, theme names exist in // format colorway-variationId inside LIGHT_WEIGHT_THEMES in AboutWelcomeParent function computeColorWay(themeName, systemVariations) { return !themeName || themeName === "alpenglow" || systemVariations.includes(themeName) ? "default" : themeName.split("-")[0]; } // Set variationIndex based off activetheme value e.g. 'light', 'expressionist-soft' function computeVariationIndex(themeName, systemVariations, variations, defaultVariationIndex) { // Check if themeName is in systemVariations, if yes choose variationIndex by themeName let index = systemVariations.findIndex(theme => theme === themeName); if (index >= 0) { return index; } // If themeName is one of the colorways, select variation index from colorways let variation = themeName === null || themeName === void 0 ? void 0 : themeName.split("-")[1]; index = variations.findIndex(element => element === variation); if (index >= 0) { return index; } return defaultVariationIndex; } function Colorways(props) { let { colorways, darkVariation, defaultVariationIndex, systemVariations, variations } = props.content.tiles; let hasReverted = false; // Active theme id from JSON e.g. "expressionist" const activeId = computeColorWay(props.activeTheme, systemVariations); const [colorwayId, setState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(activeId); const [variationIndex, setVariationIndex] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(defaultVariationIndex); function revertToDefaultTheme() { if (hasReverted) return; // Spoofing an event with current target value of "navigate_away" // helps the handleAction method to read the colorways theme as "revert" // which causes the initial theme to be activated. // The "navigate_away" action is set in content in the colorways screen JSON config. // Any value in the JSON for theme will work, provided it is not ``. const event = { currentTarget: { value: "navigate_away" } }; props.handleAction(event); hasReverted = true; } // Revert to default theme if the user navigates away from the page or spotlight modal // before clicking on the primary button to officially set theme. (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { addEventListener("beforeunload", revertToDefaultTheme); addEventListener("pagehide", revertToDefaultTheme); return () => { removeEventListener("beforeunload", revertToDefaultTheme); removeEventListener("pagehide", revertToDefaultTheme); }; }); // Update state any time activeTheme changes. (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { setState(computeColorWay(props.activeTheme, systemVariations)); setVariationIndex(computeVariationIndex(props.activeTheme, systemVariations, variations, defaultVariationIndex)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.activeTheme]); //select a random colorway (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { //We don't want the default theme to be selected const randomIndex = Math.floor(Math.random() * (colorways.length - 1)) + 1; const randomColorwayId = colorways[randomIndex].id; // Change the variation to be the dark variation if configured and dark. // Additional colorway changes will remain dark while system is unchanged. if (darkVariation !== undefined && window.matchMedia("(prefers-color-scheme: dark)").matches) { variations[variationIndex] = variations[darkVariation]; } const value = `${randomColorwayId}-${variations[variationIndex]}`; props.handleAction({ currentTarget: { value } }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); 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" })), colorways.map(({ id, label, tooltip }) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { key: id + label, text: typeof tooltip === "object" ? tooltip : {} }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { className: "theme", title: label, "data-l10n-args": JSON.stringify({ colorwayName: label }) }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { text: typeof tooltip === "object" ? tooltip : {} }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", { className: "sr-only colorway label", id: `${id}-label`, "data-l10n-args": JSON.stringify({ colorwayName: tooltip }) })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, { text: typeof label === "object" ? label : {} }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "radio", "data-colorway": id, name: "theme", value: id === "default" ? systemVariations[variationIndex] : `${id}-${variations[variationIndex]}`, checked: colorwayId === id, className: "sr-only input", onClick: props.handleAction, "data-l10n-args": JSON.stringify({ colorwayName: label }), "aria-labelledby": `${id}-label` })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: `icon colorway ${colorwayId === id ? "selected" : ""} ${id}` })))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ColorwayDescription, { colorway: colorways.find(colorway => colorway.id === activeId) })); } /***/ }), /* 8 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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 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 }) : 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); }; /***/ }), /* 9 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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 MultiSelect = props => { let handleChange = event => { if (event.currentTarget.checked) { props.setActiveMultiSelect([...props.activeMultiSelect, event.currentTarget.value]); } else { props.setActiveMultiSelect(props.activeMultiSelect.filter(id => id !== event.currentTarget.value)); } }; let { data } = props.content.tiles; // When screen renders for first time, update state // with checkbox ids that has defaultvalue true (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { if (!props.activeMultiSelect) { props.setActiveMultiSelect(data.map(item => item.defaultValue && item.id).filter(item => !!item)); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { className: "multi-select-container" }, props.content.tiles.data.map(({ label, id }) => { var _props$activeMultiSel; return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { key: id + label, className: "checkbox-container multi-select-item" }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "checkbox", id: id, value: id, checked: (_props$activeMultiSel = props.activeMultiSelect) === null || _props$activeMultiSel === void 0 ? void 0 : _props$activeMultiSel.includes(id), onChange: handleChange }), /*#__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 }))); })); }; /***/ }), /* 10 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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" })))))))); }; /***/ }), /* 11 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _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)(() => { var _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]); 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); } }, [screens, negotiatedLanguage]); 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" } }); }); } }, [isAwaitingLangpack, langPackInstallPhase]); 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)))); } /***/ }), /* 12 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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)); }; /***/ }), /* 13 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* 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, alt: alt || "", role: alt ? null : "presentation" })); }; /***/ }), /* 14 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* 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 }))); }; /***/ }), /* 15 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(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 }) => { var _content$additional_b, _content$additional_b4, _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 { var _content$additional_b2, _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 })); }; /***/ }), /* 16 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* 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", { "auto-request-state": "", ref: ref }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("panel-list", null)); }; /***/ }), /* 17 */ /***/ ((__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; } /***/ }), /* 18 */ /***/ ((__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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6); /* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__ = __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/. */ 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 = { ..._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() { var _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: 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 /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var 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) => { /******/ var 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(var 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 }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __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 */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); /* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* This Source Code Form is subject to the terms of the Mozilla Public * 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() { var _window$AWGetFxAMetri, _window; 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(); } // 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 }); } } // 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: messageId, UTMTerm: UTMTerm }, aboutWelcomeProps)), document.getElementById("multi-stage-message-root")); } performance.mark("mount"); mount(); })(); /******/ })() ;