1 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "AnimationTimeline.h"
7 #include "mozilla/dom/AnimationTimelineBinding.h"
8 #include "AnimationUtils.h"
9 #include "nsContentUtils.h"
10 #include "nsIPresShell.h"
11 #include "nsPresContext.h"
12 #include "nsRefreshDriver.h"
13 #include "nsDOMNavigationTiming.h"
18 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline
, mDocument
)
20 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationTimeline
, AddRef
)
21 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationTimeline
, Release
)
24 AnimationTimeline::WrapObject(JSContext
* aCx
)
26 return AnimationTimelineBinding::Wrap(aCx
, this);
29 Nullable
<TimeDuration
>
30 AnimationTimeline::GetCurrentTime() const
32 return ToTimelineTime(GetCurrentTimeStamp());
36 AnimationTimeline::GetCurrentTimeAsDouble() const
38 return AnimationUtils::TimeDurationToDouble(GetCurrentTime());
42 AnimationTimeline::GetCurrentTimeStamp() const
44 nsRefreshDriver
* refreshDriver
= GetRefreshDriver();
45 TimeStamp refreshTime
= refreshDriver
46 ? refreshDriver
->MostRecentRefresh()
49 // Always return the same object to benefit from return-value optimization.
50 TimeStamp result
= !refreshTime
.IsNull()
52 : mLastRefreshDriverTime
;
54 // If we don't have a refresh driver and we've never had one use the
55 // timeline's zero time.
56 if (result
.IsNull()) {
57 nsRefPtr
<nsDOMNavigationTiming
> timing
= mDocument
->GetNavigationTiming();
59 result
= timing
->GetNavigationStartTimeStamp();
60 // Also, let this time represent the current refresh time. This way
61 // we'll save it as the last refresh time and skip looking up
62 // navigation timing each time.
67 if (!refreshTime
.IsNull()) {
68 mLastRefreshDriverTime
= refreshTime
;
74 Nullable
<TimeDuration
>
75 AnimationTimeline::ToTimelineTime(const TimeStamp
& aTimeStamp
) const
77 Nullable
<TimeDuration
> result
; // Initializes to null
78 if (aTimeStamp
.IsNull()) {
82 nsRefPtr
<nsDOMNavigationTiming
> timing
= mDocument
->GetNavigationTiming();
83 if (MOZ_UNLIKELY(!timing
)) {
87 result
.SetValue(aTimeStamp
- timing
->GetNavigationStartTimeStamp());
92 AnimationTimeline::ToTimeStamp(const TimeDuration
& aTimeDuration
) const
95 nsRefPtr
<nsDOMNavigationTiming
> timing
= mDocument
->GetNavigationTiming();
96 if (MOZ_UNLIKELY(!timing
)) {
100 result
= timing
->GetNavigationStartTimeStamp() + aTimeDuration
;
105 AnimationTimeline::GetRefreshDriver() const
107 nsIPresShell
* presShell
= mDocument
->GetShell();
108 if (MOZ_UNLIKELY(!presShell
)) {
112 nsPresContext
* presContext
= presShell
->GetPresContext();
113 if (MOZ_UNLIKELY(!presContext
)) {
117 return presContext
->RefreshDriver();
121 } // namespace mozilla