browser/devtools/app-manager/content/device.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:3c0494091635
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://gre/modules/Services.jsm");
7 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
8 const {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
9
10 const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
11 const {require} = devtools;
12
13 const {ConnectionManager, Connection}
14 = require("devtools/client/connection-manager");
15 const {getDeviceFront} = require("devtools/server/actors/device");
16 const {getTargetForApp, launchApp, closeApp}
17 = require("devtools/app-actor-front");
18 const DeviceStore = require("devtools/app-manager/device-store");
19 const WebappsStore = require("devtools/app-manager/webapps-store");
20 const promise = require("devtools/toolkit/deprecated-sync-thenables");
21 const DEFAULT_APP_ICON = "chrome://browser/skin/devtools/app-manager/default-app-icon.png";
22
23 window.addEventListener("message", function(event) {
24 try {
25 let message = JSON.parse(event.data);
26 if (message.name == "connection") {
27 let cid = parseInt(message.cid);
28 for (let c of ConnectionManager.connections) {
29 if (c.uid == cid) {
30 UI.connection = c;
31 UI.onNewConnection();
32 break;
33 }
34 }
35 }
36 } catch(e) {
37 Cu.reportError(e);
38 }
39 });
40
41 window.addEventListener("unload", function onUnload() {
42 window.removeEventListener("unload", onUnload);
43 UI.destroy();
44 });
45
46 let UI = {
47 init: function() {
48 this.showFooterIfNeeded();
49 this.setTab("apps");
50 if (this.connection) {
51 this.onNewConnection();
52 } else {
53 this.hide();
54 }
55 },
56
57 destroy: function() {
58 if (this.connection) {
59 this.connection.off(Connection.Events.STATUS_CHANGED, this._onConnectionStatusChange);
60 }
61 if (this.store) {
62 this.store.destroy();
63 }
64 if (this.template) {
65 this.template.destroy();
66 }
67 },
68
69 showFooterIfNeeded: function() {
70 let footer = document.querySelector("#connection-footer");
71 if (window.parent == window) {
72 // We're alone. Let's add a footer.
73 footer.removeAttribute("hidden");
74 footer.src = "chrome://browser/content/devtools/app-manager/connection-footer.xhtml";
75 } else {
76 footer.setAttribute("hidden", "true");
77 }
78 },
79
80 hide: function() {
81 document.body.classList.add("notconnected");
82 },
83
84 show: function() {
85 document.body.classList.remove("notconnected");
86 },
87
88 onNewConnection: function() {
89 this.connection.on(Connection.Events.STATUS_CHANGED, this._onConnectionStatusChange);
90
91 this.store = Utils.mergeStores({
92 "device": new DeviceStore(this.connection),
93 "apps": new WebappsStore(this.connection),
94 });
95
96 if (this.template) {
97 this.template.destroy();
98 }
99 this.template = new Template(document.body, this.store, Utils.l10n);
100
101 this.template.start();
102 this._onConnectionStatusChange();
103 },
104
105 setWallpaper: function(dataurl) {
106 document.getElementById("meta").style.backgroundImage = "url(" + dataurl + ")";
107 },
108
109 _onConnectionStatusChange: function() {
110 if (this.connection.status != Connection.Status.CONNECTED) {
111 this.hide();
112 this.listTabsResponse = null;
113 } else {
114 this.show();
115 this.connection.client.listTabs(
116 response => {
117 this.listTabsResponse = response;
118 let front = getDeviceFront(this.connection.client, this.listTabsResponse);
119 front.getWallpaper().then(longstr => {
120 longstr.string().then(dataURL => {
121 longstr.release().then(null, Cu.reportError);
122 this.setWallpaper(dataURL);
123 });
124 });
125 if (Services.prefs.getBoolPref("devtools.chrome.enabled")) {
126 let rootButton = document.getElementById("root-actor-debug");
127 if (response.consoleActor) {
128 rootButton.removeAttribute("hidden");
129 } else {
130 rootButton.setAttribute("hidden", "true");
131 }
132 }
133 }
134 );
135 }
136 },
137
138 get connected() { return !!this.listTabsResponse; },
139
140 setTab: function(name) {
141 var tab = document.querySelector(".tab.selected");
142 var panel = document.querySelector(".tabpanel.selected");
143
144 if (tab) tab.classList.remove("selected");
145 if (panel) panel.classList.remove("selected");
146
147 var tab = document.querySelector(".tab." + name);
148 var panel = document.querySelector(".tabpanel." + name);
149
150 if (tab) tab.classList.add("selected");
151 if (panel) panel.classList.add("selected");
152 },
153
154 openToolboxForRootActor: function() {
155 if (!this.connected) {
156 return;
157 }
158
159 let options = {
160 form: this.listTabsResponse,
161 client: this.connection.client,
162 chrome: true
163 };
164 devtools.TargetFactory.forRemoteTab(options).then((target) => {
165 top.UI.openAndShowToolboxForTarget(target, "Main process", null);
166 });
167 },
168
169 openToolboxForApp: function(manifest) {
170 if (!this.connected) {
171 return;
172 }
173
174 let app = this.store.object.apps.all.filter(a => a.manifestURL == manifest)[0];
175 getTargetForApp(this.connection.client,
176 this.listTabsResponse.webappsActor,
177 manifest).then((target) => {
178
179 top.UI.openAndShowToolboxForTarget(target, app.name, app.iconURL);
180 }, console.error);
181 },
182
183 _getTargetForTab: function (form) {
184 let options = {
185 form: form,
186 client: this.connection.client,
187 chrome: false
188 };
189 let deferred = promise.defer();
190 return devtools.TargetFactory.forRemoteTab(options);
191 },
192
193 openToolboxForTab: function (aNode) {
194 let index = Array.prototype.indexOf.apply(
195 aNode.parentNode.parentNode.parentNode.children,
196 [aNode.parentNode.parentNode]);
197 this.connection.client.listTabs(
198 response => {
199 let tab = response.tabs[index];
200 this._getTargetForTab(tab).then(target => {
201 top.UI.openAndShowToolboxForTarget(
202 target, tab.title, DEFAULT_APP_ICON);
203 }, console.error);
204 }
205 );
206 },
207
208 startApp: function(manifest) {
209 if (!this.connected) {
210 return promise.reject();
211 }
212 return launchApp(this.connection.client,
213 this.listTabsResponse.webappsActor,
214 manifest);
215 },
216
217 stopApp: function(manifest) {
218 if (!this.connected) {
219 return promise.reject();
220 }
221 return closeApp(this.connection.client,
222 this.listTabsResponse.webappsActor,
223 manifest);
224 },
225 }
226
227 // This must be bound immediately, as it might be used via the message listener
228 // before UI.init() has been called.
229 UI._onConnectionStatusChange = UI._onConnectionStatusChange.bind(UI);

mercurial