2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 #ifndef InspectorDOMAgent_h
31 #define InspectorDOMAgent_h
33 #include "EventListener.h"
34 #include "EventTarget.h"
35 #include "InspectorValues.h"
39 #include <wtf/Deque.h>
40 #include <wtf/ListHashSet.h>
41 #include <wtf/HashMap.h>
42 #include <wtf/HashSet.h>
43 #include <wtf/PassRefPtr.h>
44 #include <wtf/RefPtr.h>
45 #include <wtf/text/AtomicString.h>
51 class CSSStyleDeclaration;
58 class InspectorDOMAgent;
59 class InspectorFrontend;
67 struct EventListenerInfo {
68 EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
70 , eventType(eventType)
71 , eventListenerVector(eventListenerVector)
76 const AtomicString eventType;
77 const EventListenerVector eventListenerVector;
80 class InspectorDOMAgent : public EventListener {
83 virtual ~DOMListener()
86 virtual void didRemoveDocument(Document*) = 0;
87 virtual void didRemoveDOMNode(Node*) = 0;
88 virtual void didModifyDOMAttr(Element*) = 0;
91 static PassRefPtr<InspectorDOMAgent> create(InspectorFrontend* frontend)
93 return adoptRef(new InspectorDOMAgent(frontend));
96 static const InspectorDOMAgent* cast(const EventListener* listener)
98 return listener->type() == InspectorDOMAgentType
99 ? static_cast<const InspectorDOMAgent*>(listener)
103 InspectorDOMAgent(InspectorFrontend* frontend);
104 ~InspectorDOMAgent();
108 virtual bool operator==(const EventListener& other);
110 // Methods called from the frontend for DOM nodes inspection.
111 void getChildNodes(long nodeId);
112 void setAttribute(long elementId, const String& name, const String& value, bool* success);
113 void removeAttribute(long elementId, const String& name, bool* success);
114 void removeNode(long nodeId, long* outNodeId);
115 void changeTagName(long nodeId, const String& tagName, long* newId);
116 void getOuterHTML(long nodeId, WTF::String* outerHTML);
117 void setOuterHTML(long nodeId, const String& outerHTML, long* newId);
118 void setTextNodeValue(long nodeId, const String& value, bool* success);
119 void getEventListenersForNode(long nodeId, long* outNodeId, RefPtr<InspectorArray>* listenersArray);
120 void addInspectedNode(long nodeId);
121 void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
122 void searchCanceled();
123 bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorObject> details);
124 bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details);
125 bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details);
127 // Methods called from the InspectorController.
128 void setDocument(Document* document);
129 void releaseDanglingNodes();
131 void didInsertDOMNode(Node*);
132 void didRemoveDOMNode(Node*);
133 void didModifyDOMAttr(Element*);
134 void characterDataModified(CharacterData*);
136 Node* nodeForId(long nodeId);
137 long pushNodePathToFrontend(Node* node);
138 void pushChildNodesToFrontend(long nodeId);
139 void pushNodeByPathToFrontend(const String& path, long* nodeId);
140 long inspectedNode(unsigned long num);
141 void copyNode(long nodeId);
142 const ListHashSet<RefPtr<Document> >& documents() { return m_documents; }
143 void setDOMListener(DOMListener*);
145 String documentURLString(Document* document) const;
147 void setDOMBreakpoint(long nodeId, long type);
148 void removeDOMBreakpoint(long nodeId, long type);
151 void startListeningFrameDocument(Node* frameOwnerNode);
152 void startListening(Document* document);
153 void stopListening(Document* document);
155 virtual void handleEvent(ScriptExecutionContext*, Event* event);
157 // Node-related methods.
158 typedef HashMap<RefPtr<Node>, long> NodeToIdMap;
159 long bind(Node* node, NodeToIdMap* nodesMap);
160 void unbind(Node* node, NodeToIdMap* nodesMap);
162 bool pushDocumentToFrontend();
164 bool hasBreakpoint(Node* node, long type);
165 void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
166 void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description);
168 PassRefPtr<InspectorObject> buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap);
169 PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element* element);
170 PassRefPtr<InspectorArray> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap);
171 PassRefPtr<InspectorObject> buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node);
173 // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
174 // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
175 Node* innerFirstChild(Node* node);
176 Node* innerNextSibling(Node* node);
177 Node* innerPreviousSibling(Node* node);
178 unsigned innerChildNodeCount(Node* node);
179 Node* innerParentNode(Node* node);
180 bool isWhitespace(Node* node);
182 Document* mainFrameDocument() const;
184 void onMatchJobsTimer(Timer<InspectorDOMAgent>*);
185 void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector);
187 Node* nodeForPath(const String& path);
188 PassRefPtr<InspectorArray> toArray(const Vector<String>& data);
190 void discardBindings();
192 InspectorFrontend* m_frontend;
193 DOMListener* m_domListener;
194 NodeToIdMap m_documentNodeToIdMap;
195 // Owns node mappings for dangling nodes.
196 Vector<NodeToIdMap*> m_danglingNodeToIdMaps;
197 HashMap<long, Node*> m_idToNode;
198 HashMap<long, NodeToIdMap*> m_idToNodesMap;
199 HashSet<long> m_childrenRequested;
201 ListHashSet<RefPtr<Document> > m_documents;
202 Deque<MatchJob*> m_pendingMatchJobs;
203 Timer<InspectorDOMAgent> m_matchJobsTimer;
204 HashSet<RefPtr<Node> > m_searchResults;
205 Vector<long> m_inspectedNodes;
206 HashMap<Node*, uint32_t> m_breakpoints;
211 } // namespace WebCore
213 #endif // !defined(InspectorDOMAgent_h)