tor-browser

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

Worker.js (6377B)


      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  createFactory,
      9  PureComponent,
     10 } = require("resource://devtools/client/shared/vendor/react.mjs");
     11 
     12 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     13 const {
     14  connect,
     15 } = require("resource://devtools/client/shared/vendor/react-redux.js");
     16 
     17 const {
     18  a,
     19  img,
     20  p,
     21  section,
     22  span,
     23 } = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     24 
     25 const {
     26  getUnicodeUrlPath,
     27 } = require("resource://devtools/client/shared/unicode-url.js");
     28 
     29 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js");
     30 const Localized = createFactory(FluentReact.Localized);
     31 const {
     32  l10n,
     33 } = require("resource://devtools/client/application/src/modules/l10n.js");
     34 
     35 const {
     36  services,
     37 } = require("resource://devtools/client/application/src/modules/application-services.js");
     38 const Types = require("resource://devtools/client/application/src/types/index.js");
     39 
     40 const {
     41  startWorker,
     42 } = require("resource://devtools/client/application/src/actions/workers.js");
     43 
     44 const UIButton = createFactory(
     45  require("resource://devtools/client/application/src/components/ui/UIButton.js")
     46 );
     47 
     48 /**
     49 * This component is dedicated to display a worker, more accurately a service worker, in
     50 * the list of workers displayed in the application panel. It displays information about
     51 * the worker as well as action links and buttons to interact with the worker (e.g. debug,
     52 * unregister, update etc...).
     53 */
     54 class Worker extends PureComponent {
     55  static get propTypes() {
     56    return {
     57      isDebugEnabled: PropTypes.bool.isRequired,
     58      worker: PropTypes.shape(Types.worker).isRequired,
     59      // this prop get automatically injected via `connect`
     60      dispatch: PropTypes.func.isRequired,
     61    };
     62  }
     63 
     64  constructor(props) {
     65    super(props);
     66 
     67    this.debug = this.debug.bind(this);
     68    this.viewSource = this.viewSource.bind(this);
     69    this.start = this.start.bind(this);
     70  }
     71 
     72  debug() {
     73    if (!this.isRunning()) {
     74      console.log("Service workers cannot be debugged if they are not running");
     75      return;
     76    }
     77 
     78    services.openWorkerInDebugger(this.props.worker.workerDescriptorFront);
     79  }
     80 
     81  viewSource() {
     82    if (!this.isRunning()) {
     83      console.log(
     84        "Service workers cannot be inspected if they are not running"
     85      );
     86      return;
     87    }
     88 
     89    services.viewWorkerSource(this.props.worker.workerDescriptorFront);
     90  }
     91 
     92  start() {
     93    if (!this.isActive() || this.isRunning()) {
     94      console.log("Running or inactive service workers cannot be started");
     95      return;
     96    }
     97 
     98    this.props.dispatch(startWorker(this.props.worker));
     99  }
    100 
    101  isRunning() {
    102    // We know the worker is running if it has a worker actor.
    103    return !!this.props.worker.workerDescriptorFront;
    104  }
    105 
    106  isActive() {
    107    return this.props.worker.state === Ci.nsIServiceWorkerInfo.STATE_ACTIVATED;
    108  }
    109 
    110  getLocalizedStatus() {
    111    if (this.isActive() && this.isRunning()) {
    112      return l10n.getString("serviceworker-worker-status-running");
    113    } else if (this.isActive()) {
    114      return l10n.getString("serviceworker-worker-status-stopped");
    115    }
    116    // NOTE: this is already localized by the service worker front
    117    // (strings are in debugger.properties)
    118    return this.props.worker.stateText;
    119  }
    120 
    121  getClassNameForStatus() {
    122    const { state } = this.props.worker;
    123 
    124    switch (state) {
    125      case Ci.nsIServiceWorkerInfo.STATE_PARSED:
    126      case Ci.nsIServiceWorkerInfo.STATE_INSTALLING:
    127        return "worker__status--installing";
    128      case Ci.nsIServiceWorkerInfo.STATE_INSTALLED:
    129      case Ci.nsIServiceWorkerInfo.STATE_ACTIVATING:
    130        return "worker__status--waiting";
    131      case Ci.nsIServiceWorkerInfo.STATE_ACTIVATED:
    132        return "worker__status--active";
    133    }
    134 
    135    return "worker__status--default";
    136  }
    137 
    138  formatSource(source) {
    139    const parts = source.split("/");
    140    return getUnicodeUrlPath(parts[parts.length - 1]);
    141  }
    142 
    143  renderInspectLink(url) {
    144    // avoid rendering the inspect link if sw is not running
    145    const isDisabled = !this.isRunning();
    146    // view source instead of debugging when debugging sw is not available
    147    const callbackFn = this.props.isDebugEnabled ? this.debug : this.viewSource;
    148 
    149    const sourceUrl = span(
    150      { className: "js-source-url" },
    151      this.formatSource(url)
    152    );
    153 
    154    return isDisabled
    155      ? sourceUrl
    156      : a(
    157          {
    158            onClick: callbackFn,
    159            title: url,
    160            href: "#",
    161            className: "js-inspect-link",
    162          },
    163          sourceUrl,
    164          "\u00A0", //  
    165          Localized(
    166            {
    167              id: "serviceworker-worker-inspect-icon",
    168              attrs: {
    169                alt: true,
    170              },
    171            },
    172            img({
    173              src: "chrome://devtools/skin/images/application-debug.svg",
    174            })
    175          )
    176        );
    177  }
    178 
    179  renderStartButton() {
    180    // avoid rendering the button at all for workers that are either running,
    181    // or in a state that prevents them from starting (like waiting)
    182    if (this.isRunning() || !this.isActive()) {
    183      return null;
    184    }
    185 
    186    return Localized(
    187      { id: "serviceworker-worker-start3" },
    188      UIButton({
    189        onClick: this.start,
    190        className: `js-start-button`,
    191        size: "micro",
    192      })
    193    );
    194  }
    195 
    196  render() {
    197    const { worker } = this.props;
    198    const statusText = this.getLocalizedStatus();
    199    const statusClassName = this.getClassNameForStatus();
    200 
    201    return section(
    202      { className: "worker js-sw-worker" },
    203      p(
    204        { className: "worker__icon" },
    205        img({
    206          className: "worker__icon-image",
    207          src: "chrome://devtools/skin/images/debugging-workers.svg",
    208        })
    209      ),
    210      p({ className: "worker__source" }, this.renderInspectLink(worker.url)),
    211      p(
    212        { className: "worker__misc" },
    213        span(
    214          { className: `js-worker-status worker__status ${statusClassName}` },
    215          statusText
    216        ),
    217        " ",
    218        this.renderStartButton()
    219      )
    220    );
    221  }
    222 }
    223 
    224 const mapDispatchToProps = dispatch => ({ dispatch });
    225 module.exports = connect(mapDispatchToProps)(Worker);