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 "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 {
     66         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:
     91         void ref() { refEventTarget(); }
     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
    183     inline void forbidEventDispatch() { }
    184     inline void allowEventDispatch() { }
    185 #endif
    186 
    187 #if USE(JSC)
    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 
    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 
    217     inline bool EventTarget::isFiringEventListeners()
    218     {
    219         EventTargetData* d = eventTargetData();
    220         if (!d)
    221             return false;
    222         return d->firingEventIterators.size() != 0;
    223     }
    224 
    225     inline bool EventTarget::hasEventListeners()
    226     {
    227         EventTargetData* d = eventTargetData();
    228         if (!d)
    229             return false;
    230         return !d->eventListenerMap.isEmpty();
    231     }
    232 
    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