Remove inclusion of MainThread.h from Threading.h
[WebKit-https.git] / Source / WebCore / dom / EventTarget.cpp
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 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 #include "config.h"
33 #include "EventTarget.h"
34
35 #include "Event.h"
36 #include "EventException.h"
37 #include <wtf/MainThread.h>
38 #include <wtf/StdLibExtras.h>
39 #include <wtf/Vector.h>
40
41 using namespace WTF;
42
43 namespace WebCore {
44
45 #ifndef NDEBUG
46 static int gEventDispatchForbidden = 0;
47
48 void forbidEventDispatch()
49 {
50     if (!isMainThread())
51         return;
52     ++gEventDispatchForbidden;
53 }
54
55 void allowEventDispatch()
56 {
57     if (!isMainThread())
58         return;
59     if (gEventDispatchForbidden > 0)
60         --gEventDispatchForbidden;
61 }
62
63 bool eventDispatchForbidden()
64 {
65     if (!isMainThread())
66         return false;
67     return gEventDispatchForbidden > 0;
68 }
69 #endif // NDEBUG
70
71 EventTargetData::EventTargetData()
72 {
73 }
74
75 EventTargetData::~EventTargetData()
76 {
77     deleteAllValues(eventListenerMap);
78 }
79
80 EventTarget::~EventTarget()
81 {
82 }
83
84 EventSource* EventTarget::toEventSource()
85 {
86     return 0;
87 }
88
89 Node* EventTarget::toNode()
90 {
91     return 0;
92 }
93
94 DOMWindow* EventTarget::toDOMWindow()
95 {
96     return 0;
97 }
98
99 XMLHttpRequest* EventTarget::toXMLHttpRequest()
100 {
101     return 0;
102 }
103
104 XMLHttpRequestUpload* EventTarget::toXMLHttpRequestUpload()
105 {
106     return 0;
107 }
108
109 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
110 DOMApplicationCache* EventTarget::toDOMApplicationCache()
111 {
112     return 0;
113 }
114 #endif
115
116 #if ENABLE(SVG)
117 SVGElementInstance* EventTarget::toSVGElementInstance()
118 {
119     return 0;
120 }
121 #endif
122
123 #if ENABLE(WEB_AUDIO)
124 AudioContext* EventTarget::toAudioContext()
125 {
126     return 0;
127 }
128
129 JavaScriptAudioNode* EventTarget::toJavaScriptAudioNode()
130 {
131     return 0;
132 }
133 #endif
134
135 #if ENABLE(WEB_SOCKETS)
136 WebSocket* EventTarget::toWebSocket()
137 {
138     return 0;
139 }
140 #endif
141
142 MessagePort* EventTarget::toMessagePort()
143 {
144     return 0;
145 }
146
147 #if ENABLE(WORKERS)
148 Worker* EventTarget::toWorker()
149 {
150     return 0;
151 }
152
153 DedicatedWorkerContext* EventTarget::toDedicatedWorkerContext()
154 {
155     return 0;
156 }
157 #endif
158
159 #if ENABLE(SHARED_WORKERS)
160 SharedWorker* EventTarget::toSharedWorker()
161 {
162     return 0;
163 }
164 SharedWorkerContext* EventTarget::toSharedWorkerContext()
165 {
166     return 0;
167 }
168 #endif
169
170 #if ENABLE(NOTIFICATIONS)
171 Notification* EventTarget::toNotification()
172 {
173     return 0;
174 }
175 #endif
176
177 #if ENABLE(BLOB)
178 FileReader* EventTarget::toFileReader()
179 {
180     return 0;
181 }
182 #endif
183 #if ENABLE(FILE_SYSTEM)
184 FileWriter* EventTarget::toFileWriter()
185 {
186     return 0;
187 }
188 #endif
189
190 #if ENABLE(INDEXED_DATABASE)
191 IDBDatabase* EventTarget::toIDBDatabase()
192 {
193     return 0;
194 }
195 IDBRequest* EventTarget::toIDBRequest()
196 {
197     return 0;
198 }
199 IDBTransaction* EventTarget::toIDBTransaction()
200 {
201     return 0;
202 }
203 IDBVersionChangeRequest* EventTarget::toIDBVersionChangeRequest()
204 {
205     return 0;
206 }
207 #endif
208
209 #if ENABLE(MEDIA_STREAM)
210 MediaStream* EventTarget::toMediaStream()
211 {
212     return 0;
213 }
214
215 LocalMediaStream* EventTarget::toLocalMediaStream()
216 {
217     return 0;
218 }
219 #endif
220
221 bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
222 {
223     EventTargetData* d = ensureEventTargetData();
224
225     pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, 0);
226     EventListenerVector*& entry = result.first->second;
227     const bool isNewEntry = result.second;
228     if (isNewEntry)
229         entry = new EventListenerVector();
230
231     RegisteredEventListener registeredListener(listener, useCapture);
232     if (!isNewEntry) {
233         if (entry->find(registeredListener) != notFound) // duplicate listener
234             return false;
235     }
236
237     entry->append(registeredListener);
238     return true;
239 }
240
241 bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
242 {
243     EventTargetData* d = eventTargetData();
244     if (!d)
245         return false;
246
247     EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
248     if (result == d->eventListenerMap.end())
249         return false;
250     EventListenerVector* entry = result->second;
251
252     RegisteredEventListener registeredListener(listener, useCapture);
253     size_t index = entry->find(registeredListener);
254     if (index == notFound)
255         return false;
256
257     entry->remove(index);
258     if (entry->isEmpty()) {
259         delete entry;
260         d->eventListenerMap.remove(result);
261     }
262
263     // Notify firing events planning to invoke the listener at 'index' that
264     // they have one less listener to invoke.
265     for (size_t i = 0; i < d->firingEventIterators.size(); ++i) {
266         if (eventType != d->firingEventIterators[i].eventType)
267             continue;
268
269         if (index >= d->firingEventIterators[i].end)
270             continue;
271
272         --d->firingEventIterators[i].end;
273         if (index <= d->firingEventIterators[i].iterator)
274             --d->firingEventIterators[i].iterator;
275     }
276
277     return true;
278 }
279
280 bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
281 {
282     clearAttributeEventListener(eventType);
283     if (!listener)
284         return false;
285     return addEventListener(eventType, listener, false);
286 }
287
288 EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
289 {
290     const EventListenerVector& entry = getEventListeners(eventType);
291     for (size_t i = 0; i < entry.size(); ++i) {
292         if (entry[i].listener->isAttribute())
293             return entry[i].listener.get();
294     }
295     return 0;
296 }
297
298 bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
299 {
300     EventListener* listener = getAttributeEventListener(eventType);
301     if (!listener)
302         return false;
303     return removeEventListener(eventType, listener, false);
304 }
305
306 bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
307 {
308     if (!event || event->type().isEmpty()) {
309         ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
310         return false;
311     }
312
313     if (event->isBeingDispatched()) {
314         ec = EventException::DISPATCH_REQUEST_ERR;
315         return false;
316     }
317
318     if (!scriptExecutionContext())
319         return false;
320
321     return dispatchEvent(event);
322 }
323
324 bool EventTarget::dispatchEvent(PassRefPtr<Event> event)
325 {
326     event->setTarget(this);
327     event->setCurrentTarget(this);
328     event->setEventPhase(Event::AT_TARGET);
329     bool defaultPrevented = fireEventListeners(event.get());
330     event->setEventPhase(0);
331     return defaultPrevented;
332 }
333
334 void EventTarget::uncaughtExceptionInEventHandler()
335 {
336 }
337
338 bool EventTarget::fireEventListeners(Event* event)
339 {
340     ASSERT(!eventDispatchForbidden());
341     ASSERT(event && !event->type().isEmpty());
342
343     EventTargetData* d = eventTargetData();
344     if (!d)
345         return true;
346
347     EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
348     if (result != d->eventListenerMap.end())
349         fireEventListeners(event, d, *result->second);
350     
351     return !event->defaultPrevented();
352 }
353         
354 void EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventListenerVector& entry)
355 {
356     RefPtr<EventTarget> protect = this;
357
358     // Fire all listeners registered for this event. Don't fire listeners removed
359     // during event dispatch. Also, don't fire event listeners added during event
360     // dispatch. Conveniently, all new event listeners will be added after 'end',
361     // so iterating to 'end' naturally excludes new event listeners.
362
363     size_t i = 0;
364     size_t end = entry.size();
365     d->firingEventIterators.append(FiringEventIterator(event->type(), i, end));
366     for ( ; i < end; ++i) {
367         RegisteredEventListener& registeredListener = entry[i];
368         if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture)
369             continue;
370         if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture)
371             continue;
372
373         // If stopImmediatePropagation has been called, we just break out immediately, without
374         // handling any more events on this target.
375         if (event->immediatePropagationStopped())
376             break;
377
378         // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
379         // event listeners, even though that violates some versions of the DOM spec.
380         registeredListener.listener->handleEvent(scriptExecutionContext(), event);
381     }
382     d->firingEventIterators.removeLast();
383 }
384
385 const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType)
386 {
387     DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ());
388
389     EventTargetData* d = eventTargetData();
390     if (!d)
391         return emptyVector;
392     EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
393     if (it == d->eventListenerMap.end())
394         return emptyVector;
395     return *it->second;
396 }
397
398 void EventTarget::removeAllEventListeners()
399 {
400     EventTargetData* d = eventTargetData();
401     if (!d)
402         return;
403     deleteAllValues(d->eventListenerMap);
404     d->eventListenerMap.clear();
405
406     // Notify firing events planning to invoke the listener at 'index' that
407     // they have one less listener to invoke.
408     for (size_t i = 0; i < d->firingEventIterators.size(); ++i) {
409         d->firingEventIterators[i].iterator = 0;
410         d->firingEventIterators[i].end = 0;
411     }
412 }
413
414 EventListenerIterator::EventListenerIterator()
415     : m_index(0)
416 {
417 }
418
419 EventListenerIterator::EventListenerIterator(EventTarget* target)
420     : m_index(0)
421 {
422     EventTargetData* data = target->eventTargetData();
423     if (!data)
424         return;
425     m_mapIterator = data->eventListenerMap.begin();
426     m_mapEnd = data->eventListenerMap.end();
427 }
428
429 EventListener* EventListenerIterator::nextListener()
430 {
431     for (; m_mapIterator != m_mapEnd; ++m_mapIterator) {
432         EventListenerVector& listeners = *m_mapIterator->second;
433         if (m_index < listeners.size())
434             return listeners[m_index++].listener.get();
435         m_index = 0;
436     }
437     return 0;
438 }
439
440 } // namespace WebCore