Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / dom / 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 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 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 "EventListenerMap.h"
35
36 #include "Event.h"
37 #include "EventTarget.h"
38 #include <wtf/MainThread.h>
39 #include <wtf/NeverDestroyed.h>
40 #include <wtf/StdLibExtras.h>
41 #include <wtf/Vector.h>
42
43 using namespace WTF;
44
45 namespace WebCore {
46
47 #ifndef NDEBUG
48 void EventListenerMap::assertNoActiveIterators()
49 {
50     ASSERT(!m_activeIteratorCount);
51 }
52 #endif
53
54 EventListenerMap::EventListenerMap()
55 {
56 }
57
58 bool EventListenerMap::contains(const AtomicString& eventType) const
59 {
60     for (auto& entry : m_entries) {
61         if (entry.first == eventType)
62             return true;
63     }
64     return false;
65 }
66
67 bool EventListenerMap::containsCapturing(const AtomicString& eventType) const
68 {
69     for (auto& entry : m_entries) {
70         if (entry.first == eventType) {
71             for (auto& eventListener : *entry.second) {
72                 if (eventListener.useCapture)
73                     return true;
74             }
75         }
76     }
77     return false;
78 }
79
80 void EventListenerMap::clear()
81 {
82     assertNoActiveIterators();
83
84     m_entries.clear();
85 }
86
87 Vector<AtomicString> EventListenerMap::eventTypes() const
88 {
89     Vector<AtomicString> types;
90     types.reserveInitialCapacity(m_entries.size());
91
92     for (auto& entry : m_entries)
93         types.uncheckedAppend(entry.first);
94
95     return types;
96 }
97
98 static bool addListenerToVector(EventListenerVector* vector, PassRefPtr<EventListener> listener, bool useCapture)
99 {
100     RegisteredEventListener registeredListener(listener, useCapture);
101
102     if (vector->find(registeredListener) != notFound)
103         return false; // Duplicate listener.
104
105     vector->append(registeredListener);
106     return true;
107 }
108
109 bool EventListenerMap::add(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
110 {
111     assertNoActiveIterators();
112
113     for (auto& entry : m_entries) {
114         if (entry.first == eventType)
115             return addListenerToVector(entry.second.get(), listener, useCapture);
116     }
117
118     m_entries.append(std::make_pair(eventType, std::make_unique<EventListenerVector>()));
119     return addListenerToVector(m_entries.last().second.get(), listener, useCapture);
120 }
121
122 static bool removeListenerFromVector(EventListenerVector* listenerVector, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
123 {
124     RegisteredEventListener registeredListener(listener, useCapture);
125     indexOfRemovedListener = listenerVector->find(registeredListener);
126     if (indexOfRemovedListener == notFound)
127         return false;
128     listenerVector->remove(indexOfRemovedListener);
129     return true;
130 }
131
132 bool EventListenerMap::remove(const AtomicString& eventType, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
133 {
134     assertNoActiveIterators();
135
136     for (unsigned i = 0; i < m_entries.size(); ++i) {
137         if (m_entries[i].first == eventType) {
138             bool wasRemoved = removeListenerFromVector(m_entries[i].second.get(), listener, useCapture, indexOfRemovedListener);
139             if (m_entries[i].second->isEmpty())
140                 m_entries.remove(i);
141             return wasRemoved;
142         }
143     }
144
145     return false;
146 }
147
148 EventListenerVector* EventListenerMap::find(const AtomicString& eventType)
149 {
150     assertNoActiveIterators();
151
152     for (auto& entry : m_entries) {
153         if (entry.first == eventType)
154             return entry.second.get();
155     }
156
157     return nullptr;
158 }
159
160 static void removeFirstListenerCreatedFromMarkup(EventListenerVector& listenerVector)
161 {
162     bool foundListener = listenerVector.removeFirstMatching([] (const RegisteredEventListener& listener) {
163         return listener.listener->wasCreatedFromMarkup();
164     });
165     ASSERT_UNUSED(foundListener, foundListener);
166 }
167
168 void EventListenerMap::removeFirstEventListenerCreatedFromMarkup(const AtomicString& eventType)
169 {
170     assertNoActiveIterators();
171
172     for (unsigned i = 0; i < m_entries.size(); ++i) {
173         if (m_entries[i].first == eventType) {
174             removeFirstListenerCreatedFromMarkup(*m_entries[i].second);
175             if (m_entries[i].second->isEmpty())
176                 m_entries.remove(i);
177             return;
178         }
179     }
180 }
181
182 static void copyListenersNotCreatedFromMarkupToTarget(const AtomicString& eventType, EventListenerVector* listenerVector, EventTarget* target)
183 {
184     for (auto& listener : *listenerVector) {
185         // Event listeners created from markup have already been transfered to the shadow tree during cloning.
186         if (listener.listener->wasCreatedFromMarkup())
187             continue;
188         target->addEventListener(eventType, listener.listener.copyRef(), listener.useCapture);
189     }
190 }
191
192 void EventListenerMap::copyEventListenersNotCreatedFromMarkupToTarget(EventTarget* target)
193 {
194     assertNoActiveIterators();
195
196     for (auto& entry : m_entries)
197         copyListenersNotCreatedFromMarkupToTarget(entry.first, entry.second.get(), target);
198 }
199
200 EventListenerIterator::EventListenerIterator(EventTarget* target)
201 {
202     ASSERT(target);
203     EventTargetData* data = target->eventTargetData();
204
205     if (!data)
206         return;
207
208     m_map = &data->eventListenerMap;
209
210 #ifndef NDEBUG
211     m_map->m_activeIteratorCount++;
212 #endif
213 }
214
215 #ifndef NDEBUG
216 EventListenerIterator::~EventListenerIterator()
217 {
218     if (m_map)
219         m_map->m_activeIteratorCount--;
220 }
221 #endif
222
223 EventListener* EventListenerIterator::nextListener()
224 {
225     if (!m_map)
226         return 0;
227
228     for (; m_entryIndex < m_map->m_entries.size(); ++m_entryIndex) {
229         EventListenerVector& listeners = *m_map->m_entries[m_entryIndex].second;
230         if (m_index < listeners.size())
231             return listeners[m_index++].listener.get();
232         m_index = 0;
233     }
234
235     return 0;
236 }
237
238 } // namespace WebCore