void EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, WidgetEvent* aEvent, nsIDOMEvent** aDOMEvent, EventTarget* aCurrentTarget, nsEventStatus* aEventStatus) { //Set the value of the internal PreventDefault flag properly based on aEventStatus if (*aEventStatus == nsEventStatus_eConsumeNoDefault) { aEvent->mFlags.mDefaultPrevented = true; } nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners); Maybe<nsAutoPopupStatePusher> popupStatePusher; if (mIsMainThreadELM) { popupStatePusher.construct(Event::GetEventPopupControlState(aEvent)); } bool hasListener = false; while (iter.HasMore()) { if (aEvent->mFlags.mImmediatePropagationStopped) { break; } Listener* listener = &iter.GetNext(); // Check that the phase is same in event and event listener. // Handle only trusted events, except when listener permits untrusted events. if (ListenerCanHandle(listener, aEvent)) { hasListener = true; if (listener->IsListening(aEvent) && (aEvent->mFlags.mIsTrusted || listener->mFlags.mAllowUntrustedEvents)) { if (!*aDOMEvent) { // This is tiny bit slow, but happens only once per event. nsCOMPtr<EventTarget> et = do_QueryInterface(aEvent->originalTarget); EventDispatcher::CreateEvent(et, aPresContext, aEvent, EmptyString(), aDOMEvent); } if (*aDOMEvent) { if (!aEvent->currentTarget) { aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent(); if (!aEvent->currentTarget) { break; } } if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) { aEvent->mFlags.mExceptionHasBeenRisen = true; } } } } } aEvent->currentTarget = nullptr; if (mIsMainThreadELM && !hasListener) { mNoListenerForEvent = aEvent->message; mNoListenerForEventAtom = aEvent->userType; } if (aEvent->mFlags.mDefaultPrevented) { *aEventStatus = nsEventStatus_eConsumeNoDefault; } }
void EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, WidgetEvent* aEvent, nsIDOMEvent** aDOMEvent, EventTarget* aCurrentTarget, nsEventStatus* aEventStatus) { //Set the value of the internal PreventDefault flag properly based on aEventStatus if (*aEventStatus == nsEventStatus_eConsumeNoDefault) { aEvent->mFlags.mDefaultPrevented = true; } nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners); Maybe<nsAutoPopupStatePusher> popupStatePusher; if (mIsMainThreadELM) { popupStatePusher.emplace(Event::GetEventPopupControlState(aEvent, *aDOMEvent)); } bool hasListener = false; while (iter.HasMore()) { if (aEvent->mFlags.mImmediatePropagationStopped) { break; } Listener* listener = &iter.GetNext(); // Check that the phase is same in event and event listener. // Handle only trusted events, except when listener permits untrusted events. if (ListenerCanHandle(listener, aEvent)) { hasListener = true; if (listener->IsListening(aEvent) && (aEvent->mFlags.mIsTrusted || listener->mFlags.mAllowUntrustedEvents)) { if (!*aDOMEvent) { // This is tiny bit slow, but happens only once per event. nsCOMPtr<EventTarget> et = do_QueryInterface(aEvent->originalTarget); EventDispatcher::CreateEvent(et, aPresContext, aEvent, EmptyString(), aDOMEvent); } if (*aDOMEvent) { if (!aEvent->currentTarget) { aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent(); if (!aEvent->currentTarget) { break; } } // Maybe add a marker to the docshell's timeline, but only // bother with all the logic if some docshell is recording. nsCOMPtr<nsIDocShell> docShell; bool isTimelineRecording = false; if (mIsMainThreadELM && nsDocShell::gProfileTimelineRecordingsCount > 0 && listener->mListenerType != Listener::eNativeListener) { docShell = GetDocShellForTarget(); if (docShell) { docShell->GetRecordProfileTimelineMarkers(&isTimelineRecording); } if (isTimelineRecording) { nsDocShell* ds = static_cast<nsDocShell*>(docShell.get()); nsAutoString typeStr; (*aDOMEvent)->GetType(typeStr); uint16_t phase; (*aDOMEvent)->GetEventPhase(&phase); mozilla::UniquePtr<TimelineMarker> marker = MakeUnique<EventTimelineMarker>(ds, TRACING_INTERVAL_START, phase, typeStr); ds->AddProfileTimelineMarker(Move(marker)); } } if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) { aEvent->mFlags.mExceptionHasBeenRisen = true; } if (isTimelineRecording) { nsDocShell* ds = static_cast<nsDocShell*>(docShell.get()); ds->AddProfileTimelineMarker("DOMEvent", TRACING_INTERVAL_END); } } } } } aEvent->currentTarget = nullptr; if (mIsMainThreadELM && !hasListener) { mNoListenerForEvent = aEvent->message; mNoListenerForEventAtom = aEvent->userType; } if (aEvent->mFlags.mDefaultPrevented) { *aEventStatus = nsEventStatus_eConsumeNoDefault; } }