michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: const Cu = Components.utils; michael@0: Cu.import("resource:///modules/devtools/gDevTools.jsm"); michael@0: const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); michael@0: const {require} = devtools; michael@0: const {ConnectionManager, Connection} = require("devtools/client/connection-manager"); michael@0: const promise = require("devtools/toolkit/deprecated-sync-thenables"); michael@0: const prefs = require('sdk/preferences/service'); michael@0: michael@0: michael@0: let UI = { michael@0: _toolboxTabCursor: 0, michael@0: _handledTargets: new Map(), michael@0: michael@0: connection: null, michael@0: michael@0: init: function() { michael@0: this.onLoad = this.onLoad.bind(this); michael@0: this.onUnload = this.onUnload.bind(this); michael@0: this.onMessage = this.onMessage.bind(this); michael@0: this.onConnected = this.onConnected.bind(this); michael@0: this.onDisconnected = this.onDisconnected.bind(this); michael@0: michael@0: window.addEventListener("load", this.onLoad); michael@0: window.addEventListener("unload", this.onUnload); michael@0: window.addEventListener("message", this.onMessage); michael@0: }, michael@0: michael@0: onLoad: function() { michael@0: window.removeEventListener("load", this.onLoad); michael@0: let defaultPanel = prefs.get("devtools.appmanager.lastTab"); michael@0: let panelExists = !!document.querySelector("." + defaultPanel + "-panel"); michael@0: this.selectTab(panelExists ? defaultPanel : "projects"); michael@0: }, michael@0: michael@0: onUnload: function() { michael@0: for (let [target, toolbox] of this._handledTargets) { michael@0: toolbox.destroy(); michael@0: } michael@0: michael@0: window.removeEventListener("unload", this.onUnload); michael@0: window.removeEventListener("message", this.onMessage); michael@0: if (this.connection) { michael@0: this.connection.off(Connection.Status.CONNECTED, this.onConnected); michael@0: this.connection.off(Connection.Status.DISCONNECTED, this.onDisconnected); michael@0: } michael@0: }, michael@0: michael@0: onMessage: function(event) { michael@0: try { michael@0: let json = JSON.parse(event.data); michael@0: switch (json.name) { michael@0: case "connection": michael@0: let cid = +json.cid; michael@0: for (let c of ConnectionManager.connections) { michael@0: if (c.uid == cid) { michael@0: this.onNewConnection(c); michael@0: break; michael@0: } michael@0: } michael@0: break; michael@0: case "closeHelp": michael@0: this.selectTab("projects"); michael@0: break; michael@0: case "toolbox-raise": michael@0: window.top.focus(); michael@0: this.selectTab(json.uid); michael@0: break; michael@0: case "toolbox-close": michael@0: this.closeToolboxTab(json.uid); michael@0: break; michael@0: case "toolbox-title": michael@0: // Not implemented michael@0: break; michael@0: default: michael@0: Cu.reportError("Unknown message: " + json.name); michael@0: } michael@0: } catch(e) { Cu.reportError(e); } michael@0: michael@0: // Forward message michael@0: let panels = document.querySelectorAll(".panel"); michael@0: for (let frame of panels) { michael@0: frame.contentWindow.postMessage(event.data, "*"); michael@0: } michael@0: }, michael@0: michael@0: selectTabFromButton: function(button) { michael@0: if (!button.hasAttribute("panel")) michael@0: return; michael@0: this.selectTab(button.getAttribute("panel")); michael@0: }, michael@0: michael@0: selectTab: function(panel) { michael@0: let isToolboxTab = false; michael@0: for (let type of ["button", "panel"]) { michael@0: let oldSelection = document.querySelector("." + type + "[selected]"); michael@0: let newSelection = document.querySelector("." + panel + "-" + type); michael@0: if (oldSelection) oldSelection.removeAttribute("selected"); michael@0: if (newSelection) { michael@0: newSelection.setAttribute("selected", "true"); michael@0: if (newSelection.classList.contains("toolbox")) { michael@0: isToolboxTab = true; michael@0: } michael@0: } michael@0: } michael@0: if (!isToolboxTab) { michael@0: prefs.set("devtools.appmanager.lastTab", panel); michael@0: } michael@0: }, michael@0: michael@0: onNewConnection: function(connection) { michael@0: this.connection = connection; michael@0: this.connection.on(Connection.Status.CONNECTED, this.onConnected); michael@0: this.connection.on(Connection.Status.DISCONNECTED, this.onDisconnected); michael@0: }, michael@0: michael@0: onConnected: function() { michael@0: document.querySelector("#content").classList.add("connected"); michael@0: }, michael@0: michael@0: onDisconnected: function() { michael@0: for (let [,toolbox] of this._handledTargets) { michael@0: if (toolbox) { michael@0: toolbox.destroy(); michael@0: } michael@0: } michael@0: this._handledTargets.clear(); michael@0: document.querySelector("#content").classList.remove("connected"); michael@0: }, michael@0: michael@0: createToolboxTab: function(name, iconURL, uid) { michael@0: let button = document.createElement("button"); michael@0: button.className = "button toolbox " + uid + "-button"; michael@0: button.setAttribute("panel", uid); michael@0: button.textContent = name; michael@0: button.setAttribute("style", "background-image: url(" + iconURL + ")"); michael@0: let toolboxTabs = document.querySelector("#toolbox-tabs"); michael@0: toolboxTabs.appendChild(button); michael@0: let iframe = document.createElement("iframe"); michael@0: iframe.setAttribute("flex", "1"); michael@0: iframe.className = "panel toolbox " + uid + "-panel"; michael@0: let panels = document.querySelector("#tab-panels"); michael@0: panels.appendChild(iframe); michael@0: this.selectTab(uid); michael@0: return iframe; michael@0: }, michael@0: michael@0: closeToolboxTab: function(uid) { michael@0: let buttonToDestroy = document.querySelector("." + uid + "-button"); michael@0: let panelToDestroy = document.querySelector("." + uid + "-panel"); michael@0: michael@0: if (buttonToDestroy.hasAttribute("selected")) { michael@0: let lastTab = prefs.get("devtools.appmanager.lastTab"); michael@0: this.selectTab(lastTab); michael@0: } michael@0: michael@0: buttonToDestroy.remove(); michael@0: panelToDestroy.remove(); michael@0: }, michael@0: michael@0: openAndShowToolboxForTarget: function(target, name, icon) { michael@0: let host = devtools.Toolbox.HostType.CUSTOM; michael@0: let toolbox = gDevTools.getToolbox(target); michael@0: if (!toolbox) { michael@0: let uid = "uid" + this._toolboxTabCursor++; michael@0: let iframe = this.createToolboxTab(name, icon, uid); michael@0: let options = { customIframe: iframe , uid: uid }; michael@0: this._handledTargets.set(target, null); michael@0: return gDevTools.showToolbox(target, null, host, options).then(toolbox => { michael@0: this._handledTargets.set(target, toolbox); michael@0: toolbox.once("destroyed", () => { michael@0: this._handledTargets.delete(target) michael@0: }); michael@0: }); michael@0: } else { michael@0: return gDevTools.showToolbox(target, null, host); michael@0: } michael@0: } michael@0: } michael@0: michael@0: UI.init();