tor-browser

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

App.js (6793B)


      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
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  connect,
      9 } = require("resource://devtools/client/shared/vendor/react-redux.js");
     10 const {
     11  createFactory,
     12  PureComponent,
     13 } = require("resource://devtools/client/shared/vendor/react.mjs");
     14 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     15 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     16 
     17 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js");
     18 const Localized = createFactory(FluentReact.Localized);
     19 
     20 const Route = createFactory(
     21  require("resource://devtools/client/shared/vendor/react-router-dom.js").Route
     22 );
     23 const Switch = createFactory(
     24  require("resource://devtools/client/shared/vendor/react-router-dom.js").Switch
     25 );
     26 const Redirect = createFactory(
     27  require("resource://devtools/client/shared/vendor/react-router-dom.js")
     28    .Redirect
     29 );
     30 
     31 const Types = require("resource://devtools/client/aboutdebugging/src/types/index.js");
     32 const {
     33  PAGE_TYPES,
     34  RUNTIMES,
     35 } = require("resource://devtools/client/aboutdebugging/src/constants.js");
     36 
     37 const ConnectPage = createFactory(
     38  require("resource://devtools/client/aboutdebugging/src/components/connect/ConnectPage.js")
     39 );
     40 const RuntimePage = createFactory(
     41  require("resource://devtools/client/aboutdebugging/src/components/RuntimePage.js")
     42 );
     43 const Sidebar = createFactory(
     44  require("resource://devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js")
     45 );
     46 
     47 class App extends PureComponent {
     48  static get propTypes() {
     49    return {
     50      adbAddonStatus: Types.adbAddonStatus,
     51      // The "dispatch" helper is forwarded to the App component via connect.
     52      // From that point, components are responsible for forwarding the dispatch
     53      // property to all components who need to dispatch actions.
     54      dispatch: PropTypes.func.isRequired,
     55      // getString prop is injected by the withLocalization wrapper
     56      getString: PropTypes.func.isRequired,
     57      isAdbReady: PropTypes.bool.isRequired,
     58      isScanningUsb: PropTypes.bool.isRequired,
     59      networkLocations: PropTypes.arrayOf(Types.location).isRequired,
     60      networkRuntimes: PropTypes.arrayOf(Types.runtime).isRequired,
     61      selectedPage: Types.page,
     62      selectedRuntimeId: PropTypes.string,
     63      usbRuntimes: PropTypes.arrayOf(Types.runtime).isRequired,
     64    };
     65  }
     66 
     67  componentDidUpdate() {
     68    this.updateTitle();
     69  }
     70 
     71  updateTitle() {
     72    const { getString, selectedPage, selectedRuntimeId } = this.props;
     73 
     74    const pageTitle =
     75      selectedPage === PAGE_TYPES.RUNTIME
     76        ? getString("about-debugging-page-title-runtime-page", {
     77            selectedRuntimeId,
     78          })
     79        : getString("about-debugging-page-title-setup-page");
     80 
     81    document.title = pageTitle;
     82  }
     83 
     84  renderConnect() {
     85    const { adbAddonStatus, dispatch, networkLocations } = this.props;
     86 
     87    return ConnectPage({
     88      adbAddonStatus,
     89      dispatch,
     90      networkLocations,
     91    });
     92  }
     93 
     94  // The `match` object here is passed automatically by the Route object.
     95  // We are using it to read the route path.
     96  // See react-router docs:
     97  // https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/match.md
     98  renderRuntime({ match }) {
     99    const isRuntimeAvailable = id => {
    100      const runtimes = [
    101        ...this.props.networkRuntimes,
    102        ...this.props.usbRuntimes,
    103      ];
    104      const runtime = runtimes.find(x => x.id === id);
    105      return runtime?.runtimeDetails;
    106    };
    107 
    108    const { dispatch } = this.props;
    109 
    110    let runtimeId = match.params.runtimeId || RUNTIMES.THIS_FIREFOX;
    111    if (match.params.runtimeId !== RUNTIMES.THIS_FIREFOX) {
    112      const rawId = decodeURIComponent(match.params.runtimeId);
    113      if (isRuntimeAvailable(rawId)) {
    114        runtimeId = rawId;
    115      } else {
    116        // Also redirect to "This Firefox" if runtime is not found
    117        return Redirect({ to: `/runtime/${RUNTIMES.THIS_FIREFOX}` });
    118      }
    119    }
    120 
    121    // we need to pass a key so the component updates when we want to showcase
    122    // a different runtime
    123    return RuntimePage({ dispatch, key: runtimeId, runtimeId });
    124  }
    125 
    126  renderRoutes() {
    127    return Switch(
    128      {},
    129      Route({
    130        path: "/setup",
    131        render: () => this.renderConnect(),
    132      }),
    133      Route({
    134        path: "/runtime/:runtimeId",
    135        render: routeProps => this.renderRuntime(routeProps),
    136      }),
    137      // default route when there's no match which includes "/"
    138      // TODO: the url does not match "/" means invalid URL,
    139      // in this case maybe we'd like to do something else than a redirect.
    140      // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1509897
    141      Route({
    142        render: routeProps => {
    143          const { pathname } = routeProps.location;
    144          // The old about:debugging supported the following routes:
    145          // about:debugging#workers, about:debugging#addons and about:debugging#tabs.
    146          // Such links can still be found in external documentation pages.
    147          // We redirect to This Firefox rather than the Setup Page here.
    148          if (
    149            pathname === "/workers" ||
    150            pathname === "/addons" ||
    151            pathname === "/tabs"
    152          ) {
    153            return Redirect({ to: `/runtime/${RUNTIMES.THIS_FIREFOX}` });
    154          }
    155          return Redirect({ to: "/setup" });
    156        },
    157      })
    158    );
    159  }
    160 
    161  render() {
    162    const {
    163      adbAddonStatus,
    164      dispatch,
    165      isAdbReady,
    166      isScanningUsb,
    167      networkRuntimes,
    168      selectedPage,
    169      selectedRuntimeId,
    170      usbRuntimes,
    171    } = this.props;
    172 
    173    return Localized(
    174      {},
    175      dom.div(
    176        { className: "app" },
    177        Sidebar({
    178          adbAddonStatus,
    179          className: "app__sidebar",
    180          dispatch,
    181          isAdbReady,
    182          isScanningUsb,
    183          networkRuntimes,
    184          selectedPage,
    185          selectedRuntimeId,
    186          usbRuntimes,
    187        }),
    188        dom.main({ className: "app__content" }, this.renderRoutes())
    189      )
    190    );
    191  }
    192 }
    193 
    194 const mapStateToProps = state => {
    195  return {
    196    adbAddonStatus: state.ui.adbAddonStatus,
    197    isAdbReady: state.ui.isAdbReady,
    198    isScanningUsb: state.ui.isScanningUsb,
    199    networkLocations: state.ui.networkLocations,
    200    networkRuntimes: state.runtimes.networkRuntimes,
    201    selectedPage: state.ui.selectedPage,
    202    selectedRuntimeId: state.runtimes.selectedRuntimeId,
    203    usbRuntimes: state.runtimes.usbRuntimes,
    204  };
    205 };
    206 
    207 const mapDispatchToProps = dispatch => ({
    208  dispatch,
    209 });
    210 
    211 module.exports = FluentReact.withLocalization(
    212  connect(mapStateToProps, mapDispatchToProps)(App)
    213 );