tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

aboutwelcome.jsx (4258B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import React from "react";
      6 import ReactDOM from "react-dom";
      7 import { AboutWelcomeUtils } from "./lib/aboutwelcome-utils.mjs";
      8 import { MultiStageAboutWelcome } from "./components/MultiStageAboutWelcome";
      9 
     10 class AboutWelcome extends React.PureComponent {
     11  constructor(props) {
     12    super(props);
     13    this.state = { metricsFlowUri: null };
     14    this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this);
     15  }
     16 
     17  async fetchFxAFlowUri() {
     18    this.setState({ metricsFlowUri: await window.AWGetFxAMetricsFlowURI?.() });
     19  }
     20 
     21  componentDidMount() {
     22    if (!this.props.skipFxA) {
     23      this.fetchFxAFlowUri();
     24    }
     25 
     26    if (document.location.href === "about:welcome") {
     27      // Record impression with performance data after allowing the page to load
     28      const recordImpression = domState => {
     29        const { domComplete, domInteractive } = performance
     30          .getEntriesByType("navigation")
     31          .pop();
     32        AboutWelcomeUtils.sendImpressionTelemetry(this.props.messageId, {
     33          domComplete,
     34          domInteractive,
     35          mountStart: performance.getEntriesByName("mount").pop().startTime,
     36          domState,
     37          source: this.props.UTMTerm,
     38        });
     39      };
     40      if (document.readyState === "complete") {
     41        // Page might have already triggered a load event because it waited for async data,
     42        // e.g., attribution, so the dom load timing could be of a empty content
     43        // with domState in telemetry captured as 'complete'
     44        recordImpression(document.readyState);
     45      } else {
     46        window.addEventListener("load", () => recordImpression("load"), {
     47          once: true,
     48        });
     49      }
     50 
     51      // Captures user has seen about:welcome by setting
     52      // firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId
     53      window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.props.messageId);
     54    }
     55  }
     56 
     57  render() {
     58    const { props } = this;
     59    return (
     60      <MultiStageAboutWelcome
     61        addonId={props.addonId}
     62        addonType={props.type}
     63        addonName={props.name || ""}
     64        addonURL={props.url}
     65        addonIconURL={props.iconURL}
     66        themeScreenshots={props.screenshots}
     67        message_id={props.messageId}
     68        defaultScreens={props.screens}
     69        updateHistory={!props.disableHistoryUpdates}
     70        metricsFlowUri={this.state.metricsFlowUri}
     71        utm_term={props.UTMTerm}
     72        transitions={props.transitions}
     73        backdrop={props.backdrop}
     74        startScreen={props.startScreen || 0}
     75        appAndSystemLocaleInfo={props.appAndSystemLocaleInfo}
     76        ariaRole={props.aria_role}
     77        gateInitialPaint={true}
     78      />
     79    );
     80  }
     81 }
     82 
     83 // Computes messageId and UTMTerm info used in telemetry
     84 function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) {
     85  let messageId =
     86    welcomeContent.template === "return_to_amo"
     87      ? `RTAMO_DEFAULT_WELCOME_${welcomeContent.type.toUpperCase()}`
     88      : "DEFAULT_ID";
     89  let UTMTerm = "aboutwelcome-default";
     90 
     91  if (welcomeContent.id) {
     92    messageId = welcomeContent.id.toUpperCase();
     93  }
     94 
     95  if (experimentId && branchId) {
     96    UTMTerm = `aboutwelcome-${experimentId}-${branchId}`.toLowerCase();
     97  }
     98  return {
     99    messageId,
    100    UTMTerm,
    101  };
    102 }
    103 
    104 async function retrieveRenderContent() {
    105  // Feature config includes RTAMO attribution data if exists
    106  // else below data in order specified
    107  // user prefs
    108  // experiment data
    109  // defaults
    110  let featureConfig = await window.AWGetFeatureConfig();
    111 
    112  let { messageId, UTMTerm } = ComputeTelemetryInfo(
    113    featureConfig,
    114    featureConfig.slug,
    115    featureConfig.branch && featureConfig.branch.slug
    116  );
    117  return { featureConfig, messageId, UTMTerm };
    118 }
    119 
    120 async function mount() {
    121  let {
    122    featureConfig: aboutWelcomeProps,
    123    messageId,
    124    UTMTerm,
    125  } = await retrieveRenderContent();
    126  ReactDOM.render(
    127    <AboutWelcome
    128      messageId={messageId}
    129      UTMTerm={UTMTerm}
    130      {...aboutWelcomeProps}
    131    />,
    132    document.getElementById("multi-stage-message-root")
    133  );
    134 }
    135 
    136 performance.mark("mount");
    137 mount();