Commit 805e67f3 authored by Greg Tatum's avatar Greg Tatum
Browse files

Bug 1597376 - Break out profiler event handling into a separate component; r=julienw

Differential Revision: https://phabricator.services.mozilla.com/D55007

--HG--
rename : devtools/client/performance-new/components/Perf.js => devtools/client/performance-new/components/DevToolsAndPopup.js
extra : moz-landing-system : lando
parent 086d2b57
Loading
Loading
Loading
Loading
+126 −0
Original line number Diff line number Diff line
/* 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/. */
// @ts-check

/**
 * @template P
 * @typedef {import("react-redux").ResolveThunks<P>} ResolveThunks<P>
 */

/**
 * @typedef {Object} StateProps
 * @property {boolean?} isSupportedPlatform
 * @property {boolean?} isPopup
 * @property {string | null} promptEnvRestart
 */

/**
 * @typedef {StateProps} Props
 * @typedef {import("../@types/perf").State} StoreState
 * @typedef {import("../@types/perf").PanelWindow} PanelWindow
 */

"use strict";

const {
  PureComponent,
  createFactory,
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const {
  div,
  button,
} = require("devtools/client/shared/vendor/react-dom-factories");
const RecordingButton = createFactory(
  require("devtools/client/performance-new/components/RecordingButton.js")
);
const Settings = createFactory(
  require("devtools/client/performance-new/components/Settings.js")
);
const Description = createFactory(
  require("devtools/client/performance-new/components/Description.js")
);

const selectors = require("devtools/client/performance-new/store/selectors");
const {
  restartBrowserWithEnvironmentVariable,
} = require("devtools/client/performance-new/browser");

/**
 * This is the top level component for the DevTools panel and the profiler popup, but
 * not the about:profiling page. Eventually the profiler popup will use a different
 * implementation. See Bug 1597371 for more information about the migration plan.
 *
 * @extends {React.PureComponent<Props>}
 */
class DevToolsAndPopup extends PureComponent {
  /** @param {Props} props */
  constructor(props) {
    super(props);
    this.handleRestart = this.handleRestart.bind(this);
  }

  handleRestart() {
    const { promptEnvRestart } = this.props;
    if (!promptEnvRestart) {
      throw new Error(
        "handleRestart() should only be called when promptEnvRestart exists."
      );
    }
    restartBrowserWithEnvironmentVariable(promptEnvRestart, "1");
  }

  render() {
    const { isSupportedPlatform, isPopup, promptEnvRestart } = this.props;

    if (isSupportedPlatform === null) {
      // We don't know yet if this is a supported platform, wait for a response.
      return null;
    }

    const additionalClassName = isPopup ? "perf-popup" : "perf-devtools";

    return div(
      { className: `perf ${additionalClassName}` },
      promptEnvRestart
        ? div(
            { className: "perf-env-restart" },
            div(
              {
                className:
                  "perf-photon-message-bar perf-photon-message-bar-warning perf-env-restart-fixed",
              },
              div({ className: "perf-photon-message-bar-warning-icon" }),
              "The browser must be restarted to enable this feature.",
              button(
                {
                  className: "perf-photon-button perf-photon-button-micro",
                  type: "button",
                  onClick: this.handleRestart,
                },
                "Restart"
              )
            )
          )
        : null,
      RecordingButton(),
      Settings(),
      isPopup ? null : Description()
    );
  }
}

/**
 * @param {StoreState} state
 * @returns {StateProps}
 */
function mapStateToProps(state) {
  return {
    isSupportedPlatform: selectors.getIsSupportedPlatform(state),
    isPopup: selectors.getIsPopup(state),
    promptEnvRestart: selectors.getPromptEnvRestart(state),
  };
}

module.exports = connect(mapStateToProps)(DevToolsAndPopup);
+5 −76
Original line number Diff line number Diff line
@@ -37,44 +37,19 @@

"use strict";

const {
  PureComponent,
  createFactory,
} = require("devtools/client/shared/vendor/react");
const { PureComponent } = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const {
  div,
  button,
} = require("devtools/client/shared/vendor/react-dom-factories");
const RecordingButton = createFactory(
  require("devtools/client/performance-new/components/RecordingButton.js")
);
const Settings = createFactory(
  require("devtools/client/performance-new/components/Settings.js")
);
const Description = createFactory(
  require("devtools/client/performance-new/components/Description.js")
);
const actions = require("devtools/client/performance-new/store/actions");
const selectors = require("devtools/client/performance-new/store/selectors");
const {
  restartBrowserWithEnvironmentVariable,
} = require("devtools/client/performance-new/browser");

/**
 * This is the top level component for initializing the performance recording panel.
 * It has two jobs:
 *
 * 1) It manages state changes for the performance recording. e.g. If the profiler
 * This component state changes for the performance recording. e.g. If the profiler
 * suddenly becomes unavailable, it needs to react to those changes, and update the
 * recordingState in the store.
 *
 * 2) It mounts all of the sub components, but is itself very light on actual
 * markup for presentation.
 *
 * @extends {React.PureComponent<Props>}
 */
class Perf extends PureComponent {
class ProfilerEventHandling extends PureComponent {
  /** @param {Props} props */
  constructor(props) {
    super(props);
@@ -86,7 +61,6 @@ class Perf extends PureComponent {
    this.handlePrivateBrowsingEnding = this.handlePrivateBrowsingEnding.bind(
      this
    );
    this.handleRestart = this.handleRestart.bind(this);
  }

  componentDidMount() {
@@ -277,54 +251,9 @@ class Perf extends PureComponent {
    this.props.changeRecordingState("available-to-record");
  }

  handleRestart() {
    const { promptEnvRestart } = this.props;
    if (!promptEnvRestart) {
      throw new Error(
        "handleRestart() should only be called when promptEnvRestart exists."
      );
    }
    restartBrowserWithEnvironmentVariable(promptEnvRestart, "1");
  }

  render() {
    const { isSupportedPlatform, isPopup, promptEnvRestart } = this.props;

    if (isSupportedPlatform === null) {
      // We don't know yet if this is a supported platform, wait for a response.
    return null;
  }

    const additionalClassName = isPopup ? "perf-popup" : "perf-devtools";

    return div(
      { className: `perf ${additionalClassName}` },
      promptEnvRestart
        ? div(
            { className: "perf-env-restart" },
            div(
              {
                className:
                  "perf-photon-message-bar perf-photon-message-bar-warning perf-env-restart-fixed",
              },
              div({ className: "perf-photon-message-bar-warning-icon" }),
              "The browser must be restarted to enable this feature.",
              button(
                {
                  className: "perf-photon-button perf-photon-button-micro",
                  type: "button",
                  onClick: this.handleRestart,
                },
                "Restart"
              )
            )
          )
        : null,
      RecordingButton(),
      Settings(),
      isPopup ? null : Description()
    );
  }
}

/**
@@ -350,4 +279,4 @@ const mapDispatchToProps = {
module.exports = connect(
  mapStateToProps,
  mapDispatchToProps
)(Perf);
)(ProfilerEventHandling);
+2 −1
Original line number Diff line number Diff line
@@ -5,8 +5,9 @@

DevToolsModules(
    'Description.js',
    'DevToolsAndPopup.js',
    'DirectoryPicker.js',
    'Perf.js',
    'ProfilerEventHandling.js',
    'Range.js',
    'RecordingButton.js',
    'Settings.js',
+16 −2
Original line number Diff line number Diff line
@@ -33,9 +33,14 @@
  scope.loader = browserLoader.loader;
}

const Perf = require("devtools/client/performance-new/components/Perf");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const React = require("devtools/client/shared/vendor/react");
const DevToolsAndPopup = React.createFactory(
  require("devtools/client/performance-new/components/DevToolsAndPopup")
);
const ProfilerEventHandling = React.createFactory(
  require("devtools/client/performance-new/components/ProfilerEventHandling")
);
const createStore = require("devtools/client/shared/redux/create-store");
const selectors = require("devtools/client/performance-new/store/selectors");
const reducers = require("devtools/client/performance-new/store/reducers");
@@ -113,7 +118,16 @@ async function gInit(perfFront, preferenceFront) {
  );

  ReactDOM.render(
    React.createElement(Provider, { store }, React.createElement(Perf)),
    React.createElement(
      Provider,
      { store },
      React.createElement(
        React.Fragment,
        null,
        ProfilerEventHandling(),
        DevToolsAndPopup()
      )
    ),
    document.querySelector("#root")
  );
}
+16 −2
Original line number Diff line number Diff line
@@ -54,9 +54,14 @@ const {

const { receiveProfile } = require("devtools/client/performance-new/browser");

const Perf = require("devtools/client/performance-new/components/Perf");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const React = require("devtools/client/shared/vendor/react");
const DevToolsAndPopup = React.createFactory(
  require("devtools/client/performance-new/components/DevToolsAndPopup")
);
const ProfilerEventHandling = React.createFactory(
  require("devtools/client/performance-new/components/ProfilerEventHandling")
);
const createStore = require("devtools/client/shared/redux/create-store");
const reducers = require("devtools/client/performance-new/store/reducers");
const actions = require("devtools/client/performance-new/store/actions");
@@ -106,7 +111,16 @@ async function gInit() {
  );

  ReactDOM.render(
    React.createElement(Provider, { store }, React.createElement(Perf)),
    React.createElement(
      Provider,
      { store },
      React.createElement(
        React.Fragment,
        null,
        ProfilerEventHandling(),
        DevToolsAndPopup()
      )
    ),
    document.querySelector("#root")
  );

Loading