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