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