- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / events / EventListenerMap.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  * Copyright (C) 2011 Andreas Kling (kling@webkit.org)
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32
33 #include "config.h"
34 #include "core/events/EventListenerMap.h"
35
36 #include "core/events/EventTarget.h"
37 #include "wtf/StdLibExtras.h"
38 #include "wtf/Vector.h"
39
40 #ifndef NDEBUG
41 #include "wtf/ThreadingPrimitives.h"
42 #endif
43
44 using namespace WTF;
45
46 namespace WebCore {
47
48 #ifndef NDEBUG
49 static Mutex& activeIteratorCountMutex()
50 {
51     DEFINE_STATIC_LOCAL(Mutex, mutex, ());
52     return mutex;
53 }
54
55 void EventListenerMap::assertNoActiveIterators()
56 {
57     MutexLocker locker(activeIteratorCountMutex());
58     ASSERT(!m_activeIteratorCount);
59 }
60 #endif
61
62 EventListenerMap::EventListenerMap()
63 #ifndef NDEBUG
64     : m_activeIteratorCount(0)
65 #endif
66 {
67 }
68
69 bool EventListenerMap::contains(const AtomicString& eventType) const
70 {
71     for (unsigned i = 0; i < m_entries.size(); ++i) {
72         if (m_entries[i].first == eventType)
73             return true;
74     }
75     return false;
76 }
77
78 bool EventListenerMap::containsCapturing(const AtomicString& eventType) const
79 {
80     for (unsigned i = 0; i < m_entries.size(); ++i) {
81         if (m_entries[i].first == eventType) {
82             const EventListenerVector* vector = m_entries[i].second.get();
83             for (unsigned j = 0; j < vector->size(); ++j) {
84                 if (vector->at(j).useCapture)
85                     return true;
86             }
87         }
88     }
89     return false;
90 }
91
92 void EventListenerMap::clear()
93 {
94     assertNoActiveIterators();
95
96     m_entries.clear();
97 }
98
99 Vector<AtomicString> EventListenerMap::eventTypes() const
100 {
101     Vector<AtomicString> types;
102     types.reserveInitialCapacity(m_entries.size());
103
104     for (unsigned i = 0; i < m_entries.size(); ++i)
105         types.uncheckedAppend(m_entries[i].first);
106
107     return types;
108 }
109
110 static bool addListenerToVector(EventListenerVector* vector, PassRefPtr<EventListener> listener, bool useCapture)
111 {
112     RegisteredEventListener registeredListener(listener, useCapture);
113
114     if (vector->find(registeredListener) != kNotFound)
115         return false; // Duplicate listener.
116
117     vector->append(registeredListener);
118     return true;
119 }
120
121 bool EventListenerMap::add(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
122 {
123     assertNoActiveIterators();
124
125     for (unsigned i = 0; i < m_entries.size(); ++i) {
126         if (m_entries[i].first == eventType)
127             return addListenerToVector(m_entries[i].second.get(), listener, useCapture);
128     }
129
130     m_entries.append(std::make_pair(eventType, adoptPtr(new EventListenerVector)));
131     return addListenerToVector(m_entries.last().second.get(), listener, useCapture);
132 }
133
134 static bool removeListenerFromVector(EventListenerVector* listenerVector, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
135 {
136     RegisteredEventListener registeredListener(listener, useCapture);
137     indexOfRemovedListener = listenerVector->find(registeredListener);
138     if (indexOfRemovedListener == kNotFound)
139         return false;
140     listenerVector->remove(indexOfRemovedListener);
141     return true;
142 }
143
144 bool EventListenerMap::remove(const AtomicString& eventType, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
145 {
146     assertNoActiveIterators();
147
148     for (unsigned i = 0; i < m_entries.size(); ++i) {
149         if (m_entries[i].first == eventType) {
150             bool wasRemoved = removeListenerFromVector(m_entries[i].second.get(), listener, useCapture, indexOfRemovedListener);
151             if (m_entries[i].second->isEmpty())
152                 m_entries.remove(i);
153             return wasRemoved;
154         }
155     }
156
157     return false;
158 }
159
160 EventListenerVector* EventListenerMap::find(const AtomicString& eventType)
161 {
162     assertNoActiveIterators();
163
164     for (unsigned i = 0; i < m_entries.size(); ++i) {
165         if (m_entries[i].first == eventType)
166             return m_entries[i].second.get();
167     }
168
169     return 0;
170 }
171
172 static void removeFirstListenerCreatedFromMarkup(EventListenerVector* listenerVector)
173 {
174     bool foundListener = false;
175
176     for (size_t i = 0; i < listenerVector->size(); ++i) {
177         if (!listenerVector->at(i).listener->wasCreatedFromMarkup())
178             continue;
179         foundListener = true;
180         listenerVector->remove(i);
181         break;
182     }
183
184     ASSERT_UNUSED(foundListener, foundListener);
185 }
186
187 void EventListenerMap::removeFirstEventListenerCreatedFromMarkup(const AtomicString& eventType)
188 {
189     assertNoActiveIterators();
190
191     for (unsigned i = 0; i < m_entries.size(); ++i) {
192         if (m_entries[i].first == eventType) {
193             removeFirstListenerCreatedFromMarkup(m_entries[i].second.get());
194             if (m_entries[i].second->isEmpty())
195                 m_entries.remove(i);
196             return;
197         }
198     }
199 }
200
201 static void copyListenersNotCreatedFromMarkupToTarget(const AtomicString& eventType, EventListenerVector* listenerVector, EventTarget* target)
202 {
203     for (size_t i = 0; i < listenerVector->size(); ++i) {
204         // Event listeners created from markup have already been transfered to the shadow tree during cloning.
205         if ((*listenerVector)[i].listener->wasCreatedFromMarkup())
206             continue;
207         target->addEventListener(eventType, (*listenerVector)[i].listener, (*listenerVector)[i].useCapture);
208     }
209 }
210
211 void EventListenerMap::copyEventListenersNotCreatedFromMarkupToTarget(EventTarget* target)
212 {
213     assertNoActiveIterators();
214
215     for (unsigned i = 0; i < m_entries.size(); ++i)
216         copyListenersNotCreatedFromMarkupToTarget(m_entries[i].first, m_entries[i].second.get(), target);
217 }
218
219 EventListenerIterator::EventListenerIterator()
220     : m_map(0)
221     , m_entryIndex(0)
222     , m_index(0)
223 {
224 }
225
226 EventListenerIterator::EventListenerIterator(EventTarget* target)
227     : m_map(0)
228     , m_entryIndex(0)
229     , m_index(0)
230 {
231     ASSERT(target);
232     EventTargetData* data = target->eventTargetData();
233
234     if (!data)
235         return;
236
237     m_map = &data->eventListenerMap;
238
239 #ifndef NDEBUG
240     {
241         MutexLocker locker(activeIteratorCountMutex());
242         m_map->m_activeIteratorCount++;
243     }
244 #endif
245 }
246
247 #ifndef NDEBUG
248 EventListenerIterator::~EventListenerIterator()
249 {
250     if (m_map) {
251         MutexLocker locker(activeIteratorCountMutex());
252         m_map->m_activeIteratorCount--;
253     }
254 }
255 #endif
256
257 EventListener* EventListenerIterator::nextListener()
258 {
259     if (!m_map)
260         return 0;
261
262     for (; m_entryIndex < m_map->m_entries.size(); ++m_entryIndex) {
263         EventListenerVector& listeners = *m_map->m_entries[m_entryIndex].second;
264         if (m_index < listeners.size())
265             return listeners[m_index++].listener.get();
266         m_index = 0;
267     }
268
269     return 0;
270 }
271
272 } // namespace WebCore