• 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 "ScriptState.h"
35 #include "StringHash.h"
36 #include "Timer.h"
37 
38 #include <wtf/HashMap.h>
39 #include <wtf/HashSet.h>
40 #include <wtf/RefCounted.h>
41 #include <wtf/Vector.h>
42 
43 #if ENABLE(JAVASCRIPT_DEBUGGER)
44 #include "JavaScriptDebugListener.h"
45 
46 namespace JSC {
47     class Profile;
48     class UString;
49 }
50 #endif
51 
52 namespace WebCore {
53 
54 class CachedResource;
55 class Database;
56 class Document;
57 class DocumentLoader;
58 class GraphicsContext;
59 class HitTestResult;
60 class InspectorClient;
61 class InspectorDOMAgent;
62 class JavaScriptCallFrame;
63 class StorageArea;
64 class KURL;
65 class Node;
66 class Page;
67 struct ResourceRequest;
68 class ResourceResponse;
69 class ResourceError;
70 class ScriptCallStack;
71 class ScriptObject;
72 class ScriptString;
73 class SharedBuffer;
74 
75 class ConsoleMessage;
76 class InspectorDatabaseResource;
77 class InspectorDOMStorageResource;
78 class InspectorResource;
79 
80 #if !PLATFORM(ANDROID)
81 class InspectorBackend;
82 class InspectorFrontend;
83 #endif
84 
85 class InspectorController
86 #if ENABLE(JAVASCRIPT_DEBUGGER)
87                           : JavaScriptDebugListener
88 #endif
89                                                     {
90 public:
91     typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
92     typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
93     typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
94     typedef HashSet<RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesSet;
95 
96     typedef enum {
97         CurrentPanel,
98         ConsolePanel,
99         DatabasesPanel,
100         ElementsPanel,
101         ProfilesPanel,
102         ResourcesPanel,
103         ScriptsPanel
104     } SpecialPanels;
105 
106     struct Setting {
107         enum Type {
108             NoType, StringType, StringVectorType, DoubleType, IntegerType, BooleanType
109         };
110 
SettingSetting111         Setting()
112             : m_type(NoType)
113         {
114         }
115 
SettingSetting116         explicit Setting(bool value)
117             : m_type(BooleanType)
118         {
119             m_simpleContent.m_boolean = value;
120         }
121 
SettingSetting122         explicit Setting(unsigned value)
123             : m_type(IntegerType)
124         {
125             m_simpleContent.m_integer = value;
126         }
127 
SettingSetting128         explicit Setting(const String& value)
129             : m_type(StringType)
130         {
131             m_string = value;
132         }
133 
typeSetting134         Type type() const { return m_type; }
135 
stringSetting136         String string() const { ASSERT(m_type == StringType); return m_string; }
stringVectorSetting137         const Vector<String>& stringVector() const { ASSERT(m_type == StringVectorType); return m_stringVector; }
doubleValueSetting138         double doubleValue() const { ASSERT(m_type == DoubleType); return m_simpleContent.m_double; }
integerValueSetting139         long integerValue() const { ASSERT(m_type == IntegerType); return m_simpleContent.m_integer; }
booleanValueSetting140         bool booleanValue() const { ASSERT(m_type == BooleanType); return m_simpleContent.m_boolean; }
141 
setSetting142         void set(const String& value) { m_type = StringType; m_string = value; }
setSetting143         void set(const Vector<String>& value) { m_type = StringVectorType; m_stringVector = value; }
setSetting144         void set(double value) { m_type = DoubleType; m_simpleContent.m_double = value; }
setSetting145         void set(long value) { m_type = IntegerType; m_simpleContent.m_integer = value; }
setSetting146         void set(bool value) { m_type = BooleanType; m_simpleContent.m_boolean = value; }
147 
148     private:
149         Type m_type;
150 
151         String m_string;
152         Vector<String> m_stringVector;
153 
154         union {
155             double m_double;
156             long m_integer;
157             bool m_boolean;
158         } m_simpleContent;
159     };
160     InspectorController(Page*, InspectorClient*);
161     ~InspectorController();
162 
163 #if !PLATFORM(ANDROID)
inspectorBackend()164     InspectorBackend* inspectorBackend() { return m_inspectorBackend.get(); }
165 #endif
166 
167     void inspectedPageDestroyed();
pageDestroyed()168     void pageDestroyed() { m_page = 0; }
169 
170     bool enabled() const;
171 
inspectedPage()172     Page* inspectedPage() const { return m_inspectedPage; }
173 
174     const Setting& setting(const String& key) const;
175     void setSetting(const String& key, const Setting&);
176 
177     void inspect(Node*);
178     void highlight(Node*);
179     void hideHighlight();
180 
181     void show();
182     void showPanel(SpecialPanels);
183     void close();
184 
185     bool windowVisible();
186     void setWindowVisible(bool visible = true, bool attached = false);
187 
188     void addMessageToConsole(MessageSource, MessageType, MessageLevel, ScriptCallStack*);
189     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
190     void clearConsoleMessages();
consoleMessages()191     const Vector<ConsoleMessage*>& consoleMessages() const { return m_consoleMessages; }
192 
193     void attachWindow();
194     void detachWindow();
195 
196     void toggleSearchForNodeInPage();
searchingForNodeInPage()197     bool searchingForNodeInPage() { return m_searchingForNode; };
198     void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
199     void handleMousePressOnNode(Node*);
200 
201     void inspectedWindowScriptObjectCleared(Frame*);
202     void windowScriptObjectAvailable();
203 
204     void setFrontendProxyObject(ScriptState* state, ScriptObject object);
205 
206     void populateScriptObjects();
207     void resetScriptObjects();
208 
209     void didCommitLoad(DocumentLoader*);
210     void frameDetachedFromParent(Frame*);
211 
212     void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
213 
214     void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
215     void willSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
216     void didReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&);
217     void didReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived);
218     void didFinishLoading(DocumentLoader*, unsigned long identifier);
219     void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
220     void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
221     void scriptImported(unsigned long identifier, const String& sourceString);
222 
223     void enableResourceTracking(bool always = false);
224     void disableResourceTracking(bool always = false);
resourceTrackingEnabled()225     bool resourceTrackingEnabled() const { return m_resourceTrackingEnabled; }
226     void ensureResourceTrackingSettingsLoaded();
227 
228 #if ENABLE(DATABASE)
229     void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
230 #endif
231 #if ENABLE(DOM_STORAGE)
232     void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame);
233 #endif
234 
resources()235     const ResourcesMap& resources() const { return m_resources; }
236 
237     void drawNodeHighlight(GraphicsContext&) const;
238 
239     void count(const String& title, unsigned lineNumber, const String& sourceID);
240 
241     void startTiming(const String& title);
242     bool stopTiming(const String& title, double& elapsed);
243 
244     void startGroup(MessageSource source, ScriptCallStack* callFrame);
245     void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
246 
247 #if ENABLE(JAVASCRIPT_DEBUGGER)
248     void addProfile(PassRefPtr<JSC::Profile>, unsigned lineNumber, const JSC::UString& sourceURL);
249     void addProfileFinishedMessageToConsole(PassRefPtr<JSC::Profile>, unsigned lineNumber, const JSC::UString& sourceURL);
250     void addStartProfilingMessageToConsole(const JSC::UString& title, unsigned lineNumber, const JSC::UString& sourceURL);
251     void addScriptProfile(JSC::Profile*);
profiles()252     const ProfilesArray& profiles() const { return m_profiles; }
253 
isRecordingUserInitiatedProfile()254     bool isRecordingUserInitiatedProfile() const { return m_recordingUserInitiatedProfile; }
255 
256     JSC::UString getCurrentUserInitiatedProfileName(bool incrementProfileNumber);
257     void startUserInitiatedProfiling(Timer<InspectorController>* = 0);
258     void stopUserInitiatedProfiling();
259 
260     void enableProfiler(bool always = false, bool skipRecompile = false);
261     void disableProfiler(bool always = false);
profilerEnabled()262     bool profilerEnabled() const { return enabled() && m_profilerEnabled; }
263 
264     void enableDebugger();
265     void disableDebugger(bool always = false);
debuggerEnabled()266     bool debuggerEnabled() const { return m_debuggerEnabled; }
267 
268     void resumeDebugger();
269 
270     virtual void didParseSource(JSC::ExecState*, const JSC::SourceCode&);
271     virtual void failedToParseSource(JSC::ExecState*, const JSC::SourceCode&, int errorLine, const JSC::UString& errorMessage);
272     virtual void didPause();
273     virtual void didContinue();
274 #endif
275 
276 private:
277 #if !PLATFORM(ANDROID)
278     friend class InspectorBackend;
279 #endif
280 
281     // Following are used from InspectorBackend and internally.
282     void scriptObjectReady(bool enableDOMAgent);
283     void moveWindowBy(float x, float y) const;
284     void setAttachedWindow(bool);
285     void setAttachedWindowHeight(unsigned height);
286     void storeLastActivePanel(const String& panelName);
287     void closeWindow();
domAgent()288     InspectorDOMAgent* domAgent() { return m_domAgent.get(); }
289 
290 #if ENABLE(JAVASCRIPT_DEBUGGER)
291     void startUserInitiatedProfilingSoon();
292     void toggleRecordButton(bool);
293     void enableDebuggerFromFrontend(bool always);
294 #endif
295 
296     void focusNode();
297 
298     void addConsoleMessage(ScriptState*, ConsoleMessage*);
299 
300     void addResource(InspectorResource*);
301     void removeResource(InspectorResource*);
302     InspectorResource* getTrackedResource(long long identifier);
303 
304     void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
removeAllResources(ResourcesMap * map)305     void removeAllResources(ResourcesMap* map) { pruneResources(map); }
306 
307     void showWindow();
308 
309     bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl);
310 
311     SpecialPanels specialPanelForJSName(const String& panelName);
312 
313     Page* m_inspectedPage;
314     InspectorClient* m_client;
315 
316     RefPtr<InspectorDOMAgent> m_domAgent;
317     Page* m_page;
318     RefPtr<Node> m_nodeToFocus;
319     RefPtr<InspectorResource> m_mainResource;
320     ResourcesMap m_resources;
321     HashSet<String> m_knownResources;
322     FrameResourcesMap m_frameResources;
323     Vector<ConsoleMessage*> m_consoleMessages;
324     HashMap<String, double> m_times;
325     HashMap<String, unsigned> m_counts;
326 #if ENABLE(DATABASE)
327     DatabaseResourcesSet m_databaseResources;
328 #endif
329 #if ENABLE(DOM_STORAGE)
330     DOMStorageResourcesSet m_domStorageResources;
331 #endif
332     ScriptState* m_scriptState;
333     bool m_windowVisible;
334     SpecialPanels m_showAfterVisible;
335     long long m_nextIdentifier;
336     RefPtr<Node> m_highlightedNode;
337     unsigned m_groupLevel;
338     bool m_searchingForNode;
339     ConsoleMessage* m_previousMessage;
340     bool m_resourceTrackingEnabled;
341     bool m_resourceTrackingSettingsLoaded;
342 #if !PLATFORM(ANDROID)
343     OwnPtr<InspectorFrontend> m_frontend;
344     RefPtr<InspectorBackend> m_inspectorBackend;
345 #endif
346 #if ENABLE(JAVASCRIPT_DEBUGGER)
347     bool m_debuggerEnabled;
348     bool m_attachDebuggerWhenShown;
349     bool m_profilerEnabled;
350     bool m_recordingUserInitiatedProfile;
351     int m_currentUserInitiatedProfileNumber;
352     unsigned m_nextUserInitiatedProfileNumber;
353     Timer<InspectorController> m_startProfiling;
354     ProfilesArray m_profiles;
355 #endif
356 };
357 
358 } // namespace WebCore
359 
360 #endif // !defined(InspectorController_h)
361