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