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 "EventListenerMap.h" 36#include "EventNames.h" 37#include <wtf/Forward.h> 38#include <wtf/HashMap.h> 39#include <wtf/text/AtomicStringHash.h> 40 41namespace WebCore { 42 43 class AudioNode; 44 class AudioContext; 45 class AudioTrackList; 46 class DedicatedWorkerContext; 47 class DOMApplicationCache; 48 class DOMWindow; 49 class Event; 50 class EventListener; 51 class EventSource; 52 class FileReader; 53 class FileWriter; 54 class IDBDatabase; 55 class IDBRequest; 56 class IDBTransaction; 57 class ScriptProcessorNode; 58 class LocalMediaStream; 59 class MediaController; 60 class MediaSource; 61 class MediaStream; 62 class MessagePort; 63 class Node; 64 class Notification; 65 class SVGElementInstance; 66 class ScriptExecutionContext; 67 class SharedWorker; 68 class SharedWorkerContext; 69 class SourceBufferList; 70 class TextTrack; 71 class TextTrackCue; 72 class VideoTrackList; 73 class WebSocket; 74 class WebKitNamedFlow; 75 class Worker; 76 class XMLHttpRequest; 77 class XMLHttpRequestUpload; 78 79 typedef int ExceptionCode; 80 81 struct FiringEventIterator { 82 FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end) 83 : eventType(eventType) 84 , iterator(iterator) 85 , end(end) 86 { 87 } 88 89 const AtomicString& eventType; 90 size_t& iterator; 91 size_t& end; 92 }; 93 typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector; 94 95 struct EventTargetData { 96 WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED; 97 public: 98 EventTargetData(); 99 ~EventTargetData(); 100 101 EventListenerMap eventListenerMap; 102 OwnPtr<FiringEventIteratorVector> firingEventIterators; 103 }; 104 105 class EventTarget { 106 public: 107 void ref() { refEventTarget(); } 108 void deref() { derefEventTarget(); } 109 110 virtual const AtomicString& interfaceName() const = 0; 111 virtual ScriptExecutionContext* scriptExecutionContext() const = 0; 112 113 virtual Node* toNode(); 114 virtual DOMWindow* toDOMWindow(); 115 116 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 117 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 118 virtual void removeAllEventListeners(); 119 virtual bool dispatchEvent(PassRefPtr<Event>); 120 bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API 121 virtual void uncaughtExceptionInEventHandler(); 122 123 // Used for legacy "onEvent" attribute APIs. 124 bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>); 125 bool clearAttributeEventListener(const AtomicString& eventType); 126 EventListener* getAttributeEventListener(const AtomicString& eventType); 127 128 bool hasEventListeners(); 129 bool hasEventListeners(const AtomicString& eventType); 130 bool hasCapturingEventListeners(const AtomicString& eventType); 131 const EventListenerVector& getEventListeners(const AtomicString& eventType); 132 133 bool fireEventListeners(Event*); 134 bool isFiringEventListeners(); 135 136 void visitJSEventListeners(JSC::SlotVisitor&); 137 void invalidateJSEventListeners(JSC::JSObject*); 138 139 protected: 140 virtual ~EventTarget(); 141 142 virtual EventTargetData* eventTargetData() = 0; 143 virtual EventTargetData* ensureEventTargetData() = 0; 144 145 private: 146 virtual void refEventTarget() = 0; 147 virtual void derefEventTarget() = 0; 148 149 void fireEventListeners(Event*, EventTargetData*, EventListenerVector&); 150 151 friend class EventListenerIterator; 152 }; 153 154 // FIXME: These macros should be split into separate DEFINE and DECLARE 155 // macros to avoid causing so many header includes. 156 #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \ 157 EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 158 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 159 160 #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \ 161 virtual EventListener* on##attribute(); \ 162 virtual void setOn##attribute(PassRefPtr<EventListener> listener); \ 163 164 #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \ 165 EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \ 166 void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \ 167 168 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \ 169 EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \ 170 void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \ 171 172 #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \ 173 EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \ 174 void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \ 175 176 #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \ 177 EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \ 178 void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \ 179 180 inline void EventTarget::visitJSEventListeners(JSC::SlotVisitor& visitor) 181 { 182 EventListenerIterator iterator(this); 183 while (EventListener* listener = iterator.nextListener()) 184 listener->visitJSFunction(visitor); 185 } 186 187 inline bool EventTarget::isFiringEventListeners() 188 { 189 EventTargetData* d = eventTargetData(); 190 if (!d) 191 return false; 192 return d->firingEventIterators && !d->firingEventIterators->isEmpty(); 193 } 194 195 inline bool EventTarget::hasEventListeners() 196 { 197 EventTargetData* d = eventTargetData(); 198 if (!d) 199 return false; 200 return !d->eventListenerMap.isEmpty(); 201 } 202 203 inline bool EventTarget::hasEventListeners(const AtomicString& eventType) 204 { 205 EventTargetData* d = eventTargetData(); 206 if (!d) 207 return false; 208 return d->eventListenerMap.contains(eventType); 209 } 210 211 inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType) 212 { 213 EventTargetData* d = eventTargetData(); 214 if (!d) 215 return false; 216 return d->eventListenerMap.containsCapturing(eventType); 217 } 218 219} // namespace WebCore 220 221#endif // EventTarget_h 222