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