f9b0f21174f5418d51f7d54381b01c878212eaaf
[WebKit-https.git] / Source / WebCore / dom / EventTarget.h
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 #ifndef EventTarget_h
32 #define EventTarget_h
33
34 #include "EventListenerMap.h"
35 #include "EventNames.h"
36 #include "EventTargetInterfaces.h"
37 #include "ScriptWrappable.h"
38 #include <memory>
39 #include <wtf/Forward.h>
40 #include <wtf/HashMap.h>
41
42 namespace WTF {
43 class AtomicString;
44 }
45
46 namespace 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 ScriptExecutionContext;
69 class TextTrack;
70 class TextTrackCue;
71 class VideoTrackList;
72 class WebSocket;
73 class WebKitNamedFlow;
74 class Worker;
75 class XMLHttpRequest;
76 class XMLHttpRequestUpload;
77
78 typedef int ExceptionCode;
79
80 struct FiringEventIterator {
81     FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& size)
82         : eventType(eventType)
83         , iterator(iterator)
84         , size(size)
85     {
86     }
87
88     const AtomicString& eventType;
89     size_t& iterator;
90     size_t& size;
91 };
92 typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
93
94 struct EventTargetData {
95     WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
96 public:
97     EventTargetData();
98     ~EventTargetData();
99
100     EventListenerMap eventListenerMap;
101     std::unique_ptr<FiringEventIteratorVector> firingEventIterators;
102 };
103
104 enum EventTargetInterface {
105
106 #define DOM_EVENT_INTERFACE_DECLARE(name) name##EventTargetInterfaceType,
107 DOM_EVENT_TARGET_INTERFACES_FOR_EACH(DOM_EVENT_INTERFACE_DECLARE)
108 #undef DOM_EVENT_INTERFACE_DECLARE
109
110 };
111
112 class EventTarget : public ScriptWrappable {
113 public:
114     void ref() { refEventTarget(); }
115     void deref() { derefEventTarget(); }
116
117     virtual EventTargetInterface eventTargetInterface() const = 0;
118     virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
119
120     virtual Node* toNode();
121     virtual DOMWindow* toDOMWindow();
122     virtual bool isMessagePort() const;
123
124     virtual bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
125     virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
126     virtual void removeAllEventListeners();
127     virtual bool dispatchEvent(Event&);
128     bool dispatchEventForBindings(Event*, ExceptionCode&); // DOM API
129     virtual void uncaughtExceptionInEventHandler();
130
131     // Used for legacy "onEvent" attribute APIs.
132     bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
133     bool clearAttributeEventListener(const AtomicString& eventType);
134     EventListener* getAttributeEventListener(const AtomicString& eventType);
135
136     bool hasEventListeners() const;
137     bool hasEventListeners(const AtomicString& eventType);
138     bool hasCapturingEventListeners(const AtomicString& eventType);
139     const EventListenerVector& getEventListeners(const AtomicString& eventType);
140
141     bool fireEventListeners(Event&);
142     bool isFiringEventListeners();
143
144     void visitJSEventListeners(JSC::SlotVisitor&);
145     void invalidateJSEventListeners(JSC::JSObject*);
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     void fireEventListeners(Event&, EventTargetData*, EventListenerVector&);
158
159     friend class EventListenerIterator;
160 };
161
162 class EventTargetWithInlineData : public EventTarget {
163 protected:
164     EventTargetData* eventTargetData() final { return &m_eventTargetData; }
165     EventTargetData& ensureEventTargetData() final { return m_eventTargetData; }
166 private:
167     EventTargetData m_eventTargetData;
168 };
169
170 inline void EventTarget::visitJSEventListeners(JSC::SlotVisitor& visitor)
171 {
172     EventListenerIterator iterator(this);
173     while (EventListener* listener = iterator.nextListener())
174         listener->visitJSFunction(visitor);
175 }
176
177 inline bool EventTarget::isFiringEventListeners()
178 {
179     EventTargetData* d = eventTargetData();
180     if (!d)
181         return false;
182     return d->firingEventIterators && !d->firingEventIterators->isEmpty();
183 }
184
185 inline bool EventTarget::hasEventListeners() const
186 {
187     EventTargetData* d = const_cast<EventTarget*>(this)->eventTargetData();
188     if (!d)
189         return false;
190     return !d->eventListenerMap.isEmpty();
191 }
192
193 inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
194 {
195     EventTargetData* d = eventTargetData();
196     if (!d)
197         return false;
198     return d->eventListenerMap.contains(eventType);
199 }
200
201 inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
202 {
203     EventTargetData* d = eventTargetData();
204     if (!d)
205         return false;
206     return d->eventListenerMap.containsCapturing(eventType);
207 }
208
209 } // namespace WebCore
210
211 #endif // EventTarget_h