|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Cu = Components.utils; |
|
6 Cu.import("resource:///modules/devtools/gDevTools.jsm"); |
|
7 const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); |
|
8 const {require} = devtools; |
|
9 const {ConnectionManager, Connection} = require("devtools/client/connection-manager"); |
|
10 const promise = require("devtools/toolkit/deprecated-sync-thenables"); |
|
11 const prefs = require('sdk/preferences/service'); |
|
12 |
|
13 |
|
14 let UI = { |
|
15 _toolboxTabCursor: 0, |
|
16 _handledTargets: new Map(), |
|
17 |
|
18 connection: null, |
|
19 |
|
20 init: function() { |
|
21 this.onLoad = this.onLoad.bind(this); |
|
22 this.onUnload = this.onUnload.bind(this); |
|
23 this.onMessage = this.onMessage.bind(this); |
|
24 this.onConnected = this.onConnected.bind(this); |
|
25 this.onDisconnected = this.onDisconnected.bind(this); |
|
26 |
|
27 window.addEventListener("load", this.onLoad); |
|
28 window.addEventListener("unload", this.onUnload); |
|
29 window.addEventListener("message", this.onMessage); |
|
30 }, |
|
31 |
|
32 onLoad: function() { |
|
33 window.removeEventListener("load", this.onLoad); |
|
34 let defaultPanel = prefs.get("devtools.appmanager.lastTab"); |
|
35 let panelExists = !!document.querySelector("." + defaultPanel + "-panel"); |
|
36 this.selectTab(panelExists ? defaultPanel : "projects"); |
|
37 }, |
|
38 |
|
39 onUnload: function() { |
|
40 for (let [target, toolbox] of this._handledTargets) { |
|
41 toolbox.destroy(); |
|
42 } |
|
43 |
|
44 window.removeEventListener("unload", this.onUnload); |
|
45 window.removeEventListener("message", this.onMessage); |
|
46 if (this.connection) { |
|
47 this.connection.off(Connection.Status.CONNECTED, this.onConnected); |
|
48 this.connection.off(Connection.Status.DISCONNECTED, this.onDisconnected); |
|
49 } |
|
50 }, |
|
51 |
|
52 onMessage: function(event) { |
|
53 try { |
|
54 let json = JSON.parse(event.data); |
|
55 switch (json.name) { |
|
56 case "connection": |
|
57 let cid = +json.cid; |
|
58 for (let c of ConnectionManager.connections) { |
|
59 if (c.uid == cid) { |
|
60 this.onNewConnection(c); |
|
61 break; |
|
62 } |
|
63 } |
|
64 break; |
|
65 case "closeHelp": |
|
66 this.selectTab("projects"); |
|
67 break; |
|
68 case "toolbox-raise": |
|
69 window.top.focus(); |
|
70 this.selectTab(json.uid); |
|
71 break; |
|
72 case "toolbox-close": |
|
73 this.closeToolboxTab(json.uid); |
|
74 break; |
|
75 case "toolbox-title": |
|
76 // Not implemented |
|
77 break; |
|
78 default: |
|
79 Cu.reportError("Unknown message: " + json.name); |
|
80 } |
|
81 } catch(e) { Cu.reportError(e); } |
|
82 |
|
83 // Forward message |
|
84 let panels = document.querySelectorAll(".panel"); |
|
85 for (let frame of panels) { |
|
86 frame.contentWindow.postMessage(event.data, "*"); |
|
87 } |
|
88 }, |
|
89 |
|
90 selectTabFromButton: function(button) { |
|
91 if (!button.hasAttribute("panel")) |
|
92 return; |
|
93 this.selectTab(button.getAttribute("panel")); |
|
94 }, |
|
95 |
|
96 selectTab: function(panel) { |
|
97 let isToolboxTab = false; |
|
98 for (let type of ["button", "panel"]) { |
|
99 let oldSelection = document.querySelector("." + type + "[selected]"); |
|
100 let newSelection = document.querySelector("." + panel + "-" + type); |
|
101 if (oldSelection) oldSelection.removeAttribute("selected"); |
|
102 if (newSelection) { |
|
103 newSelection.setAttribute("selected", "true"); |
|
104 if (newSelection.classList.contains("toolbox")) { |
|
105 isToolboxTab = true; |
|
106 } |
|
107 } |
|
108 } |
|
109 if (!isToolboxTab) { |
|
110 prefs.set("devtools.appmanager.lastTab", panel); |
|
111 } |
|
112 }, |
|
113 |
|
114 onNewConnection: function(connection) { |
|
115 this.connection = connection; |
|
116 this.connection.on(Connection.Status.CONNECTED, this.onConnected); |
|
117 this.connection.on(Connection.Status.DISCONNECTED, this.onDisconnected); |
|
118 }, |
|
119 |
|
120 onConnected: function() { |
|
121 document.querySelector("#content").classList.add("connected"); |
|
122 }, |
|
123 |
|
124 onDisconnected: function() { |
|
125 for (let [,toolbox] of this._handledTargets) { |
|
126 if (toolbox) { |
|
127 toolbox.destroy(); |
|
128 } |
|
129 } |
|
130 this._handledTargets.clear(); |
|
131 document.querySelector("#content").classList.remove("connected"); |
|
132 }, |
|
133 |
|
134 createToolboxTab: function(name, iconURL, uid) { |
|
135 let button = document.createElement("button"); |
|
136 button.className = "button toolbox " + uid + "-button"; |
|
137 button.setAttribute("panel", uid); |
|
138 button.textContent = name; |
|
139 button.setAttribute("style", "background-image: url(" + iconURL + ")"); |
|
140 let toolboxTabs = document.querySelector("#toolbox-tabs"); |
|
141 toolboxTabs.appendChild(button); |
|
142 let iframe = document.createElement("iframe"); |
|
143 iframe.setAttribute("flex", "1"); |
|
144 iframe.className = "panel toolbox " + uid + "-panel"; |
|
145 let panels = document.querySelector("#tab-panels"); |
|
146 panels.appendChild(iframe); |
|
147 this.selectTab(uid); |
|
148 return iframe; |
|
149 }, |
|
150 |
|
151 closeToolboxTab: function(uid) { |
|
152 let buttonToDestroy = document.querySelector("." + uid + "-button"); |
|
153 let panelToDestroy = document.querySelector("." + uid + "-panel"); |
|
154 |
|
155 if (buttonToDestroy.hasAttribute("selected")) { |
|
156 let lastTab = prefs.get("devtools.appmanager.lastTab"); |
|
157 this.selectTab(lastTab); |
|
158 } |
|
159 |
|
160 buttonToDestroy.remove(); |
|
161 panelToDestroy.remove(); |
|
162 }, |
|
163 |
|
164 openAndShowToolboxForTarget: function(target, name, icon) { |
|
165 let host = devtools.Toolbox.HostType.CUSTOM; |
|
166 let toolbox = gDevTools.getToolbox(target); |
|
167 if (!toolbox) { |
|
168 let uid = "uid" + this._toolboxTabCursor++; |
|
169 let iframe = this.createToolboxTab(name, icon, uid); |
|
170 let options = { customIframe: iframe , uid: uid }; |
|
171 this._handledTargets.set(target, null); |
|
172 return gDevTools.showToolbox(target, null, host, options).then(toolbox => { |
|
173 this._handledTargets.set(target, toolbox); |
|
174 toolbox.once("destroyed", () => { |
|
175 this._handledTargets.delete(target) |
|
176 }); |
|
177 }); |
|
178 } else { |
|
179 return gDevTools.showToolbox(target, null, host); |
|
180 } |
|
181 } |
|
182 } |
|
183 |
|
184 UI.init(); |