2009-03-05 Dimitri Glazkov <dglazkov@chromium.org>
[WebKit-https.git] / WebCore / inspector / InspectorController.h
1 /*
2  * Copyright (C) 2007 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 "Console.h"
33 #include "PlatformString.h"
34 #include "StringHash.h"
35 #include "Timer.h"
36 #include <JavaScriptCore/JSContextRef.h>
37 #include <wtf/HashMap.h>
38 #include <wtf/HashSet.h>
39 #include <wtf/RefCounted.h>
40 #include <wtf/Vector.h>
41
42 #if ENABLE(JAVASCRIPT_DEBUGGER)
43 #include "JavaScriptDebugListener.h"
44 #endif
45
46
47 namespace JSC {
48     class Profile;
49     class UString;
50 }
51
52 namespace WebCore {
53
54 class CachedResource;
55 class Database;
56 class DocumentLoader;
57 class GraphicsContext;
58 class HitTestResult;
59 class InspectorClient;
60 class JavaScriptCallFrame;
61 class StorageArea;
62 class Node;
63 class Page;
64 struct ResourceRequest;
65 class ResourceResponse;
66 class ResourceError;
67 class ScriptCallStack;
68 class SharedBuffer;
69
70 class ConsoleMessage;
71 class InspectorDatabaseResource;
72 class InspectorDOMStorageResource;
73 class InspectorResource;
74
75 class InspectorController : public RefCounted<InspectorController>
76 #if ENABLE(JAVASCRIPT_DEBUGGER)
77                           , JavaScriptDebugListener
78 #endif
79                                                     {
80 public:
81     typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
82     typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
83     typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
84     typedef HashSet<RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesSet;
85
86     typedef enum {
87         CurrentPanel,
88         ConsolePanel,
89         DatabasesPanel,
90         ElementsPanel,
91         ProfilesPanel,
92         ResourcesPanel,
93         ScriptsPanel
94     } SpecialPanels;
95
96     struct Setting {
97         enum Type {
98             NoType, StringType, StringVectorType, DoubleType, IntegerType, BooleanType
99         };
100
101         Setting()
102             : m_type(NoType)
103         {
104         }
105
106         Type type() const { return m_type; }
107
108         String string() const { ASSERT(m_type == StringType); return m_string; }
109         const Vector<String>& stringVector() const { ASSERT(m_type == StringVectorType); return m_stringVector; }
110         double doubleValue() const { ASSERT(m_type == DoubleType); return m_simpleContent.m_double; }
111         long integerValue() const { ASSERT(m_type == IntegerType); return m_simpleContent.m_integer; }
112         bool booleanValue() const { ASSERT(m_type == BooleanType); return m_simpleContent.m_boolean; }
113
114         void set(const String& value) { m_type = StringType; m_string = value; }
115         void set(const Vector<String>& value) { m_type = StringVectorType; m_stringVector = value; }
116         void set(double value) { m_type = DoubleType; m_simpleContent.m_double = value; }
117         void set(long value) { m_type = IntegerType; m_simpleContent.m_integer = value; }
118         void set(bool value) { m_type = BooleanType; m_simpleContent.m_boolean = value; }
119
120     private:
121         Type m_type;
122
123         String m_string;
124         Vector<String> m_stringVector;
125
126         union {
127             double m_double;
128             long m_integer;
129             bool m_boolean;
130         } m_simpleContent;
131     };
132
133     InspectorController(Page*, InspectorClient*);
134     ~InspectorController();
135
136     void inspectedPageDestroyed();
137     void pageDestroyed() { m_page = 0; }
138
139     bool enabled() const;
140
141     Page* inspectedPage() const { return m_inspectedPage; }
142
143     const Setting& setting(const String& key) const;
144     void setSetting(const String& key, const Setting&);
145
146     String localizedStringsURL();
147     String hiddenPanels();
148
149     void inspect(Node*);
150     void highlight(Node*);
151     void hideHighlight();
152
153     void show();
154     void showPanel(SpecialPanels);
155     void close();
156
157     bool isRecordingUserInitiatedProfile() const { return m_recordingUserInitiatedProfile; }
158     void startUserInitiatedProfilingSoon();
159     void startUserInitiatedProfiling(Timer<InspectorController>* = 0);
160     void stopUserInitiatedProfiling();
161
162     void enableProfiler(bool skipRecompile = false);
163     void disableProfiler();
164     bool profilerEnabled() const { return enabled() && m_profilerEnabled; }
165
166     bool windowVisible();
167     void setWindowVisible(bool visible = true, bool attached = false);
168
169     bool addSourceToFrame(const String& mimeType, const String& source, Node*);
170     void addMessageToConsole(MessageSource, MessageLevel, ScriptCallStack*);
171     void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
172     void clearConsoleMessages();
173     void toggleRecordButton(bool);
174
175     void addProfile(PassRefPtr<JSC::Profile>, unsigned lineNumber, const JSC::UString& sourceURL);
176     void addProfileMessageToConsole(PassRefPtr<JSC::Profile> prpProfile, unsigned lineNumber, const JSC::UString& sourceURL);
177     void addScriptProfile(JSC::Profile* profile);
178     const ProfilesArray& profiles() const { return m_profiles; }
179
180     void attachWindow();
181     void detachWindow();
182
183     void setAttachedWindow(bool);
184     void setAttachedWindowHeight(unsigned height);
185
186     void toggleSearchForNodeInPage();
187     bool searchingForNodeInPage() { return m_searchingForNode; };
188     void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
189     void handleMousePressOnNode(Node*);
190
191     JSContextRef scriptContext() const { return m_scriptContext; };
192     void setScriptContext(JSContextRef context) { m_scriptContext = context; };
193
194     void inspectedWindowScriptObjectCleared(Frame*);
195     void windowScriptObjectAvailable();
196
197     void scriptObjectReady();
198
199     void populateScriptObjects();
200     void resetScriptObjects();
201
202     void didCommitLoad(DocumentLoader*);
203     void frameDetachedFromParent(Frame*);
204
205     void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
206
207     void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
208     void willSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
209     void didReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&);
210     void didReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived);
211     void didFinishLoading(DocumentLoader*, unsigned long identifier);
212     void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
213     void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const JSC::UString& sourceString);
214
215 #if ENABLE(DATABASE)
216     void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
217 #endif
218 #if ENABLE(DOM_STORAGE)
219     void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame);
220 #endif
221
222     const ResourcesMap& resources() const { return m_resources; }
223
224     void moveWindowBy(float x, float y) const;
225     void closeWindow();
226
227 #if ENABLE(JAVASCRIPT_DEBUGGER)
228     void enableDebugger();
229     void disableDebugger();
230     bool debuggerEnabled() const { return m_debuggerEnabled; }
231
232     JavaScriptCallFrame* currentCallFrame() const;
233
234     void addBreakpoint(intptr_t sourceID, unsigned lineNumber);
235     void removeBreakpoint(intptr_t sourceID, unsigned lineNumber);
236
237     bool pauseOnExceptions();
238     void setPauseOnExceptions(bool pause);
239
240     void pauseInDebugger();
241     void resumeDebugger();
242
243     void stepOverStatementInDebugger();
244     void stepIntoStatementInDebugger();
245     void stepOutOfFunctionInDebugger();
246 #endif
247
248     void drawNodeHighlight(GraphicsContext&) const;
249     
250     void count(const String& title, unsigned lineNumber, const String& sourceID);
251
252     void startTiming(const String& title);
253     bool stopTiming(const String& title, double& elapsed);
254
255     void startGroup(MessageSource source, ScriptCallStack* callFrame);
256     void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
257
258     const String& platform() const;
259
260 private:
261     void focusNode();
262
263     void addConsoleMessage(JSC::ExecState*, ConsoleMessage*);
264     void addScriptConsoleMessage(const ConsoleMessage*);
265
266     void addResource(InspectorResource*);
267     void removeResource(InspectorResource*);
268
269     JSObjectRef addScriptResource(InspectorResource*);
270     void removeScriptResource(InspectorResource*);
271
272     JSObjectRef addAndUpdateScriptResource(InspectorResource*);
273     void updateScriptResourceRequest(InspectorResource*);
274     void updateScriptResourceResponse(InspectorResource*);
275     void updateScriptResourceType(InspectorResource*);
276     void updateScriptResource(InspectorResource*, int length);
277     void updateScriptResource(InspectorResource*, bool finished, bool failed = false);
278     void updateScriptResource(InspectorResource*, double startTime, double responseReceivedTime, double endTime);
279
280     void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
281     void removeAllResources(ResourcesMap* map) { pruneResources(map); }
282
283 #if ENABLE(DATABASE)
284     JSObjectRef addDatabaseScriptResource(InspectorDatabaseResource*);
285     void removeDatabaseScriptResource(InspectorDatabaseResource*);
286 #endif
287 #if ENABLE(DOM_STORAGE)
288     JSObjectRef addDOMStorageScriptResource(InspectorDOMStorageResource*);
289     void removeDOMStorageScriptResource(InspectorDOMStorageResource*);
290 #endif
291
292     JSValueRef callSimpleFunction(JSContextRef, JSObjectRef thisObject, const char* functionName) const;
293     JSValueRef callFunction(JSContextRef, JSObjectRef thisObject, const char* functionName, size_t argumentCount, const JSValueRef arguments[], JSValueRef& exception) const;
294
295     bool handleException(JSContextRef, JSValueRef exception, unsigned lineNumber) const;
296
297     void showWindow();
298
299 #if ENABLE(JAVASCRIPT_DEBUGGER)
300     virtual void didParseSource(JSC::ExecState*, const JSC::SourceCode&);
301     virtual void failedToParseSource(JSC::ExecState*, const JSC::SourceCode&, int errorLine, const JSC::UString& errorMessage);
302     virtual void didPause();
303 #endif
304
305     Page* m_inspectedPage;
306     InspectorClient* m_client;
307     Page* m_page;
308     RefPtr<Node> m_nodeToFocus;
309     RefPtr<InspectorResource> m_mainResource;
310     ResourcesMap m_resources;
311     HashSet<String> m_knownResources;
312     FrameResourcesMap m_frameResources;
313     Vector<ConsoleMessage*> m_consoleMessages;
314     ProfilesArray m_profiles;
315     HashMap<String, double> m_times;
316     HashMap<String, unsigned> m_counts;
317 #if ENABLE(DATABASE)
318     DatabaseResourcesSet m_databaseResources;
319 #endif
320 #if ENABLE(DOM_STORAGE)
321     DOMStorageResourcesSet m_domStorageResources;
322 #endif
323     JSObjectRef m_scriptObject;
324     JSObjectRef m_controllerScriptObject;
325     JSContextRef m_scriptContext;
326     bool m_windowVisible;
327 #if ENABLE(JAVASCRIPT_DEBUGGER)
328     bool m_debuggerEnabled;
329     bool m_attachDebuggerWhenShown;
330 #endif
331     bool m_profilerEnabled;
332     bool m_recordingUserInitiatedProfile;
333     SpecialPanels m_showAfterVisible;
334     long long m_nextIdentifier;
335     RefPtr<Node> m_highlightedNode;
336     unsigned m_groupLevel;
337     bool m_searchingForNode;
338     int m_currentUserInitiatedProfileNumber;
339     unsigned m_nextUserInitiatedProfileNumber;
340     ConsoleMessage* m_previousMessage;
341     Timer<InspectorController> m_startProfiling;
342 };
343
344 } // namespace WebCore
345
346 #endif // !defined(InspectorController_h)