Make some things that return never-null pointers return references instead.
[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 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
41 namespace WebCore {
42
43     class AudioNode;
44     class AudioContext;
45     class AudioTrackList;
46     class DedicatedWorkerGlobalScope;
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 SharedWorkerGlobalScope;
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 DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
177         EventListener* on##attribute(); \
178         void setOn##attribute(PassRefPtr<EventListener> listener);
179
180     #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(type, recipient, attribute) \
181         EventListener* type::on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
182         void type::setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); }
183
184     inline void EventTarget::visitJSEventListeners(JSC::SlotVisitor& visitor)
185     {
186         EventListenerIterator iterator(this);
187         while (EventListener* listener = iterator.nextListener())
188             listener->visitJSFunction(visitor);
189     }
190
191     inline bool EventTarget::isFiringEventListeners()
192     {
193         EventTargetData* d = eventTargetData();
194         if (!d)
195             return false;
196         return d->firingEventIterators && !d->firingEventIterators->isEmpty();
197     }
198
199     inline bool EventTarget::hasEventListeners()
200     {
201         EventTargetData* d = eventTargetData();
202         if (!d)
203             return false;
204         return !d->eventListenerMap.isEmpty();
205     }
206
207     inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
208     {
209         EventTargetData* d = eventTargetData();
210         if (!d)
211             return false;
212         return d->eventListenerMap.contains(eventType);
213     }
214
215     inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
216     {
217         EventTargetData* d = eventTargetData();
218         if (!d)
219             return false;
220         return d->eventListenerMap.containsCapturing(eventType);
221     }
222
223 } // namespace WebCore
224
225 #endif // EventTarget_h