• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "EventNames.h"
36 #include "RegisteredEventListener.h"
37 #include <wtf/Forward.h>
38 #include <wtf/HashMap.h>
39 #include <wtf/text/AtomicStringHash.h>
40 
41 namespace WebCore {
42 
43     class AudioContext;
44     class AbstractWorker;
45     class DedicatedWorkerContext;
46     class DOMApplicationCache;
47     class DOMWindow;
48     class Event;
49     class EventListener;
50     class EventSource;
51     class FileReader;
52     class FileWriter;
53     class IDBDatabase;
54     class IDBRequest;
55     class IDBTransaction;
56     class IDBVersionChangeRequest;
57     class JavaScriptAudioNode;
58     class MessagePort;
59     class Node;
60     class Notification;
61     class SVGElementInstance;
62     class ScriptExecutionContext;
63     class SharedWorker;
64     class SharedWorkerContext;
65     class WebSocket;
66     class Worker;
67     class XMLHttpRequest;
68     class XMLHttpRequestUpload;
69 
70     typedef int ExceptionCode;
71 
72     struct FiringEventIterator {
FiringEventIteratorFiringEventIterator73         FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end)
74             : eventType(eventType)
75             , iterator(iterator)
76             , end(end)
77         {
78         }
79 
80         const AtomicString& eventType;
81         size_t& iterator;
82         size_t& end;
83     };
84     typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
85 
86     typedef Vector<RegisteredEventListener, 1> EventListenerVector;
87     typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap;
88 
89     struct EventTargetData {
90         WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
91     public:
92         EventTargetData();
93         ~EventTargetData();
94 
95         EventListenerMap eventListenerMap;
96         FiringEventIteratorVector firingEventIterators;
97     };
98 
99     class EventTarget {
100     public:
ref()101         void ref() { refEventTarget(); }
deref()102         void deref() { derefEventTarget(); }
103 
104         virtual EventSource* toEventSource();
105         virtual MessagePort* toMessagePort();
106         virtual Node* toNode();
107         virtual DOMWindow* toDOMWindow();
108         virtual XMLHttpRequest* toXMLHttpRequest();
109         virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
110 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
111         virtual DOMApplicationCache* toDOMApplicationCache();
112 #endif
113 #if ENABLE(SVG)
114         virtual SVGElementInstance* toSVGElementInstance();
115 #endif
116 #if ENABLE(WORKERS)
117         virtual Worker* toWorker();
118         virtual DedicatedWorkerContext* toDedicatedWorkerContext();
119 #endif
120 #if ENABLE(SHARED_WORKERS)
121         virtual SharedWorker* toSharedWorker();
122         virtual SharedWorkerContext* toSharedWorkerContext();
123 #endif
124 
125 #if ENABLE(WEB_AUDIO)
126         virtual AudioContext* toAudioContext();
127         virtual JavaScriptAudioNode* toJavaScriptAudioNode();
128 #endif
129 
130 #if ENABLE(WEB_SOCKETS)
131         virtual WebSocket* toWebSocket();
132 #endif
133 
134 #if ENABLE(NOTIFICATIONS)
135         virtual Notification* toNotification();
136 #endif
137 #if ENABLE(BLOB)
138         virtual FileReader* toFileReader();
139 #endif
140 #if ENABLE(FILE_SYSTEM)
141         virtual FileWriter* toFileWriter();
142 #endif
143 
144 #if ENABLE(INDEXED_DATABASE)
145         virtual IDBDatabase* toIDBDatabase();
146         virtual IDBRequest* toIDBRequest();
147         virtual IDBTransaction* toIDBTransaction();
148         virtual IDBVersionChangeRequest* toIDBVersionChangeRequest();
149 #endif
150 
151         virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
152 
153         virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
154         virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
155         virtual void removeAllEventListeners();
156         virtual bool dispatchEvent(PassRefPtr<Event>);
157         bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API
158         virtual void uncaughtExceptionInEventHandler();
159 
160         // Used for legacy "onEvent" attribute APIs.
161         bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
162         bool clearAttributeEventListener(const AtomicString& eventType);
163         EventListener* getAttributeEventListener(const AtomicString& eventType);
164 
165         bool hasEventListeners();
166         bool hasEventListeners(const AtomicString& eventType);
167         const EventListenerVector& getEventListeners(const AtomicString& eventType);
168 
169         bool fireEventListeners(Event*);
170         bool isFiringEventListeners();
171 
172 #if USE(JSC)
173         void markJSEventListeners(JSC::MarkStack&);
174         void invalidateJSEventListeners(JSC::JSObject*);
175 #endif
176 
177     protected:
178         virtual ~EventTarget();
179 
180         virtual EventTargetData* eventTargetData() = 0;
181         virtual EventTargetData* ensureEventTargetData() = 0;
182 
183     private:
184         virtual void refEventTarget() = 0;
185         virtual void derefEventTarget() = 0;
186 
187         void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
188     };
189 
190     // FIXME: These macros should be split into separate DEFINE and DECLARE
191     // macros to avoid causing so many header includes.
192     #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
193         EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
194         void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
195 
196     #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
197         virtual EventListener* on##attribute(); \
198         virtual void setOn##attribute(PassRefPtr<EventListener> listener); \
199 
200     #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \
201         EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
202         void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
203 
204     #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
205         EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \
206         void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
207 
208     #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
209         EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
210         void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
211 
212     #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
213         EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
214         void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \
215 
216 #ifndef NDEBUG
217     void forbidEventDispatch();
218     void allowEventDispatch();
219     bool eventDispatchForbidden();
220 #else
forbidEventDispatch()221     inline void forbidEventDispatch() { }
allowEventDispatch()222     inline void allowEventDispatch() { }
223 #endif
224 
225 #if USE(JSC)
markJSEventListeners(JSC::MarkStack & markStack)226     inline void EventTarget::markJSEventListeners(JSC::MarkStack& markStack)
227     {
228         EventTargetData* d = eventTargetData();
229         if (!d)
230             return;
231 
232         EventListenerMap::iterator end = d->eventListenerMap.end();
233         for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
234             EventListenerVector& entry = *it->second;
235             for (size_t i = 0; i < entry.size(); ++i)
236                 entry[i].listener->markJSFunction(markStack);
237         }
238     }
239 #endif
240 
isFiringEventListeners()241     inline bool EventTarget::isFiringEventListeners()
242     {
243         EventTargetData* d = eventTargetData();
244         if (!d)
245             return false;
246         return d->firingEventIterators.size() != 0;
247     }
248 
hasEventListeners()249     inline bool EventTarget::hasEventListeners()
250     {
251         EventTargetData* d = eventTargetData();
252         if (!d)
253             return false;
254         return !d->eventListenerMap.isEmpty();
255     }
256 
hasEventListeners(const AtomicString & eventType)257     inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
258     {
259         EventTargetData* d = eventTargetData();
260         if (!d)
261             return false;
262         return d->eventListenerMap.contains(eventType);
263     }
264 
265 } // namespace WebCore
266 
267 #endif // EventTarget_h
268