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