Reuse the same event object when dispatching bubbling/capturing phases instead of allocating new ones.

This commit is contained in:
ownedbywuigi 2026-03-27 11:57:41 +00:00
commit 8594600d9b

View file

@ -489,7 +489,9 @@ EventTargetChainItem::HandleEventTargetChain(
uint32_t childIndex = j - 1; uint32_t childIndex = j - 1;
EventTarget* newTarget = aChain[childIndex].GetNewTarget(); EventTarget* newTarget = aChain[childIndex].GetNewTarget();
if (newTarget) { if (newTarget) {
if (aVisitor.mEvent->mTarget != newTarget) {
aVisitor.mEvent->mTarget = newTarget; aVisitor.mEvent->mTarget = newTarget;
}
break; break;
} }
} }
@ -509,16 +511,21 @@ EventTargetChainItem::HandleEventTargetChain(
aChain[childIndex].GetRetargetedRelatedTarget(); aChain[childIndex].GetRetargetedRelatedTarget();
if (relatedTarget) { if (relatedTarget) {
found = true; found = true;
if (aVisitor.mEvent->mRelatedTarget != relatedTarget) {
aVisitor.mEvent->mRelatedTarget = relatedTarget; aVisitor.mEvent->mRelatedTarget = relatedTarget;
}
break; break;
} }
} }
if (!found) { if (!found) {
if (aVisitor.mEvent->mRelatedTarget !=
aVisitor.mEvent->mOriginalRelatedTarget) {
aVisitor.mEvent->mRelatedTarget = aVisitor.mEvent->mRelatedTarget =
aVisitor.mEvent->mOriginalRelatedTarget; aVisitor.mEvent->mOriginalRelatedTarget;
} }
} }
} }
}
// Target // Target
aVisitor.mEvent->mFlags.mInBubblingPhase = true; aVisitor.mEvent->mFlags.mInBubblingPhase = true;
@ -541,16 +548,20 @@ EventTargetChainItem::HandleEventTargetChain(
if (newTarget) { if (newTarget) {
// Item is at anonymous boundary. Need to retarget for the current item // Item is at anonymous boundary. Need to retarget for the current item
// and for parent items. // and for parent items.
if (aVisitor.mEvent->mTarget != newTarget) {
aVisitor.mEvent->mTarget = newTarget; aVisitor.mEvent->mTarget = newTarget;
} }
}
// https://dom.spec.whatwg.org/#dispatching-events // https://dom.spec.whatwg.org/#dispatching-events
// Step 15.2 // Step 15.2
// "Set event's relatedTarget to tuple's relatedTarget." // "Set event's relatedTarget to tuple's relatedTarget."
EventTarget* relatedTarget = item.GetRetargetedRelatedTarget(); EventTarget* relatedTarget = item.GetRetargetedRelatedTarget();
if (relatedTarget) { if (relatedTarget) {
if (aVisitor.mEvent->mRelatedTarget != relatedTarget) {
aVisitor.mEvent->mRelatedTarget = relatedTarget; aVisitor.mEvent->mRelatedTarget = relatedTarget;
} }
}
if (aVisitor.mEvent->mFlags.mBubbles || newTarget) { if (aVisitor.mEvent->mFlags.mBubbles || newTarget) {
if (!aVisitor.mEvent->PropagationStopped()) { if (!aVisitor.mEvent->PropagationStopped()) {
@ -570,7 +581,9 @@ EventTargetChainItem::HandleEventTargetChain(
aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false; aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;
// Setting back the original target of the event. // Setting back the original target of the event.
if (aVisitor.mEvent->mTarget != aVisitor.mEvent->mOriginalTarget) {
aVisitor.mEvent->mTarget = aVisitor.mEvent->mOriginalTarget; aVisitor.mEvent->mTarget = aVisitor.mEvent->mOriginalTarget;
}
// Special handling if PresShell (or some other caller) // Special handling if PresShell (or some other caller)
// used a callback object. // used a callback object.
@ -580,8 +593,13 @@ EventTargetChainItem::HandleEventTargetChain(
// Retarget for system event group (which does the default handling too). // Retarget for system event group (which does the default handling too).
// Setting back the target which was used also for default event group. // Setting back the target which was used also for default event group.
if (aVisitor.mEvent->mTarget != firstTarget) {
aVisitor.mEvent->mTarget = firstTarget; aVisitor.mEvent->mTarget = firstTarget;
}
if (aVisitor.mEvent->mRelatedTarget !=
aVisitor.mEvent->mOriginalRelatedTarget) {
aVisitor.mEvent->mRelatedTarget = aVisitor.mEvent->mOriginalRelatedTarget; aVisitor.mEvent->mRelatedTarget = aVisitor.mEvent->mOriginalRelatedTarget;
}
aVisitor.mEvent->mFlags.mInSystemGroup = true; aVisitor.mEvent->mFlags.mInSystemGroup = true;
HandleEventTargetChain(aChain, HandleEventTargetChain(aChain,
aVisitor, aVisitor,
@ -713,11 +731,13 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent()); do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
NS_ENSURE_STATE(newTarget); NS_ENSURE_STATE(newTarget);
if (target != newTarget) {
aEvent->mOriginalTarget = target; aEvent->mOriginalTarget = target;
target = newTarget; target = newTarget;
retargeted = true; retargeted = true;
} }
} }
}
if (aEvent->mFlags.mOnlyChromeDispatch) { if (aEvent->mFlags.mOnlyChromeDispatch) {
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
@ -860,12 +880,18 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
// Need to set the target of the event // Need to set the target of the event
// so that also the next retargeting works. // so that also the next retargeting works.
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget; preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
if (preVisitor.mEvent->mTarget != preVisitor.mEventTargetAtParent) {
preVisitor.mEvent->mTarget = preVisitor.mEventTargetAtParent; preVisitor.mEvent->mTarget = preVisitor.mEventTargetAtParent;
}
parentEtci->SetNewTarget(preVisitor.mEventTargetAtParent); parentEtci->SetNewTarget(preVisitor.mEventTargetAtParent);
} }
if (preVisitor.mRetargetedRelatedTarget) { if (preVisitor.mRetargetedRelatedTarget) {
preVisitor.mEvent->mRelatedTarget = preVisitor.mRetargetedRelatedTarget; if (preVisitor.mEvent->mRelatedTarget !=
preVisitor.mRetargetedRelatedTarget) {
preVisitor.mEvent->mRelatedTarget =
preVisitor.mRetargetedRelatedTarget;
}
} }
parentEtci->GetEventTargetParent(preVisitor); parentEtci->GetEventTargetParent(preVisitor);