Skip to content

Commit

Permalink
Ignore CSS property animation-range-* after setting via web-animation…
Browse files Browse the repository at this point in the history
… API

Bug: 1424538
Change-Id: I47f11a5211a1938df792313c6d4c1435e7e64d63
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4365741
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1122396}
  • Loading branch information
kevers-google authored and Chromium LUCI CQ committed Mar 27, 2023
1 parent edda9d4 commit 4d756ff
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 32 deletions.
7 changes: 7 additions & 0 deletions third_party/blink/renderer/core/animation/animation.cc
Expand Up @@ -2300,6 +2300,13 @@ void Animation::OnRangeUpdate() {
if (start_time_) {
UpdateStartTimeForViewTimeline();
}

UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);

SetCompositorPending(false);

// Inform devtools of a potential change to the play state.
NotifyProbe();
}

void Animation::CancelAnimationOnCompositor() {
Expand Down
21 changes: 13 additions & 8 deletions third_party/blink/renderer/core/animation/animation.h
Expand Up @@ -208,10 +208,10 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
using RangeBoundary = V8UnionStringOrTimelineRangeOffset;
const RangeBoundary* rangeStart();
const RangeBoundary* rangeEnd();
void setRangeStart(const RangeBoundary* range_start,
ExceptionState& exception_state);
void setRangeEnd(const RangeBoundary* range_end,
ExceptionState& exception_state);
virtual void setRangeStart(const RangeBoundary* range_start,
ExceptionState& exception_state);
virtual void setRangeEnd(const RangeBoundary* range_end,
ExceptionState& exception_state);

const absl::optional<TimelineOffset>& GetRangeStartInternal() const {
return range_start_;
Expand All @@ -221,12 +221,17 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
}
void SetRangeStartInternal(
const absl::optional<TimelineOffset>& range_start) {
range_start_ = range_start;
OnRangeUpdate();
const TimelineOffset default_timeline_offset;
if (range_start_ != range_start) {
range_start_ = range_start;
OnRangeUpdate();
}
}
void SetRangeEndInternal(const absl::optional<TimelineOffset>& range_end) {
range_end_ = range_end;
OnRangeUpdate();
if (range_end_ != range_end) {
range_end_ = range_end;
OnRangeUpdate();
}
}

void OnRangeUpdate();
Expand Down
16 changes: 13 additions & 3 deletions third_party/blink/renderer/core/animation/css/css_animation.cc
Expand Up @@ -17,9 +17,7 @@ CSSAnimation::CSSAnimation(ExecutionContext* execution_context,
const String& animation_name)
: Animation(execution_context, timeline, content),
animation_index_(animation_index),
animation_name_(animation_name),
ignore_css_play_state_(false),
ignore_css_timeline_(false) {
animation_name_(animation_name) {
// The owning_element does not always equal to the target element of an
// animation. The following spec gives an example:
// https://drafts.csswg.org/css-animations-2/#owning-element-section
Expand Down Expand Up @@ -60,6 +58,18 @@ void CSSAnimation::setTimeline(AnimationTimeline* timeline) {
ignore_css_timeline_ = true;
}

void CSSAnimation::setRangeStart(const RangeBoundary* range_start,
ExceptionState& exception_state) {
Animation::setRangeStart(range_start, exception_state);
ignore_css_range_start_ = true;
}

void CSSAnimation::setRangeEnd(const RangeBoundary* range_end,
ExceptionState& exception_state) {
Animation::setRangeEnd(range_end, exception_state);
ignore_css_range_end_ = true;
}

void CSSAnimation::setStartTime(const V8CSSNumberish* start_time,
ExceptionState& exception_state) {
PlayStateTransitionScope scope(*this);
Expand Down
25 changes: 19 additions & 6 deletions third_party/blink/renderer/core/animation/css/css_animation.h
Expand Up @@ -53,14 +53,23 @@ class CORE_EXPORT CSSAnimation : public Animation {
void setTimeline(AnimationTimeline*) override;
void setStartTime(const V8CSSNumberish* start_time,
ExceptionState& exception_state) override;
void setRangeStart(const RangeBoundary* range_start,
ExceptionState& exception_state) override;
void setRangeEnd(const RangeBoundary* range_end,
ExceptionState& exception_state) override;

// When set, subsequent changes to animation-play-state no longer affect the
// play state.
// When set, subsequent changes to animation-<property> no longer affect
// <property>.
// https://drafts.csswg.org/css-animations-2/#interaction-between-animation-play-state-and-web-animations-API
bool getIgnoreCSSPlayState() { return ignore_css_play_state_; }
void resetIgnoreCSSPlayState() { ignore_css_play_state_ = false; }
bool GetIgnoreCSSPlayState() { return ignore_css_play_state_; }
void ResetIgnoreCSSPlayState() { ignore_css_play_state_ = false; }
bool GetIgnoreCSSTimeline() const { return ignore_css_timeline_; }
void ResetIgnoreCSSTimeline() { ignore_css_timeline_ = false; }
bool GetIgnoreCSSRangeStart() { return ignore_css_range_start_; }
void ResetIgnoreCSSRangeStart() { ignore_css_range_start_ = false; }
bool GetIgnoreCSSRangeEnd() { return ignore_css_range_end_; }
void ResetIgnoreCSSRangeEnd() { ignore_css_range_end_ = false; }

void Trace(blink::Visitor* visitor) const override {
Animation::Trace(visitor);
visitor->Trace(owning_element_);
Expand Down Expand Up @@ -99,9 +108,13 @@ class CORE_EXPORT CSSAnimation : public Animation {

// When set, the web-animation API is overruling the animation-play-state
// style.
bool ignore_css_play_state_;
bool ignore_css_play_state_ = false;
// When set, changes to the 'animation-timeline' property will be ignored.
bool ignore_css_timeline_;
bool ignore_css_timeline_ = false;
// When set changes to 'animation-range-*' will be ignored.
bool ignore_css_range_start_ = false;
bool ignore_css_range_end_ = false;

// The owning element of an animation refers to the element or pseudo-element
// whose animation-name property was applied that generated the animation
// The spec: https://drafts.csswg.org/css-animations-2/#owning-element-section
Expand Down
Expand Up @@ -40,6 +40,8 @@ bool CSSAnimationData::AnimationsMatchForStyleRecalc(
iteration_count_list_ == other.iteration_count_list_ &&
direction_list_ == other.direction_list_ &&
fill_mode_list_ == other.fill_mode_list_ &&
range_start_list_ == other.range_start_list_ &&
range_end_list_ == other.range_end_list_ &&
TimingMatchForStyleRecalc(other);
}

Expand Down
42 changes: 27 additions & 15 deletions third_party/blink/renderer/core/animation/css/css_animations.cc
Expand Up @@ -1196,7 +1196,7 @@ void CSSAnimations::CalculateAnimationUpdate(
bool will_be_playing = false;
const Animation::AnimationPlayState play_state =
animation->CalculateAnimationPlayState();
if (is_paused != was_paused && !animation->getIgnoreCSSPlayState()) {
if (is_paused != was_paused && !animation->GetIgnoreCSSPlayState()) {
switch (play_state) {
case Animation::kIdle:
break;
Expand Down Expand Up @@ -1227,14 +1227,18 @@ void CSSAnimations::CalculateAnimationUpdate(
existing_animation->Timeline());
}

bool range_changed =
((range_start != existing_animation->RangeStart()) &&
!animation->GetIgnoreCSSRangeStart()) ||
((range_end != existing_animation->RangeEnd()) &&
!animation->GetIgnoreCSSRangeEnd());

if (keyframes_rule != existing_animation->style_rule ||
keyframes_rule->Version() !=
existing_animation->style_rule_version ||
existing_animation->specified_timing != specified_timing ||
is_paused != was_paused || logical_property_mapping_change ||
timeline != existing_animation->Timeline() ||
range_start != existing_animation->RangeStart() ||
range_end != existing_animation->RangeEnd()) {
timeline != existing_animation->Timeline() || range_changed) {
DCHECK(!is_animation_style_change);
absl::optional<AnimationTimeDelta> inherited_time;
absl::optional<AnimationTimeDelta> timeline_duration;
Expand Down Expand Up @@ -1578,10 +1582,10 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {

if (animation->Paused()) {
animation->Unpause();
animation->resetIgnoreCSSPlayState();
animation->ResetIgnoreCSSPlayState();
} else {
animation->pause();
animation->resetIgnoreCSSPlayState();
animation->ResetIgnoreCSSPlayState();
}
if (animation->Outdated())
animation->Update(kTimingUpdateOnDemand);
Expand All @@ -1597,15 +1601,20 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
effect->SetModel(entry.effect->Model());
effect->UpdateSpecifiedTiming(entry.effect->SpecifiedTiming());
}
if (entry.animation->timeline() != entry.timeline) {
entry.animation->setTimeline(entry.timeline);
To<CSSAnimation>(*entry.animation).ResetIgnoreCSSTimeline();
CSSAnimation& css_animation = To<CSSAnimation>(*entry.animation);
if (css_animation.timeline() != entry.timeline) {
css_animation.setTimeline(entry.timeline);
css_animation.ResetIgnoreCSSTimeline();
}
if (entry.animation->GetRangeStartInternal() != entry.range_start) {
entry.animation->SetRangeStartInternal(entry.range_start);
if (!css_animation.GetIgnoreCSSRangeStart() &&
css_animation.GetRangeStartInternal() != entry.range_start) {
css_animation.SetRangeStartInternal(entry.range_start);
css_animation.ResetIgnoreCSSRangeStart();
}
if (entry.animation->GetRangeEndInternal() != entry.range_end) {
entry.animation->SetRangeEndInternal(entry.range_end);
if (!css_animation.GetIgnoreCSSRangeEnd() &&
css_animation.GetRangeEndInternal() != entry.range_end) {
css_animation.SetRangeEndInternal(entry.range_end);
css_animation.ResetIgnoreCSSRangeEnd();
}

running_animations_[entry.index]->Update(entry);
Expand All @@ -1621,8 +1630,9 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
*running_animations_[cancelled_indices[i]]->animation;
animation.ClearOwningElement();
if (animation.IsCSSAnimation() &&
!DynamicTo<CSSAnimation>(animation)->getIgnoreCSSPlayState())
!DynamicTo<CSSAnimation>(animation)->GetIgnoreCSSPlayState()) {
animation.cancel();
}
animation.Update(kTimingUpdateOnDemand);
running_animations_.EraseAt(cancelled_indices[i]);
}
Expand All @@ -1640,9 +1650,11 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
animation->play();
if (inert_animation->Paused())
animation->pause();
animation->resetIgnoreCSSPlayState();
animation->ResetIgnoreCSSPlayState();
animation->SetRangeStartInternal(entry.range_start);
animation->SetRangeEndInternal(entry.range_end);
animation->ResetIgnoreCSSRangeStart();
animation->ResetIgnoreCSSRangeEnd();
animation->Update(kTimingUpdateOnDemand);

running_animations_.push_back(
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/animation/view_timeline.cc
Expand Up @@ -269,6 +269,7 @@ AnimationTimeDelta ViewTimeline::CalculateIntrinsicIterationDuration(

active_interval -= start;
active_interval -= (1 - end);
active_interval = std::max(0., active_interval);

// Start and end delays are proportional to the active interval.
double start_delay = timing.start_delay.relative_delay.value_or(0);
Expand Down

0 comments on commit 4d756ff

Please sign in to comment.