gecko/dom/animation/AnimationTimeline.cpp
Brian Birtles fa65372e57 Bug 1002332 - Make AnimationTimeline record the last refresh time and use that when there is no refresh driver; r=bz
A document that belongs to an iframe that is display:none as no associated pres
context from which to get a refresh driver. However, in this case
document.timeline.currentTime should still never go backwards (since document
timelines are supposed to be monotonically increasing).

This patch makes AnimationTimeline record the last value returned for the
current time so that if the document becomes display:none we can still return
the most recently used time.
2014-07-24 13:37:38 +09:00

89 lines
2.5 KiB
C++

/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AnimationTimeline.h"
#include "mozilla/dom/AnimationTimelineBinding.h"
#include "nsContentUtils.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsRefreshDriver.h"
#include "nsDOMNavigationTiming.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline, mDocument)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationTimeline, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationTimeline, Release)
JSObject*
AnimationTimeline::WrapObject(JSContext* aCx)
{
return AnimationTimelineBinding::Wrap(aCx, this);
}
Nullable<double>
AnimationTimeline::GetCurrentTime() const
{
return ToTimelineTime(GetCurrentTimeStamp());
}
TimeStamp
AnimationTimeline::GetCurrentTimeStamp() const
{
// Always return the same object to benefit from return-value optimization.
TimeStamp result = mLastCurrentTime;
// If we've never been sampled, initialize the current time to the timeline's
// zero time since that is the time we'll use if we don't have a refresh
// driver.
if (result.IsNull()) {
nsRefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
if (!timing) {
return result;
}
result = timing->GetNavigationStartTimeStamp();
}
nsIPresShell* presShell = mDocument->GetShell();
if (MOZ_UNLIKELY(!presShell)) {
return result;
}
nsPresContext* presContext = presShell->GetPresContext();
if (MOZ_UNLIKELY(!presContext)) {
return result;
}
result = presContext->RefreshDriver()->MostRecentRefresh();
// FIXME: We would like to assert that:
// mLastCurrentTime.IsNull() || result >= mLastCurrentTime
// but due to bug 1043078 this will not be the case when the refresh driver
// is restored from test control.
mLastCurrentTime = result;
return result;
}
Nullable<double>
AnimationTimeline::ToTimelineTime(const mozilla::TimeStamp& aTimeStamp) const
{
Nullable<double> result; // Initializes to null
if (aTimeStamp.IsNull()) {
return result;
}
nsRefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
if (MOZ_UNLIKELY(!timing)) {
return result;
}
result.SetValue(timing->TimeStampToDOMHighRes(aTimeStamp));
return result;
}
} // namespace dom
} // namespace mozilla