browser/devtools/framework/connect/connect.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 "use strict";
     9 const Cu = Components.utils;
    10 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
    11 Cu.import("resource://gre/modules/Services.jsm");
    12 Cu.import("resource://gre/modules/Task.jsm");
    13 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
    14 let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
    15 let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
    16 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
    18 let gClient;
    19 let gConnectionTimeout;
    21 XPCOMUtils.defineLazyGetter(window, 'l10n', function () {
    22   return Services.strings.createBundle('chrome://browser/locale/devtools/connection-screen.properties');
    23 });
    25 /**
    26  * Once DOM is ready, we prefil the host/port inputs with
    27  * pref-stored values.
    28  */
    29 window.addEventListener("DOMContentLoaded", function onDOMReady() {
    30   window.removeEventListener("DOMContentLoaded", onDOMReady, true);
    31   let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
    32   let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
    34   if (host) {
    35     document.getElementById("host").value = host;
    36   }
    38   if (port) {
    39     document.getElementById("port").value = port;
    40   }
    42   let form = document.querySelector("#connection-form form");
    43   form.addEventListener("submit", function() {
    44     window.submit();
    45   });
    46 }, true);
    48 /**
    49  * Called when the "connect" button is clicked.
    50  */
    51 function submit() {
    52   // Show the "connecting" screen
    53   document.body.classList.add("connecting");
    55   // Save the host/port values
    56   let host = document.getElementById("host").value;
    57   Services.prefs.setCharPref("devtools.debugger.remote-host", host);
    59   let port = document.getElementById("port").value;
    60   Services.prefs.setIntPref("devtools.debugger.remote-port", port);
    62   // Initiate the connection
    63   let transport;
    64   try {
    65     transport = debuggerSocketConnect(host, port);
    66   } catch(e) {
    67     // Bug 921850: catch rare exception from debuggerSocketConnect
    68     showError("unexpected");
    69     return;
    70   }
    71   gClient = new DebuggerClient(transport);
    72   let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout");
    73   gConnectionTimeout = setTimeout(handleConnectionTimeout, delay);
    74   gClient.connect(onConnectionReady);
    75 }
    77 /**
    78  * Connection is ready. List actors and build buttons.
    79  */
    80 let onConnectionReady = Task.async(function*(aType, aTraits) {
    81   clearTimeout(gConnectionTimeout);
    83   let deferred = promise.defer();
    84   gClient.listAddons(deferred.resolve);
    85   let response = yield deferred.promise;
    87   let parent = document.getElementById("addonActors")
    88   if (!response.error && response.addons.length > 0) {
    89     // Add one entry for each add-on.
    90     for (let addon of response.addons) {
    91       if (!addon.debuggable) {
    92         continue;
    93       }
    94       buildAddonLink(addon, parent);
    95     }
    96   }
    97   else {
    98     // Hide the section when there are no add-ons
    99     parent.previousElementSibling.remove();
   100     parent.remove();
   101   }
   103   deferred = promise.defer();
   104   gClient.listTabs(deferred.resolve);
   105   response = yield deferred.promise;
   107   parent = document.getElementById("tabActors");
   109   // Add Global Process debugging...
   110   let globals = JSON.parse(JSON.stringify(response));
   111   delete globals.tabs;
   112   delete globals.selected;
   113   // ...only if there are appropriate actors (a 'from' property will always
   114   // be there).
   116   // Add one entry for each open tab.
   117   for (let i = 0; i < response.tabs.length; i++) {
   118     buildTabLink(response.tabs[i], parent, i == response.selected);
   119   }
   121   let gParent = document.getElementById("globalActors");
   123   // Build the Remote Process button
   124   if (Object.keys(globals).length > 1) {
   125     let a = document.createElement("a");
   126     a.onclick = function() {
   127       openToolbox(globals, true);
   129     }
   130     a.title = a.textContent = window.l10n.GetStringFromName("mainProcess");
   131     a.className = "remote-process";
   132     a.href = "#";
   133     gParent.appendChild(a);
   134   }
   135   // Move the selected tab on top
   136   let selectedLink = parent.querySelector("a.selected");
   137   if (selectedLink) {
   138     parent.insertBefore(selectedLink, parent.firstChild);
   139   }
   141   document.body.classList.remove("connecting");
   142   document.body.classList.add("actors-mode");
   144   // Ensure the first link is focused
   145   let firstLink = parent.querySelector("a:first-of-type");
   146   if (firstLink) {
   147     firstLink.focus();
   148   }
   149 });
   151 /**
   152  * Build one button for an add-on actor.
   153  */
   154 function buildAddonLink(addon, parent) {
   155   let a = document.createElement("a");
   156   a.onclick = function() {
   157     openToolbox({ addonActor: addon.actor, title: addon.name }, true, "jsdebugger");
   158   }
   160   a.textContent = addon.name;
   161   a.title = addon.id;
   162   a.href = "#";
   164   parent.appendChild(a);
   165 }
   167 /**
   168  * Build one button for a tab actor.
   169  */
   170 function buildTabLink(tab, parent, selected) {
   171   let a = document.createElement("a");
   172   a.onclick = function() {
   173     openToolbox(tab);
   174   }
   176   a.textContent = tab.title;
   177   a.title = tab.url;
   178   if (!a.textContent) {
   179     a.textContent = tab.url;
   180   }
   181   a.href = "#";
   183   if (selected) {
   184     a.classList.add("selected");
   185   }
   187   parent.appendChild(a);
   188 }
   190 /**
   191  * An error occured. Let's show it and return to the first screen.
   192  */
   193 function showError(type) {
   194   document.body.className = "error";
   195   let activeError = document.querySelector(".error-message.active");
   196   if (activeError) {
   197     activeError.classList.remove("active");
   198   }
   199   activeError = document.querySelector(".error-" + type);
   200   if (activeError) {
   201     activeError.classList.add("active");
   202   }
   203 }
   205 /**
   206  * Connection timeout.
   207  */
   208 function handleConnectionTimeout() {
   209   showError("timeout");
   210 }
   212 /**
   213  * The user clicked on one of the buttons.
   214  * Opens the toolbox.
   215  */
   216 function openToolbox(form, chrome=false, tool="webconsole") {
   217   let options = {
   218     form: form,
   219     client: gClient,
   220     chrome: chrome
   221   };
   222   devtools.TargetFactory.forRemoteTab(options).then((target) => {
   223     let hostType = devtools.Toolbox.HostType.WINDOW;
   224     gDevTools.showToolbox(target, tool, hostType).then((toolbox) => {
   225       toolbox.once("destroyed", function() {
   226         gClient.close();
   227       });
   228     });
   229     window.close();
   230   });
   231 }

mercurial