1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller (mueller (at) kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2006 Alexey Proskuryakov (ap (at) webkit.org) 7 * (C) 2007, 2008 Nikolas Zimmermann <zimmermann (at) 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 { 73 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: 101 void ref() { refEventTarget(); } 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 markJSEventListeners(JSC::MarkStack&); 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 190 // FIXME: These macros should be split into separate DEFINE and DECLARE 191 // macros to avoid causing so many header includes. 192 #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ 193 EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 194 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 195 196 #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ 197 virtual EventListener* on##attribute(); \ 198 virtual void setOn##attribute(PassRefPtr<EventListener> listener); \ 199 200 #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \ 201 EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 202 void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 203 204 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ 205 EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ 206 void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ 207 208 #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ 209 EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ 210 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ 211 212 #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ 213 EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ 214 void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ 215 216 #ifndef NDEBUG 217 void forbidEventDispatch(); 218 void allowEventDispatch(); 219 bool eventDispatchForbidden(); 220 #else 221 inline void forbidEventDispatch() { } 222 inline void allowEventDispatch() { } 223 #endif 224 225 #if USE(JSC) 226 inline void EventTarget::markJSEventListeners(JSC::MarkStack& markStack) 227 { 228 EventTargetData* d = eventTargetData(); 229 if (!d) 230 return; 231 232 EventListenerMap::iterator end = d->eventListenerMap.end(); 233 for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) { 234 EventListenerVector& entry = *it->second; 235 for (size_t i = 0; i < entry.size(); ++i) 236 entry[i].listener->markJSFunction(markStack); 237 } 238 } 239 #endif 240 241 inline bool EventTarget::isFiringEventListeners() 242 { 243 EventTargetData* d = eventTargetData(); 244 if (!d) 245 return false; 246 return d->firingEventIterators.size() != 0; 247 } 248 249 inline bool EventTarget::hasEventListeners() 250 { 251 EventTargetData* d = eventTargetData(); 252 if (!d) 253 return false; 254 return !d->eventListenerMap.isEmpty(); 255 } 256 257 inline bool EventTarget::hasEventListeners(const AtomicString& eventType) 258 { 259 EventTargetData* d = eventTargetData(); 260 if (!d) 261 return false; 262 return d->eventListenerMap.contains(eventType); 263 } 264 265 } // namespace WebCore 266 267 #endif // EventTarget_h 268