--- a/dom/animation/ScrollTimeline.cpp
+++ b/dom/animation/ScrollTimeline.cpp
@@ -90,32 +90,68 @@ ScrollTimeline::ToTimelineTime(const Tim
// memo: This function is member function of AnimationTimeline.
void
ScrollTimeline::NotifyAnimationUpdated(Animation& aAnimation)
{
// MEMO: Should I pause animation when setting animation?
AnimationTimeline::NotifyAnimationUpdated(aAnimation);
CalculateTimeRange();
+}
- if (!mIsObservingRefreshDriver) {
- nsRefreshDriver* refreshDriver = GetRefreshDriver();
- if (refreshDriver) {
- refreshDriver->AddRefreshObserver(this, Flush_Style);
- mIsObservingRefreshDriver = true;
+void
+ScrollTimeline::RemoveAnimation(Animation* aAnimation)
+{
+ AnimationTimeline::RemoveAnimation(aAnimation);
+ CalculateTimeRange();
+}
+
+TimeStamp
+ScrollTimeline::ToTimeStamp(const TimeDuration& aTimeDuration) const
+{
+ TimeStamp result;
+ RefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
+ if (MOZ_UNLIKELY(!timing)) {
+ return result;
+ }
+
+ result =
+ timing->GetNavigationStartTimeStamp() + aTimeDuration;
+ return result;
+}
+
+void
+ScrollTimeline::CalculateTimeRange()
+{
+ mTimeRange = 0;
+ for (Animation* animation : mAnimationOrder) {
+ StickyTimeDuration endTime = animation->EffectEnd();
+ mTimeRange = StickyTimeDuration::Max(endTime, mTimeRange);
+ }
+}
+
+void
+ScrollTimeline::QueryScrollValues()
+{
+ if (mElement) {
+ if (mOrientation == Orientation::Horizontal) {
+ mCurrentScroll = mElement->ScrollLeft();
+ mMinScroll = mElement->ScrollLeftMin();
+ mMaxScroll = mElement->ScrollLeftMax();
+ } else {
+ mCurrentScroll = mElement->ScrollTop();
+ mMinScroll = mElement->ScrollTopMin();
+ mMaxScroll = mElement->ScrollTopMax();
}
}
}
void
-ScrollTimeline::WillRefresh(mozilla::TimeStamp aTime)
-{
- MOZ_ASSERT(mIsObservingRefreshDriver);
- MOZ_ASSERT(GetRefreshDriver(),
- "Should be able to reach refresh driver from within WillRefresh");
+ScrollTimeline::Tick() {
+ QueryScrollValues();
bool needsTicks = false;
nsTArray<Animation*> animationsToRemove(mAnimations.Count());
nsAutoAnimationMutationBatch mb(mDocument);
for (Animation* animation = mAnimationOrder.getFirst(); animation;
animation = animation->getNext()) {
@@ -138,125 +174,18 @@ ScrollTimeline::WillRefresh(mozilla::Tim
if (!animation->IsRelevant() && !animation->NeedsTicks()) {
animationsToRemove.AppendElement(animation);
}
}
for (Animation* animation : animationsToRemove) {
RemoveAnimation(animation);
}
-
- if (!needsTicks) {
- // We already assert that GetRefreshDriver() is non-null at the beginning
- // of this function but we check it again here to be sure that ticking
- // animations does not have any side effects that cause us to lose the
- // connection with the refresh driver, such as triggering the destruction
- // of mDocument's PresShell.
- MOZ_ASSERT(GetRefreshDriver(),
- "Refresh driver should still be valid at end of WillRefresh");
- GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
- mIsObservingRefreshDriver = false;
- }
-}
-
-void
-ScrollTimeline::NotifyRefreshDriverCreated(nsRefreshDriver* aDriver)
-{
- MOZ_ASSERT(!mIsObservingRefreshDriver,
- "Timeline should not be observing the refresh driver before"
- " it is created");
-
- if (!mAnimationOrder.isEmpty()) {
- aDriver->AddRefreshObserver(this, Flush_Style);
- mIsObservingRefreshDriver = true;
- }
-}
-
-void
-ScrollTimeline::NotifyRefreshDriverDestroying(nsRefreshDriver* aDriver)
-{
- if (!mIsObservingRefreshDriver) {
- return;
- }
-
- aDriver->RemoveRefreshObserver(this, Flush_Style);
- mIsObservingRefreshDriver = false;
-}
-
-void
-ScrollTimeline::RemoveAnimation(Animation* aAnimation)
-{
- AnimationTimeline::RemoveAnimation(aAnimation);
- CalculateTimeRange();
-
- if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) {
- MOZ_ASSERT(GetRefreshDriver(),
- "Refresh driver should still be valid when "
- "mIsObservingRefreshDriver is true");
- GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
- mIsObservingRefreshDriver = false;
- }
-}
-
-TimeStamp
-ScrollTimeline::ToTimeStamp(const TimeDuration& aTimeDuration) const
-{
- TimeStamp result;
- RefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
- if (MOZ_UNLIKELY(!timing)) {
- return result;
- }
-
- result =
- timing->GetNavigationStartTimeStamp() + aTimeDuration;
- return result;
-}
-
-nsRefreshDriver*
-ScrollTimeline::GetRefreshDriver() const
-{
- nsIPresShell* presShell = mDocument->GetShell();
- if (MOZ_UNLIKELY(!presShell)) {
- return nullptr;
- }
-
- nsPresContext* presContext = presShell->GetPresContext();
- if (MOZ_UNLIKELY(!presContext)) {
- return nullptr;
- }
-
- return presContext->RefreshDriver();
-}
-
-void
-ScrollTimeline::CalculateTimeRange()
-{
- mTimeRange = 0;
- for (Animation* animation : mAnimationOrder) {
- StickyTimeDuration endTime = animation->EffectEnd();
- mTimeRange = StickyTimeDuration::Max(endTime, mTimeRange);
- }
-}
-
-void
-ScrollTimeline::SetScrollValues()
-{
- if (mElement) {
- if (mOrientation == Orientation::Horizontal) {
- mCurrentScroll = mElement->ScrollLeft();
- mMinScroll = mElement->ScrollLeftMin();
- mMaxScroll = mElement->ScrollLeftMax();
- } else {
- mCurrentScroll = mElement->ScrollTop();
- mMinScroll = mElement->ScrollTopMin();
- mMaxScroll = mElement->ScrollTopMax();
- }
- }
}
void
ScrollObserverImpl::notify()
{
- mTimeline->SetScrollValues();
+ mTimeline->Tick();
}
} // namespace dom
} // namespace mozilla
--- a/dom/animation/ScrollTimeline.h
+++ b/dom/animation/ScrollTimeline.h
@@ -31,43 +31,39 @@ public:
void notify() override;
private:
ScrollTimeline* mTimeline;
};
class ScrollTimeline final
: public AnimationTimeline
- , public nsARefreshObserver
{
public:
ScrollTimeline(nsIDocument* aDocument,
Element* aTarget,
Orientation aOrientation,
const Optional<double>& maxTime)
: AnimationTimeline(aDocument->GetParentObject())
, mDocument(aDocument)
- , mIsObservingRefreshDriver(false)
, mOrientation(aOrientation)
, mElement(aTarget)
, mCurrentScroll(0)
, mMinScroll(0)
, mMaxScroll(0)
{
mScrollObserver = new ScrollObserverImpl(this);
aTarget->RegistScrollTimelineObserver(mScrollObserver);
CalculateTimeRange();
- SetScrollValues();
+ QueryScrollValues();
}
protected:
virtual ~ScrollTimeline()
{
- MOZ_ASSERT(!mIsObservingRefreshDriver, "Timeline should have disassociated"
- " from the refresh driver before being destroyed");
if (mScrollObserver) {
mElement.get()->UnregistScrollTimelineObserver();
}
}
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ScrollTimeline,
@@ -82,51 +78,36 @@ public:
const Orientation orientation,
const Optional<double>& maxTime,
ErrorResult& aRv);
virtual Nullable<TimeDuration> GetCurrentTime() const override;
bool TracksWallclockTime() const override
{
- nsRefreshDriver* refreshDriver = GetRefreshDriver();
- return !refreshDriver ||
- !refreshDriver->IsTestControllingRefreshesEnabled();
+ return true;
}
Nullable<TimeDuration> ToTimelineTime(const TimeStamp& aTimeStamp) const
override;
TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const override;
void NotifyAnimationUpdated(Animation& aAnimation) override;
void RemoveAnimation(Animation* aAnimation) override;
- // nsARefreshObserver methods
- void WillRefresh(TimeStamp aTime) override;
-
- void NotifyRefreshDriverCreated(nsRefreshDriver* aDriver);
- void NotifyRefreshDriverDestroying(nsRefreshDriver* aDriver);
-
- void SetScrollValues();
+ void Tick();
+ void QueryScrollValues();
bool SupportsOMTA() const override { return false; }
protected:
- nsRefreshDriver* GetRefreshDriver() const;
void CalculateTimeRange();
nsCOMPtr<nsIDocument> mDocument;
- // The most recently used refresh driver time. This is used in cases where
- // we don't have a refresh driver (e.g. because we are in a display:none
- // iframe).
- mutable TimeStamp mLastRefreshDriverTime;
- bool mIsObservingRefreshDriver;
-
-
Orientation mOrientation;
double mMaxTime;
ScrollObserverImpl *mScrollObserver;
RefPtr<Element> mElement;
StickyTimeDuration mTimeRange;
double mCurrentScroll, mMinScroll, mMaxScroll;
};