|
1 /* |
|
2 * Copyright (C) 2010 Google Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions are |
|
6 * met: |
|
7 * |
|
8 * * Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * * Redistributions in binary form must reproduce the above |
|
11 * copyright notice, this list of conditions and the following disclaimer |
|
12 * in the documentation and/or other materials provided with the |
|
13 * distribution. |
|
14 * * Neither the name of Google Inc. nor the names of its |
|
15 * contributors may be used to endorse or promote products derived from |
|
16 * this software without specific prior written permission. |
|
17 * |
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 */ |
|
30 |
|
31 /** |
|
32 * FIXME: change field naming style to use trailing underscore. |
|
33 * @fileoverview Tools is a main class that wires all components of the |
|
34 * DevTools frontend together. It is also responsible for overriding existing |
|
35 * WebInspector functionality while it is getting upstreamed into WebCore. |
|
36 */ |
|
37 |
|
38 /** |
|
39 * Dispatches raw message from the host. |
|
40 * @param {string} remoteName |
|
41 * @prama {string} methodName |
|
42 * @param {string} param1, param2, param3 Arguments to dispatch. |
|
43 */ |
|
44 devtools$$dispatch = function(remoteName, methodName, param1, param2, param3) |
|
45 { |
|
46 remoteName = "Remote" + remoteName.substring(0, remoteName.length - 8); |
|
47 var agent = window[remoteName]; |
|
48 if (!agent) { |
|
49 debugPrint("No remote agent '" + remoteName + "' found."); |
|
50 return; |
|
51 } |
|
52 var method = agent[methodName]; |
|
53 if (!method) { |
|
54 debugPrint("No method '" + remoteName + "." + methodName + "' found."); |
|
55 return; |
|
56 } |
|
57 method.call(this, param1, param2, param3); |
|
58 }; |
|
59 |
|
60 |
|
61 devtools.ToolsAgent = function() |
|
62 { |
|
63 RemoteToolsAgent.didDispatchOn = WebInspector.Callback.processCallback; |
|
64 RemoteToolsAgent.dispatchOnClient = this.dispatchOnClient_.bind(this); |
|
65 this.profilerAgent_ = new devtools.ProfilerAgent(); |
|
66 }; |
|
67 |
|
68 |
|
69 /** |
|
70 * @param {string} script Script exression to be evaluated in the context of the |
|
71 * inspected page. |
|
72 * @param {function(Object|string, boolean):undefined} opt_callback Function to |
|
73 * call with the result. |
|
74 */ |
|
75 devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, opt_callback) |
|
76 { |
|
77 InspectorBackend.evaluate(script, opt_callback || function() {}); |
|
78 }; |
|
79 |
|
80 |
|
81 /** |
|
82 * @return {devtools.ProfilerAgent} Profiler agent instance. |
|
83 */ |
|
84 devtools.ToolsAgent.prototype.getProfilerAgent = function() |
|
85 { |
|
86 return this.profilerAgent_; |
|
87 }; |
|
88 |
|
89 |
|
90 /** |
|
91 * @param {string} message Serialized call to be dispatched on WebInspector. |
|
92 * @private |
|
93 */ |
|
94 devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) |
|
95 { |
|
96 var args = JSON.parse(message); |
|
97 var methodName = args[0]; |
|
98 var parameters = args.slice(1); |
|
99 WebInspector[methodName].apply(WebInspector, parameters); |
|
100 }; |
|
101 |
|
102 |
|
103 /** |
|
104 * Evaluates js expression. |
|
105 * @param {string} expr |
|
106 */ |
|
107 devtools.ToolsAgent.prototype.evaluate = function(expr) |
|
108 { |
|
109 RemoteToolsAgent.evaluate(expr); |
|
110 }; |
|
111 |
|
112 |
|
113 /** |
|
114 * Prints string to the inspector console or shows alert if the console doesn't |
|
115 * exist. |
|
116 * @param {string} text |
|
117 */ |
|
118 function debugPrint(text) { |
|
119 WebInspector.log(text); |
|
120 } |
|
121 |
|
122 |
|
123 /** |
|
124 * Global instance of the tools agent. |
|
125 * @type {devtools.ToolsAgent} |
|
126 */ |
|
127 devtools.tools = null; |
|
128 |
|
129 |
|
130 var context = {}; // Used by WebCore's inspector routines. |
|
131 |
|
132 /////////////////////////////////////////////////////////////////////////////// |
|
133 // Here and below are overrides to existing WebInspector methods only. |
|
134 // TODO(pfeldman): Patch WebCore and upstream changes. |
|
135 var oldLoaded = WebInspector.loaded; |
|
136 WebInspector.loaded = function() |
|
137 { |
|
138 devtools.tools = new devtools.ToolsAgent(); |
|
139 |
|
140 Preferences.ignoreWhitespace = false; |
|
141 Preferences.samplingCPUProfiler = true; |
|
142 Preferences.heapProfilerPresent = true; |
|
143 Preferences.debuggerAlwaysEnabled = true; |
|
144 Preferences.profilerAlwaysEnabled = true; |
|
145 Preferences.canEditScriptSource = true; |
|
146 Preferences.appCacheEnabled = false; |
|
147 |
|
148 oldLoaded.call(this); |
|
149 |
|
150 InspectorFrontendHost.loaded(); |
|
151 }; |
|
152 |
|
153 devtools.domContentLoaded = function() |
|
154 { |
|
155 var queryParams = window.location.search; |
|
156 if (queryParams) { |
|
157 var params = queryParams.substring(1).split("&"); |
|
158 var paramsObject = {}; |
|
159 for (var i = 0; i < params.length; ++i) { |
|
160 var pair = params[i].split("="); |
|
161 paramsObject[pair[0]] = pair[1]; |
|
162 } |
|
163 WebInspector.setAttachedWindow(paramsObject.docked === "true"); |
|
164 if (paramsObject.toolbar_color && paramsObject.text_color) |
|
165 WebInspector.setToolbarColors(paramsObject.toolbar_color, paramsObject.text_color); |
|
166 } |
|
167 } |
|
168 document.addEventListener("DOMContentLoaded", devtools.domContentLoaded, false); |
|
169 |
|
170 |
|
171 (function InterceptProfilesPanelEvents() |
|
172 { |
|
173 var oldShow = WebInspector.ProfilesPanel.prototype.show; |
|
174 WebInspector.ProfilesPanel.prototype.show = function() |
|
175 { |
|
176 devtools.tools.getProfilerAgent().initializeProfiling(); |
|
177 this.enableToggleButton.visible = false; |
|
178 oldShow.call(this); |
|
179 // Show is called on every show event of a panel, so |
|
180 // we only need to intercept it once. |
|
181 WebInspector.ProfilesPanel.prototype.show = oldShow; |
|
182 }; |
|
183 })(); |
|
184 |
|
185 |
|
186 /* |
|
187 * @override |
|
188 * TODO(mnaganov): Restore l10n when it will be agreed that it is needed. |
|
189 */ |
|
190 WebInspector.UIString = function(string) |
|
191 { |
|
192 return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); |
|
193 }; |
|
194 |
|
195 |
|
196 /** Pending WebKit upstream by apavlov). Fixes iframe vs drag problem. */ |
|
197 (function() |
|
198 { |
|
199 var originalDragStart = WebInspector.elementDragStart; |
|
200 WebInspector.elementDragStart = function(element) |
|
201 { |
|
202 if (element) { |
|
203 var glassPane = document.createElement("div"); |
|
204 glassPane.style.cssText = "position:absolute;width:100%;height:100%;opacity:0;z-index:1"; |
|
205 glassPane.id = "glass-pane-for-drag"; |
|
206 element.parentElement.appendChild(glassPane); |
|
207 } |
|
208 |
|
209 originalDragStart.apply(this, arguments); |
|
210 }; |
|
211 |
|
212 var originalDragEnd = WebInspector.elementDragEnd; |
|
213 WebInspector.elementDragEnd = function() |
|
214 { |
|
215 originalDragEnd.apply(this, arguments); |
|
216 |
|
217 var glassPane = document.getElementById("glass-pane-for-drag"); |
|
218 if (glassPane) |
|
219 glassPane.parentElement.removeChild(glassPane); |
|
220 }; |
|
221 })(); |
|
222 |
|
223 |
|
224 |
|
225 /////////////////////////////////////////// |
|
226 // Chromium layout test harness support. // |
|
227 /////////////////////////////////////////// |
|
228 |
|
229 WebInspector.runAfterPendingDispatchesQueue = []; |
|
230 |
|
231 WebInspector.TestController.prototype.runAfterPendingDispatches = function(callback) |
|
232 { |
|
233 WebInspector.runAfterPendingDispatchesQueue.push(callback); |
|
234 }; |
|
235 |
|
236 WebInspector.queuesAreEmpty = function() |
|
237 { |
|
238 var copy = this.runAfterPendingDispatchesQueue.slice(); |
|
239 this.runAfterPendingDispatchesQueue = []; |
|
240 for (var i = 0; i < copy.length; ++i) |
|
241 copy[i].call(this); |
|
242 }; |
|
243 |
|
244 |
|
245 ///////////////////////////// |
|
246 // Chromium theme support. // |
|
247 ///////////////////////////// |
|
248 |
|
249 WebInspector.setToolbarColors = function(backgroundColor, color) |
|
250 { |
|
251 if (!WebInspector._themeStyleElement) { |
|
252 WebInspector._themeStyleElement = document.createElement("style"); |
|
253 document.head.appendChild(WebInspector._themeStyleElement); |
|
254 } |
|
255 WebInspector._themeStyleElement.textContent = |
|
256 "#toolbar {\ |
|
257 background-image: none !important;\ |
|
258 background-color: " + backgroundColor + " !important;\ |
|
259 }\ |
|
260 \ |
|
261 .toolbar-label {\ |
|
262 color: " + color + " !important;\ |
|
263 text-shadow: none;\ |
|
264 }"; |
|
265 } |
|
266 |
|
267 WebInspector.resetToolbarColors = function() |
|
268 { |
|
269 if (WebInspector._themeStyleElement) |
|
270 WebInspector._themeStyleElement.textContent = ""; |
|
271 |
|
272 } |
|
273 |
|
274 // TODO(yurys): should be removed when eclipse debugger stops using it. |
|
275 if (window.RemoteDebuggerAgent) { |
|
276 RemoteDebuggerAgent.setContextId = function() {}; |
|
277 } |