diff --git a/.eslintignore b/.eslintignore
index 0bd1e7a1d584..3a4fa11ef33b 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -55,7 +55,6 @@ browser/components/pocket/content/panels/js/main.bundle.js
!browser/components/storybook/.storybook/*.js
# Ignore newtab files
-browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
browser/components/newtab/data/
browser/components/newtab/logs/
diff --git a/browser/components/aboutwelcome/.eslintrc.js b/browser/components/aboutwelcome/.eslintrc.js
new file mode 100644
index 000000000000..a12110d0fe45
--- /dev/null
+++ b/browser/components/aboutwelcome/.eslintrc.js
@@ -0,0 +1,173 @@
+/* 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/. */
+
+module.exports = {
+ // When adding items to this file please check for effects on sub-directories.
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ plugins: ["import", "react", "jsx-a11y"],
+ settings: {
+ react: {
+ version: "16.2.0",
+ },
+ },
+ extends: ["plugin:jsx-a11y/recommended"],
+ overrides: [
+ {
+ // Only mark the files as modules which are actually modules.
+ files: ["content-src/**"],
+ parserOptions: {
+ sourceType: "module",
+ },
+ },
+ {
+ // These files use fluent-dom to insert content
+ files: [
+ "content-src/components/Zap.jsx",
+ "content-src/components/MultiStageAboutWelcome.jsx",
+ "content-src/components/MultiStageScreen.jsx",
+ "content-src/components/MultiStageProtonScreen.jsx",
+ "content-src/components/MultiSelect.jsx",
+ "content-src/components/ReturnToAMO.jsx",
+ ],
+ rules: {
+ "jsx-a11y/anchor-has-content": "off",
+ "jsx-a11y/heading-has-content": "off",
+ "jsx-a11y/label-has-associated-control": "off",
+ "jsx-a11y/no-onchange": "off",
+ },
+ },
+ {
+ files: ["./*.js", "content-src/**"],
+ env: {
+ node: true,
+ },
+ },
+ {
+ // Use a configuration that's appropriate for modules, workers and
+ // non-production files.
+ files: ["tests/**"],
+ rules: {
+ "no-implicit-globals": "off",
+ },
+ },
+ {
+ files: ["content-src/**"],
+ rules: {
+ // Disallow commonjs in these directories.
+ "import/no-commonjs": 2,
+ // Allow JSX with arrow functions.
+ "react/jsx-no-bind": 0,
+ },
+ },
+ {
+ files: "tests/**",
+ rules: {
+ "func-name-matching": 0,
+ "lines-between-class-members": 0,
+ "require-await": 0,
+ },
+ },
+ ],
+ rules: {
+ "fetch-options/no-fetch-credentials": "error",
+
+ "react/jsx-boolean-value": ["error", "always"],
+ "react/jsx-key": "error",
+ "react/jsx-no-bind": "error",
+ "react/jsx-no-comment-textnodes": "error",
+ "react/jsx-no-duplicate-props": "error",
+ "react/jsx-no-target-blank": "error",
+ "react/jsx-no-undef": "error",
+ "react/jsx-pascal-case": "error",
+ "react/jsx-uses-react": "error",
+ "react/jsx-uses-vars": "error",
+ "react/no-access-state-in-setstate": "error",
+ "react/no-danger": "error",
+ "react/no-deprecated": "error",
+ "react/no-did-mount-set-state": "error",
+ "react/no-did-update-set-state": "error",
+ "react/no-direct-mutation-state": "error",
+ "react/no-is-mounted": "error",
+ "react/no-unknown-property": "error",
+ "react/require-render-return": "error",
+
+ "accessor-pairs": ["error", { setWithoutGet: true, getWithoutSet: false }],
+ "array-callback-return": "error",
+ "block-scoped-var": "error",
+ "consistent-this": ["error", "use-bind"],
+ eqeqeq: "error",
+ "for-direction": "error",
+ "func-name-matching": "error",
+ "getter-return": "error",
+ "guard-for-in": "error",
+ "handle-callback-err": "error",
+ "lines-between-class-members": "error",
+ "max-depth": ["error", 4],
+ "max-nested-callbacks": ["error", 4],
+ "max-params": ["error", 6],
+ "max-statements": ["error", 50],
+ "max-statements-per-line": ["error", { max: 2 }],
+ "new-cap": ["error", { newIsCap: true, capIsNew: false }],
+ "no-alert": "error",
+ "no-buffer-constructor": "error",
+ "no-console": ["error", { allow: ["error"] }],
+ "no-div-regex": "error",
+ "no-duplicate-imports": "error",
+ "no-eq-null": "error",
+ "no-extend-native": "error",
+ "no-extra-label": "error",
+ "no-implicit-coercion": ["error", { allow: ["!!"] }],
+ "no-implicit-globals": "error",
+ "no-loop-func": "error",
+ "no-mixed-requires": "error",
+ "no-multi-assign": "error",
+ "no-multi-str": "error",
+ "no-new": "error",
+ "no-new-func": "error",
+ "no-new-require": "error",
+ "no-octal-escape": "error",
+ "no-param-reassign": "error",
+ "no-path-concat": "error",
+ "no-process-exit": "error",
+ "no-proto": "error",
+ "no-prototype-builtins": "error",
+ "no-return-assign": ["error", "except-parens"],
+ "no-script-url": "error",
+ "no-shadow": "error",
+ "no-template-curly-in-string": "error",
+ "no-undef-init": "error",
+ "no-unmodified-loop-condition": "error",
+ "no-unused-expressions": "error",
+ "no-use-before-define": "error",
+ "no-useless-computed-key": "error",
+ "no-useless-constructor": "error",
+ "no-useless-rename": "error",
+ "no-var": "error",
+ "no-void": ["error", { allowAsStatement: true }],
+ "one-var": ["error", "never"],
+ "operator-assignment": ["error", "always"],
+ "prefer-destructuring": [
+ "error",
+ {
+ AssignmentExpression: { array: true },
+ VariableDeclarator: { array: true, object: true },
+ },
+ ],
+ "prefer-numeric-literals": "error",
+ "prefer-promise-reject-errors": "error",
+ "prefer-rest-params": "error",
+ "prefer-spread": "error",
+ "prefer-template": "error",
+ radix: ["error", "always"],
+ "require-await": "error",
+ "sort-vars": "error",
+ "symbol-description": "error",
+ "vars-on-top": "error",
+ yoda: ["error", "never"],
+ },
+};
diff --git a/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx b/browser/components/aboutwelcome/content-src/aboutwelcome.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
rename to browser/components/aboutwelcome/content-src/aboutwelcome.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.scss b/browser/components/aboutwelcome/content-src/aboutwelcome.scss
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/aboutwelcome.scss
rename to browser/components/aboutwelcome/content-src/aboutwelcome.scss
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/AdditionalCTA.jsx b/browser/components/aboutwelcome/content-src/components/AdditionalCTA.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/AdditionalCTA.jsx
rename to browser/components/aboutwelcome/content-src/components/AdditionalCTA.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/AddonsPicker.jsx b/browser/components/aboutwelcome/content-src/components/AddonsPicker.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/AddonsPicker.jsx
rename to browser/components/aboutwelcome/content-src/components/AddonsPicker.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/CTAParagraph.jsx b/browser/components/aboutwelcome/content-src/components/CTAParagraph.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/CTAParagraph.jsx
rename to browser/components/aboutwelcome/content-src/components/CTAParagraph.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/EmbeddedMigrationWizard.jsx b/browser/components/aboutwelcome/content-src/components/EmbeddedMigrationWizard.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/EmbeddedMigrationWizard.jsx
rename to browser/components/aboutwelcome/content-src/components/EmbeddedMigrationWizard.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/HelpText.jsx b/browser/components/aboutwelcome/content-src/components/HelpText.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/HelpText.jsx
rename to browser/components/aboutwelcome/content-src/components/HelpText.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/HeroImage.jsx b/browser/components/aboutwelcome/content-src/components/HeroImage.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/HeroImage.jsx
rename to browser/components/aboutwelcome/content-src/components/HeroImage.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/LanguageSwitcher.jsx b/browser/components/aboutwelcome/content-src/components/LanguageSwitcher.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/LanguageSwitcher.jsx
rename to browser/components/aboutwelcome/content-src/components/LanguageSwitcher.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/LinkParagraph.jsx b/browser/components/aboutwelcome/content-src/components/LinkParagraph.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/LinkParagraph.jsx
rename to browser/components/aboutwelcome/content-src/components/LinkParagraph.jsx
diff --git a/browser/components/aboutwelcome/content-src/components/MRColorways.jsx b/browser/components/aboutwelcome/content-src/components/MRColorways.jsx
new file mode 100644
index 000000000000..758e6ddc4afe
--- /dev/null
+++ b/browser/components/aboutwelcome/content-src/components/MRColorways.jsx
@@ -0,0 +1,200 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import React, { useState, useEffect } from "react";
+import { Localized } from "./MSLocalized";
+
+export const ColorwayDescription = props => {
+ const { colorway } = props;
+ if (!colorway) {
+ return null;
+ }
+ const { label, description } = colorway;
+ return (
+
+
+
+ );
+};
+
+// 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
+export 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'
+export 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?.split("-")[1];
+ index = variations.findIndex(element => element === variation);
+ if (index >= 0) {
+ return index;
+ }
+ return defaultVariationIndex;
+}
+
+export 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] = useState(activeId);
+ const [variationIndex, setVariationIndex] = 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.
+ useEffect(() => {
+ addEventListener("beforeunload", revertToDefaultTheme);
+ addEventListener("pagehide", revertToDefaultTheme);
+
+ return () => {
+ removeEventListener("beforeunload", revertToDefaultTheme);
+ removeEventListener("pagehide", revertToDefaultTheme);
+ };
+ });
+ // Update state any time activeTheme changes.
+ 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
+ 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 (
+
+
+
+
+
colorway.id === activeId)}
+ />
+
+ );
+}
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/MSLocalized.jsx b/browser/components/aboutwelcome/content-src/components/MSLocalized.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/MSLocalized.jsx
rename to browser/components/aboutwelcome/content-src/components/MSLocalized.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/MobileDownloads.jsx b/browser/components/aboutwelcome/content-src/components/MobileDownloads.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/MobileDownloads.jsx
rename to browser/components/aboutwelcome/content-src/components/MobileDownloads.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/MultiSelect.jsx b/browser/components/aboutwelcome/content-src/components/MultiSelect.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/MultiSelect.jsx
rename to browser/components/aboutwelcome/content-src/components/MultiSelect.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx b/browser/components/aboutwelcome/content-src/components/MultiStageAboutWelcome.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx
rename to browser/components/aboutwelcome/content-src/components/MultiStageAboutWelcome.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/MultiStageProtonScreen.jsx b/browser/components/aboutwelcome/content-src/components/MultiStageProtonScreen.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/MultiStageProtonScreen.jsx
rename to browser/components/aboutwelcome/content-src/components/MultiStageProtonScreen.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/OnboardingVideo.jsx b/browser/components/aboutwelcome/content-src/components/OnboardingVideo.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/OnboardingVideo.jsx
rename to browser/components/aboutwelcome/content-src/components/OnboardingVideo.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/ReturnToAMO.jsx b/browser/components/aboutwelcome/content-src/components/ReturnToAMO.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/ReturnToAMO.jsx
rename to browser/components/aboutwelcome/content-src/components/ReturnToAMO.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/Themes.jsx b/browser/components/aboutwelcome/content-src/components/Themes.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/Themes.jsx
rename to browser/components/aboutwelcome/content-src/components/Themes.jsx
diff --git a/browser/components/newtab/content-src/aboutwelcome/components/Zap.jsx b/browser/components/aboutwelcome/content-src/components/Zap.jsx
similarity index 100%
rename from browser/components/newtab/content-src/aboutwelcome/components/Zap.jsx
rename to browser/components/aboutwelcome/content-src/components/Zap.jsx
diff --git a/browser/components/aboutwelcome/content/aboutwelcome.bundle.js b/browser/components/aboutwelcome/content/aboutwelcome.bundle.js
new file mode 100644
index 000000000000..cfda9de8d0ee
--- /dev/null
+++ b/browser/components/aboutwelcome/content/aboutwelcome.bundle.js
@@ -0,0 +1,4158 @@
+/*!
+ *
+ * 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__(11);
+ /* harmony import */ let _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ =
+ __webpack_require__(19);
+ /* 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 = {
+ ..._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;
+ 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.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:
+ *
+ * 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 */ 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 _MRColorways__WEBPACK_IMPORTED_MODULE_3__ =
+ __webpack_require__(7);
+ /* harmony import */ let _MobileDownloads__WEBPACK_IMPORTED_MODULE_4__ =
+ __webpack_require__(8);
+ /* harmony import */ let _MultiSelect__WEBPACK_IMPORTED_MODULE_5__ =
+ __webpack_require__(9);
+ /* harmony import */ let _Themes__WEBPACK_IMPORTED_MODULE_6__ =
+ __webpack_require__(10);
+ /* harmony import */ let _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_7__ =
+ __webpack_require__(4);
+ /* harmony import */ let _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_8__ =
+ __webpack_require__(11);
+ /* harmony import */ let _CTAParagraph__WEBPACK_IMPORTED_MODULE_9__ =
+ __webpack_require__(12);
+ /* harmony import */ let _HeroImage__WEBPACK_IMPORTED_MODULE_10__ =
+ __webpack_require__(13);
+ /* harmony import */ let _OnboardingVideo__WEBPACK_IMPORTED_MODULE_11__ =
+ __webpack_require__(14);
+ /* harmony import */ let _AdditionalCTA__WEBPACK_IMPORTED_MODULE_12__ =
+ __webpack_require__(15);
+ /* harmony import */ let _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_13__ =
+ __webpack_require__(16);
+ /* harmony import */ let _AddonsPicker__WEBPACK_IMPORTED_MODULE_14__ =
+ __webpack_require__(17);
+ /* harmony import */ let _LinkParagraph__WEBPACK_IMPORTED_MODULE_15__ =
+ __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/. */
+
+ 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_12__.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_7__.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_14__.AddonsPicker,
+ {
+ content,
+ message_id: this.props.messageId,
+ handleAction: this.props.handleAction,
+ }
+ )
+ : null,
+ content.tiles &&
+ content.tiles.type === "colorway" &&
+ content.tiles.colorways
+ ? /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
+ _MRColorways__WEBPACK_IMPORTED_MODULE_3__.Colorways,
+ {
+ 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_6__.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_4__.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_5__.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_13__.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_8__.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_7__.ProgressBar,
+ {
+ step: currentStep,
+ previousStep,
+ totalNumberOfScreens: total,
+ }
+ )
+ : /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
+ _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_7__.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_10__.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_15__.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_7__.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_9__.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_11__.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 */ ColorwayDescription: () =>
+ /* binding */ ColorwayDescription,
+ /* harmony export */ computeColorWay: () =>
+ /* binding */ computeColorWay,
+ /* harmony export */ computeVariationIndex: () =>
+ /* binding */ computeVariationIndex,
+ /* harmony export */ Colorways: () => /* binding */ Colorways,
+ /* 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 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 */ 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
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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
+ )
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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",
+ }
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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
+ )
+ )
+ )
+ );
+ }
+
+ /***/
+ },
+ /* 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 */ 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
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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",
+ }
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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,
+ }
+ )
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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,
+ }
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 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 */ 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,
+ }
+ );
+ };
+
+ /***/
+ },
+ /* 17 */
+ /***/ (
+ __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
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 18 */
+ /***/ (
+ __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",
+ },
+ " "
+ )
+ )
+ )
+ );
+ };
+
+ /***/
+ },
+ /* 19 */
+ /***/ (
+ __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;
+ }
+
+ /***/
+ },
+ /* 20 */
+ /***/ (
+ __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 _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_3__ =
+ __webpack_require__(19);
+ /* 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() {
+ 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__(20);
+ function _extends() {
+ _extends =
+ Object.assign ||
+ 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();
+ })();
+
+ /******/
+})();
diff --git a/browser/components/aboutwelcome/jar.mn b/browser/components/aboutwelcome/jar.mn
index 5f5fe6cd42e9..99af5a3d6d46 100644
--- a/browser/components/aboutwelcome/jar.mn
+++ b/browser/components/aboutwelcome/jar.mn
@@ -6,3 +6,4 @@ browser.jar:
res/activity-stream/aboutwelcome/lib/ (./modules/*)
content/activity-stream/aboutwelcome/aboutwelcome.css (./content/aboutwelcome.css)
res/activity-stream/aboutwelcome/aboutwelcome.html (./content/aboutwelcome.html)
+ res/activity-stream/aboutwelcome/aboutwelcome.bundle.js (./content/aboutwelcome.bundle.js)
diff --git a/browser/components/newtab/webpack.aboutwelcome.config.js b/browser/components/aboutwelcome/webpack.aboutwelcome.config.js
similarity index 100%
rename from browser/components/newtab/webpack.aboutwelcome.config.js
rename to browser/components/aboutwelcome/webpack.aboutwelcome.config.js
diff --git a/browser/components/newtab/.eslintrc.js b/browser/components/newtab/.eslintrc.js
index c28858797539..76c93036eedd 100644
--- a/browser/components/newtab/.eslintrc.js
+++ b/browser/components/newtab/.eslintrc.js
@@ -27,12 +27,6 @@ module.exports = {
{
// These files use fluent-dom to insert content
files: [
- "content-src/aboutwelcome/components/Zap.jsx",
- "content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx",
- "content-src/aboutwelcome/components/MultiStageScreen.jsx",
- "content-src/aboutwelcome/components/MultiStageProtonScreen.jsx",
- "content-src/aboutwelcome/components/MultiSelect.jsx",
- "content-src/aboutwelcome/components/ReturnToAMO.jsx",
"content-src/asrouter/templates/OnboardingMessage/**",
"content-src/asrouter/templates/FirstRun/**",
"content-src/components/TopSites/**",
diff --git a/browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js b/browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
deleted file mode 100644
index 49c785e5a870..000000000000
--- a/browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
+++ /dev/null
@@ -1,2523 +0,0 @@
-/*!
- *
- * 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
- }));
- },
-
- 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 */ 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__(10);
-/* harmony import */ var _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
- }) => {
- 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 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: 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: activeMultiSelects[screen.id],
- setActiveMultiSelect: setActiveMultiSelect,
- autoAdvance: screen.auto_advance,
- negotiatedLanguage: negotiatedLanguage,
- langPackInstallPhase: langPackInstallPhase,
- forceHideStepsIndicator: screen.force_hide_steps_indicator,
- ariaRole: props.ariaRole,
- aboveButtonStepsIndicator: screen.above_button_steps_indicator
- }) : null;
- })));
-};
-const SecondaryCTA = props => {
- var _props$content$second, _props$content$tiles, _props$content$second2;
-
- 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) {
- var _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 = { ..._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;
- action = JSON.parse(JSON.stringify(action));
-
- if (action.collectSelect) {
- var _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, _props$content$tiles2, _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 => {
- 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,
- 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 */ 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", "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:
- *
- * 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 _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
-/* harmony import */ var _MobileDownloads__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
-/* harmony import */ var _MultiSelect__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8);
-/* harmony import */ var _Themes__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9);
-/* harmony import */ var _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4);
-/* harmony import */ var _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(10);
-/* harmony import */ var _CTAParagraph__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(11);
-/* harmony import */ var _HeroImage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(12);
-/* harmony import */ var _OnboardingVideo__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(13);
-/* harmony import */ var _AdditionalCTA__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(14);
-/* harmony import */ var _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(15);
-/* harmony import */ var _AddonsPicker__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(16);
-/* harmony import */ var _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 => {
- var _content$checkbox, _content$primary_butt, _content$additional_b, _content$primary_butt2, _content$primary_butt3, _content$primary_butt4, _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) {
- var _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: 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, 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: 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: 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: 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() {
- 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() {
- var _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: 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() {
- var _content$tiles, _content$tiles2, _this$props$appAndSys, _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: 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: 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 */ 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/. */
-
-
-
-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 */ 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 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 => {
- var _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: type // checkbox or radio
- ,
- id: 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 */ 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"
- }))))))));
-};
-
-/***/ }),
-/* 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 */ 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, 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 */ 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));
-};
-
-/***/ }),
-/* 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 */ 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);
-/* 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 */ 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
- })));
-};
-
-/***/ }),
-/* 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 */ 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
- }));
-};
-
-/***/ }),
-/* 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 */ 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", {
- "force-show-import-all": "false",
- "auto-request-state": "",
- ref: 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 */ 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 _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 */ 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 LinkParagraph = props => {
- var _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: 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 */ 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__(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 = { ..._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__(19);
-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();
- }
-
- 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: messageId,
- UTMTerm: UTMTerm
- }, aboutWelcomeProps)), document.getElementById("multi-stage-message-root"));
-}
-
-performance.mark("mount");
-mount();
-})();
-
-/******/ })()
-;
\ No newline at end of file
diff --git a/browser/components/newtab/package.json b/browser/components/newtab/package.json
index 3f862d6ba496..cb49825372af 100644
--- a/browser/components/newtab/package.json
+++ b/browser/components/newtab/package.json
@@ -83,16 +83,12 @@
"bundle": "npm-run-all bundle:*",
"bundle:webpack": "webpack-cli --config webpack.system-addon.config.js",
"bundle:css": "sass content-src/styles:css --no-source-map",
- "bundle:welcomeBundle": "webpack-cli --config webpack.aboutwelcome.config.js",
- "bundle:welcomeCss": "sass content-src/aboutwelcome:aboutwelcome/content --no-source-map",
"bundle:html": "rimraf prerendered && node ./bin/render-activity-stream-html.js",
"buildmc": "npm-run-all buildmc:*",
"buildmc:bundle": "npm run bundle",
"watchmc": "npm-run-all --parallel watchmc:*",
"watchmc:webpack": "npm run bundle:webpack -- --env development -w",
"watchmc:css": "npm run bundle:css -- --source-map --embed-sources --embed-source-map --load-path=content-src -w",
- "watchmc:welcomeBundle": "npm run bundle:welcomeBundle -- --env development -w",
- "watchmc:welcomeCss": "npm run bundle:welcomeCss -- --source-map --embed-sources --embed-source-map -w",
"testmc": "npm-run-all testmc:*",
"testmc:lint": "npm run lint",
"testmc:build": "npm run bundle:webpack",
diff --git a/browser/components/newtab/yamscripts.yml b/browser/components/newtab/yamscripts.yml
index 7d94912a756e..7e9501751a1f 100644
--- a/browser/components/newtab/yamscripts.yml
+++ b/browser/components/newtab/yamscripts.yml
@@ -8,8 +8,6 @@ scripts:
bundle:
webpack: webpack-cli --config webpack.system-addon.config.js
css: sass content-src/styles:css --no-source-map
- welcomeBundle: webpack-cli --config webpack.aboutwelcome.config.js
- welcomeCss: sass content-src/aboutwelcome:aboutwelcome/content --no-source-map
html: rimraf prerendered && node ./bin/render-activity-stream-html.js
# buildmc: Used to do stuff when this code was in GitHub, now just an
@@ -22,8 +20,6 @@ scripts:
_parallel: true
webpack: =>bundle:webpack -- --env development -w
css: =>bundle:css -- --source-map --embed-sources --embed-source-map --load-path=content-src -w
- welcomeBundle: =>bundle:welcomeBundle -- --env development -w
- welcomeCss: =>bundle:welcomeCss -- --source-map --embed-sources --embed-source-map -w
testmc:
lint: =>lint