diff options
Diffstat (limited to 'toolkit/devtools/framework/toolbox-process-window.js')
-rw-r--r-- | toolkit/devtools/framework/toolbox-process-window.js | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/toolkit/devtools/framework/toolbox-process-window.js b/toolkit/devtools/framework/toolbox-process-window.js new file mode 100644 index 000000000..7cc5c9dff --- /dev/null +++ b/toolkit/devtools/framework/toolbox-process-window.js @@ -0,0 +1,185 @@ +/* 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"; + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {}); +let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +let { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); +let { DebuggerClient } = + Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {}); +let { ViewHelpers } = + Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {}); +let { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); + +/** + * Shortcuts for accessing various debugger preferences. + */ +let Prefs = new ViewHelpers.Prefs("devtools.debugger", { + chromeDebuggingHost: ["Char", "chrome-debugging-host"], + chromeDebuggingPort: ["Int", "chrome-debugging-port"] +}); + +let gToolbox, gClient; + +let connect = Task.async(function*() { + window.removeEventListener("load", connect); + // Initiate the connection + let transport = yield DebuggerClient.socketConnect({ + host: Prefs.chromeDebuggingHost, + port: Prefs.chromeDebuggingPort + }); + gClient = new DebuggerClient(transport); + gClient.connect(() => { + let addonID = getParameterByName("addonID"); + + if (addonID) { + gClient.listAddons(({addons}) => { + let addonActor = addons.filter(addon => addon.id === addonID).pop(); + openToolbox(addonActor); + }); + } else { + gClient.listTabs(openToolbox); + } + }); +}); + +// Certain options should be toggled since we can assume chrome debugging here +function setPrefDefaults() { + Services.prefs.setBoolPref("devtools.inspector.showUserAgentStyles", true); + Services.prefs.setBoolPref("devtools.profiler.ui.show-platform-data", true); + Services.prefs.setBoolPref("browser.devedition.theme.showCustomizeButton", false); + Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true); +} + +window.addEventListener("load", function() { + let cmdClose = document.getElementById("toolbox-cmd-close"); + cmdClose.addEventListener("command", onCloseCommand); + setPrefDefaults(); + connect().catch(Cu.reportError); +}); + +function onCloseCommand(event) { + window.close(); +} + +function openToolbox(form) { + let options = { + form: form, + client: gClient, + chrome: true + }; + devtools.TargetFactory.forRemoteTab(options).then(target => { + let frame = document.getElementById("toolbox-iframe"); + let selectedTool = "jsdebugger"; + + try { + // Remember the last panel that was used inside of this profile. + selectedTool = Services.prefs.getCharPref("devtools.toolbox.selectedTool"); + } catch(e) {} + + try { + // But if we are testing, then it should always open the debugger panel. + selectedTool = Services.prefs.getCharPref("devtools.browsertoolbox.panel"); + } catch(e) {} + + let options = { customIframe: frame }; + gDevTools.showToolbox(target, + selectedTool, + devtools.Toolbox.HostType.CUSTOM, + options) + .then(onNewToolbox); + }); +} + +function onNewToolbox(toolbox) { + gToolbox = toolbox; + bindToolboxHandlers(); + raise(); +} + +function bindToolboxHandlers() { + gToolbox.once("destroyed", quitApp); + window.addEventListener("unload", onUnload); + +#ifdef XP_MACOSX + // Badge the dock icon to differentiate this process from the main application process. + updateBadgeText(false); + + // Once the debugger panel opens listen for thread pause / resume. + gToolbox.getPanelWhenReady("jsdebugger").then(panel => { + setupThreadListeners(panel); + }); +#endif +} + +function setupThreadListeners(panel) { + updateBadgeText(panel._controller.activeThread.state == "paused"); + + let onPaused = updateBadgeText.bind(null, true); + let onResumed = updateBadgeText.bind(null, false); + panel.target.on("thread-paused", onPaused); + panel.target.on("thread-resumed", onResumed); + + panel.once("destroyed", () => { + panel.off("thread-paused", onPaused); + panel.off("thread-resumed", onResumed); + }); +} + +function updateBadgeText(paused) { + let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"].getService(Ci.nsIMacDockSupport); + dockSupport.badgeText = paused ? "▐▐ " : " ▶"; +} + +function onUnload() { + window.removeEventListener("unload", onUnload); + window.removeEventListener("message", onMessage); + let cmdClose = document.getElementById("toolbox-cmd-close"); + cmdClose.removeEventListener("command", onCloseCommand); + gToolbox.destroy(); +} + +function onMessage(event) { + try { + let json = JSON.parse(event.data); + switch (json.name) { + case "toolbox-raise": + raise(); + break; + case "toolbox-title": + setTitle(json.data.value); + break; + } + } catch(e) { Cu.reportError(e); } +} + +window.addEventListener("message", onMessage); + +function raise() { + window.focus(); +} + +function setTitle(title) { + document.title = title; +} + +function quitApp() { + let quit = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); + Services.obs.notifyObservers(quit, "quit-application-requested", null); + + let shouldProceed = !quit.data; + if (shouldProceed) { + Services.startup.quit(Ci.nsIAppStartup.eForceQuit); + } +} + +function getParameterByName (name) { + name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); + let regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + let results = regex.exec(window.location.search); + return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); +} |