bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options) { EventTargetData* d = eventTargetData(); if (!d) return false; size_t indexOfRemovedListener; if (!d->eventListenerMap.remove(eventType, listener, options.capture, indexOfRemovedListener)) return false; // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. if (!d->firingEventIterators) return true; for (auto& firingIterator : *d->firingEventIterators) { if (eventType != firingIterator.eventType) continue; if (indexOfRemovedListener >= firingIterator.size) continue; --firingIterator.size; if (indexOfRemovedListener <= firingIterator.iterator) --firingIterator.iterator; } return true; }
EventTargetData& SVGElementInstance::ensureEventTargetData() { // EventTarget would use these methods if we were actually using its add/removeEventListener logic. // As we're forwarding those calls to the correspondingElement(), no one should ever call this function. ASSERT_NOT_REACHED(); return *eventTargetData(); }
const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType) { auto* data = eventTargetData(); auto* listenerVector = data ? data->eventListenerMap.find(eventType) : nullptr; static NeverDestroyed<EventListenerVector> emptyVector; return listenerVector ? *listenerVector : emptyVector.get(); }
EventListenerVector* EventTarget::getEventListeners(const AtomicString& eventType) { EventTargetData* data = eventTargetData(); if (!data) return nullptr; return data->eventListenerMap.find(eventType); }
bool EventTarget::fireEventListeners(Event& event) { ASSERT_WITH_SECURITY_IMPLICATION(!NoEventDispatchAssertion::isEventDispatchForbidden()); ASSERT(event.isInitialized()); EventTargetData* d = eventTargetData(); if (!d) return true; EventListenerVector* legacyListenersVector = nullptr; const AtomicString& legacyTypeName = legacyType(event); if (!legacyTypeName.isEmpty()) legacyListenersVector = d->eventListenerMap.find(legacyTypeName); EventListenerVector* listenersVector = d->eventListenerMap.find(event.type()); if (listenersVector) fireEventListeners(event, d, *listenersVector); else if (legacyListenersVector) { AtomicString typeName = event.type(); event.setType(legacyTypeName); fireEventListeners(event, d, *legacyListenersVector); event.setType(typeName); } return !event.defaultPrevented(); }
bool EventTarget::fireEventListeners(Event* event) { ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); ASSERT(event && !event->type().isEmpty()); EventTargetData* d = eventTargetData(); if (!d) return true; EventListenerVector* legacyListenersVector = nullptr; AtomicString legacyTypeName = legacyType(event); if (!legacyTypeName.isEmpty()) legacyListenersVector = d->eventListenerMap.find(legacyTypeName); EventListenerVector* listenersVector = d->eventListenerMap.find(event->type()); if (listenersVector) { fireEventListeners(event, d, *listenersVector); } else if (legacyListenersVector) { AtomicString unprefixedTypeName = event->type(); event->setType(legacyTypeName); fireEventListeners(event, d, *legacyListenersVector); event->setType(unprefixedTypeName); } Editor::countEvent(executionContext(), event); countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector); return !event->defaultPrevented(); }
bool EventTarget::removeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { // FIXME: listener null check should throw TypeError (and be done in // generated bindings), but breaks legacy content. http://crbug.com/249598 if (!listener) return false; EventTargetData* d = eventTargetData(); if (!d) return false; size_t indexOfRemovedListener; if (!d->eventListenerMap.remove(eventType, listener.get(), useCapture, indexOfRemovedListener)) return false; // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. if (!d->firingEventIterators) return true; for (size_t i = 0; i < d->firingEventIterators->size(); ++i) { FiringEventIterator& firingIterator = d->firingEventIterators->at(i); if (eventType != firingIterator.eventType) continue; if (indexOfRemovedListener >= firingIterator.end) continue; --firingIterator.end; if (indexOfRemovedListener <= firingIterator.iterator) --firingIterator.iterator; } return true; }
const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType) { AtomicallyInitializedStatic(EventListenerVector*, emptyVector = new EventListenerVector); EventTargetData* d = eventTargetData(); if (!d) return *emptyVector; EventListenerVector* listenerVector = d->eventListenerMap.find(eventType); if (!listenerVector) return *emptyVector; return *listenerVector; }
void EventTarget::removeAllEventListeners() { EventTargetData* d = eventTargetData(); if (!d) return; d->eventListenerMap.clear(); // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. if (d->firingEventIterators) { for (auto& firingEventIterator : *d->firingEventIterators) { firingEventIterator.iterator = 0; firingEventIterator.size = 0; } } }
void EventTarget::removeAllEventListeners() { EventTargetData* d = eventTargetData(); if (!d) return; d->eventListenerMap.clear(); // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. if (d->firingEventIterators) { for (size_t i = 0; i < d->firingEventIterators->size(); ++i) { d->firingEventIterators->at(i).iterator = 0; d->firingEventIterators->at(i).end = 0; } } }
bool EventTarget::removeEventListenerInternal(const AtomicString& eventType, PassRefPtrWillBeRawPtr<EventListener> listener, const EventListenerOptions& options) { if (!listener) return false; EventTargetData* d = eventTargetData(); if (!d) return false; size_t indexOfRemovedListener; if (!d->eventListenerMap.remove(eventType, listener.get(), options, indexOfRemovedListener)) return false; // Notify firing events planning to invoke the listener at 'index' that // they have one less listener to invoke. if (!d->firingEventIterators) return true; for (size_t i = 0; i < d->firingEventIterators->size(); ++i) { FiringEventIterator& firingIterator = d->firingEventIterators->at(i); if (eventType != firingIterator.eventType) continue; if (indexOfRemovedListener >= firingIterator.end) continue; --firingIterator.end; // Note that when firing an event listener, // firingIterator.iterator indicates the next event listener // that would fire, not the currently firing event // listener. See EventTarget::fireEventListeners. if (indexOfRemovedListener < firingIterator.iterator) --firingIterator.iterator; } return true; }
bool EventTarget::fireEventListeners(Event* event) { ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); ASSERT(event && !event->type().isEmpty()); EventTargetData* d = eventTargetData(); if (!d) return true; EventListenerVector* legacyListenersVector = 0; AtomicString legacyTypeName = legacyType(event); if (!legacyTypeName.isEmpty()) legacyListenersVector = d->eventListenerMap.find(legacyTypeName); EventListenerVector* listenersVector = d->eventListenerMap.find(event->type()); if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && (event->type() == EventTypeNames::animationiteration || event->type() == EventTypeNames::animationend || event->type() == EventTypeNames::animationstart) // Some code out-there uses custom events to dispatch unprefixed animation events manually, // we can safely remove all this block when cssAnimationUnprefixedEnabled is always on, this // is really a special case. DO NOT ADD MORE EVENTS HERE. && event->interfaceName() != EventNames::CustomEvent) listenersVector = 0; if (listenersVector) { fireEventListeners(event, d, *listenersVector); } else if (legacyListenersVector) { AtomicString unprefixedTypeName = event->type(); event->setType(legacyTypeName); fireEventListeners(event, d, *legacyListenersVector); event->setType(unprefixedTypeName); } Editor::countEvent(executionContext(), event); countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector); return !event->defaultPrevented(); }
Vector<AtomicString> EventTarget::eventTypes() { EventTargetData* d = eventTargetData(); return d ? d->eventListenerMap.eventTypes() : Vector<AtomicString>(); }