1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 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 "AtomicString.h" 34 #include "EventListener.h" 35 #include "EventTarget.h" 36 #include "ScriptArray.h" 37 #include "ScriptObject.h" 38 #include "ScriptState.h" 39 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 46 namespace WebCore { 47 class ContainerNode; 48 class Element; 49 class Event; 50 class Document; 51 class InspectorFrontend; 52 class NameNodeMap; 53 class Node; 54 class Page; 55 56 struct EventListenerInfo { EventListenerInfoEventListenerInfo57 EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector) 58 : node(node) 59 , eventType(eventType) 60 , eventListenerVector(eventListenerVector) 61 { 62 } 63 64 Node* node; 65 const AtomicString eventType; 66 const EventListenerVector eventListenerVector; 67 }; 68 69 class InspectorDOMAgent : public EventListener { 70 public: create(InspectorFrontend * frontend)71 static PassRefPtr<InspectorDOMAgent> create(InspectorFrontend* frontend) 72 { 73 return adoptRef(new InspectorDOMAgent(frontend)); 74 } 75 cast(const EventListener * listener)76 static const InspectorDOMAgent* cast(const EventListener* listener) 77 { 78 return listener->type() == InspectorDOMAgentType 79 ? static_cast<const InspectorDOMAgent*>(listener) 80 : 0; 81 } 82 83 InspectorDOMAgent(InspectorFrontend* frontend); 84 ~InspectorDOMAgent(); 85 86 void reset(); 87 88 virtual bool operator==(const EventListener& other); 89 90 // Methods called from the frontend. 91 void getChildNodes(long callId, long nodeId); 92 void setAttribute(long callId, long elementId, const String& name, const String& value); 93 void removeAttribute(long callId, long elementId, const String& name); 94 void setTextNodeValue(long callId, long nodeId, const String& value); 95 void getEventListenersForNode(long callId, long nodeId); 96 97 // Methods called from the InspectorController. 98 void setDocument(Document* document); 99 void releaseDanglingNodes(); 100 101 void didInsertDOMNode(Node*); 102 void didRemoveDOMNode(Node*); 103 void didModifyDOMAttr(Element*); 104 105 Node* nodeForId(long nodeId); 106 Node* nodeForPath(const String& path); 107 long pushNodePathToFrontend(Node* node); 108 void pushChildNodesToFrontend(long nodeId); 109 110 private: 111 void startListening(Document* document); 112 void stopListening(Document* document); 113 114 virtual void handleEvent(ScriptExecutionContext*, Event* event); 115 116 typedef HashMap<RefPtr<Node>, long> NodeToIdMap; 117 long bind(Node* node, NodeToIdMap* nodesMap); 118 void unbind(Node* node, NodeToIdMap* nodesMap); 119 120 bool pushDocumentToFrontend(); 121 122 ScriptObject buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap); 123 ScriptArray buildArrayForElementAttributes(Element* element); 124 ScriptArray buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); 125 126 ScriptObject buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node); 127 128 // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently. 129 // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics. 130 Node* innerFirstChild(Node* node); 131 Node* innerNextSibling(Node* node); 132 Node* innerPreviousSibling(Node* node); 133 unsigned innerChildNodeCount(Node* node); 134 Node* innerParentNode(Node* node); 135 bool isWhitespace(Node* node); 136 137 Document* mainFrameDocument() const; 138 String documentURLString(Document* document) const; 139 void discardBindings(); 140 141 InspectorFrontend* m_frontend; 142 NodeToIdMap m_documentNodeToIdMap; 143 // Owns node mappings for dangling nodes. 144 Vector<NodeToIdMap*> m_danglingNodeToIdMaps; 145 HashMap<long, Node*> m_idToNode; 146 HashMap<long, NodeToIdMap*> m_idToNodesMap; 147 HashSet<long> m_childrenRequested; 148 long m_lastNodeId; 149 ListHashSet<RefPtr<Document> > m_documents; 150 }; 151 152 153 } // namespace WebCore 154 155 #endif // !defined(InspectorDOMAgent_h) 156