123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
- /* 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";
- var Cu = Components.utils;
- var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
- var Services = require("Services");
- var {gDevTools} = require("devtools/client/framework/devtools");
- var {TargetFactory} = require("devtools/client/framework/target");
- var {Toolbox} = require("devtools/client/framework/toolbox");
- var {DebuggerClient} = require("devtools/shared/client/main");
- var {Task} = require("devtools/shared/task");
- var {LocalizationHelper} = require("devtools/shared/l10n");
- var L10N = new LocalizationHelper("devtools/client/locales/connection-screen.properties");
- var gClient;
- var gConnectionTimeout;
- /**
- * Once DOM is ready, we prefil the host/port inputs with
- * pref-stored values.
- */
- window.addEventListener("DOMContentLoaded", function onDOMReady() {
- window.removeEventListener("DOMContentLoaded", onDOMReady, true);
- let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
- let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
- if (host) {
- document.getElementById("host").value = host;
- }
- if (port) {
- document.getElementById("port").value = port;
- }
- let form = document.querySelector("#connection-form form");
- form.addEventListener("submit", function () {
- window.submit().catch(e => {
- console.error(e);
- // Bug 921850: catch rare exception from DebuggerClient.socketConnect
- showError("unexpected");
- });
- });
- }, true);
- /**
- * Called when the "connect" button is clicked.
- */
- var submit = Task.async(function* () {
- // Show the "connecting" screen
- document.body.classList.add("connecting");
- let host = document.getElementById("host").value;
- let port = document.getElementById("port").value;
- // Save the host/port values
- try {
- Services.prefs.setCharPref("devtools.debugger.remote-host", host);
- Services.prefs.setIntPref("devtools.debugger.remote-port", port);
- } catch (e) {
- // Fails in e10s mode, but not a critical feature.
- }
- // Initiate the connection
- let transport = yield DebuggerClient.socketConnect({ host, port });
- gClient = new DebuggerClient(transport);
- let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout");
- gConnectionTimeout = setTimeout(handleConnectionTimeout, delay);
- let response = yield gClient.connect();
- yield onConnectionReady(...response);
- });
- /**
- * Connection is ready. List actors and build buttons.
- */
- var onConnectionReady = Task.async(function* ([aType, aTraits]) {
- clearTimeout(gConnectionTimeout);
- let response = yield gClient.listAddons();
- let parent = document.getElementById("addonActors");
- if (!response.error && response.addons.length > 0) {
- // Add one entry for each add-on.
- for (let addon of response.addons) {
- if (!addon.debuggable) {
- continue;
- }
- buildAddonLink(addon, parent);
- }
- }
- else {
- // Hide the section when there are no add-ons
- parent.previousElementSibling.remove();
- parent.remove();
- }
- response = yield gClient.listTabs();
- parent = document.getElementById("tabActors");
- // Add Global Process debugging...
- let globals = Cu.cloneInto(response, {});
- delete globals.tabs;
- delete globals.selected;
- // ...only if there are appropriate actors (a 'from' property will always
- // be there).
- // Add one entry for each open tab.
- for (let i = 0; i < response.tabs.length; i++) {
- buildTabLink(response.tabs[i], parent, i == response.selected);
- }
- let gParent = document.getElementById("globalActors");
- // Build the Remote Process button
- // If Fx<39, tab actors were used to be exposed on RootActor
- // but in Fx>=39, chrome is debuggable via getProcess() and ChromeActor
- if (globals.consoleActor || gClient.mainRoot.traits.allowChromeProcess) {
- let a = document.createElement("a");
- a.onclick = function () {
- if (gClient.mainRoot.traits.allowChromeProcess) {
- gClient.getProcess()
- .then(aResponse => {
- openToolbox(aResponse.form, true);
- });
- } else if (globals.consoleActor) {
- openToolbox(globals, true, "webconsole", false);
- }
- };
- a.title = a.textContent = L10N.getStr("mainProcess");
- a.className = "remote-process";
- a.href = "#";
- gParent.appendChild(a);
- }
- // Move the selected tab on top
- let selectedLink = parent.querySelector("a.selected");
- if (selectedLink) {
- parent.insertBefore(selectedLink, parent.firstChild);
- }
- document.body.classList.remove("connecting");
- document.body.classList.add("actors-mode");
- // Ensure the first link is focused
- let firstLink = parent.querySelector("a:first-of-type");
- if (firstLink) {
- firstLink.focus();
- }
- });
- /**
- * Build one button for an add-on actor.
- */
- function buildAddonLink(addon, parent) {
- let a = document.createElement("a");
- a.onclick = function () {
- openToolbox(addon, true, "jsdebugger", false);
- };
- a.textContent = addon.name;
- a.title = addon.id;
- a.href = "#";
- parent.appendChild(a);
- }
- /**
- * Build one button for a tab actor.
- */
- function buildTabLink(tab, parent, selected) {
- let a = document.createElement("a");
- a.onclick = function () {
- openToolbox(tab);
- };
- a.textContent = tab.title;
- a.title = tab.url;
- if (!a.textContent) {
- a.textContent = tab.url;
- }
- a.href = "#";
- if (selected) {
- a.classList.add("selected");
- }
- parent.appendChild(a);
- }
- /**
- * An error occured. Let's show it and return to the first screen.
- */
- function showError(type) {
- document.body.className = "error";
- let activeError = document.querySelector(".error-message.active");
- if (activeError) {
- activeError.classList.remove("active");
- }
- activeError = document.querySelector(".error-" + type);
- if (activeError) {
- activeError.classList.add("active");
- }
- }
- /**
- * Connection timeout.
- */
- function handleConnectionTimeout() {
- showError("timeout");
- }
- /**
- * The user clicked on one of the buttons.
- * Opens the toolbox.
- */
- function openToolbox(form, chrome = false, tool = "webconsole", isTabActor) {
- let options = {
- form: form,
- client: gClient,
- chrome: chrome,
- isTabActor: isTabActor
- };
- TargetFactory.forRemoteTab(options).then((target) => {
- let hostType = Toolbox.HostType.WINDOW;
- gDevTools.showToolbox(target, tool, hostType).then((toolbox) => {
- toolbox.once("destroyed", function () {
- gClient.close();
- });
- }, console.error.bind(console));
- window.close();
- }, console.error.bind(console));
- }
|