dfe7669d251cb8d1744d12d385616335f8e9df2c
[WebKit-https.git] / Source / WebCore / inspector / InspectorDOMAgent.h
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  * Copyright (C) 2009-2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef InspectorDOMAgent_h
31 #define InspectorDOMAgent_h
32
33 #include "EventTarget.h"
34 #include "InjectedScript.h"
35 #include "InjectedScriptManager.h"
36 #include "InspectorFrontend.h"
37 #include "InspectorValues.h"
38 #include "Timer.h"
39
40 #include <wtf/Deque.h>
41 #include <wtf/ListHashSet.h>
42 #include <wtf/HashMap.h>
43 #include <wtf/HashSet.h>
44 #include <wtf/OwnPtr.h>
45 #include <wtf/PassOwnPtr.h>
46 #include <wtf/RefPtr.h>
47 #include <wtf/Vector.h>
48 #include <wtf/text/AtomicString.h>
49
50 namespace WebCore {
51 class ContainerNode;
52 class CharacterData;
53 class Document;
54 class Element;
55 class Event;
56 class GraphicsContext;
57 class InspectorDOMAgent;
58 class InspectorFrontend;
59 class HitTestResult;
60 class MatchJob;
61 class HTMLElement;
62 class InspectorState;
63 class InstrumentingAgents;
64 class NameNodeMap;
65 class Node;
66 class Page;
67 class RevalidateStyleAttributeTask;
68 class ScriptValue;
69
70 typedef String ErrorString;
71
72 #if ENABLE(INSPECTOR)
73
74 struct EventListenerInfo {
75     EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
76         : node(node)
77         , eventType(eventType)
78         , eventListenerVector(eventListenerVector)
79     {
80     }
81
82     Node* node;
83     const AtomicString eventType;
84     const EventListenerVector eventListenerVector;
85 };
86
87 class InspectorDOMAgent {
88 public:
89     struct DOMListener {
90         virtual ~DOMListener()
91         {
92         }
93         virtual void didRemoveDocument(Document*) = 0;
94         virtual void didRemoveDOMNode(Node*) = 0;
95         virtual void didModifyDOMAttr(Element*) = 0;
96     };
97
98     static PassOwnPtr<InspectorDOMAgent> create(InstrumentingAgents* instrumentingAgents, Page* page, InspectorState* inspectorState, InjectedScriptManager* injectedScriptManager)
99     {
100         return adoptPtr(new InspectorDOMAgent(instrumentingAgents, page, inspectorState, injectedScriptManager));
101     }
102
103     ~InspectorDOMAgent();
104
105     void setFrontend(InspectorFrontend*);
106     void clearFrontend();
107     void restore();
108
109     Vector<Document*> documents();
110     void reset();
111
112     // Methods called from the frontend for DOM nodes inspection.
113     void querySelector(ErrorString*, int nodeId, const String& selectors, bool documentWide, int* elementId);
114     void querySelectorAll(ErrorString*, int nodeId, const String& selectors, bool documentWide, RefPtr<InspectorArray>* result);
115     void getDocument(ErrorString*, RefPtr<InspectorObject>* root);
116     void getChildNodes(ErrorString*, int nodeId);
117     void setAttribute(ErrorString*, int elementId, const String& name, const String& value);
118     void removeAttribute(ErrorString*, int elementId, const String& name);
119     void removeNode(ErrorString*, int nodeId);
120     void setNodeName(ErrorString*, int nodeId, const String& name, int* newId);
121     void getOuterHTML(ErrorString*, int nodeId, WTF::String* outerHTML);
122     void setOuterHTML(ErrorString*, int nodeId, const String& outerHTML, int* newId);
123     void setNodeValue(ErrorString*, int nodeId, const String& value);
124     void getEventListenersForNode(ErrorString*, int nodeId, RefPtr<InspectorArray>* listenersArray);
125     void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, bool runSynchronously);
126     void cancelSearch(ErrorString*);
127     void resolveNode(ErrorString*, int nodeId, RefPtr<InspectorObject>* result);
128     void setSearchingForNode(ErrorString*, bool enabled, bool* newState);
129     void pushNodeToFrontend(ErrorString*, const String& objectId, int* nodeId);
130     void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId);
131     void hideHighlight(ErrorString*);
132     void highlightDOMNode(ErrorString*, int nodeId);
133     void hideDOMNodeHighlight(ErrorString* error) { hideHighlight(error); }
134     void highlightFrame(ErrorString*, const String& frameId);
135     void hideFrameHighlight(ErrorString* error) { hideHighlight(error); }
136
137     // Methods called from the InspectorInstrumentation.
138     void setDocument(Document*);
139     void releaseDanglingNodes();
140
141     void mainFrameDOMContentLoaded();
142     void loadEventFired(Document*);
143
144     void didInsertDOMNode(Node*);
145     void didRemoveDOMNode(Node*);
146     void didModifyDOMAttr(Element*);
147     void characterDataModified(CharacterData*);
148     void didInvalidateStyleAttr(Node*);
149
150     Node* nodeForId(int nodeId);
151     int boundNodeId(Node*);
152     void copyNode(ErrorString*, int nodeId);
153     void setDOMListener(DOMListener*);
154
155     String documentURLString(Document*) const;
156
157     PassRefPtr<InspectorObject> resolveNode(Node*);
158     bool handleMousePress();
159     bool searchingForNodeInPage() const;
160     void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
161
162     void drawNodeHighlight(GraphicsContext&) const;
163
164     // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
165     // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
166     static Node* innerFirstChild(Node*);
167     static Node* innerNextSibling(Node*);
168     static Node* innerPreviousSibling(Node*);
169     static unsigned innerChildNodeCount(Node*);
170     static Node* innerParentNode(Node*);
171     static bool isWhitespace(Node*);
172
173 private:
174     InspectorDOMAgent(InstrumentingAgents*, Page*, InspectorState*, InjectedScriptManager*);
175
176     void setSearchingForNode(bool enabled);
177     void highlight(ErrorString*, Node*);
178
179     // Node-related methods.
180     typedef HashMap<RefPtr<Node>, int> NodeToIdMap;
181     int bind(Node*, NodeToIdMap*);
182     void unbind(Node*, NodeToIdMap*);
183     Node* assertNode(ErrorString*, int nodeId);
184     Element* assertElement(ErrorString*, int nodeId);
185     HTMLElement* assertHTMLElement(ErrorString*, int nodeId);
186     Node* nodeToSelectOn(ErrorString*, int nodeId, bool documentWide);
187
188     int pushNodePathToFrontend(Node*);
189     void pushChildNodesToFrontend(int nodeId);
190
191     bool hasBreakpoint(Node*, int type);
192     void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
193     void descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, PassRefPtr<InspectorObject> description);
194
195     PassRefPtr<InspectorObject> buildObjectForNode(Node*, int depth, NodeToIdMap*);
196     PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element*);
197     PassRefPtr<InspectorArray> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap);
198     PassRefPtr<InspectorObject> buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*);
199
200     void onMatchJobsTimer(Timer<InspectorDOMAgent>*);
201     void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector);
202
203     Node* nodeForPath(const String& path);
204     PassRefPtr<InspectorArray> toArray(const Vector<String>& data);
205
206     void discardBindings();
207
208     InstrumentingAgents* m_instrumentingAgents;
209     Page* m_inspectedPage;
210     InspectorState* m_inspectorState;
211     InjectedScriptManager* m_injectedScriptManager;
212     InspectorFrontend::DOM* m_frontend;
213     DOMListener* m_domListener;
214     NodeToIdMap m_documentNodeToIdMap;
215     // Owns node mappings for dangling nodes.
216     Vector<NodeToIdMap*> m_danglingNodeToIdMaps;
217     HashMap<int, Node*> m_idToNode;
218     HashMap<int, NodeToIdMap*> m_idToNodesMap;
219     HashSet<int> m_childrenRequested;
220     int m_lastNodeId;
221     RefPtr<Document> m_document;
222     Deque<MatchJob*> m_pendingMatchJobs;
223     Timer<InspectorDOMAgent> m_matchJobsTimer;
224     HashSet<RefPtr<Node> > m_searchResults;
225     OwnPtr<RevalidateStyleAttributeTask> m_revalidateStyleAttrTask;
226     RefPtr<Node> m_highlightedNode;
227     bool m_searchingForNode;
228 };
229
230 #endif // ENABLE(INSPECTOR)
231
232 } // namespace WebCore
233
234 #endif // !defined(InspectorDOMAgent_h)