void EventListenerMap::removeFirstEventListenerCreatedFromMarkup(const AtomicString& eventType) { ASSERT(!m_activeIteratorCount); if (m_hashMap) { EventListenerHashMap::iterator result = m_hashMap->find(eventType); ASSERT(result != m_hashMap->end()); EventListenerVector* listenerVector = result->second; ASSERT(listenerVector); removeFirstListenerCreatedFromMarkup(listenerVector); if (listenerVector->isEmpty()) { delete listenerVector; m_hashMap->remove(result); } return; } ASSERT(m_singleEventListenerVector); ASSERT(m_singleEventListenerType == eventType); removeFirstListenerCreatedFromMarkup(m_singleEventListenerVector.get()); if (m_singleEventListenerVector->isEmpty()) { m_singleEventListenerVector.clear(); m_singleEventListenerType = nullAtom; } }
void EventListenerInfo::getEventListeners(EventTarget* target, WillBeHeapVector<EventListenerInfo>& eventInformation, bool includeAncestors) { // The Node's Ancestors including self. WillBeHeapVector<RawPtrWillBeMember<EventTarget>> ancestors; ancestors.append(target); if (includeAncestors) { Node* node = target->toNode(); for (ContainerNode* ancestor = node ? node->parentOrShadowHostNode() : nullptr; ancestor; ancestor = ancestor->parentOrShadowHostNode()) ancestors.append(ancestor); } // Nodes and their Listeners for the concerned event types (order is top to bottom) for (size_t i = ancestors.size(); i; --i) { EventTarget* ancestor = ancestors[i - 1]; Vector<AtomicString> eventTypes = ancestor->eventTypes(); for (size_t j = 0; j < eventTypes.size(); ++j) { AtomicString& type = eventTypes[j]; EventListenerVector* listeners = ancestor->getEventListeners(type); if (!listeners) continue; EventListenerVector filteredListeners; filteredListeners.reserveCapacity(listeners->size()); for (size_t k = 0; k < listeners->size(); ++k) { if (listeners->at(k).listener->type() == EventListener::JSEventListenerType) filteredListeners.append(listeners->at(k)); } if (!filteredListeners.isEmpty()) eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners)); } } }
bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { EventTargetData* d = eventTargetData(); if (!d) return false; EventListenerMap::iterator result = d->eventListenerMap.find(eventType); if (result == d->eventListenerMap.end()) return false; EventListenerVector* entry = result->second; RegisteredEventListener registeredListener(listener, useCapture); size_t index = entry->find(registeredListener); if (index == notFound) return false; entry->remove(index); if (entry->isEmpty()) { delete entry; d->eventListenerMap.remove(result); } // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. for (size_t i = 0; i < d->firingEventIterators.size(); ++i) { if (eventType != d->firingEventIterators[i].eventType) continue; if (index >= d->firingEventIterators[i].end) continue; --d->firingEventIterators[i].end; if (index <= d->firingEventIterators[i].iterator) --d->firingEventIterators[i].iterator; } return true; }