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);