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