tor-browser

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

worker.js (4175B)


      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 "use strict";
      5 
      6 const {
      7  workerDescriptorSpec,
      8 } = require("resource://devtools/shared/specs/descriptors/worker.js");
      9 const {
     10  FrontClassWithSpec,
     11  registerFront,
     12 } = require("resource://devtools/shared/protocol.js");
     13 const {
     14  TargetMixin,
     15 } = require("resource://devtools/client/fronts/targets/target-mixin.js");
     16 const {
     17  DescriptorMixin,
     18 } = require("resource://devtools/client/fronts/descriptors/descriptor-mixin.js");
     19 const DESCRIPTOR_TYPES = require("resource://devtools/client/fronts/descriptors/descriptor-types.js");
     20 
     21 class WorkerDescriptorFront extends DescriptorMixin(
     22  TargetMixin(FrontClassWithSpec(workerDescriptorSpec))
     23 ) {
     24  constructor(client, targetFront, parentFront) {
     25    super(client, targetFront, parentFront);
     26 
     27    this.traits = {};
     28  }
     29 
     30  descriptorType = DESCRIPTOR_TYPES.WORKER;
     31 
     32  form(json) {
     33    this.actorID = json.actor;
     34    this.id = json.id;
     35 
     36    // Save the full form for Target class usage.
     37    // Do not use `form` name to avoid colliding with protocol.js's `form` method
     38    this.targetForm = json;
     39    this._url = json.url;
     40    this.origin = json.origin;
     41    this.type = json.type;
     42    this.scope = json.scope;
     43    this.fetch = json.fetch;
     44    this.traits = json.traits;
     45  }
     46 
     47  get name() {
     48    // this._url is nullified in TargetMixin#destroy.
     49    if (!this.url) {
     50      return null;
     51    }
     52 
     53    return this.url.split("/").pop();
     54  }
     55 
     56  get isWorkerDescriptor() {
     57    return true;
     58  }
     59 
     60  get isDedicatedWorker() {
     61    return this.type === Ci.nsIWorkerDebugger.TYPE_DEDICATED;
     62  }
     63 
     64  get isSharedWorker() {
     65    return this.type === Ci.nsIWorkerDebugger.TYPE_SHARED;
     66  }
     67 
     68  get isServiceWorker() {
     69    return this.type === Ci.nsIWorkerDebugger.TYPE_SERVICE;
     70  }
     71 
     72  // For now, WorkerDescriptor is morphed into a WorkerTarget when calling this method.
     73  // Ideally, we would split this into two distinct classes.
     74  async morphWorkerDescriptorIntoWorkerTarget() {
     75    // temporary, will be moved once we have a target actor
     76    return this.getTarget();
     77  }
     78 
     79  async getTarget() {
     80    if (this._attach) {
     81      return this._attach;
     82    }
     83 
     84    this._attach = (async () => {
     85      if (this.isDestroyedOrBeingDestroyed()) {
     86        return this;
     87      }
     88 
     89      if (this.isServiceWorker) {
     90        this.registration = await this._getRegistrationIfActive();
     91        if (this.registration) {
     92          await this.registration.preventShutdown();
     93        }
     94      }
     95 
     96      if (this.isDestroyedOrBeingDestroyed()) {
     97        return this;
     98      }
     99 
    100      const workerTargetForm = await super.getTarget();
    101 
    102      // Set the console and thread actor IDs on the form so it is accessible by TargetMixin.getFront
    103      this.targetForm.consoleActor = workerTargetForm.consoleActor;
    104      this.targetForm.threadActor = workerTargetForm.threadActor;
    105      this.targetForm.tracerActor = workerTargetForm.tracerActor;
    106 
    107      this.targetForm.targetType = workerTargetForm.targetType;
    108 
    109      if (this.isDestroyedOrBeingDestroyed()) {
    110        return this;
    111      }
    112 
    113      return this;
    114    })();
    115    return this._attach;
    116  }
    117 
    118  async detach() {
    119    try {
    120      await super.detach();
    121 
    122      if (this.registration) {
    123        // Bug 1644772 - Sometimes, the Browser Toolbox fails opening with a connection timeout
    124        // with an exception related to this call to allowShutdown and its usage of detachDebugger API.
    125        await this.registration.allowShutdown();
    126        this.registration = null;
    127      }
    128    } catch (e) {
    129      this.logDetachError(e, "worker");
    130    }
    131  }
    132 
    133  async _getRegistrationIfActive() {
    134    const { registrations } =
    135      await this.client.mainRoot.listServiceWorkerRegistrations();
    136    return registrations.find(({ activeWorker }) => {
    137      return activeWorker && this.id === activeWorker.id;
    138    });
    139  }
    140 
    141  reconfigure() {
    142    // Toolbox and options panel are calling this method but Worker Target can't be
    143    // reconfigured. So we ignore this call here.
    144    return Promise.resolve();
    145  }
    146 }
    147 
    148 registerFront(WorkerDescriptorFront);