EventTarget.h revision 81bc750723a18f21cd17d1b173cd2a4dda9cea6e
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 41namespace WebCore { 42 43 class AbstractWorker; 44 class DedicatedWorkerContext; 45 class DOMApplicationCache; 46 class DOMWindow; 47 class Event; 48 class EventListener; 49 class EventSource; 50 class FileReader; 51 class FileWriter; 52 class IDBDatabase; 53 class IDBRequest; 54 class IDBTransaction; 55 class IDBVersionChangeRequest; 56 class JavaScriptAudioNode; 57 class MessagePort; 58 class Node; 59 class Notification; 60 class SVGElementInstance; 61 class ScriptExecutionContext; 62 class SharedWorker; 63 class SharedWorkerContext; 64 class WebSocket; 65 class Worker; 66 class XMLHttpRequest; 67 class XMLHttpRequestUpload; 68 69 typedef int ExceptionCode; 70 71 struct FiringEventIterator { 72 FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end) 73 : eventType(eventType) 74 , iterator(iterator) 75 , end(end) 76 { 77 } 78 79 const AtomicString& eventType; 80 size_t& iterator; 81 size_t& end; 82 }; 83 typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector; 84 85 typedef Vector<RegisteredEventListener, 1> EventListenerVector; 86 typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap; 87 88 struct EventTargetData { 89 WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED; 90 public: 91 EventTargetData(); 92 ~EventTargetData(); 93 94 EventListenerMap eventListenerMap; 95 FiringEventIteratorVector firingEventIterators; 96 }; 97 98 class EventTarget { 99 public: 100 void ref() { refEventTarget(); } 101 void deref() { derefEventTarget(); } 102 103 virtual EventSource* toEventSource(); 104 virtual MessagePort* toMessagePort(); 105 virtual Node* toNode(); 106 virtual DOMWindow* toDOMWindow(); 107 virtual XMLHttpRequest* toXMLHttpRequest(); 108 virtual XMLHttpRequestUpload* toXMLHttpRequestUpload(); 109#if ENABLE(OFFLINE_WEB_APPLICATIONS) 110 virtual DOMApplicationCache* toDOMApplicationCache(); 111#endif 112#if ENABLE(SVG) 113 virtual SVGElementInstance* toSVGElementInstance(); 114#endif 115#if ENABLE(WORKERS) 116 virtual Worker* toWorker(); 117 virtual DedicatedWorkerContext* toDedicatedWorkerContext(); 118#endif 119#if ENABLE(SHARED_WORKERS) 120 virtual SharedWorker* toSharedWorker(); 121 virtual SharedWorkerContext* toSharedWorkerContext(); 122#endif 123 124#if ENABLE(WEB_AUDIO) 125 virtual JavaScriptAudioNode* toJavaScriptAudioNode(); 126#endif 127 128#if ENABLE(WEB_SOCKETS) 129 virtual WebSocket* toWebSocket(); 130#endif 131 132#if ENABLE(NOTIFICATIONS) 133 virtual Notification* toNotification(); 134#endif 135#if ENABLE(BLOB) 136 virtual FileReader* toFileReader(); 137#endif 138#if ENABLE(FILE_SYSTEM) 139 virtual FileWriter* toFileWriter(); 140#endif 141 142#if ENABLE(INDEXED_DATABASE) 143 virtual IDBDatabase* toIDBDatabase(); 144 virtual IDBRequest* toIDBRequest(); 145 virtual IDBTransaction* toIDBTransaction(); 146 virtual IDBVersionChangeRequest* toIDBVersionChangeRequest(); 147#endif 148 149 virtual ScriptExecutionContext* scriptExecutionContext() const = 0; 150 151 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 152 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 153 virtual void removeAllEventListeners(); 154 virtual bool dispatchEvent(PassRefPtr<Event>); 155 bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API 156 virtual void uncaughtExceptionInEventHandler(); 157 158 // Used for legacy "onEvent" attribute APIs. 159 bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); 160 bool clearAttributeEventListener(const AtomicString& eventType); 161 EventListener* getAttributeEventListener(const AtomicString& eventType); 162 163 bool hasEventListeners(); 164 bool hasEventListeners(const AtomicString& eventType); 165 const EventListenerVector& getEventListeners(const AtomicString& eventType); 166 167 bool fireEventListeners(Event*); 168 bool isFiringEventListeners(); 169 170#if USE(JSC) 171 void markJSEventListeners(JSC::MarkStack&); 172 void invalidateJSEventListeners(JSC::JSObject*); 173#endif 174 175 protected: 176 virtual ~EventTarget(); 177 178 virtual EventTargetData* eventTargetData() = 0; 179 virtual EventTargetData* ensureEventTargetData() = 0; 180 181 private: 182 virtual void refEventTarget() = 0; 183 virtual void derefEventTarget() = 0; 184 185 void fireEventListeners(Event*, EventTargetData*, EventListenerVector&); 186 }; 187 188 // FIXME: These macros should be split into separate DEFINE and DECLARE 189 // macros to avoid causing so many header includes. 190 #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ 191 EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 192 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 193 194 #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ 195 virtual EventListener* on##attribute(); \ 196 virtual void setOn##attribute(PassRefPtr<EventListener> listener); \ 197 198 #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \ 199 EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 200 void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 201 202 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ 203 EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ 204 void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ 205 206 #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ 207 EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ 208 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ 209 210 #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ 211 EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ 212 void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ 213 214#ifndef NDEBUG 215 void forbidEventDispatch(); 216 void allowEventDispatch(); 217 bool eventDispatchForbidden(); 218#else 219 inline void forbidEventDispatch() { } 220 inline void allowEventDispatch() { } 221#endif 222 223#if USE(JSC) 224 inline void EventTarget::markJSEventListeners(JSC::MarkStack& markStack) 225 { 226 EventTargetData* d = eventTargetData(); 227 if (!d) 228 return; 229 230 EventListenerMap::iterator end = d->eventListenerMap.end(); 231 for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) { 232 EventListenerVector& entry = *it->second; 233 for (size_t i = 0; i < entry.size(); ++i) 234 entry[i].listener->markJSFunction(markStack); 235 } 236 } 237#endif 238 239 inline bool EventTarget::isFiringEventListeners() 240 { 241 EventTargetData* d = eventTargetData(); 242 if (!d) 243 return false; 244 return d->firingEventIterators.size() != 0; 245 } 246 247 inline bool EventTarget::hasEventListeners() 248 { 249 EventTargetData* d = eventTargetData(); 250 if (!d) 251 return false; 252 return !d->eventListenerMap.isEmpty(); 253 } 254 255 inline bool EventTarget::hasEventListeners(const AtomicString& eventType) 256 { 257 EventTargetData* d = eventTargetData(); 258 if (!d) 259 return false; 260 return d->eventListenerMap.contains(eventType); 261 } 262 263} // namespace WebCore 264 265#endif // EventTarget_h 266