Home | History | Annotate | Download | only in events
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      6  * Copyright (C) 2006 Alexey Proskuryakov (ap (at) webkit.org)
      7  *           (C) 2007, 2008 Nikolas Zimmermann <zimmermann (at) 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 "core/events/EventListenerMap.h"
     36 #include "core/events/ThreadLocalEventNames.h"
     37 #include "wtf/Forward.h"
     38 
     39 namespace WebCore {
     40 
     41 class ApplicationCache;
     42 class AudioContext;
     43 class DOMWindow;
     44 class DedicatedWorkerGlobalScope;
     45 class Event;
     46 class EventListener;
     47 class EventSource;
     48 class ExceptionState;
     49 class FileReader;
     50 class FileWriter;
     51 class IDBDatabase;
     52 class IDBRequest;
     53 class IDBTransaction;
     54 class MIDIAccess;
     55 class MIDIInput;
     56 class MIDIPort;
     57 class MediaController;
     58 class MediaStream;
     59 class MessagePort;
     60 class NamedFlow;
     61 class Node;
     62 class Notification;
     63 class SVGElementInstance;
     64 class ExecutionContext;
     65 class ScriptProcessorNode;
     66 class SharedWorker;
     67 class SharedWorkerGlobalScope;
     68 class TextTrack;
     69 class TextTrackCue;
     70 class WebSocket;
     71 class Worker;
     72 class XMLHttpRequest;
     73 class XMLHttpRequestUpload;
     74 
     75 struct FiringEventIterator {
     76     FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end)
     77         : eventType(eventType)
     78         , iterator(iterator)
     79         , end(end)
     80     {
     81     }
     82 
     83     const AtomicString& eventType;
     84     size_t& iterator;
     85     size_t& end;
     86 };
     87 typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
     88 
     89 struct EventTargetData {
     90     WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
     91 public:
     92     EventTargetData();
     93     ~EventTargetData();
     94 
     95     EventListenerMap eventListenerMap;
     96     OwnPtr<FiringEventIteratorVector> firingEventIterators;
     97 };
     98 
     99 class EventTarget {
    100 public:
    101     void ref() { refEventTarget(); }
    102     void deref() { derefEventTarget(); }
    103 
    104     virtual const AtomicString& interfaceName() const = 0;
    105     virtual ExecutionContext* executionContext() const = 0;
    106 
    107     virtual Node* toNode();
    108     virtual DOMWindow* toDOMWindow();
    109     virtual MessagePort* toMessagePort();
    110 
    111     virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
    112     virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
    113     virtual void removeAllEventListeners();
    114     virtual bool dispatchEvent(PassRefPtr<Event>);
    115     bool dispatchEvent(PassRefPtr<Event>, ExceptionState&); // DOM API
    116     virtual void uncaughtExceptionInEventHandler();
    117 
    118     // Used for legacy "onEvent" attribute APIs.
    119     bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
    120     EventListener* getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld = 0);
    121 
    122     bool hasEventListeners() const;
    123     bool hasEventListeners(const AtomicString& eventType) const;
    124     bool hasCapturingEventListeners(const AtomicString& eventType);
    125     const EventListenerVector& getEventListeners(const AtomicString& eventType);
    126 
    127     bool fireEventListeners(Event*);
    128     bool isFiringEventListeners();
    129 
    130 protected:
    131     virtual ~EventTarget();
    132 
    133     // Subclasses should likely not override these themselves; instead, they should subclass EventTargetWithInlineData.
    134     virtual EventTargetData* eventTargetData() = 0;
    135     virtual EventTargetData& ensureEventTargetData() = 0;
    136 
    137 private:
    138     // Subclasses should likely not override these themselves; instead, they should use the REFCOUNTED_EVENT_TARGET() macro.
    139     virtual void refEventTarget() = 0;
    140     virtual void derefEventTarget() = 0;
    141 
    142     DOMWindow* executingWindow();
    143     void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
    144     void countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector*, EventListenerVector*);
    145 
    146     bool clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
    147 
    148     friend class EventListenerIterator;
    149 };
    150 
    151 class EventTargetWithInlineData : public EventTarget {
    152 protected:
    153     virtual EventTargetData* eventTargetData() OVERRIDE FINAL { return &m_eventTargetData; }
    154     virtual EventTargetData& ensureEventTargetData() OVERRIDE FINAL { return m_eventTargetData; }
    155 private:
    156     EventTargetData m_eventTargetData;
    157 };
    158 
    159 // FIXME: These macros should be split into separate DEFINE and DECLARE
    160 // macros to avoid causing so many header includes.
    161 #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
    162     EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
    163     void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld = 0) { setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
    164 
    165 #define DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(attribute) \
    166     static EventListener* on##attribute(EventTarget* eventTarget, DOMWrapperWorld* isolatedWorld) { return eventTarget->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
    167     static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld = 0) { eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
    168 
    169 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
    170     EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return document().getWindowAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
    171     void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { document().setWindowAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
    172 
    173 #define DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
    174     static EventListener* on##attribute(EventTarget* eventTarget, DOMWrapperWorld* isolatedWorld) { \
    175         if (Node* node = eventTarget->toNode()) \
    176             return node->document().getWindowAttributeEventListener(EventTypeNames::attribute, isolatedWorld); \
    177         ASSERT(eventTarget->toDOMWindow()); \
    178         return eventTarget->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); \
    179     } \
    180     static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { \
    181         if (Node* node = eventTarget->toNode()) \
    182             node->document().setWindowAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
    183         else { \
    184             ASSERT(eventTarget->toDOMWindow()); \
    185             eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
    186         } \
    187     }
    188 
    189 #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
    190     EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(EventTypeNames::eventName, isolatedWorld); } \
    191     void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(EventTypeNames::eventName, listener, isolatedWorld); } \
    192 
    193 #define DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
    194     EventListener* on##attribute(DOMWrapperWorld* isolatedWorld); \
    195     void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld);
    196 
    197 #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(type, recipient, attribute) \
    198     EventListener* type::on##attribute(DOMWrapperWorld* isolatedWorld) { return recipient ? recipient->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld) : 0; } \
    199     void type::setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) \
    200     { \
    201         if (recipient) \
    202             recipient->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
    203     }
    204 
    205 inline bool EventTarget::isFiringEventListeners()
    206 {
    207     EventTargetData* d = eventTargetData();
    208     if (!d)
    209         return false;
    210     return d->firingEventIterators && !d->firingEventIterators->isEmpty();
    211 }
    212 
    213 inline bool EventTarget::hasEventListeners() const
    214 {
    215     // FIXME: We should have a const version of eventTargetData.
    216     if (const EventTargetData* d = const_cast<EventTarget*>(this)->eventTargetData())
    217         return !d->eventListenerMap.isEmpty();
    218     return false;
    219 }
    220 
    221 inline bool EventTarget::hasEventListeners(const AtomicString& eventType) const
    222 {
    223     // FIXME: We should have const version of eventTargetData.
    224     if (const EventTargetData* d = const_cast<EventTarget*>(this)->eventTargetData())
    225         return d->eventListenerMap.contains(eventType);
    226     return false;
    227 }
    228 
    229 inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
    230 {
    231     EventTargetData* d = eventTargetData();
    232     if (!d)
    233         return false;
    234     return d->eventListenerMap.containsCapturing(eventType);
    235 }
    236 
    237 } // namespace WebCore
    238 
    239 #define DEFINE_EVENT_TARGET_REFCOUNTING(baseClass) \
    240 public: \
    241     using baseClass::ref; \
    242     using baseClass::deref; \
    243 private: \
    244     virtual void refEventTarget() OVERRIDE FINAL { ref(); } \
    245     virtual void derefEventTarget() OVERRIDE FINAL { deref(); } \
    246     typedef int thisIsHereToForceASemiColonAfterThisEventTargetMacro
    247 
    248 // Use this macro if your EventTarget subclass is also a subclass of WTF::RefCounted.
    249 // A ref-counted class that uses a different method of refcounting should use DEFINE_EVENT_TARGET_REFCOUNTING directly.
    250 // Both of these macros are meant to be placed just before the "public:" section of the class declaration.
    251 #define REFCOUNTED_EVENT_TARGET(className) DEFINE_EVENT_TARGET_REFCOUNTING(RefCounted<className>)
    252 
    253 #endif // EventTarget_h
    254