2010-12-29 Pavel Feldman <pfeldman@chromium.org>
[WebKit-https.git] / WebCore / inspector / InspectorController.h
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 Apple 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
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #ifndef InspectorController_h
30 #define InspectorController_h
31
32 #include "CharacterData.h"
33 #include "Console.h"
34 #include "Cookie.h"
35 #include "Page.h"
36 #include "PlatformString.h"
37 #include <wtf/HashMap.h>
38 #include <wtf/HashSet.h>
39 #include <wtf/ListHashSet.h>
40 #include <wtf/RefCounted.h>
41 #include <wtf/Vector.h>
42 #include <wtf/text/StringHash.h>
43
44 namespace WebCore {
45
46 class CachedResource;
47 class CharacterData;
48 class ConsoleMessage;
49 class Database;
50 class Document;
51 class DocumentLoader;
52 class FloatRect;
53 class GraphicsContext;
54 class HTTPHeaderMap;
55 class HitTestResult;
56 class InjectedScript;
57 class InjectedScriptHost;
58 class InspectorArray;
59 class InspectorBackend;
60 class InspectorBackendDispatcher;
61 class InspectorClient;
62 class InspectorCSSAgent;
63 class InspectorDOMAgent;
64 class InspectorDOMStorageResource;
65 class InspectorDatabaseResource;
66 class InspectorDebuggerAgent;
67 class InspectorFrontend;
68 class InspectorFrontendClient;
69 class InspectorObject;
70 class InspectorProfilerAgent;
71 class InspectorResourceAgent;
72 class InspectorState;
73 class InspectorStorageAgent;
74 class InspectorTimelineAgent;
75 class InspectorValue;
76 class InspectorWorkerResource;
77 class IntRect;
78 class KURL;
79 class Node;
80 class Page;
81 class ResourceRequest;
82 class ResourceResponse;
83 class ResourceError;
84 class ScriptArguments;
85 class ScriptCallStack;
86 class ScriptProfile;
87 class SharedBuffer;
88 class Storage;
89 class StorageArea;
90
91 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
92 class InspectorApplicationCacheAgent;
93 #endif
94
95 #if ENABLE(FILE_SYSTEM)
96 class InspectorFileSystemAgent;
97 #endif
98
99 #if ENABLE(WEB_SOCKETS)
100 class WebSocketHandshakeRequest;
101 class WebSocketHandshakeResponse;
102 #endif
103
104 class InspectorController : public Noncopyable {
105 public:
106     typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
107     typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap;
108
109     static const char* const ConsolePanel;
110     static const char* const ElementsPanel;
111     static const char* const ProfilesPanel;
112     static const char* const ScriptsPanel;
113
114     InspectorController(Page*, InspectorClient*);
115     ~InspectorController();
116
117     InspectorBackend* inspectorBackend() { return m_inspectorBackend.get(); }
118     InspectorBackendDispatcher* inspectorBackendDispatcher() { return m_inspectorBackendDispatcher.get(); }
119     InspectorClient* inspectorClient() { return m_client; }
120     InjectedScriptHost* injectedScriptHost() { return m_injectedScriptHost.get(); }
121
122     void inspectedPageDestroyed();
123
124     bool enabled() const;
125
126     Page* inspectedPage() const { return m_inspectedPage; }
127     void reloadPage();
128
129     void restoreInspectorStateFromCookie(const String& inspectorCookie);
130
131     void inspect(Node*);
132     void highlight(Node*);
133     void hideHighlight();
134     void highlightDOMNode(long nodeId);
135     void hideDOMNodeHighlight() { hideHighlight(); }
136
137     void highlightFrame(unsigned long frameId);
138     void hideFrameHighlight() { hideHighlight(); }
139
140     void show();
141     void showPanel(const String&);
142     void close();
143
144     void connectFrontend();
145     void reuseFrontend();
146     void disconnectFrontend();
147
148     void setConsoleMessagesEnabled(bool enabled, bool* newState);
149     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack>);
150     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String&);
151     void clearConsoleMessages();
152     const Vector<OwnPtr<ConsoleMessage> >& consoleMessages() const { return m_consoleMessages; }
153
154     bool searchingForNodeInPage() const;
155     void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
156     void handleMousePress();
157
158     void setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> client);
159     bool hasInspectorFrontendClient() const { return m_inspectorFrontendClient; }
160
161     void inspectedWindowScriptObjectCleared(Frame*);
162
163     void didCommitLoad(DocumentLoader*);
164     void frameDetachedFromParent(Frame*);
165     void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
166
167     void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
168     void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
169     void markResourceAsCached(unsigned long identifier);
170     void didReceiveResponse(unsigned long identifier, DocumentLoader*, const ResourceResponse&);
171     void didReceiveContentLength(unsigned long identifier, int lengthReceived);
172     void didFinishLoading(unsigned long identifier, double finishTime);
173     void didFailLoading(unsigned long identifier, const ResourceError&);
174     void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber);
175     void scriptImported(unsigned long identifier, const String& sourceString);
176
177     void setExtraHeaders(PassRefPtr<InspectorObject>);
178
179     void ensureSettingsLoaded();
180
181     void startTimelineProfiler();
182     void stopTimelineProfiler();
183     InspectorTimelineAgent* timelineAgent() { return m_timelineAgent.get(); }
184
185     void getCookies(RefPtr<InspectorArray>* cookies, WTF::String* cookiesString);
186     void deleteCookie(const String& cookieName, const String& domain);
187
188 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
189     InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); }
190 #endif
191
192 #if ENABLE(FILE_SYSTEM)
193     InspectorFileSystemAgent* fileSystemAgent() { return m_fileSystemAgent.get(); }
194 #endif 
195
196     void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&);
197     void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&);
198
199 #if ENABLE(WORKERS)
200     enum WorkerAction { WorkerCreated, WorkerDestroyed };
201
202     void postWorkerNotificationToFrontend(const InspectorWorkerResource&, WorkerAction);
203     void didCreateWorker(intptr_t, const String& url, bool isSharedWorker);
204     void didDestroyWorker(intptr_t);
205 #endif
206
207 #if ENABLE(DATABASE)
208     void didOpenDatabase(PassRefPtr<Database>, const String& domain, const String& name, const String& version);
209 #endif
210 #if ENABLE(DOM_STORAGE)
211     void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame);
212     void selectDOMStorage(Storage* storage);
213     void getDOMStorageEntries(long storageId, RefPtr<InspectorArray>* entries);
214     void setDOMStorageItem(long storageId, const String& key, const String& value, bool* success);
215     void removeDOMStorageItem(long storageId, const String& key, bool* success);
216 #endif
217 #if ENABLE(WEB_SOCKETS)
218     void didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL);
219     void willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest&);
220     void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse&);
221     void didCloseWebSocket(unsigned long identifier);
222 #endif
223
224     bool hasFrontend() const { return m_frontend; }
225
226     void drawNodeHighlight(GraphicsContext&) const;
227     void openInInspectedWindow(const String& url);
228     void drawElementTitle(GraphicsContext&, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings*) const;
229
230     void count(const String& title, unsigned lineNumber, const String& sourceID);
231
232     void startTiming(const String& title);
233     bool stopTiming(const String& title, double& elapsed);
234
235     void startGroup(PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack> callFrame, bool collapsed = false);
236     void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
237
238     void markTimeline(const String& message);
239
240 #if ENABLE(JAVASCRIPT_DEBUGGER)
241     void addProfile(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
242     void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
243     void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
244     bool isRecordingUserInitiatedProfile() const;
245     String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false);
246     void startProfiling() { startUserInitiatedProfiling(); }
247     void startUserInitiatedProfiling();
248     void stopProfiling() { stopUserInitiatedProfiling(); }
249     void stopUserInitiatedProfiling();
250     void enableProfiler(bool always = false, bool skipRecompile = false);
251     void disableProfiler(bool always = false);
252     bool profilerEnabled() const;
253     InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); }
254
255     void enableDebugger();
256     void disableDebugger(bool always = false);
257     bool debuggerEnabled() const { return m_debuggerAgent; }
258     InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); }
259     void resume();
260
261     void setStickyBreakpoints(PassRefPtr<InspectorObject> breakpoints);
262     void setEventListenerBreakpoint(const String& eventName);
263     void removeEventListenerBreakpoint(const String& eventName);
264     bool hasEventListenerBreakpoint(const String& eventName);
265     void setXHRBreakpoint(const String& url);
266     void removeXHRBreakpoint(const String& url);
267     bool hasXHRBreakpoint(const String& url, String* breakpointURL);
268 #endif
269
270     void evaluateForTestInFrontend(long testCallId, const String& script);
271
272     InjectedScript injectedScriptForNodeId(long id);
273
274     void addScriptToEvaluateOnLoad(const String& source);
275     void removeAllScriptsToEvaluateOnLoad();
276     void setInspectorExtensionAPI(const String& source);
277
278     bool inspectorStartsAttached();
279     void setInspectorStartsAttached(bool);
280     void setInspectorAttachedHeight(long height);
281     int inspectorAttachedHeight() const;
282
283     static const unsigned defaultAttachedHeight;
284
285 private:
286     void getInspectorState(RefPtr<InspectorObject>* state);
287     void setConsoleMessagesEnabled(bool enabled);
288
289     friend class InspectorBackend;
290     friend class InspectorBackendDispatcher;
291     friend class InspectorInstrumentation;
292     friend class InjectedScriptHost;
293
294     enum ProfilerRestoreAction {
295         ProfilerRestoreNoAction = 0,
296         ProfilerRestoreResetAgent = 1
297     };
298     
299     void populateScriptObjects();
300     void restoreDebugger();
301     void restoreProfiler(ProfilerRestoreAction action);
302     void unbindAllResources();
303     void setSearchingForNode(bool enabled);
304
305     // Following are used from InspectorBackend and internally.
306     void setSearchingForNode(bool enabled, bool* newState);
307
308     void setMonitoringXHREnabled(bool enabled, bool* newState);
309     InspectorCSSAgent* cssAgent() { return m_cssAgent.get(); }
310     InspectorDOMAgent* domAgent() { return m_domAgent.get(); }
311     void releaseFrontendLifetimeAgents();
312
313 #if ENABLE(JAVASCRIPT_DEBUGGER)
314     void toggleRecordButton(bool);
315     void enableDebuggerFromFrontend(bool always);
316     void restoreStickyBreakpoints();
317     void restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint);
318 #endif
319 #if ENABLE(DATABASE)
320     void selectDatabase(Database* database);
321     Database* databaseForId(long databaseId);
322 #endif
323 #if ENABLE(DOM_STORAGE)
324     InspectorDOMStorageResource* getDOMStorageResourceForId(long storageId);
325 #endif
326
327     PassRefPtr<InspectorObject> buildObjectForCookie(const Cookie&);
328     PassRefPtr<InspectorArray> buildArrayForCookies(ListHashSet<Cookie>&);
329
330     void focusNode();
331
332     void addConsoleMessage(PassOwnPtr<ConsoleMessage>);
333
334     bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl);
335
336     void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
337
338     Page* m_inspectedPage;
339     InspectorClient* m_client;
340     OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
341     bool m_openingFrontend;
342     OwnPtr<InspectorFrontend> m_frontend;
343     OwnPtr<InspectorCSSAgent> m_cssAgent;
344     RefPtr<InspectorDOMAgent> m_domAgent;
345     RefPtr<InspectorStorageAgent> m_storageAgent;
346     OwnPtr<InspectorTimelineAgent> m_timelineAgent;
347     OwnPtr<InspectorState> m_state;
348
349 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
350     OwnPtr<InspectorApplicationCacheAgent> m_applicationCacheAgent;
351 #endif
352     
353 #if ENABLE(FILE_SYSTEM)
354     RefPtr<InspectorFileSystemAgent> m_fileSystemAgent;
355 #endif 
356
357     RefPtr<Node> m_nodeToFocus;
358     RefPtr<InspectorResourceAgent> m_resourceAgent;
359     unsigned long m_mainResourceIdentifier;
360     Vector<OwnPtr<ConsoleMessage> > m_consoleMessages;
361     unsigned m_expiredConsoleMessageCount;
362     HashMap<String, double> m_times;
363     HashMap<String, unsigned> m_counts;
364 #if ENABLE(DATABASE)
365     DatabaseResourcesMap m_databaseResources;
366 #endif
367 #if ENABLE(DOM_STORAGE)
368     DOMStorageResourcesMap m_domStorageResources;
369 #endif
370     String m_showAfterVisible;
371     RefPtr<Node> m_highlightedNode;
372     ConsoleMessage* m_previousMessage;
373     bool m_settingsLoaded;
374     RefPtr<InspectorBackend> m_inspectorBackend;
375     OwnPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
376     RefPtr<InjectedScriptHost> m_injectedScriptHost;
377
378     typedef HashMap<String, String> Settings;
379     mutable Settings m_settings;
380
381     Vector<pair<long, String> > m_pendingEvaluateTestCommands;
382     Vector<String> m_scriptsToEvaluateOnLoad;
383     String m_inspectorExtensionAPI;
384 #if ENABLE(JAVASCRIPT_DEBUGGER)
385     bool m_attachDebuggerWhenShown;
386     OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
387
388     HashSet<String> m_eventListenerBreakpoints;
389     HashSet<String> m_XHRBreakpoints;
390     bool m_hasXHRBreakpointWithEmptyURL;
391
392     OwnPtr<InspectorProfilerAgent> m_profilerAgent;
393 #endif
394     OwnPtr<HTTPHeaderMap> m_extraHeaders;
395 #if ENABLE(WORKERS)
396     typedef HashMap<intptr_t, RefPtr<InspectorWorkerResource> > WorkersMap;
397
398     WorkersMap m_workers;
399 #endif
400 };
401
402 } // namespace WebCore
403
404 #endif // !defined(InspectorController_h)