Bug 1826603 - Don't dispatch transition events if there are no listeners, r=masayuki

Differential Revision: https://phabricator.services.mozilla.com/D174829
This commit is contained in:
Olli Pettay 2023-04-06 09:09:33 +00:00
parent d52c9ae90f
commit ce96f3bd14
6 changed files with 46 additions and 1 deletions

View File

@ -280,6 +280,18 @@ struct AnimationEventInfo {
MOZ_ASSERT(mEvent.is<InternalTransitionEvent>() ||
mEvent.is<InternalAnimationEvent>());
if (mEvent.is<InternalTransitionEvent>() && target->IsNode()) {
nsPIDOMWindowInner* inner =
target->AsNode()->OwnerDoc()->GetInnerWindow();
if (inner && !inner->HasTransitionEventListeners()) {
MOZ_ASSERT(AsWidgetEvent()->mMessage == eTransitionStart ||
AsWidgetEvent()->mMessage == eTransitionRun ||
AsWidgetEvent()->mMessage == eTransitionEnd ||
AsWidgetEvent()->mMessage == eTransitionCancel);
return;
}
}
EventDispatcher::Dispatch(target, aPresContext, AsWidgetEvent());
}
};

View File

@ -7931,6 +7931,7 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
mMayHaveFormSelectEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mMayHaveTransitionEventListener(false),
mMayHaveBeforeInputEventListenerForTelemetry(false),
mMutationObserverHasObservedNodeForTelemetry(false),
mOuterWindow(aOuterWindow),

View File

@ -3388,6 +3388,9 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
if (elm->MayHaveFormSelectEventListener()) {
window->SetHasFormSelectEventListeners();
}
if (elm->MayHaveTransitionEventListener()) {
window->SetHasTransitionEventListeners();
}
}
}
if (wasRegistered) {

View File

@ -236,6 +236,20 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
mMayHavePointerEnterLeaveEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a transition* event listeners.
*/
bool HasTransitionEventListeners() { return mMayHaveTransitionEventListener; }
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a transition* event listener.
*/
void SetHasTransitionEventListeners() {
mMayHaveTransitionEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a beforeinput event listener.
@ -667,6 +681,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
bool mMayHaveFormSelectEventListener;
bool mMayHaveMouseEnterLeaveEventListener;
bool mMayHavePointerEnterLeaveEventListener;
bool mMayHaveTransitionEventListener;
// Only used for telemetry probes. This may be wrong if some nodes have
// come from another document with `Document.adoptNode`.
bool mMayHaveBeforeInputEventListenerForTelemetry;

View File

@ -114,6 +114,7 @@ EventListenerManagerBase::EventListenerManagerBase()
mMayHaveInputOrCompositionEventListener(false),
mMayHaveSelectionChangeEventListener(false),
mMayHaveFormSelectEventListener(false),
mMayHaveTransitionEventListener(false),
mClearingListeners(false),
mIsMainThreadELM(NS_IsMainThread()),
mHasNonPrivilegedClickListeners(false),
@ -461,6 +462,16 @@ void EventListenerManager::AddEventListenerInternal(
}
}
break;
case eTransitionStart:
case eTransitionRun:
case eTransitionEnd:
case eTransitionCancel:
case eWebkitTransitionEnd:
mMayHaveTransitionEventListener = true;
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
window->SetHasTransitionEventListeners();
}
break;
default:
// XXX Use NS_ASSERTION here to print resolvedEventMessage since
// MOZ_ASSERT can take only string literal, not pointer to

View File

@ -157,11 +157,11 @@ class EventListenerManagerBase {
uint16_t mMayHaveInputOrCompositionEventListener : 1;
uint16_t mMayHaveSelectionChangeEventListener : 1;
uint16_t mMayHaveFormSelectEventListener : 1;
uint16_t mMayHaveTransitionEventListener : 1;
uint16_t mClearingListeners : 1;
uint16_t mIsMainThreadELM : 1;
uint16_t mHasNonPrivilegedClickListeners : 1;
uint16_t mUnknownNonPrivilegedClickListeners : 1;
// uint16_t mUnused : 1;
};
/*
@ -490,6 +490,9 @@ class EventListenerManager final : public EventListenerManagerBase {
bool MayHaveFormSelectEventListener() const {
return mMayHaveFormSelectEventListener;
}
bool MayHaveTransitionEventListener() {
return mMayHaveTransitionEventListener;
}
bool HasNonPrivilegedClickListeners();