tor-browser

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

ProfilerDialog.js (5332B)


      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 Actions = require("resource://devtools/client/aboutdebugging/src/actions/index.js");
     21 const Types = require("resource://devtools/client/aboutdebugging/src/types/index.js");
     22 const {
     23  PROFILER_PAGE_CONTEXT,
     24 } = require("resource://devtools/client/aboutdebugging/src/constants.js");
     25 
     26 /**
     27 * This component is a modal dialog containing the performance profiler UI. It uses
     28 * the simplified DevTools panel located in devtools/client/performance-new. When
     29 * using a custom preset, and editing the settings, the page context switches
     30 * to about:profiling, which receives the PerfFront of the remote debuggee.
     31 */
     32 class ProfilerDialog extends PureComponent {
     33  static get propTypes() {
     34    return {
     35      runtimeDetails: Types.runtimeDetails.isRequired,
     36      profilerContext: PropTypes.string.isRequired,
     37      hideProfilerDialog: PropTypes.func.isRequired,
     38      switchProfilerContext: PropTypes.func.isRequired,
     39    };
     40  }
     41 
     42  hide() {
     43    this.props.hideProfilerDialog();
     44  }
     45 
     46  setProfilerIframeDirection(frameWindow) {
     47    // Set iframe direction according to the parent document direction.
     48    const { documentElement } = document;
     49    const dir = window.getComputedStyle(documentElement).direction;
     50    frameWindow.document.documentElement.setAttribute("dir", dir);
     51  }
     52 
     53  /**
     54   * The profiler iframe can either be the simplified devtools recording panel,
     55   * or the more detailed about:profiling settings page.
     56   */
     57  renderProfilerIframe() {
     58    const {
     59      runtimeDetails: { clientWrapper },
     60      switchProfilerContext,
     61      profilerContext,
     62    } = this.props;
     63 
     64    let src, onLoad;
     65 
     66    switch (profilerContext) {
     67      case PROFILER_PAGE_CONTEXT.DEVTOOLS_REMOTE:
     68        src = clientWrapper.getPerformancePanelUrl();
     69        onLoad = e => {
     70          const frameWindow = e.target.contentWindow;
     71          this.setProfilerIframeDirection(frameWindow);
     72 
     73          clientWrapper.loadPerformanceProfiler(frameWindow, () => {
     74            switchProfilerContext(PROFILER_PAGE_CONTEXT.ABOUTPROFILING_REMOTE);
     75          });
     76        };
     77        break;
     78 
     79      case PROFILER_PAGE_CONTEXT.ABOUTPROFILING_REMOTE:
     80        src = "about:profiling#remote";
     81        onLoad = e => {
     82          const frameWindow = e.target.contentWindow;
     83          this.setProfilerIframeDirection(frameWindow);
     84 
     85          clientWrapper.loadAboutProfiling(frameWindow, () => {
     86            switchProfilerContext(PROFILER_PAGE_CONTEXT.DEVTOOLS_REMOTE);
     87          });
     88        };
     89        break;
     90 
     91      default:
     92        throw new Error(`Unhandled profiler context: "${profilerContext}"`);
     93    }
     94 
     95    return dom.iframe({
     96      key: profilerContext,
     97      className: "profiler-dialog__frame",
     98      src,
     99      onLoad,
    100    });
    101  }
    102 
    103  render() {
    104    const { profilerContext, switchProfilerContext } = this.props;
    105    const dialogSizeClassName =
    106      profilerContext === PROFILER_PAGE_CONTEXT.DEVTOOLS_REMOTE
    107        ? "profiler-dialog__inner--medium"
    108        : "profiler-dialog__inner--large";
    109 
    110    return dom.div(
    111      {
    112        className: "profiler-dialog__mask qa-profiler-dialog-mask",
    113        onClick: () => this.hide(),
    114      },
    115      dom.article(
    116        {
    117          className: `profiler-dialog__inner ${dialogSizeClassName} qa-profiler-dialog`,
    118          onClick: e => e.stopPropagation(),
    119        },
    120        dom.header(
    121          {
    122            className: "profiler-dialog__header",
    123          },
    124          Localized(
    125            {
    126              id: "about-debugging-profiler-dialog-title2",
    127            },
    128            dom.h1(
    129              {
    130                className: "profiler-dialog__header__title",
    131              },
    132              "about-debugging-profiler-dialog-title2"
    133            )
    134          ),
    135          dom.button(
    136            {
    137              className: "ghost-button qa-profiler-dialog-close",
    138              onClick: () => {
    139                if (profilerContext === PROFILER_PAGE_CONTEXT.DEVTOOLS_REMOTE) {
    140                  this.hide();
    141                } else {
    142                  switchProfilerContext(PROFILER_PAGE_CONTEXT.DEVTOOLS_REMOTE);
    143                }
    144              },
    145            },
    146            dom.img({
    147              src: "chrome://devtools/skin/images/close.svg",
    148            })
    149          )
    150        ),
    151        this.renderProfilerIframe()
    152      )
    153    );
    154  }
    155 }
    156 
    157 const mapStateToProps = state => {
    158  return {
    159    profilerContext: state.ui.profilerContext,
    160  };
    161 };
    162 
    163 const mapDispatchToProps = {
    164  hideProfilerDialog: Actions.hideProfilerDialog,
    165  switchProfilerContext: Actions.switchProfilerContext,
    166 };
    167 
    168 module.exports = connect(mapStateToProps, mapDispatchToProps)(ProfilerDialog);