Commit 108ec45b authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

IsCurrent: Only return before-phase animations when they have positive playback rate

See https://drafts.csswg.org/web-animations-1/#current

Bug: 1005848
Change-Id: I95981797ced813d6a7a0e57a1b719f3bb0bd736b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1814200Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699744}
parent 97111d78
......@@ -100,10 +100,12 @@ HeapVector<Member<Animation>> Animatable::getAnimations(
element->GetDocument().Timeline().getAnimations()) {
DCHECK(animation->effect());
Element* target = ToKeyframeEffect(animation->effect())->target();
if (element == target || (use_subtree && element->contains(target))) {
if (animation->effect()->IsCurrent() || animation->effect()->IsInEffect())
animations.push_back(animation);
// DocumentTimeline::getAnimations should only give us animations that are
// either current or in effect.
DCHECK(animation->effect()->IsCurrent() ||
animation->effect()->IsInEffect());
animations.push_back(animation);
}
}
return animations;
......
......@@ -76,8 +76,11 @@ void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing,
void AnimationEffect::UpdateInheritedTime(double inherited_time,
TimingUpdateReason reason) const {
base::Optional<double> playback_rate = base::nullopt;
if (GetAnimation())
playback_rate = GetAnimation()->playbackRate();
const Timing::AnimationDirection direction =
(GetAnimation() && GetAnimation()->playbackRate() < 0)
(playback_rate && playback_rate.value() < 0)
? Timing::AnimationDirection::kBackwards
: Timing::AnimationDirection::kForwards;
bool needs_update =
......@@ -91,7 +94,7 @@ void AnimationEffect::UpdateInheritedTime(double inherited_time,
const double local_time = inherited_time;
if (needs_update) {
Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings(
local_time, direction, IsKeyframeEffect());
local_time, direction, IsKeyframeEffect(), playback_rate);
const bool was_canceled = calculated.phase != calculated_.phase &&
calculated.phase == Timing::kPhaseNone;
......
......@@ -155,7 +155,8 @@ ComputedEffectTiming* Timing::getComputedTiming(
Timing::CalculatedTiming Timing::CalculateTimings(
double local_time,
AnimationDirection animation_direction,
bool is_keyframe_effect) const {
bool is_keyframe_effect,
base::Optional<double> playback_rate) const {
const double active_duration = ActiveDuration();
const Timing::Phase current_phase =
......@@ -219,8 +220,10 @@ Timing::CalculatedTiming Timing::CalculateTimings(
DCHECK(!calculated.is_in_effect ||
(current_iteration.has_value() && progress.has_value()));
calculated.is_in_play = calculated.phase == Timing::kPhaseActive;
calculated.is_current =
calculated.phase == Timing::kPhaseBefore || calculated.is_in_play;
// https://drafts.csswg.org/web-animations-1/#current
calculated.is_current = calculated.is_in_play ||
(playback_rate.has_value() && playback_rate > 0 &&
calculated.phase == Timing::kPhaseBefore);
calculated.local_time = local_time;
calculated.time_to_next_iteration = time_to_next_iteration;
......
......@@ -150,7 +150,8 @@ struct CORE_EXPORT Timing {
CalculatedTiming CalculateTimings(double local_time,
AnimationDirection animation_direction,
bool is_keyframe_effect) const;
bool is_keyframe_effect,
base::Optional<double> playback_rate) const;
ComputedEffectTiming* getComputedTiming(const CalculatedTiming& calculated,
bool is_keyframe_effect) const;
};
......
......@@ -31,8 +31,14 @@ ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const {
last_update_time_ = local_time;
if (needs_update) {
// The playback rate is needed to calculate whether the effect is current or
// not (https://drafts.csswg.org/web-animations-1/#current). Since we only
// use this information to create a ComputedEffectTiming, which does not
// include that information, we do not need to supply one.
base::Optional<double> playback_rate = base::nullopt;
calculated_ = specified_timing_.CalculateTimings(
local_time, Timing::AnimationDirection::kForwards, false);
local_time, Timing::AnimationDirection::kForwards, false,
playback_rate);
}
return specified_timing_.getComputedTiming(calculated_,
......
......@@ -10,10 +10,10 @@ PASS Returns animations for a foreign element
PASS Does not return finished animations that do not fill forwards
PASS Returns finished animations that fill forwards
PASS Returns animations yet to reach their active phase
FAIL Does not return reversed finished animations that do not fill backwards assert_array_equals: lengths differ, expected 0 got 1
PASS Does not return reversed finished animations that do not fill backwards
PASS Returns reversed finished animations that fill backwards
FAIL Returns reversed animations yet to reach their active phase assert_array_equals: lengths differ, expected 1 got 0
FAIL Does not return animations with zero playback rate in before phase assert_array_equals: lengths differ, expected 0 got 1
PASS Does not return animations with zero playback rate in before phase
PASS Does not return animations with zero playback rate in after phase
PASS Returns animations based on dynamic changes to individual animations' duration
PASS Returns animations based on dynamic changes to individual animations' end delay
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment