1/* 2 * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#ifndef SVGElementInstance_h 22#define SVGElementInstance_h 23 24#if ENABLE(SVG) 25#include "EventTarget.h" 26#include "SVGElement.h" 27#include "TreeShared.h" 28 29namespace WebCore { 30 31namespace Private { 32template<class GenericNode, class GenericNodeContainer> 33void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container); 34}; 35 36class SVGUseElement; 37class SVGElementInstanceList; 38class SVGStyledElement; 39 40// SVGElementInstance mimics Node, but without providing all its functionality 41class SVGElementInstance : public EventTarget, public TreeShared<SVGElementInstance> { 42public: 43 static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement) 44 { 45 return adoptRef(new SVGElementInstance(correspondingUseElement, directUseElement, originalElement)); 46 } 47 48 virtual ~SVGElementInstance(); 49 50 void setParentOrShadowHostNode(SVGElementInstance* instance) { m_parentInstance = instance; } 51 52 virtual const AtomicString& interfaceName() const; 53 virtual ScriptExecutionContext* scriptExecutionContext() const; 54 55 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 56 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 57 virtual void removeAllEventListeners(); 58 59 using EventTarget::dispatchEvent; 60 virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE; 61 62 SVGElement* correspondingElement() const { return m_element.get(); } 63 SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; } 64 SVGUseElement* directUseElement() const { return m_directUseElement; } 65 SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); } 66 67 void detach(); 68 69 SVGElementInstance* parentNode() const { return m_parentInstance; } 70 PassRefPtr<SVGElementInstanceList> childNodes(); 71 72 SVGElementInstance* previousSibling() const { return m_previousSibling; } 73 SVGElementInstance* nextSibling() const { return m_nextSibling; } 74 75 SVGElementInstance* firstChild() const { return m_firstChild; } 76 SVGElementInstance* lastChild() const { return m_lastChild; } 77 78 Document* ownerDocument() const { return m_element ? m_element->ownerDocument() : 0; } 79 80 class InvalidationGuard { 81 WTF_MAKE_NONCOPYABLE(InvalidationGuard); 82 public: 83 InvalidationGuard(SVGElement* element) : m_element(element) { } 84 ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); } 85 private: 86 SVGElement* m_element; 87 }; 88 89 class InstanceUpdateBlocker { 90 WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker); 91 public: 92 InstanceUpdateBlocker(SVGElement* targetElement); 93 ~InstanceUpdateBlocker(); 94 95 private: 96 SVGStyledElement* m_targetElement; 97 }; 98 99 static void invalidateAllInstancesOfElement(SVGElement*); 100 101 using TreeShared<SVGElementInstance>::ref; 102 using TreeShared<SVGElementInstance>::deref; 103 104 // EventTarget API 105 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort); 106 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur); 107 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change); 108 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click); 109 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu); 110 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick); 111 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error); 112 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus); 113 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input); 114 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown); 115 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress); 116 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup); 117 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load); 118 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown); 119 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseenter); 120 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseleave); 121 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove); 122 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout); 123 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover); 124 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup); 125 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel); 126 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut); 127 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut); 128 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy); 129 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy); 130 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste); 131 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste); 132 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter); 133 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover); 134 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave); 135 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop); 136 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart); 137 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag); 138 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend); 139 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset); 140 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize); 141 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll); 142 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search); 143 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select); 144 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart); 145 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit); 146 DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload); 147 148private: 149 friend class SVGUseElement; 150 friend class TreeShared<SVGElementInstance>; 151 152 SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement); 153 154 void removedLastRef(); 155 bool hasTreeSharedParent() const { return !!m_parentInstance; } 156 157 virtual Node* toNode() { return shadowTreeElement(); } 158 159 void appendChild(PassRefPtr<SVGElementInstance> child); 160 void setShadowTreeElement(SVGElement*); 161 162 template<class GenericNode, class GenericNodeContainer> 163 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container); 164 165 template<class GenericNode, class GenericNodeContainer> 166 friend void removeDetachedChildrenInContainer(GenericNodeContainer*); 167 168 template<class GenericNode, class GenericNodeContainer> 169 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container); 170 171 bool hasChildNodes() const { return m_firstChild; } 172 173 void setFirstChild(SVGElementInstance* child) { m_firstChild = child; } 174 void setLastChild(SVGElementInstance* child) { m_lastChild = child; } 175 176 void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; } 177 void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; } 178 179 virtual void refEventTarget() { ref(); } 180 virtual void derefEventTarget() { deref(); } 181 virtual EventTargetData* eventTargetData(); 182 virtual EventTargetData* ensureEventTargetData(); 183 184 SVGElementInstance* m_parentInstance; 185 186 SVGUseElement* m_correspondingUseElement; 187 SVGUseElement* m_directUseElement; 188 RefPtr<SVGElement> m_element; 189 RefPtr<SVGElement> m_shadowTreeElement; 190 191 SVGElementInstance* m_previousSibling; 192 SVGElementInstance* m_nextSibling; 193 194 SVGElementInstance* m_firstChild; 195 SVGElementInstance* m_lastChild; 196}; 197 198} // namespace WebCore 199 200#endif // ENABLE(SVG) 201#endif 202