EventListenerManager::Listener* EventListenerManager::SetEventHandlerInternal( nsIAtom* aName, const nsAString& aTypeString, const TypedEventHandler& aTypedHandler, bool aPermitUntrustedEvents) { MOZ_ASSERT(aName || !aTypeString.IsEmpty()); uint32_t eventType = nsContentUtils::GetEventId(aName); Listener* listener = FindEventHandler(eventType, aName, aTypeString); if (!listener) { // If we didn't find a script listener or no listeners existed // create and add a new one. EventListenerFlags flags; flags.mListenerIsJSListener = true; nsCOMPtr<JSEventHandler> jsEventHandler; NS_NewJSEventHandler(mTarget, aName, aTypedHandler, getter_AddRefs(jsEventHandler)); EventListenerHolder listenerHolder(jsEventHandler); AddEventListenerInternal(listenerHolder, eventType, aName, aTypeString, flags, true); listener = FindEventHandler(eventType, aName, aTypeString); } else { JSEventHandler* jsEventHandler = listener->GetJSEventHandler(); MOZ_ASSERT(jsEventHandler, "How can we have an event handler with no JSEventHandler?"); bool same = jsEventHandler->GetTypedEventHandler() == aTypedHandler; // Possibly the same listener, but update still the context and scope. jsEventHandler->SetHandler(aTypedHandler); if (mTarget && !same && aName) { mTarget->EventListenerRemoved(aName); mTarget->EventListenerAdded(aName); } if (mIsMainThreadELM && mTarget) { EventListenerService::NotifyAboutMainThreadListenerChange(mTarget); } } // Set flag to indicate possible need for compilation later listener->mHandlerIsString = !aTypedHandler.HasEventHandler(); if (aPermitUntrustedEvents) { listener->mFlags.mAllowUntrustedEvents = true; } return listener; }
const TypedEventHandler* EventListenerManager::GetTypedEventHandler(nsIAtom* aEventName, const nsAString& aTypeString) { uint32_t eventType = nsContentUtils::GetEventId(aEventName); Listener* listener = FindEventHandler(eventType, aEventName, aTypeString); if (!listener) { return nullptr; } JSEventHandler* jsEventHandler = listener->GetJSEventHandler(); if (listener->mHandlerIsString) { CompileEventHandlerInternal(listener, nullptr, nullptr); } const TypedEventHandler& typedHandler = jsEventHandler->GetTypedEventHandler(); return typedHandler.HasEventHandler() ? &typedHandler : nullptr; }