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