• 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 "AtomicStringHash.h"
36 #include "EventNames.h"
37 #include "RegisteredEventListener.h"
38 #include <wtf/Forward.h>
39 #include <wtf/HashMap.h>
40 
41 namespace WebCore {
42 
43     class AbstractWorker;
44     class AtomicString;
45     class DedicatedWorkerContext;
46     class DOMApplicationCache;
47     class DOMWindow;
48     class Event;
49     class EventListener;
50     class EventSource;
51     class MessagePort;
52     class Node;
53     class Notification;
54     class SVGElementInstance;
55     class ScriptExecutionContext;
56     class SharedWorker;
57     class SharedWorkerContext;
58     class WebSocket;
59     class Worker;
60     class XMLHttpRequest;
61     class XMLHttpRequestUpload;
62 
63     typedef int ExceptionCode;
64 
65     struct FiringEventIterator {
FiringEventIteratorFiringEventIterator66         FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& end)
67             : eventType(eventType)
68             , iterator(iterator)
69             , end(end)
70         {
71         }
72 
73         const AtomicString& eventType;
74         size_t& iterator;
75         size_t& end;
76     };
77     typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
78 
79     typedef Vector<RegisteredEventListener, 1> EventListenerVector;
80     typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap;
81 
82     struct EventTargetData : Noncopyable {
83         ~EventTargetData();
84 
85         EventListenerMap eventListenerMap;
86         FiringEventIteratorVector firingEventIterators;
87     };
88 
89     class EventTarget {
90     public:
ref()91         void ref() { refEventTarget(); }
deref()92         void deref() { derefEventTarget(); }
93 
94         virtual EventSource* toEventSource();
95         virtual MessagePort* toMessagePort();
96         virtual Node* toNode();
97         virtual DOMWindow* toDOMWindow();
98         virtual XMLHttpRequest* toXMLHttpRequest();
99         virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
100 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
101         virtual DOMApplicationCache* toDOMApplicationCache();
102 #endif
103 #if ENABLE(SVG)
104         virtual SVGElementInstance* toSVGElementInstance();
105 #endif
106 #if ENABLE(WORKERS)
107         virtual Worker* toWorker();
108         virtual DedicatedWorkerContext* toDedicatedWorkerContext();
109 #endif
110 #if ENABLE(SHARED_WORKERS)
111         virtual SharedWorker* toSharedWorker();
112         virtual SharedWorkerContext* toSharedWorkerContext();
113 #endif
114 #if ENABLE(WEB_SOCKETS)
115         virtual WebSocket* toWebSocket();
116 #endif
117 
118 #if ENABLE(NOTIFICATIONS)
119         virtual Notification* toNotification();
120 #endif
121 
122         virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
123 
124         virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
125         virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
126         virtual void removeAllEventListeners();
127         virtual bool dispatchEvent(PassRefPtr<Event>);
128         bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API
129 
130         // Used for legacy "onEvent" attribute APIs.
131         bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
132         bool clearAttributeEventListener(const AtomicString& eventType);
133         EventListener* getAttributeEventListener(const AtomicString& eventType);
134 
135         bool hasEventListeners();
136         bool hasEventListeners(const AtomicString& eventType);
137         const EventListenerVector& getEventListeners(const AtomicString& eventType);
138 
139         bool fireEventListeners(Event*);
140         bool isFiringEventListeners();
141 
142 #if USE(JSC)
143         void markJSEventListeners(JSC::MarkStack&);
144         void invalidateJSEventListeners(JSC::JSObject*);
145 #endif
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 
158     #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
159         EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
160         void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
161 
162     #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
163         virtual EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
164         virtual void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
165 
166     #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
167         EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \
168         void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
169 
170     #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
171         EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
172         void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
173 
174     #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
175         EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
176         void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \
177 
178 #ifndef NDEBUG
179     void forbidEventDispatch();
180     void allowEventDispatch();
181     bool eventDispatchForbidden();
182 #else
forbidEventDispatch()183     inline void forbidEventDispatch() { }
allowEventDispatch()184     inline void allowEventDispatch() { }
185 #endif
186 
187 #if USE(JSC)
markJSEventListeners(JSC::MarkStack & markStack)188     inline void EventTarget::markJSEventListeners(JSC::MarkStack& markStack)
189     {
190         EventTargetData* d = eventTargetData();
191         if (!d)
192             return;
193 
194         EventListenerMap::iterator end = d->eventListenerMap.end();
195         for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
196             EventListenerVector& entry = *it->second;
197             for (size_t i = 0; i < entry.size(); ++i)
198                 entry[i].listener->markJSFunction(markStack);
199         }
200     }
201 
invalidateJSEventListeners(JSC::JSObject * wrapper)202     inline void EventTarget::invalidateJSEventListeners(JSC::JSObject* wrapper)
203     {
204         EventTargetData* d = eventTargetData();
205         if (!d)
206             return;
207 
208         EventListenerMap::iterator end = d->eventListenerMap.end();
209         for (EventListenerMap::iterator it = d->eventListenerMap.begin(); it != end; ++it) {
210             EventListenerVector& entry = *it->second;
211             for (size_t i = 0; i < entry.size(); ++i)
212                 entry[i].listener->invalidateJSFunction(wrapper);
213         }
214     }
215 #endif
216 
isFiringEventListeners()217     inline bool EventTarget::isFiringEventListeners()
218     {
219         EventTargetData* d = eventTargetData();
220         if (!d)
221             return false;
222         return d->firingEventIterators.size() != 0;
223     }
224 
hasEventListeners()225     inline bool EventTarget::hasEventListeners()
226     {
227         EventTargetData* d = eventTargetData();
228         if (!d)
229             return false;
230         return !d->eventListenerMap.isEmpty();
231     }
232 
hasEventListeners(const AtomicString & eventType)233     inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
234     {
235         EventTargetData* d = eventTargetData();
236         if (!d)
237             return false;
238         return d->eventListenerMap.contains(eventType);
239     }
240 
241 } // namespace WebCore
242 
243 #endif // EventTarget_h
244