summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/index.js')
-rw-r--r--devtools/shared/commands/index.js133
1 files changed, 133 insertions, 0 deletions
diff --git a/devtools/shared/commands/index.js b/devtools/shared/commands/index.js
new file mode 100644
index 0000000000..94cf7717cb
--- /dev/null
+++ b/devtools/shared/commands/index.js
@@ -0,0 +1,133 @@
+/* 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";
+
+// List of all command modules
+// (please try to keep the list alphabetically sorted)
+/* eslint sort-keys: "error" */
+/* eslint-enable sort-keys */
+const Commands = {
+ inspectedWindowCommand:
+ "devtools/shared/commands/inspected-window/inspected-window-command",
+ inspectorCommand: "devtools/shared/commands/inspector/inspector-command",
+ networkCommand: "devtools/shared/commands/network/network-command",
+ resourceCommand: "devtools/shared/commands/resource/resource-command",
+ rootResourceCommand:
+ "devtools/shared/commands/root-resource/root-resource-command",
+ scriptCommand: "devtools/shared/commands/script/script-command",
+ targetCommand: "devtools/shared/commands/target/target-command",
+ targetConfigurationCommand:
+ "devtools/shared/commands/target-configuration/target-configuration-command",
+ threadConfigurationCommand:
+ "devtools/shared/commands/thread-configuration/thread-configuration-command",
+};
+/* eslint-disable sort-keys */
+
+/**
+ * For a given descriptor and its related Targets, already initialized,
+ * return the dictionary with all command instances.
+ * This dictionary is lazy and commands will be loaded and instanciated on-demand.
+ */
+async function createCommandsDictionary(descriptorFront) {
+ // Bug 1675763: Watcher actor is not available in all situations yet.
+ let watcherFront;
+ const supportsWatcher = descriptorFront.traits?.watcher;
+ if (supportsWatcher) {
+ watcherFront = await descriptorFront.getWatcher();
+ }
+ const { client } = descriptorFront;
+
+ const allInstantiatedCommands = new Set();
+
+ const dictionary = {
+ // Expose both client and descriptor for legacy codebases, or tests.
+ // But ideally only commands should interact with these two objects
+ client,
+ descriptorFront,
+ watcherFront,
+
+ // Expose for tests
+ waitForRequestsToSettle() {
+ return descriptorFront.client.waitForRequestsToSettle();
+ },
+
+ // Boolean flag to know if the DevtoolsClient should be closed
+ // when this commands happens to be destroyed.
+ // This is set by:
+ // * commands-from-url in case we are opening a toolbox
+ // with a dedicated DevToolsClient (mostly from about:debugging, when the client isn't "cached").
+ // * CommandsFactory, when we are connecting to a local tab and expect
+ // the client, toolbox and descriptor to all follow the same lifecycle.
+ shouldCloseClient: true,
+
+ /**
+ * Destroy the commands which will destroy:
+ * - all inner commands,
+ * - the related descriptor,
+ * - the related DevToolsClient (not always)
+ */
+ async destroy() {
+ descriptorFront.off("descriptor-destroyed", this.destroy);
+
+ // Destroy all inner command modules
+ for (const command of allInstantiatedCommands) {
+ if (typeof command.destroy == "function") {
+ command.destroy();
+ }
+ }
+ allInstantiatedCommands.clear();
+
+ // Destroy the descriptor front, and all its children fronts.
+ // Watcher, targets,...
+ //
+ // Note that DescriptorFront.destroy will be null because of Pool.destroy
+ // when this function is called while the descriptor front itself is being
+ // destroyed.
+ if (!descriptorFront.isDestroyed()) {
+ await descriptorFront.destroy();
+ }
+
+ // Close the DevToolsClient. Shutting down the connection
+ // to the debuggable context and its DevToolsServer.
+ //
+ // See shouldCloseClient jsdoc about this condition.
+ if (this.shouldCloseClient) {
+ await client.close();
+ }
+ },
+ };
+ dictionary.destroy = dictionary.destroy.bind(dictionary);
+
+ // Automatically destroy the commands object if the descriptor
+ // happens to be destroyed. Which means that the debuggable context
+ // is no longer debuggable.
+ descriptorFront.on("descriptor-destroyed", dictionary.destroy);
+
+ for (const name in Commands) {
+ loader.lazyGetter(dictionary, name, () => {
+ const Constructor = require(Commands[name]);
+ const command = new Constructor({
+ // Commands can use other commands
+ commands: dictionary,
+
+ // The context to inspect identified by this descriptor
+ descriptorFront,
+
+ // The front for the Watcher Actor, related to the given descriptor
+ // This is a key actor to watch for targets and resources and pull global actors running in the parent process
+ watcherFront,
+
+ // From here, we could pass DevToolsClient, or any useful protocol classes...
+ // so that we abstract where and how to fetch all necessary interfaces
+ // and avoid having to know that you might pull the client via descriptorFront.client
+ });
+ allInstantiatedCommands.add(command);
+ return command;
+ });
+ }
+
+ return dictionary;
+}
+exports.createCommandsDictionary = createCommandsDictionary;