mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
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.
This commit is contained in:
parent
c7d7b28ccf
commit
fb9a1a8fb3
@ -5,7 +5,6 @@
|
||||
|
||||
#include "AnimationTimeline.h"
|
||||
#include "mozilla/dom/AnimationTimelineBinding.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
@ -36,7 +35,18 @@ TimeStamp
|
||||
AnimationTimeline::GetCurrentTimeStamp() const
|
||||
{
|
||||
// Always return the same object to benefit from return-value optimization.
|
||||
TimeStamp result; // Initializes to null timestamp
|
||||
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)) {
|
||||
@ -49,6 +59,11 @@ AnimationTimeline::GetCurrentTimeStamp() const
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,13 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
struct JSContext;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class TimeStamp;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class AnimationTimeline MOZ_FINAL : public nsWrapperCache
|
||||
@ -44,6 +42,11 @@ protected:
|
||||
virtual ~AnimationTimeline() { }
|
||||
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
// Store the most recently returned value of current 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 mozilla::TimeStamp mLastCurrentTime;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -7,6 +7,7 @@
|
||||
<script src="/resources/idlharness.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe src="data:text/html;charset=utf-8," width="10" height="10" id="iframe"></iframe>
|
||||
<iframe src="data:text/html;charset=utf-8,%3Chtml%20style%3D%22display%3Anone%22%3E%3C%2Fhtml%3E" width="10" height="10" id="hidden-iframe"></iframe>
|
||||
<script type="text/plain" id="AnimationTimeline-IDL">
|
||||
interface AnimationTimeline {
|
||||
readonly attribute double? currentTime;
|
||||
@ -102,4 +103,50 @@ async_test(function(t) {
|
||||
author: 'Brian Birtles'
|
||||
});
|
||||
|
||||
test(function() {
|
||||
var hiddenIFrame = document.getElementById('hidden-iframe');
|
||||
assert_equals(typeof hiddenIFrame.contentDocument.timeline.currentTime,
|
||||
'number',
|
||||
'currentTime of an initially hidden subframe\'s timeline is a number');
|
||||
assert_true(hiddenIFrame.contentDocument.timeline.currentTime >= 0,
|
||||
'currentTime of an initially hidden subframe\'s timeline is >= 0');
|
||||
}, 'document.timeline.currentTime hidden subframe test');
|
||||
|
||||
async_test(function(t) {
|
||||
var hiddenIFrame = document.getElementById('hidden-iframe');
|
||||
|
||||
// Don't run the test until after the iframe has completed loading or else the
|
||||
// contentDocument may change.
|
||||
var testToRunOnLoad = t.step_func(function() {
|
||||
// Remove display:none
|
||||
hiddenIFrame.style.display = 'block';
|
||||
window.getComputedStyle(hiddenIFrame).display;
|
||||
|
||||
window.requestAnimationFrame(t.step_func(function() {
|
||||
assert_true(hiddenIFrame.contentDocument.timeline.currentTime > 0,
|
||||
'document.timeline.currentTime is positive after removing'
|
||||
+ ' display:none');
|
||||
var previousValue = hiddenIFrame.contentDocument.timeline.currentTime;
|
||||
|
||||
// Re-introduce display:none
|
||||
hiddenIFrame.style.display = 'none';
|
||||
window.getComputedStyle(hiddenIFrame).display;
|
||||
|
||||
window.requestAnimationFrame(t.step_func(function() {
|
||||
assert_true(
|
||||
hiddenIFrame.contentDocument.timeline.currentTime >= previousValue,
|
||||
'document.timeline.currentTime does not go backwards after'
|
||||
+ ' re-setting display:none');
|
||||
t.done();
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
||||
if (hiddenIFrame.contentDocument.readyState === 'complete') {
|
||||
testToRunOnLoad();
|
||||
} else {
|
||||
hiddenIFrame.addEventListener("load", testToRunOnLoad);
|
||||
}
|
||||
}, 'document.timeline.currentTime hidden subframe dynamic test');
|
||||
|
||||
</script>
|
||||
|
@ -435,8 +435,8 @@ ElementAnimation::CurrentTime() const
|
||||
// (but not AnimationPlayers) is always 0, these are currently identical.
|
||||
Nullable<TimeDuration> currentTime = GetLocalTime();
|
||||
|
||||
// The current time is currently only going to be null when don't have a
|
||||
// refresh driver (e.g. because we are in a display:none iframe).
|
||||
// The current time is only going to be null when we don't have a refresh
|
||||
// driver or navigation timing object and never did.
|
||||
//
|
||||
// Web Animations says that in this case we should use a timeline time of
|
||||
// 0 (the "effective timeline time") and calculate the current time from that.
|
||||
|
Loading…
Reference in New Issue
Block a user