forked from mirrors/gecko-dev
Bug 1890002 - Don't create DOM event for those animation events which don't need to be dispatched, r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D206819
This commit is contained in:
parent
d068628cec
commit
672dda40c9
4 changed files with 46 additions and 26 deletions
|
|
@ -10,7 +10,6 @@
|
||||||
#include "AnimationUtils.h"
|
#include "AnimationUtils.h"
|
||||||
#include "mozAutoDocUpdate.h"
|
#include "mozAutoDocUpdate.h"
|
||||||
#include "mozilla/dom/AnimationBinding.h"
|
#include "mozilla/dom/AnimationBinding.h"
|
||||||
#include "mozilla/dom/AnimationPlaybackEvent.h"
|
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/DocumentInlines.h"
|
#include "mozilla/dom/DocumentInlines.h"
|
||||||
#include "mozilla/dom/DocumentTimeline.h"
|
#include "mozilla/dom/DocumentTimeline.h"
|
||||||
|
|
@ -644,7 +643,8 @@ void Animation::Cancel(PostRestyleMode aPostRestyle) {
|
||||||
}
|
}
|
||||||
ResetFinishedPromise();
|
ResetFinishedPromise();
|
||||||
|
|
||||||
QueuePlaybackEvent(u"cancel"_ns, GetTimelineCurrentTimeAsTimeStamp());
|
QueuePlaybackEvent(nsGkAtoms::oncancel,
|
||||||
|
GetTimelineCurrentTimeAsTimeStamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
StickyTimeDuration activeTime =
|
StickyTimeDuration activeTime =
|
||||||
|
|
@ -1187,7 +1187,7 @@ void Animation::Remove() {
|
||||||
UpdateEffect(PostRestyleMode::IfNeeded);
|
UpdateEffect(PostRestyleMode::IfNeeded);
|
||||||
PostUpdate();
|
PostUpdate();
|
||||||
|
|
||||||
QueuePlaybackEvent(u"remove"_ns, GetTimelineCurrentTimeAsTimeStamp());
|
QueuePlaybackEvent(nsGkAtoms::onremove, GetTimelineCurrentTimeAsTimeStamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::HasLowerCompositeOrderThan(const Animation& aOther) const {
|
bool Animation::HasLowerCompositeOrderThan(const Animation& aOther) const {
|
||||||
|
|
@ -1866,10 +1866,11 @@ void Animation::DoFinishNotificationImmediately(MicroTaskRunnable* aAsync) {
|
||||||
|
|
||||||
MaybeResolveFinishedPromise();
|
MaybeResolveFinishedPromise();
|
||||||
|
|
||||||
QueuePlaybackEvent(u"finish"_ns, AnimationTimeToTimeStamp(EffectEnd()));
|
QueuePlaybackEvent(nsGkAtoms::onfinish,
|
||||||
|
AnimationTimeToTimeStamp(EffectEnd()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::QueuePlaybackEvent(const nsAString& aName,
|
void Animation::QueuePlaybackEvent(nsAtom* aOnEvent,
|
||||||
TimeStamp&& aScheduledEventTime) {
|
TimeStamp&& aScheduledEventTime) {
|
||||||
// Use document for timing.
|
// Use document for timing.
|
||||||
// https://drafts.csswg.org/web-animations-1/#document-for-timing
|
// https://drafts.csswg.org/web-animations-1/#document-for-timing
|
||||||
|
|
@ -1883,20 +1884,19 @@ void Animation::QueuePlaybackEvent(const nsAString& aName,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationPlaybackEventInit init;
|
Nullable<double> currentTime;
|
||||||
if (aName.EqualsLiteral("finish") || aName.EqualsLiteral("remove")) {
|
if (aOnEvent == nsGkAtoms::onfinish || aOnEvent == nsGkAtoms::onremove) {
|
||||||
init.mCurrentTime = GetCurrentTimeAsDouble();
|
currentTime = GetCurrentTimeAsDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Nullable<double> timelineTime;
|
||||||
if (mTimeline) {
|
if (mTimeline) {
|
||||||
init.mTimelineTime = mTimeline->GetCurrentTimeAsDouble();
|
timelineTime = mTimeline->GetCurrentTimeAsDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<AnimationPlaybackEvent> event =
|
presContext->AnimationEventDispatcher()->QueueEvent(
|
||||||
AnimationPlaybackEvent::Constructor(this, aName, init);
|
AnimationEventInfo(aOnEvent, currentTime, timelineTime,
|
||||||
event->SetTrusted(true);
|
std::move(aScheduledEventTime), this));
|
||||||
|
|
||||||
presContext->AnimationEventDispatcher()->QueueEvent(AnimationEventInfo(
|
|
||||||
std::move(event), std::move(aScheduledEventTime), this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::IsRunningOnCompositor() const {
|
bool Animation::IsRunningOnCompositor() const {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ struct JSContext;
|
||||||
class nsCSSPropertyIDSet;
|
class nsCSSPropertyIDSet;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsIGlobalObject;
|
class nsIGlobalObject;
|
||||||
|
class nsAtom;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
|
@ -449,8 +450,7 @@ class Animation : public DOMEventTargetHelper,
|
||||||
void DoFinishNotification(SyncNotifyFlag aSyncNotifyFlag);
|
void DoFinishNotification(SyncNotifyFlag aSyncNotifyFlag);
|
||||||
friend class AsyncFinishNotification;
|
friend class AsyncFinishNotification;
|
||||||
void DoFinishNotificationImmediately(MicroTaskRunnable* aAsync = nullptr);
|
void DoFinishNotificationImmediately(MicroTaskRunnable* aAsync = nullptr);
|
||||||
void QueuePlaybackEvent(const nsAString& aName,
|
void QueuePlaybackEvent(nsAtom* aOnEvent, TimeStamp&& aScheduledEventTime);
|
||||||
TimeStamp&& aScheduledEventTime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove this animation from the pending animation tracker and reset
|
* Remove this animation from the pending animation tracker and reset
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationEventDispatcher)
|
||||||
ImplCycleCollectionTraverse(
|
ImplCycleCollectionTraverse(
|
||||||
cb, target->mElement,
|
cb, target->mElement,
|
||||||
"mozilla::AnimationEventDispatcher.mPendingEvents.mTarget");
|
"mozilla::AnimationEventDispatcher.mPendingEvents.mTarget");
|
||||||
} else {
|
|
||||||
ImplCycleCollectionTraverse(
|
|
||||||
cb, info.mData.as<AnimationEventInfo::WebAnimationData>().mEvent,
|
|
||||||
"mozilla::AnimationEventDispatcher.mPendingEvents.mEvent");
|
|
||||||
}
|
}
|
||||||
ImplCycleCollectionTraverse(
|
ImplCycleCollectionTraverse(
|
||||||
cb, info.mAnimation,
|
cb, info.mAnimation,
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/ContentEvents.h"
|
#include "mozilla/ContentEvents.h"
|
||||||
#include "mozilla/EventDispatcher.h"
|
#include "mozilla/EventDispatcher.h"
|
||||||
|
#include "mozilla/EventListenerManager.h"
|
||||||
#include "mozilla/Variant.h"
|
#include "mozilla/Variant.h"
|
||||||
#include "mozilla/dom/AnimationPlaybackEvent.h"
|
#include "mozilla/dom/AnimationPlaybackEvent.h"
|
||||||
#include "mozilla/dom/KeyframeEffect.h"
|
#include "mozilla/dom/KeyframeEffect.h"
|
||||||
|
|
@ -44,7 +45,10 @@ struct AnimationEventInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WebAnimationData {
|
struct WebAnimationData {
|
||||||
RefPtr<dom::AnimationPlaybackEvent> mEvent;
|
const RefPtr<nsAtom> mOnEvent;
|
||||||
|
const dom::Nullable<double> mCurrentTime;
|
||||||
|
const dom::Nullable<double> mTimelineTime;
|
||||||
|
const TimeStamp mEventEnqueueTimeStamp{TimeStamp::Now()};
|
||||||
};
|
};
|
||||||
|
|
||||||
using Data = Variant<CssAnimationData, CssTransitionData, WebAnimationData>;
|
using Data = Variant<CssAnimationData, CssTransitionData, WebAnimationData>;
|
||||||
|
|
@ -100,12 +104,15 @@ struct AnimationEventInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For web animation events
|
// For web animation events
|
||||||
AnimationEventInfo(RefPtr<dom::AnimationPlaybackEvent>&& aEvent,
|
AnimationEventInfo(nsAtom* aOnEvent,
|
||||||
|
const dom::Nullable<double>& aCurrentTime,
|
||||||
|
const dom::Nullable<double>& aTimelineTime,
|
||||||
TimeStamp&& aScheduledEventTimeStamp,
|
TimeStamp&& aScheduledEventTimeStamp,
|
||||||
dom::Animation* aAnimation)
|
dom::Animation* aAnimation)
|
||||||
: mAnimation(aAnimation),
|
: mAnimation(aAnimation),
|
||||||
mScheduledEventTimeStamp(std::move(aScheduledEventTimeStamp)),
|
mScheduledEventTimeStamp(std::move(aScheduledEventTimeStamp)),
|
||||||
mData(WebAnimationData{std::move(aEvent)}) {}
|
mData(WebAnimationData{RefPtr{aOnEvent}, aCurrentTime, aTimelineTime}) {
|
||||||
|
}
|
||||||
|
|
||||||
AnimationEventInfo(const AnimationEventInfo& aOther) = delete;
|
AnimationEventInfo(const AnimationEventInfo& aOther) = delete;
|
||||||
AnimationEventInfo& operator=(const AnimationEventInfo& aOther) = delete;
|
AnimationEventInfo& operator=(const AnimationEventInfo& aOther) = delete;
|
||||||
|
|
@ -137,10 +144,27 @@ struct AnimationEventInfo {
|
||||||
// TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
|
// TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
|
||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Dispatch(nsPresContext* aPresContext) {
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Dispatch(nsPresContext* aPresContext) {
|
||||||
if (mData.is<WebAnimationData>()) {
|
if (mData.is<WebAnimationData>()) {
|
||||||
RefPtr playbackEvent = mData.as<WebAnimationData>().mEvent;
|
const auto& data = mData.as<WebAnimationData>();
|
||||||
|
EventListenerManager* elm = mAnimation->GetExistingListenerManager();
|
||||||
|
if (!elm || !elm->HasListenersFor(data.mOnEvent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dom::AnimationPlaybackEventInit init;
|
||||||
|
init.mCurrentTime = data.mCurrentTime;
|
||||||
|
init.mTimelineTime = data.mTimelineTime;
|
||||||
|
MOZ_ASSERT(nsDependentAtomString(data.mOnEvent).Find(u"on"_ns) == 0,
|
||||||
|
"mOnEvent atom should start with 'on'!");
|
||||||
|
RefPtr<dom::AnimationPlaybackEvent> event =
|
||||||
|
dom::AnimationPlaybackEvent::Constructor(
|
||||||
|
mAnimation, Substring(nsDependentAtomString(data.mOnEvent), 2),
|
||||||
|
init);
|
||||||
|
event->SetTrusted(true);
|
||||||
|
event->WidgetEventPtr()->AssignEventTime(
|
||||||
|
WidgetEventTime(data.mEventEnqueueTimeStamp));
|
||||||
RefPtr target = mAnimation;
|
RefPtr target = mAnimation;
|
||||||
EventDispatcher::DispatchDOMEvent(target, nullptr /* WidgetEvent */,
|
EventDispatcher::DispatchDOMEvent(target, nullptr /* WidgetEvent */,
|
||||||
playbackEvent, aPresContext,
|
event, aPresContext,
|
||||||
nullptr /* nsEventStatus */);
|
nullptr /* nsEventStatus */);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue