|
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 "use strict"; |
|
5 |
|
6 const { classes: Cc, interfaces: Ci, utils: Cu } = Components; |
|
7 |
|
8 let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {}); |
|
9 let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); |
|
10 let { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); |
|
11 let { debuggerSocketConnect, DebuggerClient } = |
|
12 Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {}); |
|
13 let { ViewHelpers } = |
|
14 Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {}); |
|
15 |
|
16 /** |
|
17 * Shortcuts for accessing various debugger preferences. |
|
18 */ |
|
19 let Prefs = new ViewHelpers.Prefs("devtools.debugger", { |
|
20 chromeDebuggingHost: ["Char", "chrome-debugging-host"], |
|
21 chromeDebuggingPort: ["Int", "chrome-debugging-port"] |
|
22 }); |
|
23 |
|
24 let gToolbox, gClient; |
|
25 |
|
26 function connect() { |
|
27 window.removeEventListener("load", connect); |
|
28 // Initiate the connection |
|
29 let transport = debuggerSocketConnect( |
|
30 Prefs.chromeDebuggingHost, |
|
31 Prefs.chromeDebuggingPort |
|
32 ); |
|
33 gClient = new DebuggerClient(transport); |
|
34 gClient.connect(() => { |
|
35 let addonID = getParameterByName("addonID"); |
|
36 |
|
37 if (addonID) { |
|
38 gClient.listAddons(({addons}) => { |
|
39 let addonActor = addons.filter(addon => addon.id === addonID).pop(); |
|
40 openToolbox({ addonActor: addonActor.actor, title: addonActor.name }); |
|
41 }); |
|
42 } else { |
|
43 gClient.listTabs(openToolbox); |
|
44 } |
|
45 }); |
|
46 } |
|
47 |
|
48 window.addEventListener("load", connect); |
|
49 |
|
50 function openToolbox(form) { |
|
51 let options = { |
|
52 form: form, |
|
53 client: gClient, |
|
54 chrome: true |
|
55 }; |
|
56 devtools.TargetFactory.forRemoteTab(options).then(target => { |
|
57 let frame = document.getElementById("toolbox-iframe"); |
|
58 let options = { customIframe: frame }; |
|
59 gDevTools.showToolbox(target, |
|
60 "jsdebugger", |
|
61 devtools.Toolbox.HostType.CUSTOM, |
|
62 options) |
|
63 .then(onNewToolbox); |
|
64 }); |
|
65 } |
|
66 |
|
67 function onNewToolbox(toolbox) { |
|
68 gToolbox = toolbox; |
|
69 bindToolboxHandlers(); |
|
70 raise(); |
|
71 } |
|
72 |
|
73 function bindToolboxHandlers() { |
|
74 gToolbox.once("destroyed", quitApp); |
|
75 window.addEventListener("unload", onUnload); |
|
76 } |
|
77 |
|
78 function onUnload() { |
|
79 window.removeEventListener("unload", onUnload); |
|
80 window.removeEventListener("message", onMessage); |
|
81 gToolbox.destroy(); |
|
82 } |
|
83 |
|
84 function onMessage(event) { |
|
85 try { |
|
86 let json = JSON.parse(event.data); |
|
87 switch (json.name) { |
|
88 case "toolbox-raise": |
|
89 raise(); |
|
90 break; |
|
91 case "toolbox-title": |
|
92 setTitle(json.data.value); |
|
93 break; |
|
94 } |
|
95 } catch(e) { Cu.reportError(e); } |
|
96 } |
|
97 |
|
98 window.addEventListener("message", onMessage); |
|
99 |
|
100 function raise() { |
|
101 window.focus(); |
|
102 } |
|
103 |
|
104 function setTitle(title) { |
|
105 document.title = title; |
|
106 } |
|
107 |
|
108 function quitApp() { |
|
109 let quit = Cc["@mozilla.org/supports-PRBool;1"] |
|
110 .createInstance(Ci.nsISupportsPRBool); |
|
111 Services.obs.notifyObservers(quit, "quit-application-requested", null); |
|
112 |
|
113 let shouldProceed = !quit.data; |
|
114 if (shouldProceed) { |
|
115 Services.startup.quit(Ci.nsIAppStartup.eForceQuit); |
|
116 } |
|
117 } |
|
118 |
|
119 function getParameterByName (name) { |
|
120 let name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); |
|
121 let regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); |
|
122 let results = regex.exec(window.location.search); |
|
123 return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); |
|
124 } |