summaryrefslogtreecommitdiffstats
path: root/devtools/client/framework/toolbox-init.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/framework/toolbox-init.js')
-rw-r--r--devtools/client/framework/toolbox-init.js135
1 files changed, 135 insertions, 0 deletions
diff --git a/devtools/client/framework/toolbox-init.js b/devtools/client/framework/toolbox-init.js
new file mode 100644
index 0000000000..de2bce080a
--- /dev/null
+++ b/devtools/client/framework/toolbox-init.js
@@ -0,0 +1,135 @@
+/* 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/. */
+
+/* eslint-env browser */
+
+"use strict";
+
+const { require } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/Loader.sys.mjs"
+);
+
+// URL constructor doesn't support about: scheme
+const href = window.location.href.replace("about:", "http://");
+const url = new window.URL(href);
+
+// `host` is the frame element loading the toolbox.
+let host = window.browsingContext.embedderElement;
+
+// If there's no containerElement (which happens when loading about:devtools-toolbox as
+// a top level document), use the current window.
+if (!host) {
+ host = {
+ contentWindow: window,
+ contentDocument: document,
+ // toolbox-host-manager.js wants to set attributes on the frame that contains it,
+ // but that is fine to skip and doesn't make sense when using the current window.
+ setAttribute() {},
+ ownerDocument: document,
+ // toolbox-host-manager.js wants to listen for unload events from outside the frame,
+ // but this is fine to skip since the toolbox code listens inside the frame as well,
+ // and there is no outer document in this case.
+ addEventListener() {},
+ };
+}
+
+const onLoad = new Promise(r => {
+ host.contentWindow.addEventListener("DOMContentLoaded", r, { once: true });
+});
+
+async function showErrorPage(doc, errorMessage) {
+ const win = doc.defaultView;
+ const { BrowserLoader } = ChromeUtils.import(
+ "resource://devtools/shared/loader/browser-loader.js"
+ );
+ const browserRequire = BrowserLoader({
+ window: win,
+ useOnlyShared: true,
+ }).require;
+
+ const React = browserRequire("devtools/client/shared/vendor/react");
+ const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
+ const DebugTargetErrorPage = React.createFactory(
+ require("resource://devtools/client/framework/components/DebugTargetErrorPage.js")
+ );
+ const { LocalizationHelper } = browserRequire("devtools/shared/l10n");
+ const L10N = new LocalizationHelper(
+ "devtools/client/locales/toolbox.properties"
+ );
+
+ // mount the React component into our XUL container once the DOM is ready
+ await onLoad;
+
+ // Update the tab title.
+ document.title = L10N.getStr("toolbox.debugTargetInfo.tabTitleError");
+
+ const mountEl = doc.querySelector("#toolbox-error-mount");
+ const element = DebugTargetErrorPage({
+ errorMessage,
+ L10N,
+ });
+ ReactDOM.render(element, mountEl);
+
+ // make sure we unmount the component when the page is destroyed
+ win.addEventListener(
+ "unload",
+ () => {
+ ReactDOM.unmountComponentAtNode(mountEl);
+ },
+ { once: true }
+ );
+}
+
+async function initToolbox(url, host) {
+ const {
+ gDevTools,
+ } = require("resource://devtools/client/framework/devtools.js");
+
+ const {
+ commandsFromURL,
+ } = require("resource://devtools/client/framework/commands-from-url.js");
+ const {
+ Toolbox,
+ } = require("resource://devtools/client/framework/toolbox.js");
+
+ // Specify the default tool to open
+ const tool = url.searchParams.get("tool");
+
+ try {
+ const commands = await commandsFromURL(url);
+ const toolbox = gDevTools.getToolboxForCommands(commands);
+ if (toolbox && toolbox.isDestroying()) {
+ // If a toolbox already exists for the commands, wait for current
+ // toolbox destroy to be finished.
+ await toolbox.destroy();
+ }
+
+ // Display an error page if we are connected to a remote target and we lose it
+ commands.descriptorFront.once("descriptor-destroyed", function () {
+ // Prevent trying to display the error page if the toolbox tab is being destroyed
+ if (host.contentDocument) {
+ const error = new Error("Debug target was disconnected");
+ showErrorPage(host.contentDocument, `${error}`);
+ }
+ });
+
+ const options = { customIframe: host };
+ await gDevTools.showToolbox(commands, {
+ toolId: tool,
+ hostType: Toolbox.HostType.PAGE,
+ hostOptions: options,
+ });
+ } catch (error) {
+ // When an error occurs, show error page with message.
+ console.error("Exception while loading the toolbox", error);
+ showErrorPage(host.contentDocument, `${error}`);
+ }
+}
+
+// Only use this method to attach the toolbox if some query parameters are given
+if (url.search.length > 1) {
+ initToolbox(url, host);
+}
+// TODO: handle no params in about:devtool-toolbox
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1526996