1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 7 * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32 #ifndef EventTarget_h 33 #define EventTarget_h 34 35 #include "EventNames.h" 36 #include "RegisteredEventListener.h" 37 #include <wtf/Forward.h> 38 #include <wtf/HashMap.h> 39 #include <wtf/text/AtomicStringHash.h> 40 41 namespace WebCore { 42 43 class AudioContext; 44 class AbstractWorker; 45 class DedicatedWorkerContext; 46 class DOMApplicationCache; 47 class DOMWindow; 48 class Event; 49 class EventListener; 50 class EventSource; 51 class FileReader; 52 class FileWriter; 53 class IDBDatabase; 54 class IDBRequest; 55 class IDBTransaction; 56 class IDBVersionChangeRequest; 57 class JavaScriptAudioNode; 58 class MessagePort; 59 class Node; 60 class Notification; 61 class SVGElementInstance; 62 class ScriptExecutionContext; 63 class SharedWorker; 64 class SharedWorkerContext; 65 class WebSocket; 66 class Worker; 67 class XMLHttpRequest; 68 class XMLHttpRequestUpload; 69 70 typedef int ExceptionCode; 71 72 struct FiringEventIterator { FiringEventIteratorFiringEventIterator73 FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end) 74 : eventType(eventType) 75 , iterator(iterator) 76 , end(end) 77 { 78 } 79 80 const AtomicString& eventType; 81 size_t& iterator; 82 size_t& end; 83 }; 84 typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector; 85 86 typedef Vector<RegisteredEventListener, 1> EventListenerVector; 87 typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap; 88 89 struct EventTargetData { 90 WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED; 91 public: 92 EventTargetData(); 93 ~EventTargetData(); 94 95 EventListenerMap eventListenerMap; 96 FiringEventIteratorVector firingEventIterators; 97 }; 98 99 class EventTarget { 100 public: ref()101 void ref() { refEventTarget(); } deref()102 void deref() { derefEventTarget(); } 103 104 virtual EventSource* toEventSource(); 105 virtual MessagePort* toMessagePort(); 106 virtual Node* toNode(); 107 virtual DOMWindow* toDOMWindow(); 108 virtual XMLHttpRequest* toXMLHttpRequest(); 109 virtual XMLHttpRequestUpload* toXMLHttpRequestUpload(); 110 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 111 virtual DOMApplicationCache* toDOMApplicationCache(); 112 #endif 113 #if ENABLE(SVG) 114 virtual SVGElementInstance* toSVGElementInstance(); 115 #endif 116 #if ENABLE(WORKERS) 117 virtual Worker* toWorker(); 118 virtual DedicatedWorkerContext* toDedicatedWorkerContext(); 119 #endif 120 #if ENABLE(SHARED_WORKERS) 121 virtual SharedWorker* toSharedWorker(); 122 virtual SharedWorkerContext* toSharedWorkerContext(); 123 #endif 124 125 #if ENABLE(WEB_AUDIO) 126 virtual AudioContext* toAudioContext(); 127 virtual JavaScriptAudioNode* toJavaScriptAudioNode(); 128 #endif 129 130 #if ENABLE(WEB_SOCKETS) 131 virtual WebSocket* toWebSocket(); 132 #endif 133 134 #if ENABLE(NOTIFICATIONS) 135 virtual Notification* toNotification(); 136 #endif 137 #if ENABLE(BLOB) 138 virtual FileReader* toFileReader(); 139 #endif 140 #if ENABLE(FILE_SYSTEM) 141 virtual FileWriter* toFileWriter(); 142 #endif 143 144 #if ENABLE(INDEXED_DATABASE) 145 virtual IDBDatabase* toIDBDatabase(); 146 virtual IDBRequest* toIDBRequest(); 147 virtual IDBTransaction* toIDBTransaction(); 148 virtual IDBVersionChangeRequest* toIDBVersionChangeRequest(); 149 #endif 150 151 virtual ScriptExecutionContext* scriptExecutionContext() const = 0; 152 153 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 154 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 155 virtual void removeAllEventListeners(); 156 virtual bool dispatchEvent(PassRefPtr<Event>); 157 bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API 158 virtual void uncaughtExceptionInEventHandler(); 159 160 // Used for legacy "onEvent" attribute APIs. 161 bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); 162 bool clearAttributeEventListener(const AtomicString& eventType); 163 EventListener* getAttributeEventListener(const AtomicString& eventType); 164 165 bool hasEventListeners(); 166 bool hasEventListeners(const AtomicString& eventType); 167 const EventListenerVector& getEventListeners(const AtomicString& eventType); 168 169 bool fireEventListeners(Event*); 170 bool isFiringEventListeners(); 171 172 #if USE(JSC) 173 void visitJSEventListeners(JSC::SlotVisitor&); 174 void invalidateJSEventListeners(JSC::JSObject*); 175 #endif 176 177 protected: 178 virtual ~EventTarget(); 179 180 virtual EventTargetData* eventTargetData() = 0; 181 virtual EventTargetData* ensureEventTargetData() = 0; 182 183 private: 184 virtual void refEventTarget() = 0; 185 virtual void derefEventTarget() = 0; 186 187 void fireEventListeners(Event*, EventTargetData*, EventListenerVector&); 188 189 friend class EventListenerIterator; 190 }; 191 192 class EventListenerIterator { 193 public: 194 EventListenerIterator(); 195 196 // EventTarget must not be modified while an iterator is active. 197 EventListenerIterator(EventTarget*); 198 199 EventListener* nextListener(); 200 201 private: 202 EventListenerMap::iterator m_mapIterator; 203 EventListenerMap::iterator m_mapEnd; 204 unsigned m_index; 205 }; 206 207 // FIXME: These macros should be split into separate DEFINE and DECLARE 208 // macros to avoid causing so many header includes. 209 #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ 210 EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 211 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 212 213 #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ 214 virtual EventListener* on##attribute(); \ 215 virtual void setOn##attribute(PassRefPtr<EventListener> listener); \ 216 217 #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \ 218 EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 219 void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 220 221 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ 222 EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ 223 void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ 224 225 #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ 226 EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ 227 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ 228 229 #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ 230 EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ 231 void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ 232 233 #ifndef NDEBUG 234 void forbidEventDispatch(); 235 void allowEventDispatch(); 236 bool eventDispatchForbidden(); 237 #else forbidEventDispatch()238 inline void forbidEventDispatch() { } allowEventDispatch()239 inline void allowEventDispatch() { } 240 #endif 241 242 #if USE(JSC) visitJSEventListeners(JSC::SlotVisitor & visitor)243 inline void EventTarget::visitJSEventListeners(JSC::SlotVisitor& visitor) 244 { 245 EventTargetData* d = eventTargetData(); 246 if (!d) 247 return; 248 249 EventListenerMap::iterator end = d->eventListenerMap.end(); 250 for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) { 251 EventListenerVector& entry = *it->second; 252 for (size_t i = 0; i < entry.size(); ++i) 253 entry[i].listener->visitJSFunction(visitor); 254 } 255 } 256 #endif 257 isFiringEventListeners()258 inline bool EventTarget::isFiringEventListeners() 259 { 260 EventTargetData* d = eventTargetData(); 261 if (!d) 262 return false; 263 return d->firingEventIterators.size() != 0; 264 } 265 hasEventListeners()266 inline bool EventTarget::hasEventListeners() 267 { 268 EventTargetData* d = eventTargetData(); 269 if (!d) 270 return false; 271 return !d->eventListenerMap.isEmpty(); 272 } 273 hasEventListeners(const AtomicString & eventType)274 inline bool EventTarget::hasEventListeners(const AtomicString& eventType) 275 { 276 EventTargetData* d = eventTargetData(); 277 if (!d) 278 return false; 279 return d->eventListenerMap.contains(eventType); 280 } 281 282 } // namespace WebCore 283 284 #endif // EventTarget_h 285