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