2009-12-08 Alexander Pavlov <apavlov@chromium.org>
[WebKit-https.git] / WebCore / inspector / InspectorBackend.cpp
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "InspectorBackend.h"
32
33 #if ENABLE(INSPECTOR)
34
35 #if ENABLE(DATABASE)
36 #include "Database.h"
37 #endif
38
39 #include "Element.h"
40 #include "Frame.h"
41 #include "FrameLoader.h"
42 #include "HTMLFrameOwnerElement.h"
43 #include "InspectorClient.h"
44 #include "InspectorController.h"
45 #include "InspectorDOMAgent.h"
46 #include "InspectorFrontend.h"
47 #include "InspectorResource.h"
48 #include "Pasteboard.h"
49 #include "ScriptArray.h"
50 #include "ScriptFunctionCall.h"
51
52 #if ENABLE(DOM_STORAGE)
53 #include "Storage.h"
54 #endif
55
56 #if ENABLE(JAVASCRIPT_DEBUGGER)
57 #include "JavaScriptCallFrame.h"
58 #include "JavaScriptDebugServer.h"
59 using namespace JSC;
60 #endif
61
62 #include "markup.h"
63
64 #include <wtf/RefPtr.h>
65 #include <wtf/StdLibExtras.h>
66
67 using namespace std;
68
69 namespace WebCore {
70
71 InspectorBackend::InspectorBackend(InspectorController* inspectorController)
72     : m_inspectorController(inspectorController)
73 {
74 }
75
76 InspectorBackend::~InspectorBackend()
77 {
78 }
79
80 void InspectorBackend::clearMessages(bool clearUI)
81 {
82     if (m_inspectorController)
83         m_inspectorController->clearConsoleMessages(clearUI);
84 }
85
86 void InspectorBackend::storeLastActivePanel(const String& panelName)
87 {
88     if (m_inspectorController)
89         m_inspectorController->storeLastActivePanel(panelName);
90 }
91
92 void InspectorBackend::toggleNodeSearch()
93 {
94     if (m_inspectorController)
95         m_inspectorController->toggleSearchForNodeInPage();
96 }
97
98 bool InspectorBackend::searchingForNode()
99 {
100     if (m_inspectorController)
101         return m_inspectorController->searchingForNodeInPage();
102     return false;
103 }
104
105 bool InspectorBackend::resourceTrackingEnabled() const
106 {
107     if (m_inspectorController)
108         return m_inspectorController->resourceTrackingEnabled();
109     return false;
110 }
111
112 void InspectorBackend::enableResourceTracking(bool always)
113 {
114     if (m_inspectorController)
115         m_inspectorController->enableResourceTracking(always);
116 }
117
118 void InspectorBackend::disableResourceTracking(bool always)
119 {
120     if (m_inspectorController)
121         m_inspectorController->disableResourceTracking(always);
122 }
123
124 void InspectorBackend::startTimelineProfiler()
125 {
126     if (m_inspectorController)
127         m_inspectorController->startTimelineProfiler();
128 }
129
130 void InspectorBackend::stopTimelineProfiler()
131 {
132     if (m_inspectorController)
133         m_inspectorController->stopTimelineProfiler();
134 }
135
136 #if ENABLE(JAVASCRIPT_DEBUGGER)
137 bool InspectorBackend::debuggerEnabled() const
138 {
139     if (m_inspectorController)
140         return m_inspectorController->debuggerEnabled();
141     return false;
142 }
143
144 void InspectorBackend::enableDebugger(bool always)
145 {
146     if (m_inspectorController)
147         m_inspectorController->enableDebuggerFromFrontend(always);
148 }
149
150 void InspectorBackend::disableDebugger(bool always)
151 {
152     if (m_inspectorController)
153         m_inspectorController->disableDebugger(always);
154 }
155
156 void InspectorBackend::addBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition)
157 {
158     intptr_t sourceIDValue = sourceID.toIntPtr();
159     JavaScriptDebugServer::shared().addBreakpoint(sourceIDValue, lineNumber, condition);
160 }
161
162 void InspectorBackend::updateBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition)
163 {
164     intptr_t sourceIDValue = sourceID.toIntPtr();
165     JavaScriptDebugServer::shared().updateBreakpoint(sourceIDValue, lineNumber, condition);
166 }
167
168 void InspectorBackend::removeBreakpoint(const String& sourceID, unsigned lineNumber)
169 {
170     intptr_t sourceIDValue = sourceID.toIntPtr();
171     JavaScriptDebugServer::shared().removeBreakpoint(sourceIDValue, lineNumber);
172 }
173
174 void InspectorBackend::pauseInDebugger()
175 {
176     JavaScriptDebugServer::shared().pauseProgram();
177 }
178
179 void InspectorBackend::resumeDebugger()
180 {
181     if (m_inspectorController)
182         m_inspectorController->resumeDebugger();
183 }
184
185 void InspectorBackend::stepOverStatementInDebugger()
186 {
187     JavaScriptDebugServer::shared().stepOverStatement();
188 }
189
190 void InspectorBackend::stepIntoStatementInDebugger()
191 {
192     JavaScriptDebugServer::shared().stepIntoStatement();
193 }
194
195 void InspectorBackend::stepOutOfFunctionInDebugger()
196 {
197     JavaScriptDebugServer::shared().stepOutOfFunction();
198 }
199
200 bool InspectorBackend::pauseOnExceptions()
201 {
202     return JavaScriptDebugServer::shared().pauseOnExceptions();
203 }
204
205 void InspectorBackend::setPauseOnExceptions(bool pause)
206 {
207     JavaScriptDebugServer::shared().setPauseOnExceptions(pause);
208 }
209
210 bool InspectorBackend::profilerEnabled()
211 {
212     if (m_inspectorController)
213         return m_inspectorController->profilerEnabled();
214     return false;
215 }
216
217 void InspectorBackend::enableProfiler(bool always)
218 {
219     if (m_inspectorController)
220         m_inspectorController->enableProfiler(always);
221 }
222
223 void InspectorBackend::disableProfiler(bool always)
224 {
225     if (m_inspectorController)
226         m_inspectorController->disableProfiler(always);
227 }
228
229 void InspectorBackend::startProfiling()
230 {
231     if (m_inspectorController)
232         m_inspectorController->startUserInitiatedProfiling();
233 }
234
235 void InspectorBackend::stopProfiling()
236 {
237     if (m_inspectorController)
238         m_inspectorController->stopUserInitiatedProfiling();
239 }
240
241 void InspectorBackend::getProfileHeaders(long callId)
242 {
243     if (m_inspectorController)
244         m_inspectorController->getProfileHeaders(callId);
245 }
246
247 void InspectorBackend::getProfile(long callId, unsigned uid)
248 {
249     if (m_inspectorController)
250         m_inspectorController->getProfile(callId, uid);
251 }
252
253 JavaScriptCallFrame* InspectorBackend::currentCallFrame() const
254 {
255     return JavaScriptDebugServer::shared().currentCallFrame();
256 }
257 #endif
258
259 void InspectorBackend::dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments, bool async)
260 {
261     InspectorFrontend* frontend = inspectorFrontend();
262     if (!frontend)
263         return;
264
265     ScriptFunctionCall function(m_inspectorController->m_scriptState, m_inspectorController->m_injectedScriptObj, "dispatch");
266     function.appendArgument(methodName);
267     function.appendArgument(arguments);
268     if (async)
269         function.appendArgument(callId);
270     bool hadException = false;
271     ScriptValue result = function.call(hadException);
272     if (async)
273         return;  // InjectedScript will return result asynchronously by means of ::reportDidDispatchOnInjectedScript.
274     if (hadException)
275         frontend->didDispatchOnInjectedScript(callId, "", true);
276     else
277         frontend->didDispatchOnInjectedScript(callId, result.toString(m_inspectorController->m_scriptState), false);
278 }
279
280 void InspectorBackend::getChildNodes(long callId, long nodeId)
281 {
282     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
283         domAgent->getChildNodes(callId, nodeId);
284 }
285
286 void InspectorBackend::setAttribute(long callId, long elementId, const String& name, const String& value)
287 {
288     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
289         domAgent->setAttribute(callId, elementId, name, value);
290 }
291
292 void InspectorBackend::removeAttribute(long callId, long elementId, const String& name)
293 {
294     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
295         domAgent->removeAttribute(callId, elementId, name);
296 }
297
298 void InspectorBackend::setTextNodeValue(long callId, long nodeId, const String& value)
299 {
300     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
301         domAgent->setTextNodeValue(callId, nodeId, value);
302 }
303
304 void InspectorBackend::getEventListenersForNode(long callId, long nodeId)
305 {
306     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
307         domAgent->getEventListenersForNode(callId, nodeId);
308 }
309
310 void InspectorBackend::copyNode(long nodeId)
311 {
312     Node* node = nodeForId(nodeId);
313     if (!node)
314         return;
315     String markup = createMarkup(node);
316     Pasteboard::generalPasteboard()->writePlainText(markup);
317 }
318     
319 void InspectorBackend::removeNode(long callId, long nodeId)
320 {
321     InspectorFrontend* frontend = inspectorFrontend();
322     if (!frontend)
323         return;
324
325     Node* node = nodeForId(nodeId);
326     if (!node) {
327         // Use -1 to denote an error condition.
328         frontend->didRemoveNode(callId, -1);
329         return;
330     }
331
332     Node* parentNode = node->parentNode();
333     if (!parentNode) {
334         frontend->didRemoveNode(callId, -1);
335         return;
336     }
337
338     ExceptionCode code;
339     parentNode->removeChild(node, code);
340     if (code) {
341         frontend->didRemoveNode(callId, -1);
342         return;
343     }
344
345     frontend->didRemoveNode(callId, nodeId);
346 }
347
348 void InspectorBackend::highlightDOMNode(long nodeId)
349 {
350     if (Node* node = nodeForId(nodeId))
351         m_inspectorController->highlight(node);
352 }
353
354 void InspectorBackend::hideDOMNodeHighlight()
355 {
356     if (m_inspectorController)
357         m_inspectorController->hideHighlight();
358 }
359
360 void InspectorBackend::getCookies(long callId)
361 {
362     if (!m_inspectorController)
363         return;
364     m_inspectorController->getCookies(callId);
365 }
366
367 void InspectorBackend::deleteCookie(const String& cookieName, const String& domain)
368 {
369     if (!m_inspectorController)
370         return;
371     m_inspectorController->deleteCookie(cookieName, domain);
372 }
373
374 void InspectorBackend::releaseWrapperObjectGroup(const String& objectGroup)
375 {
376     if (m_inspectorController)
377         m_inspectorController->releaseWrapperObjectGroup(objectGroup);
378 }
379
380 void InspectorBackend::didEvaluateForTestInFrontend(long callId, const String& jsonResult)
381 {
382     if (m_inspectorController)
383         m_inspectorController->didEvaluateForTestInFrontend(callId, jsonResult);
384 }
385
386 #if ENABLE(DATABASE)
387 void InspectorBackend::getDatabaseTableNames(long callId, long databaseId)
388 {
389     if (InspectorFrontend* frontend = inspectorFrontend()) {
390         ScriptArray result = frontend->newScriptArray();
391         Database* database = m_inspectorController->databaseForId(databaseId);
392         if (database) {
393             Vector<String> tableNames = database->tableNames();
394             unsigned length = tableNames.size();
395             for (unsigned i = 0; i < length; ++i)
396                 result.set(i, tableNames[i]);
397         }
398         frontend->didGetDatabaseTableNames(callId, result);
399     }
400 }
401 #endif
402
403 #if ENABLE(DOM_STORAGE)
404 void InspectorBackend::getDOMStorageEntries(long callId, long storageId)
405 {
406     if (m_inspectorController)
407         m_inspectorController->getDOMStorageEntries(callId, storageId);
408 }
409
410 void InspectorBackend::setDOMStorageItem(long callId, long storageId, const String& key, const String& value)
411 {
412     if (m_inspectorController)
413         m_inspectorController->setDOMStorageItem(callId, storageId, key, value);
414 }
415
416 void InspectorBackend::removeDOMStorageItem(long callId, long storageId, const String& key)
417 {
418     if (m_inspectorController)
419         m_inspectorController->removeDOMStorageItem(callId, storageId, key);
420 }
421 #endif
422
423 InspectorDOMAgent* InspectorBackend::inspectorDOMAgent()
424 {
425     if (!m_inspectorController)
426         return 0;
427     return m_inspectorController->domAgent();
428 }
429
430 InspectorFrontend* InspectorBackend::inspectorFrontend()
431 {
432     if (!m_inspectorController)
433         return 0;
434     return m_inspectorController->m_frontend.get();
435 }
436
437 Node* InspectorBackend::nodeForId(long nodeId)
438 {
439     if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
440         return domAgent->nodeForId(nodeId);
441     return 0;
442 }
443
444 } // namespace WebCore
445
446 #endif // ENABLE(INSPECTOR)