d26e746b40b515ded91cf1e68d66c110ff8448de
[WebKit-https.git] / Source / WebCore / inspector / InspectorController.cpp
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
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
66 InspectorController::~InspectorController()
67 {
68 }
69
70 void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
71 {
72     m_inspectorFrontendClient = inspectorFrontendClient;
73 }
74
75 bool InspectorController::hasInspectorFrontendClient() const
76 {
77     return m_inspectorFrontendClient;
78 }
79
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
91 void InspectorController::startTimelineProfiler()
92 {
93     ErrorString error;
94     m_inspectorAgent->timelineAgent()->start(&error);
95 }
96
97 void InspectorController::stopTimelineProfiler()
98 {
99     ErrorString error;
100     m_inspectorAgent->timelineAgent()->stop(&error);
101 }
102
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 = 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.get(),
136         m_inspectorAgent->resourceAgent(),
137         m_inspectorAgent->pageAgent(),
138 #if ENABLE(JAVASCRIPT_DEBUGGER)
139         m_inspectorAgent->profilerAgent(),
140 #endif
141         m_inspectorAgent->runtimeAgent(),
142         m_inspectorAgent->timelineAgent());
143
144     if (m_startUserInitiatedDebuggingWhenFrontedIsConnected) {
145         m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
146         m_startUserInitiatedDebuggingWhenFrontedIsConnected = false;
147     }
148 }
149
150 void InspectorController::disconnectFrontend()
151 {
152     if (!m_inspectorFrontend)
153         return;
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
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
183 void InspectorController::close()
184 {
185     if (!m_inspectorFrontend)
186         return;
187     m_inspectorFrontend->inspector()->disconnectFromBackend();
188     disconnectFrontend();
189 }
190
191 void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie)
192 {
193     ASSERT(!m_inspectorFrontend);
194     connectFrontend();
195     m_inspectorAgent->restoreInspectorStateFromCookie(inspectorStateCookie);
196 }
197
198 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
199 {
200     m_inspectorAgent->evaluateForTestInFrontend(callId, script);
201 }
202
203 void InspectorController::drawNodeHighlight(GraphicsContext& context) const
204 {
205     m_inspectorAgent->domAgent()->drawNodeHighlight(context);
206 }
207
208 void InspectorController::showConsole()
209 {
210     if (!enabled())
211         return;
212     show();
213     m_inspectorAgent->showConsole();
214 }
215
216 void InspectorController::inspect(Node* node)
217 {
218     if (!enabled())
219         return;
220
221     show();
222
223     m_inspectorAgent->domAgent()->inspect(node);
224 }
225
226 bool InspectorController::enabled() const
227 {
228     return m_inspectorAgent->enabled();
229 }
230
231 Page* InspectorController::inspectedPage() const
232 {
233     return m_inspectorAgent->inspectedPage();
234 }
235
236 bool InspectorController::timelineProfilerEnabled()
237 {
238     return m_inspectorAgent->timelineAgent()->started();
239 }
240
241 void InspectorController::setInspectorExtensionAPI(const String& source)
242 {
243     m_inspectorAgent->setInspectorExtensionAPI(source);
244 }
245
246 void InspectorController::dispatchMessageFromFrontend(const String& message)
247 {
248     if (m_inspectorBackendDispatcher)
249         m_inspectorBackendDispatcher->dispatch(message);
250 }
251
252 void InspectorController::hideHighlight()
253 {
254     ErrorString error;
255     m_inspectorAgent->domAgent()->hideHighlight(&error);
256 }
257
258 #if ENABLE(JAVASCRIPT_DEBUGGER)
259 void InspectorController::enableProfiler()
260 {
261     ErrorString error;
262     m_inspectorAgent->profilerAgent()->enable(&error);
263 }
264
265 void InspectorController::disableProfiler()
266 {
267     ErrorString error;
268     m_inspectorAgent->profilerAgent()->disable(&error);
269 }
270
271 bool InspectorController::profilerEnabled()
272 {
273     return m_inspectorAgent->profilerAgent()->enabled();
274 }
275
276 bool InspectorController::debuggerEnabled()
277 {
278     return m_inspectorAgent->debuggerAgent()->enabled();
279 }
280
281 void InspectorController::showAndEnableDebugger()
282 {
283     if (!enabled())
284         return;
285     show();
286
287     if (m_inspectorFrontend)
288         m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
289     else
290         m_startUserInitiatedDebuggingWhenFrontedIsConnected = true;
291 }
292
293 void InspectorController::disableDebugger()
294 {
295     m_inspectorAgent->debuggerAgent()->disable();
296 }
297
298 void InspectorController::startUserInitiatedProfiling()
299 {
300     m_inspectorAgent->profilerAgent()->startUserInitiatedProfiling();
301 }
302
303 void InspectorController::stopUserInitiatedProfiling()
304 {
305     if (!enabled())
306         return;
307     show();
308     m_inspectorAgent->profilerAgent()->stopUserInitiatedProfiling();
309     m_inspectorAgent->showProfilesPanel();
310 }
311
312 bool InspectorController::isRecordingUserInitiatedProfile() const
313 {
314     return m_inspectorAgent->profilerAgent()->isRecordingUserInitiatedProfile();
315 }
316
317 void InspectorController::resume()
318 {
319     if (InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent()) {
320         ErrorString error;
321         debuggerAgent->resume(&error);
322     }
323 }
324
325 #endif
326
327 } // namespace WebCore
328
329 #endif // ENABLE(INSPECTOR)