/* 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/. */ "use strict";
// Cache root form as this will always be the same value.
Object.defineProperty(this, "rootForm", {
get() { deletethis.rootForm; this.rootForm = this.getRoot(); returnthis.rootForm;
},
configurable: true,
});
// Cache of already created global scoped fronts // [typeName:string => Front instance] this.fronts = new Map();
this._client = client;
}
form(form) { // Root Front is a special Front. It is the only one to set its actor ID manually // out of the form object returned by RootActor.sayHello which is called when calling // DevToolsClient.connect(). this.actorID = form.from;
this.applicationType = form.applicationType; this.traits = form.traits;
} /** * Retrieve all service worker registrations with their corresponding workers. * @param {Array} [workerTargets] (optional) * Array containing the result of a call to `listAllWorkerTargets`. * (this exists to avoid duplication of calls to that method) * @return {Object[]} result - An Array of Objects with the following format * - {result[].registration} - The registration front * - {result[].workers} Array of form-like objects for service workers
*/
async listAllServiceWorkers(workerTargets) { const result = []; const { registrations } = await this.listServiceWorkerRegistrations(); const allWorkers = workerTargets
? workerTargets
: await this.listAllWorkerTargets();
for (const registrationFront of registrations) { // workers from the registration, ordered from most recent to older const workers = [
registrationFront.activeWorker,
registrationFront.waitingWorker,
registrationFront.installingWorker,
registrationFront.evaluatingWorker,
] // filter out non-existing workers
.filter(w => !!w) // build a worker object with its WorkerDescriptorFront
.map(workerFront => { const workerDescriptorFront = allWorkers.find(
targetFront => targetFront.id === workerFront.id
);
// TODO: return only the worker targets. See Bug 1620605
result.push({
registration: registrationFront,
workers,
});
}
return result;
}
/** * Retrieve all service worker registrations as well as workers from the parent and * content processes. Listing service workers involves merging information coming from * registrations and workers, this method will combine this information to present a * unified array of serviceWorkers. If you are only interested in other workers, use * listWorkers. * * @return {Object} * - {Array} service * array of form-like objects for serviceworkers * - {Array} shared * Array of WorkerTargetActor forms, containing shared workers. * - {Array} other * Array of WorkerTargetActor forms, containing other workers.
*/
async listAllWorkers() { const allWorkers = await this.listAllWorkerTargets(); const serviceWorkers = await this.listAllServiceWorkers(allWorkers);
// NOTE: listAllServiceWorkers() now returns all the workers belonging to // a registration. To preserve the usual behavior at about:debugging, // in which we show only the most recent one, we grab the first // worker in the array only. const result = {
service: serviceWorkers
.map(({ registration, workers }) => { return workers.slice(0, 1).map(worker => { return Object.assign(worker, {
registrationFront: registration,
fetch: registration.fetch,
});
});
})
.flat(),
shared: [],
other: [],
};
switch (front.type) { case Ci.nsIWorkerDebugger.TYPE_SERVICE: // do nothing, since we already fetched them in `serviceWorkers` break; case Ci.nsIWorkerDebugger.TYPE_SHARED:
result.shared.push(worker); break; default:
result.other.push(worker);
}
});
return result;
}
/** Get the target fronts for all worker threads running in any process. */
async listAllWorkerTargets() { const listParentWorkers = async () => { const { workers } = await this.listWorkers(); return workers;
}; const listChildWorkers = async () => { const processes = await this.listProcesses(); const processWorkers = await Promise.all(
processes.map(async processDescriptorFront => { // Ignore parent process if (processDescriptorFront.isParentProcessDescriptor) { return [];
} try { const front = await processDescriptorFront.getTarget(); if (!front) { return [];
} const response = await front.listWorkers(); return response.workers;
} catch (e) { if (e.message.includes("Connection closed")) { return [];
} throw e;
}
})
);
/** * Fetch the ProcessDescriptorFront for the main process. * * `getProcess` requests allows to fetch the descriptor for any process and * the main process is having the process ID zero.
*/
getMainProcess() { returnthis.getProcess(0);
}
/** * Fetch the tab descriptor for the currently selected tab, or for a specific * tab given as first parameter. * * @param [optional] object filter * A dictionary object with following optional attributes: * - browserId: use to match any tab * - tab: a reference to xul:tab element (used for local tab debugging) * - isWebExtension: an optional boolean to flag TabDescriptors * If nothing is specified, returns the actor for the currently * selected tab.
*/
async getTab(filter) { const packet = {}; if (filter) { if (typeof filter.browserId == "number") {
packet.browserId = filter.browserId;
} elseif ("tab" in filter) { const browser = filter.tab.linkedBrowser;
packet.browserId = browser.browserId;
} else { // Throw if a filter object have been passed but without // any clearly idenfified filter. thrownew Error("Unsupported argument given to getTab request");
}
}
// Will flag TabDescriptor used by WebExtension codebase. if (filter?.isWebExtension) {
descriptorFront.setIsForWebExtension(true);
}
// If the tab is a local tab, forward it to the descriptor. if (filter?.tab?.tagName == "tab") { // Ignore the fake `tab` object we receive, where there is only a // `linkedBrowser` attribute, but this isn't a real <tab> element. // devtools/client/framework/test/browser_toolbox_target.js is passing such // a fake tab.
descriptorFront.setLocalTab(filter.tab);
}
return descriptorFront;
}
/** * Fetch the target front for a given add-on. * This is just an helper on top of `listAddons` request. * * @param object filter * A dictionary object with following attribute: * - id: used to match the add-on to connect to.
*/
async getAddon({ id }) { const addons = await this.listAddons(); const webextensionDescriptorFront = addons.find(addon => addon.id === id); return webextensionDescriptorFront;
}
/** * Fetch the target front for a given worker. * This is just an helper on top of `listAllWorkers` request. * * @param id
*/
async getWorker(id) { const { service, shared, other } = await this.listAllWorkers(); const worker = [...service, ...shared, ...other].find(w => w.id === id); if (!worker) { returnnull;
} return worker.workerDescriptorFront || worker.registrationFront;
}
/** * Test request that returns the object passed as first argument. * * `echo` is special as all the property of the given object have to be passed * on the packet object. That's not something that can be achieve by requester helper.
*/
/* * This function returns a protocol.js Front for any root actor. * i.e. the one directly served from RootActor.listTabs or getRoot. * * @param String typeName * The type name used in protocol.js's spec for this actor.
*/
async getFront(typeName) {
let front = this.fronts.get(typeName); if (front) { return front;
} const rootForm = await this.rootForm;
front = getFront(this._client, typeName, rootForm); this.fronts.set(typeName, front); return front;
}
/* * This function returns true if the root actor has a registered global actor * with a given name. * @param {String} actorName * The name of a global actor. * * @return {Boolean}
*/
async hasActor(actorName) { const rootForm = await this.rootForm; return !!rootForm[actorName + "Actor"];
}
}
exports.RootFront = RootFront;
registerFront(RootFront);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.