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