1 /*
2 * Copyright (C) 2011 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 #include "config.h"
32 #include "InspectorController.h"
33
34 #if ENABLE(INSPECTOR)
35
36 #include "Frame.h"
37 #include "GraphicsContext.h"
38 #include "InjectedScriptHost.h"
39 #include "InjectedScriptManager.h"
40 #include "InspectorAgent.h"
41 #include "InspectorBackendDispatcher.h"
42 #include "InspectorBrowserDebuggerAgent.h"
43 #include "InspectorDebuggerAgent.h"
44 #include "InspectorClient.h"
45 #include "InspectorDOMAgent.h"
46 #include "InspectorFrontend.h"
47 #include "InspectorFrontendClient.h"
48 #include "InspectorInstrumentation.h"
49 #include "InspectorProfilerAgent.h"
50 #include "InspectorTimelineAgent.h"
51 #include "Page.h"
52 #include "ScriptObject.h"
53 #include "Settings.h"
54
55 namespace WebCore {
56
InspectorController(Page * page,InspectorClient * inspectorClient)57 InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient)
58 : m_injectedScriptManager(InjectedScriptManager::createForPage())
59 , m_inspectorAgent(new InspectorAgent(page, inspectorClient, m_injectedScriptManager.get()))
60 , m_inspectorClient(inspectorClient)
61 , m_openingFrontend(false)
62 , m_startUserInitiatedDebuggingWhenFrontedIsConnected(false)
63 {
64 }
65
~InspectorController()66 InspectorController::~InspectorController()
67 {
68 }
69
setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)70 void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
71 {
72 m_inspectorFrontendClient = inspectorFrontendClient;
73 }
74
hasInspectorFrontendClient() const75 bool InspectorController::hasInspectorFrontendClient() const
76 {
77 return m_inspectorFrontendClient;
78 }
79
didClearWindowObjectInWorld(Frame * frame,DOMWrapperWorld * world)80 void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
81 {
82 if (world != mainThreadNormalWorld())
83 return;
84
85 // If the page is supposed to serve as InspectorFrontend notify inspector frontend
86 // client that it's cleared so that the client can expose inspector bindings.
87 if (m_inspectorFrontendClient && frame == m_inspectorAgent->inspectedPage()->mainFrame())
88 m_inspectorFrontendClient->windowObjectCleared();
89 }
90
startTimelineProfiler()91 void InspectorController::startTimelineProfiler()
92 {
93 ErrorString error;
94 m_inspectorAgent->timelineAgent()->start(&error);
95 }
96
stopTimelineProfiler()97 void InspectorController::stopTimelineProfiler()
98 {
99 ErrorString error;
100 m_inspectorAgent->timelineAgent()->stop(&error);
101 }
102
connectFrontend()103 void InspectorController::connectFrontend()
104 {
105 m_openingFrontend = false;
106 m_inspectorFrontend = new InspectorFrontend(m_inspectorClient);
107 m_injectedScriptManager->injectedScriptHost()->setFrontend(m_inspectorFrontend.get());
108 m_inspectorAgent->setFrontend(m_inspectorFrontend.get());
109
110 if (!InspectorInstrumentation::hasFrontends())
111 ScriptController::setCaptureCallStackForUncaughtExceptions(true);
112 InspectorInstrumentation::frontendCreated();
113
114 ASSERT(m_inspectorClient);
115 m_inspectorBackendDispatcher = adoptRef(new InspectorBackendDispatcher(
116 m_inspectorClient,
117 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
118 m_inspectorAgent->applicationCacheAgent(),
119 #endif
120 #if ENABLE(JAVASCRIPT_DEBUGGER)
121 m_inspectorAgent->browserDebuggerAgent(),
122 #endif
123 m_inspectorAgent->cssAgent(),
124 m_inspectorAgent->consoleAgent(),
125 m_inspectorAgent->domAgent(),
126 #if ENABLE(DOM_STORAGE)
127 m_inspectorAgent->domStorageAgent(),
128 #endif
129 #if ENABLE(DATABASE)
130 m_inspectorAgent->databaseAgent(),
131 #endif
132 #if ENABLE(JAVASCRIPT_DEBUGGER)
133 m_inspectorAgent->debuggerAgent(),
134 #endif
135 m_inspectorAgent->resourceAgent(),
136 m_inspectorAgent->pageAgent(),
137 #if ENABLE(JAVASCRIPT_DEBUGGER)
138 m_inspectorAgent->profilerAgent(),
139 #endif
140 m_inspectorAgent->runtimeAgent(),
141 m_inspectorAgent->timelineAgent()));
142
143 if (m_startUserInitiatedDebuggingWhenFrontedIsConnected) {
144 m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
145 m_startUserInitiatedDebuggingWhenFrontedIsConnected = false;
146 }
147 }
148
disconnectFrontend()149 void InspectorController::disconnectFrontend()
150 {
151 if (!m_inspectorFrontend)
152 return;
153 m_inspectorBackendDispatcher->clearFrontend();
154 m_inspectorBackendDispatcher.clear();
155
156 m_inspectorAgent->disconnectFrontend();
157 m_injectedScriptManager->injectedScriptHost()->clearFrontend();
158
159 m_inspectorFrontend.clear();
160
161 InspectorInstrumentation::frontendDeleted();
162 if (!InspectorInstrumentation::hasFrontends())
163 ScriptController::setCaptureCallStackForUncaughtExceptions(false);
164
165 }
166
show()167 void InspectorController::show()
168 {
169 if (!enabled())
170 return;
171
172 if (m_openingFrontend)
173 return;
174
175 if (m_inspectorFrontend)
176 m_inspectorFrontend->inspector()->bringToFront();
177 else {
178 m_openingFrontend = true;
179 m_inspectorClient->openInspectorFrontend(this);
180 }
181 }
182
close()183 void InspectorController::close()
184 {
185 if (!m_inspectorFrontend)
186 return;
187 m_inspectorFrontend->inspector()->disconnectFromBackend();
188 disconnectFrontend();
189 }
190
restoreInspectorStateFromCookie(const String & inspectorStateCookie)191 void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie)
192 {
193 ASSERT(!m_inspectorFrontend);
194 connectFrontend();
195 m_inspectorAgent->restoreInspectorStateFromCookie(inspectorStateCookie);
196 }
197
evaluateForTestInFrontend(long callId,const String & script)198 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
199 {
200 m_inspectorAgent->evaluateForTestInFrontend(callId, script);
201 }
202
drawNodeHighlight(GraphicsContext & context) const203 void InspectorController::drawNodeHighlight(GraphicsContext& context) const
204 {
205 m_inspectorAgent->domAgent()->drawNodeHighlight(context);
206 }
207
showConsole()208 void InspectorController::showConsole()
209 {
210 if (!enabled())
211 return;
212 show();
213 m_inspectorAgent->showConsole();
214 }
215
inspect(Node * node)216 void InspectorController::inspect(Node* node)
217 {
218 if (!enabled())
219 return;
220
221 show();
222
223 m_inspectorAgent->domAgent()->inspect(node);
224 }
225
enabled() const226 bool InspectorController::enabled() const
227 {
228 return m_inspectorAgent->enabled();
229 }
230
inspectedPage() const231 Page* InspectorController::inspectedPage() const
232 {
233 return m_inspectorAgent->inspectedPage();
234 }
235
timelineProfilerEnabled()236 bool InspectorController::timelineProfilerEnabled()
237 {
238 return m_inspectorAgent->timelineAgent()->started();
239 }
240
setInspectorExtensionAPI(const String & source)241 void InspectorController::setInspectorExtensionAPI(const String& source)
242 {
243 m_inspectorAgent->setInspectorExtensionAPI(source);
244 }
245
dispatchMessageFromFrontend(const String & message)246 void InspectorController::dispatchMessageFromFrontend(const String& message)
247 {
248 if (m_inspectorBackendDispatcher)
249 m_inspectorBackendDispatcher->dispatch(message);
250 }
251
hideHighlight()252 void InspectorController::hideHighlight()
253 {
254 ErrorString error;
255 m_inspectorAgent->domAgent()->hideHighlight(&error);
256 }
257
highlightedNode() const258 Node* InspectorController::highlightedNode() const
259 {
260 return m_inspectorAgent->domAgent()->highlightedNode();
261 }
262
263 #if ENABLE(JAVASCRIPT_DEBUGGER)
enableProfiler()264 void InspectorController::enableProfiler()
265 {
266 ErrorString error;
267 m_inspectorAgent->profilerAgent()->enable(&error);
268 }
269
disableProfiler()270 void InspectorController::disableProfiler()
271 {
272 ErrorString error;
273 m_inspectorAgent->profilerAgent()->disable(&error);
274 }
275
profilerEnabled()276 bool InspectorController::profilerEnabled()
277 {
278 return m_inspectorAgent->profilerAgent()->enabled();
279 }
280
debuggerEnabled()281 bool InspectorController::debuggerEnabled()
282 {
283 return m_inspectorAgent->debuggerAgent()->enabled();
284 }
285
showAndEnableDebugger()286 void InspectorController::showAndEnableDebugger()
287 {
288 if (!enabled())
289 return;
290 show();
291
292 if (m_inspectorFrontend)
293 m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
294 else
295 m_startUserInitiatedDebuggingWhenFrontedIsConnected = true;
296 }
297
disableDebugger()298 void InspectorController::disableDebugger()
299 {
300 m_inspectorAgent->debuggerAgent()->disable();
301 }
302
startUserInitiatedProfiling()303 void InspectorController::startUserInitiatedProfiling()
304 {
305 m_inspectorAgent->profilerAgent()->startUserInitiatedProfiling();
306 }
307
stopUserInitiatedProfiling()308 void InspectorController::stopUserInitiatedProfiling()
309 {
310 if (!enabled())
311 return;
312 show();
313 m_inspectorAgent->profilerAgent()->stopUserInitiatedProfiling();
314 m_inspectorAgent->showProfilesPanel();
315 }
316
isRecordingUserInitiatedProfile() const317 bool InspectorController::isRecordingUserInitiatedProfile() const
318 {
319 return m_inspectorAgent->profilerAgent()->isRecordingUserInitiatedProfile();
320 }
321
resume()322 void InspectorController::resume()
323 {
324 if (InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent()) {
325 ErrorString error;
326 debuggerAgent->resume(&error);
327 }
328 }
329
330 #endif
331
332 } // namespace WebCore
333
334 #endif // ENABLE(INSPECTOR)
335