diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/animation')
85 files changed, 2287 insertions, 1025 deletions
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.cc b/chromium/third_party/blink/renderer/core/animation/animatable.cc index 2db8c01030c..3cea3241785 100644 --- a/chromium/third_party/blink/renderer/core/animation/animatable.cc +++ b/chromium/third_party/blink/renderer/core/animation/animatable.cc @@ -7,6 +7,8 @@ #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_get_animations_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/document_animations.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" @@ -43,6 +45,25 @@ void ReportPermissionsPolicyViolationsIfNecessary( } } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* CoerceEffectOptions( + const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options) { + switch (options->GetContentType()) { + case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType:: + kKeyframeAnimationOptions: + return MakeGarbageCollected< + V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + options->GetAsKeyframeAnimationOptions()); + case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType:: + kUnrestrictedDouble: + return MakeGarbageCollected< + V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + options->GetAsUnrestrictedDouble()); + } + NOTREACHED(); + return nullptr; +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions( UnrestrictedDoubleOrKeyframeAnimationOptions options) { if (options.IsKeyframeAnimationOptions()) { @@ -53,6 +74,7 @@ UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions( options.GetAsUnrestrictedDouble()); } } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } // namespace @@ -60,7 +82,11 @@ UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions( Animation* Animatable::animate( ScriptState* script_state, const ScriptValue& keyframes, +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const UnrestrictedDoubleOrKeyframeAnimationOptions& options, +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ExceptionState& exception_state) { if (!script_state->ContextIsValid()) return nullptr; @@ -80,12 +106,22 @@ Animation* Animatable::animate( ReportPermissionsPolicyViolationsIfNecessary(*element->GetExecutionContext(), *effect->Model()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + if (!options->IsKeyframeAnimationOptions()) + return element->GetDocument().Timeline().Play(effect); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) if (!options.IsKeyframeAnimationOptions()) return element->GetDocument().Timeline().Play(effect); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animation; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + const KeyframeAnimationOptions* options_dict = + options->GetAsKeyframeAnimationOptions(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const KeyframeAnimationOptions* options_dict = options.GetAsKeyframeAnimationOptions(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) if (!options_dict->hasTimeline()) { animation = element->GetDocument().Timeline().Play(effect); } else if (AnimationTimeline* timeline = options_dict->timeline()) { diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.h b/chromium/third_party/blink/renderer/core/animation/animatable.h index 041953e4ea4..5ed319271f4 100644 --- a/chromium/third_party/blink/renderer/core/animation/animatable.h +++ b/chromium/third_party/blink/renderer/core/animation/animatable.h @@ -38,12 +38,13 @@ namespace blink { class Animation; -class ExceptionState; class Element; +class ExceptionState; class GetAnimationsOptions; class ScriptState; class ScriptValue; class UnrestrictedDoubleOrKeyframeAnimationOptions; +class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble; // https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin class CORE_EXPORT Animatable { @@ -52,10 +53,18 @@ class CORE_EXPORT Animatable { // called on. virtual Element* GetAnimationTarget() = 0; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + Animation* animate( + ScriptState* script_state, + const ScriptValue& keyframes, + const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, + ExceptionState& exception_state); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animate(ScriptState*, const ScriptValue&, const UnrestrictedDoubleOrKeyframeAnimationOptions&, ExceptionState&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animate(ScriptState*, const ScriptValue&, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/core/animation/animation.cc b/chromium/third_party/blink/renderer/core/animation/animation.cc index 1bc225ecea2..4efce95eeaa 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation.cc @@ -37,6 +37,8 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/animation_utils.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" @@ -78,6 +80,17 @@ namespace blink { namespace { +// Ensure the time is bounded such that it can be resolved to microsecond +// accuracy. Beyond this limit, we can effectively stall an animation when +// ticking (i.e. b + delta == b for high enough floating point value of b). +// Furthermore, we can encounter numeric overflows when converting to a +// time format that is backed by a 64-bit integer. +bool SupportedTimeValue(double time_in_ms) { + return std::abs(time_in_ms) < std::pow(std::numeric_limits<double>::radix, + std::numeric_limits<double>::digits) / + 1000; +} + enum PseudoPriority { kNone, kMarker, kBefore, kOther, kAfter }; unsigned NextSequenceNumber() { @@ -172,6 +185,19 @@ bool GreaterThanOrEqualWithinTimeTolerance(const AnimationTimeDelta& a, return a_ms > b_ms; } + +#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* CSSNumberishToV8CSSNumberish(const CSSNumberish& value) { + if (value.IsDouble()) { + return MakeGarbageCollected<V8CSSNumberish>(value.GetAsDouble()); + } else if (value.IsCSSNumericValue()) { + return MakeGarbageCollected<V8CSSNumberish>(value.GetAsCSSNumericValue()); + } + DCHECK(value.IsNull()); + return nullptr; +} +#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + } // namespace Animation* Animation::Create(AnimationEffect* effect, @@ -188,14 +214,24 @@ Animation* Animation::Create(AnimationEffect* effect, // TODO(crbug.com/1097041): Support 'auto' value. if (timeline->IsScrollTimeline()) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* time_range = To<ScrollTimeline>(timeline)->timeRange(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DoubleOrScrollTimelineAutoKeyword time_range; To<ScrollTimeline>(timeline)->timeRange(time_range); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // TODO(crbug.com/1140602): Support progress based animations // We are currently abusing the intended use of the "auto" keyword. We are // using it here as a signal to use progress based timeline instead of // having a range based current time. We are doing this maintain backwards // compatibility with existing tests. - if (time_range.IsScrollTimelineAutoKeyword()) { + if ( +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + time_range->IsScrollTimelineAutoKeyword() +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + time_range.IsScrollTimelineAutoKeyword() +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + ) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "progress based animations are not supported"); @@ -287,12 +323,11 @@ void Animation::Dispose() { } AnimationTimeDelta Animation::EffectEnd() const { - return content_ ? AnimationTimeDelta::FromSecondsD( - content_->SpecifiedTiming().EndTimeInternal()) + return content_ ? content_->SpecifiedTiming().EndTimeInternal() : AnimationTimeDelta(); } -bool Animation::Limited(base::Optional<AnimationTimeDelta> current_time) const { +bool Animation::Limited(absl::optional<AnimationTimeDelta> current_time) const { if (!current_time) return false; @@ -307,14 +342,14 @@ Document* Animation::GetDocument() const { return document_; } -base::Optional<double> Animation::TimelineTime() const { - return timeline_ ? timeline_->CurrentTimeMilliseconds() : base::nullopt; +absl::optional<double> Animation::TimelineTime() const { + return timeline_ ? timeline_->CurrentTimeMilliseconds() : absl::nullopt; } // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation. -void Animation::setCurrentTime(CSSNumberish current_time, +void Animation::setCurrentTime(const V8CSSNumberish* current_time, ExceptionState& exception_state) { - if (current_time.IsNull()) { + if (!current_time) { // If the current time is resolved, then throw a TypeError. if (CurrentTimeInternal()) { exception_state.ThrowTypeError( @@ -323,7 +358,7 @@ void Animation::setCurrentTime(CSSNumberish current_time, return; } - if (current_time.IsCSSNumericValue()) { + if (current_time->IsCSSNumericValue()) { // Throw exception for CSSNumberish that is a CSSNumericValue exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, @@ -331,10 +366,10 @@ void Animation::setCurrentTime(CSSNumberish current_time, return; } - DCHECK(current_time.IsDouble()); + DCHECK(current_time->IsDouble()); // Convert from double to AnimationTimeDelta for internal use. - base::Optional<AnimationTimeDelta> new_current_time = - AnimationTimeDelta::FromMillisecondsD(current_time.GetAsDouble()); + absl::optional<AnimationTimeDelta> new_current_time = + AnimationTimeDelta::FromMillisecondsD(current_time->GetAsDouble()); DCHECK(new_current_time); SetCurrentTimeInternal(new_current_time.value()); @@ -343,7 +378,7 @@ void Animation::setCurrentTime(CSSNumberish current_time, if (pending_pause_) { SetHoldTimeAndPhase(new_current_time, TimelinePhase::kActive); ApplyPendingPlaybackRate(); - start_time_ = base::nullopt; + start_time_ = absl::nullopt; pending_pause_ = false; if (ready_promise_) ResolvePromiseMaybeAsync(ready_promise_.Get()); @@ -358,18 +393,29 @@ void Animation::setCurrentTime(CSSNumberish current_time, NotifyProbe(); } +#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + +// https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation. +void Animation::setCurrentTime(CSSNumberish current_time, + ExceptionState& exception_state) { + // Forward to the new implementation. + setCurrentTime(CSSNumberishToV8CSSNumberish(current_time), exception_state); +} + void Animation::setCurrentTime(CSSNumberish current_time) { NonThrowableExceptionState exception_state; setCurrentTime(current_time, exception_state); } +#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation // See steps for silently setting the current time. The preliminary step of // handling an unresolved time are to be handled by the caller. void Animation::SetCurrentTimeInternal(AnimationTimeDelta new_current_time) { - base::Optional<AnimationTimeDelta> previous_start_time = start_time_; - base::Optional<AnimationTimeDelta> previous_hold_time = hold_time_; - base::Optional<TimelinePhase> previous_hold_phase = hold_phase_; + absl::optional<AnimationTimeDelta> previous_start_time = start_time_; + absl::optional<AnimationTimeDelta> previous_hold_time = hold_time_; + absl::optional<TimelinePhase> previous_hold_phase = hold_phase_; // Update either the hold time or the start time. if (hold_time_ || !start_time_ || !timeline_ || !timeline_->IsActive() || @@ -383,10 +429,10 @@ void Animation::SetCurrentTimeInternal(AnimationTimeDelta new_current_time) { // Preserve invariant that we can only set a start time or a hold time in the // absence of an active timeline. if (!timeline_ || !timeline_->IsActive()) - start_time_ = base::nullopt; + start_time_ = absl::nullopt; // Reset the previous current time. - previous_current_time_ = base::nullopt; + previous_current_time_ = absl::nullopt; if (previous_start_time != start_time_ || previous_hold_time != hold_time_ || previous_hold_phase != hold_phase_) @@ -394,24 +440,67 @@ void Animation::SetCurrentTimeInternal(AnimationTimeDelta new_current_time) { } void Animation::SetHoldTimeAndPhase( - base::Optional<AnimationTimeDelta> new_hold_time, + absl::optional<AnimationTimeDelta> new_hold_time, TimelinePhase new_hold_phase) { hold_time_ = new_hold_time; hold_phase_ = new_hold_phase; } void Animation::ResetHoldTimeAndPhase() { - hold_time_ = base::nullopt; - hold_phase_ = base::nullopt; + hold_time_ = absl::nullopt; + hold_phase_ = absl::nullopt; } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* Animation::startTime() const { + if (start_time_) { + return MakeGarbageCollected<V8CSSNumberish>( + start_time_.value().InMillisecondsF()); + } + return nullptr; +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void Animation::startTime(CSSNumberish& startTime) const { startTime = start_time_ ? CSSNumberish::FromDouble(start_time_.value().InMillisecondsF()) : CSSNumberish(); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +// https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation +V8CSSNumberish* Animation::currentTime() const { + // 1. If the animation’s hold time is resolved, + // The current time is the animation’s hold time. + if (hold_time_.has_value()) { + return MakeGarbageCollected<V8CSSNumberish>( + hold_time_.value().InMillisecondsF()); + } + + // 2. If any of the following are true: + // * the animation has no associated timeline, or + // * the associated timeline is inactive, or + // * the animation’s start time is unresolved. + // The current time is an unresolved time value. + if (!timeline_ || !timeline_->IsActive() || !start_time_) + return nullptr; + + // 3. Otherwise, + // current time = (timeline time - start time) × playback rate + absl::optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); + + // An active timeline should always have a value, and since inactive timeline + // is handled in step 2 above, make sure that timeline_time has a value. + DCHECK(timeline_time.has_value()); + AnimationTimeDelta calculated_current_time = + (timeline_time.value() - start_time_.value()) * playback_rate_; + + return MakeGarbageCollected<V8CSSNumberish>( + calculated_current_time.InMillisecondsF()); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation void Animation::currentTime(CSSNumberish& currentTime) const { // 1. If the animation’s hold time is resolved, @@ -432,7 +521,7 @@ void Animation::currentTime(CSSNumberish& currentTime) const { // 3. Otherwise, // current time = (timeline time - start time) × playback rate - base::Optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); + absl::optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); // An active timeline should always have a value, and since inactive timeline // is handled in step 2 above, make sure that timeline_time has a value. @@ -444,6 +533,7 @@ void Animation::currentTime(CSSNumberish& currentTime) const { currentTime = CSSNumberish::FromDouble(calculated_current_time.InMillisecondsF()); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool Animation::ValidateHoldTimeAndPhase() const { return hold_phase_ || @@ -451,7 +541,7 @@ bool Animation::ValidateHoldTimeAndPhase() const { !hold_time_); } -base::Optional<AnimationTimeDelta> Animation::CurrentTimeInternal() const { +absl::optional<AnimationTimeDelta> Animation::CurrentTimeInternal() const { DCHECK(ValidateHoldTimeAndPhase()); return hold_time_ ? hold_time_ : CalculateCurrentTime(); } @@ -461,7 +551,7 @@ TimelinePhase Animation::CurrentPhaseInternal() const { return hold_phase_ ? hold_phase_.value() : CalculateCurrentPhase(); } -base::Optional<AnimationTimeDelta> Animation::UnlimitedCurrentTime() const { +absl::optional<AnimationTimeDelta> Animation::UnlimitedCurrentTime() const { return CalculateAnimationPlayState() == kPaused || !start_time_ ? CurrentTimeInternal() : CalculateCurrentTime(); @@ -513,8 +603,6 @@ bool Animation::PreCommit( CompositorAnimations::FailureReasons failure_reasons = CheckCanStartAnimationOnCompositor(paint_artifact_compositor, &unsupported_properties); - if (supplemental_failure_reasons_.has_value()) - failure_reasons |= supplemental_failure_reasons_.value(); RecordCompositorAnimationFailureReasons(failure_reasons); if (failure_reasons == CompositorAnimations::kNoFailure) { @@ -654,8 +742,8 @@ void Animation::NotifyReady(AnimationTimeDelta ready_time) { DCHECK(!compositor_state_->start_time); compositor_state_->pending_action = kNone; compositor_state_->start_time = - start_time_ ? base::make_optional(start_time_.value().InSecondsF()) - : base::nullopt; + start_time_ ? absl::make_optional(start_time_.value().InSecondsF()) + : absl::nullopt; } // Notify of change to play state. @@ -744,7 +832,7 @@ void Animation::CommitPendingPause(AnimationTimeDelta ready_time) { // 3. Apply any pending playback rate on animation. // 4. Make animation’s start time unresolved. ApplyPendingPlaybackRate(); - start_time_ = base::nullopt; + start_time_ = absl::nullopt; // 5. Resolve animation’s current ready promise with animation. if (ready_promise_ && @@ -790,7 +878,7 @@ void Animation::setTimeline(AnimationTimeline* timeline) { UpdateIfNecessary(); AnimationPlayState old_play_state = CalculateAnimationPlayState(); - base::Optional<AnimationTimeDelta> old_current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> old_current_time = CurrentTimeInternal(); CancelAnimationOnCompositor(); @@ -832,7 +920,7 @@ void Animation::setTimeline(AnimationTimeline* timeline) { case kPaused: if (old_current_time) { reset_current_time_on_resume_ = true; - start_time_ = base::nullopt; + start_time_ = absl::nullopt; SetHoldTimeAndPhase(old_current_time, TimelinePhase::kInactive); } else if (PendingInternal()) { start_time_ = boundary_time; @@ -873,11 +961,11 @@ void Animation::setTimeline(AnimationTimeline* timeline) { NotifyProbe(); } -base::Optional<AnimationTimeDelta> Animation::CalculateStartTime( +absl::optional<AnimationTimeDelta> Animation::CalculateStartTime( AnimationTimeDelta current_time) const { - base::Optional<AnimationTimeDelta> start_time; + absl::optional<AnimationTimeDelta> start_time; if (timeline_) { - base::Optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); + absl::optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); if (timeline_time) start_time = timeline_time.value() - current_time / playback_rate_; // TODO(crbug.com/916117): Handle NaN time for scroll-linked animations. @@ -886,11 +974,11 @@ base::Optional<AnimationTimeDelta> Animation::CalculateStartTime( return start_time; } -base::Optional<AnimationTimeDelta> Animation::CalculateCurrentTime() const { +absl::optional<AnimationTimeDelta> Animation::CalculateCurrentTime() const { if (!start_time_ || !timeline_ || !timeline_->IsActive()) - return base::nullopt; + return absl::nullopt; - base::Optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); + absl::optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); // timeline_ must be active here, make sure it is returning a current_time. DCHECK(timeline_time); @@ -904,9 +992,9 @@ TimelinePhase Animation::CalculateCurrentPhase() const { } // https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation -void Animation::setStartTime(CSSNumberish start_time, +void Animation::setStartTime(const V8CSSNumberish* start_time, ExceptionState& exception_state) { - if (!start_time.IsNull() && start_time.IsCSSNumericValue()) { + if (start_time && start_time->IsCSSNumericValue()) { // Throw exception for CSSNumberish that is a CSSNumericValue exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, @@ -914,21 +1002,21 @@ void Animation::setStartTime(CSSNumberish start_time, return; } - base::Optional<AnimationTimeDelta> new_start_time = - !start_time.IsNull() - ? base::make_optional( - AnimationTimeDelta::FromMillisecondsD(start_time.GetAsDouble())) - : base::nullopt; + absl::optional<AnimationTimeDelta> new_start_time; + if (start_time) { + new_start_time = + AnimationTimeDelta::FromMillisecondsD(start_time->GetAsDouble()); + } - bool had_start_time = start_time_.has_value(); + const bool had_start_time = start_time_.has_value(); // 1. Let timeline time be the current time value of the timeline that // animation is associated with. If there is no timeline associated with // animation or the associated timeline is inactive, let the timeline time // be unresolved. - base::Optional<AnimationTimeDelta> timeline_time = + absl::optional<AnimationTimeDelta> timeline_time = timeline_ && timeline_->IsActive() ? timeline_->CurrentTime() - : base::nullopt; + : absl::nullopt; // 2. If timeline time is unresolved and new start time is resolved, make // animation’s hold time unresolved. @@ -940,7 +1028,7 @@ void Animation::setStartTime(CSSNumberish start_time, } // 3. Let previous current time be animation’s current time. - base::Optional<AnimationTimeDelta> previous_current_time = + absl::optional<AnimationTimeDelta> previous_current_time = CurrentTimeInternal(); TimelinePhase previous_current_phase = CurrentPhaseInternal(); @@ -992,7 +1080,7 @@ void Animation::setStartTime(CSSNumberish start_time, UpdateFinishedState(UpdateType::kDiscontinuous, NotificationType::kAsync); // Update user agent. - base::Optional<AnimationTimeDelta> new_current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> new_current_time = CurrentTimeInternal(); // Even when the animation is not outdated,call SetOutdated to ensure // the animation is tracked by its timeline for future timing // updates. @@ -1005,11 +1093,22 @@ void Animation::setStartTime(CSSNumberish start_time, NotifyProbe(); } +#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + +// https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation +void Animation::setStartTime(CSSNumberish start_time, + ExceptionState& exception_state) { + // Forward to the new implementation. + setStartTime(CSSNumberishToV8CSSNumberish(start_time), exception_state); +} + void Animation::setStartTime(CSSNumberish start_time) { NonThrowableExceptionState exception_state; setStartTime(start_time, exception_state); } +#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + // https://drafts.csswg.org/web-animations-1/#setting-the-associated-effect void Animation::setEffect(AnimationEffect* new_effect) { // 1. Let old effect be the current associated effect of animation, if any. @@ -1082,7 +1181,7 @@ void Animation::setEffect(AnimationEffect* new_effect) { // The timing phase is ‘before’. // Otherwise, // The timing phase is ‘after’. - base::Optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); Timing::Phase phase; if (!current_time) phase = Timing::kPhaseNone; @@ -1210,7 +1309,7 @@ void Animation::pause(ExceptionState& exception_state) { return; // 3. Let seek time be a time value that is initially unresolved. - base::Optional<AnimationTimeDelta> seek_time; + absl::optional<AnimationTimeDelta> seek_time; // 4. Let has finite timeline be true if animation has an associated timeline // that is not monotonically increasing. @@ -1315,7 +1414,7 @@ void Animation::PlayInternal(AutoRewind auto_rewind, bool enable_seek = auto_rewind == AutoRewind::kEnabled || reset_current_time_on_resume_; bool has_pending_ready_promise = false; - base::Optional<AnimationTimeDelta> seek_time; + absl::optional<AnimationTimeDelta> seek_time; bool has_finite_timeline = timeline_ && !timeline_->IsMonotonicallyIncreasing(); @@ -1343,14 +1442,14 @@ void Animation::PlayInternal(AutoRewind auto_rewind, // is unresolved, // 5c1. Set seek time to zero. double effective_playback_rate = EffectivePlaybackRate(); - base::Optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); if (reset_current_time_on_resume_) { - current_time = base::nullopt; + current_time = absl::nullopt; reset_current_time_on_resume_ = false; } - base::Optional<AnimationTimeDelta> effect_end = EffectEnd(); + absl::optional<AnimationTimeDelta> effect_end = EffectEnd(); if (effective_playback_rate > 0 && enable_seek && (!current_time || current_time < AnimationTimeDelta() || current_time >= effect_end)) { @@ -1389,7 +1488,7 @@ void Animation::PlayInternal(AutoRewind auto_rewind, // 7. If animation's hold time is resolved, let its start time be unresolved. if (hold_time_) - start_time_ = base::nullopt; + start_time_ = absl::nullopt; // 8. If animation has a pending play task or a pending pause task, // 8.1 Cancel that task. @@ -1445,7 +1544,7 @@ void Animation::reverse(ExceptionState& exception_state) { // 2. Let original pending playback rate be animation’s pending playback rate. // 3. Let animation’s pending playback rate be the additive inverse of its // effective playback rate (i.e. -effective playback rate). - base::Optional<double> original_pending_playback_rate = + absl::optional<double> original_pending_playback_rate = pending_playback_rate_; pending_playback_rate_ = -EffectivePlaybackRate(); @@ -1517,7 +1616,7 @@ void Animation::UpdateFinishedState(UpdateType update_type, // required to accommodate timelines that may change direction. Without this // distinction, a once-finished animation would remain finished even when its // timeline progresses in the opposite direction. - base::Optional<AnimationTimeDelta> unconstrained_current_time = + absl::optional<AnimationTimeDelta> unconstrained_current_time = did_seek ? CurrentTimeInternal() : CalculateCurrentTime(); // 2. Conditionally update the hold time. @@ -1531,7 +1630,7 @@ void Animation::UpdateFinishedState(UpdateType update_type, // boundary. The value of previous current time is used to retain this // value. double playback_rate = EffectivePlaybackRate(); - base::Optional<AnimationTimeDelta> hold_time; + absl::optional<AnimationTimeDelta> hold_time; TimelinePhase hold_phase; if (playback_rate > 0 && @@ -1699,18 +1798,18 @@ void Animation::updatePlaybackRate(double playback_rate, // animation with the did seek flag set to false, and the // synchronously notify flag set to false. case kFinished: { - base::Optional<AnimationTimeDelta> unconstrained_current_time = + absl::optional<AnimationTimeDelta> unconstrained_current_time = CalculateCurrentTime(); - base::Optional<AnimationTimeDelta> timeline_time = - timeline_ ? timeline_->CurrentTime() : base::nullopt; + absl::optional<AnimationTimeDelta> timeline_time = + timeline_ ? timeline_->CurrentTime() : absl::nullopt; if (playback_rate) { if (timeline_time) { start_time_ = (timeline_time && unconstrained_current_time) - ? base::make_optional<AnimationTimeDelta>( + ? absl::make_optional<AnimationTimeDelta>( (timeline_time.value() - unconstrained_current_time.value()) / playback_rate) - : base::nullopt; + : absl::nullopt; } } else { start_time_ = timeline_time; @@ -1816,13 +1915,13 @@ double Animation::EffectivePlaybackRate() const { void Animation::ApplyPendingPlaybackRate() { if (pending_playback_rate_) { playback_rate_ = pending_playback_rate_.value(); - pending_playback_rate_ = base::nullopt; + pending_playback_rate_ = absl::nullopt; } } void Animation::setPlaybackRate(double playback_rate, ExceptionState& exception_state) { - base::Optional<AnimationTimeDelta> start_time_before = start_time_; + absl::optional<AnimationTimeDelta> start_time_before = start_time_; // 1. Clear any pending playback rate on animation. // 2. Let previous time be the value of the current time of animation before @@ -1830,13 +1929,21 @@ void Animation::setPlaybackRate(double playback_rate, // 3. Set the playback rate to new playback rate. // 4. If previous time is resolved, set the current time of animation to // previous time - pending_playback_rate_ = base::nullopt; + pending_playback_rate_ = absl::nullopt; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* previous_current_time = currentTime(); + playback_rate_ = playback_rate; + if (previous_current_time) { + setCurrentTime(previous_current_time, exception_state); + } +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish previous_current_time; currentTime(previous_current_time); playback_rate_ = playback_rate; if (!previous_current_time.IsNull()) { setCurrentTime(previous_current_time, exception_state); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Adds a UseCounter to check if setting playbackRate causes a compensatory // seek forcing a change in start_time_ @@ -1902,6 +2009,15 @@ Animation::CheckCanStartAnimationOnCompositorInternal() const { if (EffectivePlaybackRate() == 0) reasons |= CompositorAnimations::kInvalidAnimationOrEffect; + // Animation times with large magnitudes cannot be accurately reflected by + // TimeTicks. These animations will stall, be finished next frame, or + // stuck in the before phase. In any case, there will be no visible changes + // after the initial frame. + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + if (current_time.has_value() && + !SupportedTimeValue(current_time.value().InMillisecondsF())) + reasons |= CompositorAnimations::kEffectHasUnsupportedTimingParameters; + if (!CurrentTimeInternal()) reasons |= CompositorAnimations::kInvalidAnimationOrEffect; @@ -1952,7 +2068,7 @@ base::TimeDelta Animation::ComputeCompositorTimeOffset() const { bool reversed = playback_rate < 0; - base::Optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); if (!current_time) return base::TimeDelta(); @@ -1973,7 +2089,7 @@ void Animation::StartAnimationOnCompositor( bool reversed = EffectivePlaybackRate() < 0; - base::Optional<AnimationTimeDelta> start_time; + absl::optional<AnimationTimeDelta> start_time; base::TimeDelta time_offset = base::TimeDelta(); // Start the animation on the compositor with either a start time or time // offset. The start time is used for synchronous updates where the @@ -1994,7 +2110,7 @@ void Animation::StartAnimationOnCompositor( DCHECK_NE(compositor_group_, 0); DCHECK(To<KeyframeEffect>(content_.Get())); - base::Optional<double> start_time_s; + absl::optional<double> start_time_s; if (start_time) { start_time_s = start_time.value().InSecondsF(); } @@ -2085,7 +2201,7 @@ bool Animation::Update(TimingUpdateReason reason) { UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync); if (content_) { - base::Optional<AnimationTimeDelta> inherited_time; + absl::optional<AnimationTimeDelta> inherited_time; TimelinePhase inherited_phase = TimelinePhase::kInactive; if (!idle) { @@ -2132,9 +2248,9 @@ bool Animation::Update(TimingUpdateReason reason) { void Animation::QueueFinishedEvent() { const AtomicString& event_type = event_type_names::kFinish; if (GetExecutionContext() && HasEventListeners(event_type)) { - base::Optional<AnimationTimeDelta> event_current_time = + absl::optional<AnimationTimeDelta> event_current_time = CurrentTimeInternal(); - base::Optional<double> event_current_time_ms; + absl::optional<double> event_current_time_ms; if (event_current_time) event_current_time_ms = event_current_time.value().InMillisecondsF(); // TODO(crbug.com/916117): Handle NaN values for scroll-linked animations. @@ -2163,13 +2279,13 @@ bool Animation::IsEventDispatchAllowed() const { return Paused() || start_time_; } -base::Optional<AnimationTimeDelta> Animation::TimeToEffectChange() { +absl::optional<AnimationTimeDelta> Animation::TimeToEffectChange() { DCHECK(!outdated_); if (!start_time_ || hold_time_ || !playback_rate_) - return base::nullopt; + return absl::nullopt; if (!content_) { - base::Optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); DCHECK(current_time); return -current_time.value() / playback_rate_; } @@ -2199,7 +2315,7 @@ void Animation::cancel() { const AtomicString& event_type = event_type_names::kCancel; if (GetExecutionContext() && HasEventListeners(event_type)) { - base::Optional<double> event_current_time = base::nullopt; + absl::optional<double> event_current_time = absl::nullopt; // TODO(crbug.com/916117): Handle NaN values for scroll-linked // animations. pending_cancelled_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( @@ -2210,12 +2326,12 @@ void Animation::cancel() { } } else { // Quietly reset without rejecting promises. - pending_playback_rate_ = base::nullopt; + pending_playback_rate_ = absl::nullopt; pending_pause_ = pending_play_ = false; } ResetHoldTimeAndPhase(); - start_time_ = base::nullopt; + start_time_ = absl::nullopt; // Apply changes synchronously. SetCompositorPending(/*effect_changed=*/false); @@ -2317,7 +2433,7 @@ void Animation::PauseForTesting(AnimationTimeDelta pause_time) { // animation. SetCurrentTimeInternal(pause_time); if (HasActiveAnimationsOnCompositor()) { - base::Optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); + absl::optional<AnimationTimeDelta> current_time = CurrentTimeInternal(); DCHECK(current_time); To<KeyframeEffect>(content_.Get()) ->PauseAnimationForTestingOnCompositor( @@ -2331,7 +2447,7 @@ void Animation::PauseForTesting(AnimationTimeDelta pause_time) { pending_pause_ = false; pending_play_ = false; SetHoldTimeAndPhase(pause_time, TimelinePhase::kActive); - start_time_ = base::nullopt; + start_time_ = absl::nullopt; } void Animation::SetEffectSuppressed(bool suppressed) { @@ -2511,9 +2627,9 @@ void Animation::RemoveReplacedAnimation() { replace_state_ = kRemoved; const AtomicString& event_type = event_type_names::kRemove; if (GetExecutionContext() && HasEventListeners(event_type)) { - base::Optional<AnimationTimeDelta> event_current_time = + absl::optional<AnimationTimeDelta> event_current_time = CurrentTimeInternal(); - base::Optional<double> event_current_time_ms; + absl::optional<double> event_current_time_ms; if (event_current_time) event_current_time_ms = event_current_time.value().InMillisecondsF(); pending_remove_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( diff --git a/chromium/third_party/blink/renderer/core/animation/animation.h b/chromium/third_party/blink/renderer/core/animation/animation.h index 4f267d18077..cb2fa53733b 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation.h +++ b/chromium/third_party/blink/renderer/core/animation/animation.h @@ -35,8 +35,8 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "base/optional.h" #include "base/time/time.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h" @@ -143,17 +143,25 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, // next frame // AnimationTimeDelta() > 0 - if this animation requires an update // after 'n' units of time - base::Optional<AnimationTimeDelta> TimeToEffectChange(); + absl::optional<AnimationTimeDelta> TimeToEffectChange(); void cancel(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* currentTime() const; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void currentTime(CSSNumberish&) const; - base::Optional<AnimationTimeDelta> CurrentTimeInternal() const; +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + absl::optional<AnimationTimeDelta> CurrentTimeInternal() const; + void setCurrentTime(const V8CSSNumberish* current_time, + ExceptionState& exception_state); +#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void setCurrentTime(CSSNumberish, ExceptionState& exception_state); void setCurrentTime(CSSNumberish); +#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void SetCurrentTimeInternal(AnimationTimeDelta); - base::Optional<AnimationTimeDelta> UnlimitedCurrentTime() const; + absl::optional<AnimationTimeDelta> UnlimitedCurrentTime() const; // https://drafts.csswg.org/web-animations/#play-states String PlayStateString() const; @@ -209,12 +217,20 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, virtual void setTimeline(AnimationTimeline* timeline); Document* GetDocument() const; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* startTime() const; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void startTime(CSSNumberish&) const; - base::Optional<AnimationTimeDelta> StartTimeInternal() const { +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + absl::optional<AnimationTimeDelta> StartTimeInternal() const { return start_time_; } + virtual void setStartTime(const V8CSSNumberish* start_time, + ExceptionState& exception_state); +#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) virtual void setStartTime(CSSNumberish, ExceptionState&); void setStartTime(CSSNumberish); +#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const AnimationEffect* effect() const { return content_.Get(); } AnimationEffect* effect() { return content_.Get(); } @@ -282,7 +298,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, void Trace(Visitor*) const override; - bool CompositorPendingForTesting() const { return compositor_pending_; } + bool CompositorPending() const { return compositor_pending_; } // Methods for handling removal and persistence of animations. bool IsReplaceable(); @@ -302,11 +318,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, bool IsInDisplayLockedSubtree(); - void SetFailureReasons(CompositorAnimations::FailureReasons failure_reasons) { - supplemental_failure_reasons_ = failure_reasons; - } - void ResetFailureReasons() { supplemental_failure_reasons_ = base::nullopt; } - base::TimeDelta ComputeCompositorTimeOffset() const; protected: @@ -321,7 +332,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, } private: - void SetHoldTimeAndPhase(base::Optional<AnimationTimeDelta> new_hold_time, + void SetHoldTimeAndPhase(absl::optional<AnimationTimeDelta> new_hold_time, TimelinePhase new_hold_phase); void ResetHoldTimeAndPhase(); bool ValidateHoldTimeAndPhase() const; @@ -330,7 +341,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, void ForceServiceOnNextFrame(); AnimationTimeDelta EffectEnd() const; - bool Limited(base::Optional<AnimationTimeDelta> current_time) const; + bool Limited(absl::optional<AnimationTimeDelta> current_time) const; // Playback rate that will take effect once any pending tasks are resolved. // If there are no pending tasks, then the effective playback rate equals the @@ -338,9 +349,9 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, double EffectivePlaybackRate() const; void ApplyPendingPlaybackRate(); - base::Optional<AnimationTimeDelta> CalculateStartTime( + absl::optional<AnimationTimeDelta> CalculateStartTime( AnimationTimeDelta current_time) const; - base::Optional<AnimationTimeDelta> CalculateCurrentTime() const; + absl::optional<AnimationTimeDelta> CalculateCurrentTime() const; TimelinePhase CalculateCurrentPhase() const; void BeginUpdatingState(); @@ -383,7 +394,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, void PlayInternal(AutoRewind auto_rewind, ExceptionState& exception_state); void ResetPendingTasks(); - base::Optional<double> TimelineTime() const; + absl::optional<double> TimelineTime() const; void ScheduleAsyncFinish(); void AsyncFinishMicrotask(); @@ -402,11 +413,11 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, // The pending playback rate is not currently in effect. It typically takes // effect when running a scheduled task in response to the animation being // ready. - base::Optional<double> pending_playback_rate_; - base::Optional<AnimationTimeDelta> start_time_; - base::Optional<AnimationTimeDelta> hold_time_; - base::Optional<TimelinePhase> hold_phase_; - base::Optional<AnimationTimeDelta> previous_current_time_; + absl::optional<double> pending_playback_rate_; + absl::optional<AnimationTimeDelta> start_time_; + absl::optional<AnimationTimeDelta> hold_time_; + absl::optional<TimelinePhase> hold_phase_; + absl::optional<AnimationTimeDelta> previous_current_time_; bool reset_current_time_on_resume_ = false; unsigned sequence_number_; @@ -465,18 +476,18 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, // AnimationTimeDelta for start_time_ and hold_time_. explicit CompositorState(Animation& animation) : start_time(animation.start_time_ - ? base::make_optional( + ? absl::make_optional( animation.start_time_.value().InSecondsF()) - : base::nullopt), + : absl::nullopt), hold_time(animation.hold_time_ - ? base::make_optional( + ? absl::make_optional( animation.hold_time_.value().InSecondsF()) - : base::nullopt), + : absl::nullopt), playback_rate(animation.EffectivePlaybackRate()), effect_changed(false), pending_action(animation.start_time_ ? kNone : kStart) {} - base::Optional<double> start_time; - base::Optional<double> hold_time; + absl::optional<double> start_time; + absl::optional<double> hold_time; double playback_rate; bool effect_changed; CompositorAction pending_action; @@ -527,12 +538,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, bool effect_suppressed_; - // For background color animation, this should be determined during the paint - // stage with the CompositeBGColorAnimation feature. - base::Optional<CompositorAnimations::FailureReasons> - supplemental_failure_reasons_; - bool can_composite_bgcolor_anim_ = false; - // Animations with an owning element stop ticking if there is an active // display lock on an ancestor element. Cache the status to minimize the // number of tree walks. diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc index 6cdacfffe51..47ad163d059 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc @@ -108,9 +108,9 @@ void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing, InvalidateAndNotifyOwner(); } -base::Optional<Timing::Phase> TimelinePhaseToTimingPhase( - base::Optional<TimelinePhase> phase) { - base::Optional<Timing::Phase> result; +absl::optional<Timing::Phase> TimelinePhaseToTimingPhase( + absl::optional<TimelinePhase> phase) { + absl::optional<Timing::Phase> result; if (phase) { switch (phase.value()) { case TimelinePhase::kBefore: @@ -131,10 +131,10 @@ base::Optional<Timing::Phase> TimelinePhaseToTimingPhase( } void AnimationEffect::UpdateInheritedTime( - base::Optional<AnimationTimeDelta> inherited_time, - base::Optional<TimelinePhase> inherited_timeline_phase, + absl::optional<AnimationTimeDelta> inherited_time, + absl::optional<TimelinePhase> inherited_timeline_phase, TimingUpdateReason reason) const { - base::Optional<double> playback_rate = base::nullopt; + absl::optional<double> playback_rate = absl::nullopt; if (GetAnimation()) playback_rate = GetAnimation()->playbackRate(); const Timing::AnimationDirection direction = @@ -142,7 +142,7 @@ void AnimationEffect::UpdateInheritedTime( ? Timing::AnimationDirection::kBackwards : Timing::AnimationDirection::kForwards; - base::Optional<Timing::Phase> timeline_phase = + absl::optional<Timing::Phase> timeline_phase = TimelinePhaseToTimingPhase(inherited_timeline_phase); bool needs_update = needs_update_ || last_update_time_ != inherited_time || @@ -152,12 +152,9 @@ void AnimationEffect::UpdateInheritedTime( last_update_time_ = inherited_time; last_update_phase_ = timeline_phase; - const base::Optional<double> local_time = - inherited_time ? base::make_optional(inherited_time.value().InSecondsF()) - : base::nullopt; if (needs_update) { Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings( - local_time, timeline_phase, direction, IsA<KeyframeEffect>(this), + inherited_time, timeline_phase, direction, IsA<KeyframeEffect>(this), playback_rate); const bool was_canceled = calculated.phase != calculated_.phase && @@ -187,9 +184,9 @@ void AnimationEffect::UpdateInheritedTime( // FIXME: This probably shouldn't be recursive. UpdateChildrenAndEffects(); calculated_.time_to_forwards_effect_change = CalculateTimeToEffectChange( - true, local_time, calculated_.time_to_next_iteration); + true, inherited_time, calculated_.time_to_next_iteration); calculated_.time_to_reverse_effect_change = CalculateTimeToEffectChange( - false, local_time, calculated_.time_to_next_iteration); + false, inherited_time, calculated_.time_to_next_iteration); } } diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.h b/chromium/third_party/blink/renderer/core/animation/animation_effect.h index c876426d7e9..5763f0cdab8 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_EFFECT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_EFFECT_H_ -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_time_delta.h" #include "third_party/blink/renderer/core/animation/timing.h" #include "third_party/blink/renderer/core/core_export.h" @@ -87,10 +87,10 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { bool IsCurrent() const { return EnsureCalculated().is_current; } bool IsInEffect() const { return EnsureCalculated().is_in_effect; } bool IsInPlay() const { return EnsureCalculated().is_in_play; } - base::Optional<double> CurrentIteration() const { + absl::optional<double> CurrentIteration() const { return EnsureCalculated().current_iteration; } - base::Optional<double> Progress() const { + absl::optional<double> Progress() const { return EnsureCalculated().progress; } AnimationTimeDelta TimeToForwardsEffectChange() const { @@ -99,7 +99,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { AnimationTimeDelta TimeToReverseEffectChange() const { return EnsureCalculated().time_to_reverse_effect_change; } - base::Optional<double> LocalTime() const { + absl::optional<AnimationTimeDelta> LocalTime() const { return EnsureCalculated().local_time; } @@ -136,8 +136,8 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { // When AnimationEffect receives a new inherited time via updateInheritedTime // it will (if necessary) recalculate timings and (if necessary) call // updateChildrenAndEffects. - void UpdateInheritedTime(base::Optional<AnimationTimeDelta> inherited_time, - base::Optional<TimelinePhase> inherited_phase, + void UpdateInheritedTime(absl::optional<AnimationTimeDelta> inherited_time, + absl::optional<TimelinePhase> inherited_phase, TimingUpdateReason) const; void Invalidate() const { needs_update_ = true; } void InvalidateAndNotifyOwner() const; @@ -158,7 +158,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { virtual AnimationTimeDelta CalculateTimeToEffectChange( bool forwards, - base::Optional<double> local_time, + absl::optional<AnimationTimeDelta> local_time, AnimationTimeDelta time_to_next_iteration) const = 0; const Animation* GetAnimation() const; @@ -170,8 +170,8 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { mutable Timing::CalculatedTiming calculated_; mutable bool needs_update_; - mutable base::Optional<AnimationTimeDelta> last_update_time_; - mutable base::Optional<Timing::Phase> last_update_phase_; + mutable absl::optional<AnimationTimeDelta> last_update_time_; + mutable absl::optional<Timing::Phase> last_update_phase_; AnimationTimeDelta cancel_time_; const Timing::CalculatedTiming& EnsureCalculated() const; }; diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc index 9a810175445..7628a5a1315 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc @@ -85,7 +85,7 @@ class TestAnimationEffect : public AnimationEffect { void UpdateInheritedTime(double time, TimingUpdateReason reason) { event_delegate_->Reset(); AnimationEffect::UpdateInheritedTime(AnimationTimeDelta::FromSecondsD(time), - /*inherited_phase*/ base::nullopt, + /*inherited_phase*/ absl::nullopt, reason); } @@ -96,23 +96,21 @@ class TestAnimationEffect : public AnimationEffect { } AnimationTimeDelta CalculateTimeToEffectChange( bool forwards, - base::Optional<double> local_time, + absl::optional<AnimationTimeDelta> local_time, AnimationTimeDelta time_to_next_iteration) const override { - DCHECK(!local_time || std::isfinite(local_time.value())); local_time_ = local_time; time_to_next_iteration_ = time_to_next_iteration; - return AnimationTimeDelta::FromSecondsD( - std::numeric_limits<double>::infinity()); + return AnimationTimeDelta::Max(); } double TakeLocalTime() { DCHECK(local_time_); - const double result = local_time_.value(); + const double result = local_time_->InSecondsF(); local_time_.reset(); return result; } - base::Optional<AnimationTimeDelta> TakeTimeToNextIteration() { - const base::Optional<AnimationTimeDelta> result = time_to_next_iteration_; + absl::optional<AnimationTimeDelta> TakeTimeToNextIteration() { + const absl::optional<AnimationTimeDelta> result = time_to_next_iteration_; time_to_next_iteration_.reset(); return result; } @@ -124,8 +122,8 @@ class TestAnimationEffect : public AnimationEffect { private: Member<TestAnimationEffectEventDelegate> event_delegate_; - mutable base::Optional<double> local_time_; - mutable base::Optional<AnimationTimeDelta> time_to_next_iteration_; + mutable absl::optional<AnimationTimeDelta> local_time_; + mutable absl::optional<AnimationTimeDelta> time_to_next_iteration_; }; TEST(AnimationAnimationEffectTest, Sanity) { @@ -140,7 +138,8 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(2, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(0, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -150,7 +149,8 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(2, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(0.5, animation_node->Progress()); animation_node->UpdateInheritedTime(2); @@ -160,7 +160,8 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_FALSE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(2, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(3); @@ -170,7 +171,8 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_FALSE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(2, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(1, animation_node->Progress()); } @@ -229,7 +231,7 @@ TEST(AnimationAnimationEffectTest, StartDelay) { Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1); timing.fill_mode = Timing::FillMode::FORWARDS; - timing.start_delay = 0.5; + timing.start_delay = AnimationTimeDelta::FromSecondsD(0.5); auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(0); @@ -250,12 +252,14 @@ TEST(AnimationAnimationEffectTest, ZeroIteration) { auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(-1); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(0, animation_node->Progress()); } @@ -271,7 +275,7 @@ TEST(AnimationAnimationEffectTest, InfiniteIteration) { EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); - EXPECT_EQ(std::numeric_limits<double>::infinity(), + EXPECT_EQ(AnimationTimeDelta::Max(), animation_node->SpecifiedTiming().ActiveDuration()); animation_node->UpdateInheritedTime(0); @@ -378,7 +382,8 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) { EXPECT_FALSE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -388,7 +393,8 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) { EXPECT_FALSE(animation_node->IsCurrent()); EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(1, animation_node->Progress()); } @@ -440,7 +446,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationFillBoth) { TEST(AnimationAnimationEffectTest, ZeroDurationStartDelay) { Timing timing; timing.fill_mode = Timing::FillMode::FORWARDS; - timing.start_delay = 0.5; + timing.start_delay = AnimationTimeDelta::FromSecondsD(0.5); auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(0); @@ -458,7 +464,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationIterationStartAndCount) { timing.iteration_start = 0.1; timing.iteration_count = 0.2; timing.fill_mode = Timing::FillMode::BOTH; - timing.start_delay = 0.3; + timing.start_delay = AnimationTimeDelta::FromSecondsD(0.3); auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(0); @@ -479,12 +485,14 @@ TEST(AnimationAnimationEffectTest, ZeroDurationInfiniteIteration) { auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(-1); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(std::numeric_limits<double>::infinity(), animation_node->CurrentIteration()); EXPECT_EQ(1, animation_node->Progress()); @@ -577,7 +585,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) { animation_node->UpdateInheritedTime(0); - EXPECT_EQ(std::numeric_limits<double>::infinity(), + EXPECT_EQ(AnimationTimeDelta::Max(), animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); @@ -588,7 +596,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) { animation_node->UpdateInheritedTime(1); - EXPECT_EQ(std::numeric_limits<double>::infinity(), + EXPECT_EQ(AnimationTimeDelta::Max(), animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); @@ -607,7 +615,8 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationZeroIterations) { animation_node->UpdateInheritedTime(0); - EXPECT_EQ(0, animation_node->SpecifiedTiming().ActiveDuration()); + EXPECT_EQ(AnimationTimeDelta(), + animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(Timing::kPhaseAfter, animation_node->GetPhase()); EXPECT_FALSE(animation_node->IsInPlay()); EXPECT_FALSE(animation_node->IsCurrent()); @@ -634,7 +643,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) { animation_node->UpdateInheritedTime(0); - EXPECT_EQ(std::numeric_limits<double>::infinity(), + EXPECT_EQ(AnimationTimeDelta::Max(), animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); @@ -645,7 +654,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) { animation_node->UpdateInheritedTime(1); - EXPECT_EQ(std::numeric_limits<double>::infinity(), + EXPECT_EQ(AnimationTimeDelta::Max(), animation_node->SpecifiedTiming().ActiveDuration()); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); @@ -657,12 +666,13 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) { TEST(AnimationAnimationEffectTest, EndTime) { Timing timing; - timing.start_delay = 1; - timing.end_delay = 2; + timing.start_delay = AnimationTimeDelta::FromSecondsD(1); + timing.end_delay = AnimationTimeDelta::FromSecondsD(2); timing.iteration_duration = AnimationTimeDelta::FromSecondsD(4); timing.iteration_count = 2; auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); - EXPECT_EQ(11, animation_node->SpecifiedTiming().EndTimeInternal()); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(11), + animation_node->SpecifiedTiming().EndTimeInternal()); } TEST(AnimationAnimationEffectTest, Events) { @@ -670,7 +680,7 @@ TEST(AnimationAnimationEffectTest, Events) { timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1); timing.fill_mode = Timing::FillMode::FORWARDS; timing.iteration_count = 2; - timing.start_delay = 1; + timing.start_delay = AnimationTimeDelta::FromSecondsD(1); auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(0.0, kTimingUpdateOnDemand); @@ -692,13 +702,13 @@ TEST(AnimationAnimationEffectTest, TimeToEffectChange) { timing.fill_mode = Timing::FillMode::FORWARDS; timing.iteration_start = 0.2; timing.iteration_count = 2.5; - timing.start_delay = 1; + timing.start_delay = AnimationTimeDelta::FromSecondsD(1); timing.direction = Timing::PlaybackDirection::ALTERNATE_NORMAL; auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); animation_node->UpdateInheritedTime(0); EXPECT_EQ(0, animation_node->TakeLocalTime()); - base::Optional<AnimationTimeDelta> time_to_next_iteration = + absl::optional<AnimationTimeDelta> time_to_next_iteration = animation_node->TakeTimeToNextIteration(); EXPECT_TRUE(time_to_next_iteration); EXPECT_TRUE(time_to_next_iteration->is_max()); @@ -853,8 +863,8 @@ TEST(AnimationAnimationEffectTest, UpdateTimingInformsOwnerOnChange) { TEST(AnimationAnimationEffectTest, UpdateTimingNoChange) { Timing timing; - timing.start_delay = 0; - timing.end_delay = 5; + timing.start_delay = AnimationTimeDelta(); + timing.end_delay = AnimationTimeDelta::FromSecondsD(5); timing.fill_mode = Timing::FillMode::BOTH; timing.iteration_start = 0.1; timing.iteration_count = 3; diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_test.cc index f76f96c1bd1..900360888d6 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_test.cc @@ -38,6 +38,7 @@ #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h" #include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h" @@ -89,7 +90,12 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { timeline = GetDocument().Timeline(); timeline->ResetForTesting(); animation = timeline->Play(nullptr); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation()); } @@ -141,13 +147,11 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); @@ -216,28 +220,44 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { GetPage().Animator().ServiceScriptedAnimations(new_time); } - bool StartTimeIsSet(Persistent<blink::Animation> animation) { + bool StartTimeIsSet(Animation* animation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + return animation->startTime(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish start_time; animation->startTime(start_time); return !start_time.IsNull(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } - bool CurrentTimeIsSet(Persistent<blink::Animation> animation) { + bool CurrentTimeIsSet(Animation* animation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + return animation->currentTime(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time; animation->currentTime(current_time); return !current_time.IsNull(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } - double GetStartTimeMs(Persistent<blink::Animation> animation) { + double GetStartTimeMs(Animation* animation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + return animation->startTime()->GetAsDouble(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish start_time; animation->startTime(start_time); return start_time.GetAsDouble(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } - double GetCurrentTimeMs(Persistent<blink::Animation> animation) { + double GetCurrentTimeMs(Animation* animation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + return animation->currentTime()->GetAsDouble(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time; animation->currentTime(current_time); return current_time.GetAsDouble(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } #define EXPECT_TIME(expected, observed) \ @@ -259,12 +279,10 @@ class AnimationAnimationTestCompositing Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue( property_id, from, SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue( property_id, to, SecureContextMode::kInsecureContext, nullptr); @@ -334,7 +352,12 @@ TEST_F(AnimationAnimationTestNoCompositing, CurrentTimeDoesNotSetOutdated) { TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) { EXPECT_EQ("running", animation->playState()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -344,14 +367,24 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) { } TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); SimulateFrame(20000); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); animation->setPlaybackRate(-2); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); // A seek can set current time outside the range [0, EffectEnd()]. EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); @@ -379,12 +412,22 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TIME(10000, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); } TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); @@ -394,7 +437,12 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { // Reversing the play direction changes the play state from finished to // running. animation->setPlaybackRate(-2); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); SimulateAwaitReady(); @@ -404,21 +452,63 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { EXPECT_TIME(10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeMax) { +TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeMax) { + ResetWithCompositedAnimation(); + EXPECT_EQ(CompositorAnimations::kNoFailure, + animation->CheckCanStartAnimationOnCompositor(nullptr)); double limit = std::numeric_limits<double>::max(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit), + ASSERT_NO_EXCEPTION); + V8CSSNumberish* current_time = animation->currentTime(); + ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(limit)); CSSNumberish current_time; animation->currentTime(current_time); ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble()); - +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) & + CompositorAnimations::kEffectHasUnsupportedTimingParameters); SimulateFrame(100000); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + current_time = animation->currentTime(); + ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->currentTime(current_time); ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble()); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +} + +TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeAboveMaxTimeDelta) { + // Similar to the SetCurrentTimeMax test. The limit is much less, but still + // too large to be expressed as a 64-bit int and thus not able to run on the + // compositor. + ResetWithCompositedAnimation(); + EXPECT_EQ(CompositorAnimations::kNoFailure, + animation->CheckCanStartAnimationOnCompositor(nullptr)); + double limit = 1e30; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit), + ASSERT_NO_EXCEPTION); + ignore_result(animation->currentTime()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(CSSNumberish::FromDouble(limit)); + CSSNumberish current_time; + animation->currentTime(current_time); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) & + CompositorAnimations::kEffectHasUnsupportedTimingParameters); } TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) { EXPECT_TIME(0, GetStartTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(1000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(1000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(-1000, GetStartTimeMs(animation)); SimulateFrame(1000); @@ -431,7 +521,12 @@ TEST_F(AnimationAnimationTestNoCompositing, SetStartTime) { EXPECT_EQ("running", animation->playState()); EXPECT_TIME(0, GetStartTimeMs(animation)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(10000, GetStartTimeMs(animation)); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -439,20 +534,35 @@ TEST_F(AnimationAnimationTestNoCompositing, SetStartTime) { SimulateFrame(30000); EXPECT_TIME(10000, GetStartTimeMs(animation)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-20000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(-20000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); } TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeLimitsAnimation) { // Setting the start time is a seek operation, which is not constrained by the // normal limits on the animation. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(-50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TRUE(animation->Limited()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); animation->setPlaybackRate(-1); EXPECT_EQ("running", animation->playState()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-100000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(-100000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(-100000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); @@ -462,14 +572,29 @@ TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeOnLimitedAnimation) { // The setStartTime method is a seek and thus not constrained by the normal // limits on the animation. SimulateFrame(30000); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(50000, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(-40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(70000, GetCurrentTimeMs(animation)); EXPECT_EQ("finished", animation->playState()); EXPECT_TRUE(animation->Limited()); @@ -551,12 +676,22 @@ TEST_F(AnimationAnimationTestNoCompositing, PausePlay) { TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { // Auto-replay when starting from limit. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(30000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(30000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); // Auto-replay when starting past the upper bound. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); @@ -566,7 +701,12 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { // from a negative value of current time. SimulateFrame(10000); EXPECT_FALSE(animation->pending()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_FALSE(animation->pending()); animation->play(); @@ -585,7 +725,12 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { EXPECT_TIME(30000, GetCurrentTimeMs(animation)); // Snap to end if playing a reversed animation starting past the upper limit. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); animation->play(); @@ -598,7 +743,12 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { // Snap to the end if playing a reversed animation starting with a negative // value for current time. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); @@ -617,11 +767,21 @@ TEST_F(AnimationAnimationTestNoCompositing, animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); } @@ -639,7 +799,12 @@ TEST_F(AnimationAnimationTestNoCompositing, } TEST_F(AnimationAnimationTestNoCompositing, Reverse) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->pause(); animation->reverse(); EXPECT_EQ("running", animation->playState()); @@ -656,7 +821,12 @@ TEST_F(AnimationAnimationTestNoCompositing, Reverse) { TEST_F(AnimationAnimationTestNoCompositing, ReverseHoldsCurrentTimeWithPlaybackRateZero) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(0); animation->pause(); animation->reverse(); @@ -670,27 +840,47 @@ TEST_F(AnimationAnimationTestNoCompositing, } TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToStart) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->reverse(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); } TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToEnd) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->reverse(); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); } TEST_F(AnimationAnimationTestNoCompositing, ReverseBeyondLimit) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->reverse(); EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->reverse(); EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); @@ -716,7 +906,12 @@ TEST_F(AnimationAnimationTestNoCompositing, Finish) { TEST_F(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) { NonThrowableExceptionState exception_state; // OK to set current time out of bounds. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->finish(exception_state); // The finish method triggers a snap to the upper boundary. EXPECT_TIME(30000, GetCurrentTimeMs(animation)); @@ -724,7 +919,12 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) { TEST_F(AnimationAnimationTestNoCompositing, FinishBeforeStart) { NonThrowableExceptionState exception_state; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->finish(exception_state); EXPECT_TIME(0, GetCurrentTimeMs(animation)); @@ -734,7 +934,12 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishDoesNothingWithPlaybackRateZero) { // Cannot finish an animation that has a playback rate of zero. DummyExceptionStateForTesting exception_state; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(0); animation->finish(exception_state); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -749,7 +954,12 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishRaisesException) { timing.iteration_count = std::numeric_limits<double>::infinity(); animation->setEffect(MakeGarbageCollected<KeyframeEffect>( nullptr, MakeEmptyEffectModel(), timing)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(10000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DummyExceptionStateForTesting exception_state; animation->finish(exception_state); @@ -845,7 +1055,12 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateZero) { SimulateFrame(20000); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(20000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } @@ -919,13 +1134,23 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileRunning) { TEST_F(AnimationAnimationTestNoCompositing, SetEffect) { animation = timeline->Play(nullptr); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) AnimationEffect* effect1 = MakeAnimation(); AnimationEffect* effect2 = MakeAnimation(); animation->setEffect(effect1); EXPECT_EQ(effect1, animation->effect()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(15000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(effect2); EXPECT_TIME(15000, GetCurrentTimeMs(animation)); EXPECT_EQ(nullptr, effect1->GetAnimationForTesting()); @@ -934,7 +1159,12 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffect) { } TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(20000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation(10)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); @@ -943,7 +1173,12 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) { } TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(40000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation(60)); EXPECT_FALSE(animation->Limited()); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); @@ -954,10 +1189,10 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) { TEST_F(AnimationAnimationTestNoCompositing, EmptyAnimationsDontUpdateEffects) { animation = timeline->Play(nullptr); animation->Update(kTimingUpdateOnDemand); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); SimulateFrame(1234); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } TEST_F(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) { @@ -974,13 +1209,18 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) { TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { Timing timing; - timing.start_delay = 1; + timing.start_delay = AnimationTimeDelta::FromSecondsD(1); timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1); - timing.end_delay = 1; + timing.end_delay = AnimationTimeDelta::FromSecondsD(1); auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>( nullptr, MakeEmptyEffectModel(), timing); animation = timeline->Play(keyframe_effect); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Next effect change at end of start delay. SimulateFrame(0); @@ -1009,10 +1249,15 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { // Still in effect if fillmode = forward|both. SimulateFrame(3000); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reset to start of animation. Next effect at the end of the start delay. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) SimulateFrame(3000); EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1), animation->TimeToEffectChange().value()); @@ -1026,10 +1271,15 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { // Effectively a paused animation. animation->setPlaybackRate(0); animation->Update(kTimingUpdateOnDemand); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reversed animation from end time. Next effect after end delay. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(3000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(3000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->Update(kTimingUpdateOnDemand); SimulateFrame(3000); @@ -1053,14 +1303,19 @@ TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenPaused) { SimulateAwaitReady(); EXPECT_FALSE(animation->pending()); animation->Update(kTimingUpdateOnDemand); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenCancelledBeforeStart) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-8000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(-8000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(2); EXPECT_EQ("running", animation->playState()); animation->cancel(); @@ -1069,21 +1324,26 @@ TEST_F(AnimationAnimationTestNoCompositing, animation->Update(kTimingUpdateOnDemand); // This frame will fire the finish event event though no start time has been // received from the compositor yet, as cancel() nukes start times. - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenCancelledBeforeStartReverse) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(9000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(9000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-3); EXPECT_EQ("running", animation->playState()); animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(animation->pending()); animation->Update(kTimingUpdateOnDemand); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } TEST_F(AnimationAnimationTestNoCompositing, @@ -1095,10 +1355,11 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(animation->pending()); animation->Update(kTimingUpdateOnDemand); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) { + // Prevent |element| from being collected by |CollectAllGarbageForTesting|. Persistent<Element> element = GetDocument().CreateElementForBinding("foo"); Timing timing; @@ -1145,7 +1406,12 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) { TEST_F(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) { animation->setPlaybackRate(-1); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(15000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(animation->pending()); @@ -1226,7 +1492,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) { animation->finish(); animation->Update(kTimingUpdateOnDemand); EXPECT_EQ("finished", animation->playState()); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reversing a finished animation marks the animation as outdated. Required // to recompute the time to next interval. @@ -1245,7 +1511,7 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) { animation->finish(); animation->Update(kTimingUpdateOnDemand); EXPECT_EQ("finished", animation->playState()); - EXPECT_EQ(base::nullopt, animation->TimeToEffectChange()); + EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reversing a finished animation marks the animation as outdated. Required // to recompute the time to next interval. The pending playback rate is @@ -1308,7 +1574,7 @@ TEST_F(AnimationAnimationTestCompositing, // At this point, the animation exists on both the compositor and blink side, // but no start time has arrived on either side. The compositor is currently // synced, no update is pending. - EXPECT_FALSE(animation->CompositorPendingForTesting()); + EXPECT_FALSE(animation->CompositorPending()); // However, if we pause the animation then the compositor should still be // marked pending. This is required because otherwise the compositor will go @@ -1316,7 +1582,7 @@ TEST_F(AnimationAnimationTestCompositing, // on the next compositor frame). animation->pause(); - EXPECT_TRUE(animation->CompositorPendingForTesting()); + EXPECT_TRUE(animation->CompositorPending()); } TEST_F(AnimationAnimationTestCompositing, PreCommitWithUnresolvedStartTimes) { @@ -1325,7 +1591,7 @@ TEST_F(AnimationAnimationTestCompositing, PreCommitWithUnresolvedStartTimes) { // At this point, the animation exists on both the compositor and blink side, // but no start time has arrived on either side. The compositor is currently // synced, no update is pending. - EXPECT_FALSE(animation->CompositorPendingForTesting()); + EXPECT_FALSE(animation->CompositorPending()); // At this point, a call to PreCommit should bail out and tell us to wait for // next commit because there are no resolved start times. @@ -1387,12 +1653,10 @@ TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) { animation->setPlaybackRate(1); // Finally, change the keyframes to something unsupported by the compositor. - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue( CSSPropertyID::kLeft, "0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kLeft, "100px", SecureContextMode::kInsecureContext, nullptr); @@ -1432,17 +1696,15 @@ TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) { // At this point, the animation exists on both the compositor and blink side, // but no start time has arrived on either side. The compositor is currently // synced, no update is pending. - EXPECT_FALSE(animation->CompositorPendingForTesting()); + EXPECT_FALSE(animation->CompositorPending()); // Now change the keyframes; this should mark the animation as compositor // pending as we need to sync the compositor side. - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); @@ -1453,7 +1715,7 @@ TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) { To<KeyframeEffect>(animation->effect())->SetKeyframes(keyframes); - EXPECT_TRUE(animation->CompositorPendingForTesting()); + EXPECT_TRUE(animation->CompositorPending()); } // crbug.com/1057076 @@ -1471,25 +1733,6 @@ TEST_F(AnimationAnimationTestCompositing, InfiniteDurationAnimation) { animation->CheckCanStartAnimationOnCompositor(nullptr)); } -// This test ensures that a background-color animation can start on compositor. -TEST_F(AnimationAnimationTestCompositing, BackgroundColorComposited) { - ScopedCompositeBGColorAnimationForTest composite_bgcolor_animation(true); - SetBodyInnerHTML(R"HTML( - <div id ="target" style="width: 100px; height: 100px"> - </div> - )HTML"); - - Animation* animation = - CreateAnimation(CSSPropertyID::kBackgroundColor, "red", "green"); - - UpdateAllLifecyclePhasesForTest(); - animation->play(); - // A basic condition for an animation to be compositable is that it is set so - // by BackgroundColorPaintWorklet::GetBGColorPaintWorkletParams. - EXPECT_EQ(animation->CheckCanStartAnimationOnCompositor(nullptr), - CompositorAnimations::kNoFailure); -} - // crbug.com/1149012 // Regression test to ensure proper restart logic for composited animations on // relative transforms after a size change. In this test, the transform depends @@ -1522,7 +1765,12 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); // Kick the animation out of the play-pending state. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // No size change and animation does not require a restart. keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( @@ -1571,7 +1819,12 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( FloatSize(100, 200)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Transform is not height dependent and a change to the height does not force // an animation restart. @@ -1613,7 +1866,12 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( FloatSize(100, 200)); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Transform is not width dependent and a change to the width does not force // an animation restart. @@ -1660,13 +1918,11 @@ TEST_F(AnimationAnimationTestCompositing, Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); @@ -1727,13 +1983,11 @@ TEST_F(AnimationAnimationTestCompositing, Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); @@ -1759,7 +2013,13 @@ TEST_F(AnimationAnimationTestCompositing, UpdateAllLifecyclePhasesForTest(); const double TEST_START_TIME = 10; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + scroll_animation->setStartTime( + MakeGarbageCollected<V8CSSNumberish>(TEST_START_TIME), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setStartTime(CSSNumberish::FromDouble(TEST_START_TIME)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->play(); EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr), CompositorAnimations::kNoFailure); @@ -1861,13 +2121,11 @@ TEST_F(AnimationAnimationTestCompositing, // Create KeyframeEffect Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); @@ -1898,14 +2156,24 @@ TEST_F(AnimationAnimationTestCompositing, // Advances the animation to "finished" state. The composited animation will // be destroyed accordingly. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ(scroll_animation->playState(), "finished"); scroll_animation->Update(kTimingUpdateForAnimationFrame); GetDocument().GetPendingAnimations().Update(nullptr, true); EXPECT_FALSE(scroll_animation->HasActiveAnimationsOnCompositor()); // Restarting the animation should create a new compositor animation. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setCurrentTime(CSSNumberish::FromDouble(100)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UpdateAllLifecyclePhasesForTest(); EXPECT_EQ(scroll_animation->playState(), "running"); scroll_animation->Update(kTimingUpdateForAnimationFrame); @@ -1942,7 +2210,12 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); // Asynchronous completion. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); } @@ -1962,7 +2235,12 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->HasPendingActivity()); // Resolving the finished promise clears the pending activity. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); SimulateMicrotask(); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -1993,8 +2271,7 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_FALSE(animation->HasPendingActivity()); // Attaching a listener for the finished event indicates pending activity. - Persistent<MockEventListener> event_listener = - MakeGarbageCollected<MockEventListener>(); + MockEventListener* event_listener = MakeGarbageCollected<MockEventListener>(); animation->addEventListener(event_type_names::kFinish, event_listener); EXPECT_TRUE(animation->HasPendingActivity()); @@ -2013,7 +2290,12 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->HasPendingActivity()); // Finishing the animation asynchronously clears the pending activity. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(50000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); SimulateMicrotask(); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -2049,13 +2331,11 @@ class AnimationPendingAnimationsTest : public RenderingTest { Animation* MakeAnimation(const char* target, CompositingMode mode) { Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); @@ -2103,8 +2383,8 @@ TEST_F(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) { RunDocumentLifecycle(); SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>"); - Persistent<Animation> animA = MakeAnimation("foo", kComposited); - Persistent<Animation> animB = MakeAnimation("bar", kNonComposited); + Animation* animA = MakeAnimation("foo", kComposited); + Animation* animB = MakeAnimation("bar", kNonComposited); // B's start time synchronized with A's start time. EXPECT_TRUE(Update()); @@ -2122,8 +2402,8 @@ TEST_F(AnimationPendingAnimationsTest, RunDocumentLifecycle(); SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>"); - Persistent<Animation> animA = MakeAnimation("foo", kComposited); - Persistent<Animation> animB = MakeAnimation("bar", kNonComposited); + Animation* animA = MakeAnimation("foo", kComposited); + Animation* animB = MakeAnimation("bar", kNonComposited); EXPECT_TRUE(Update()); EXPECT_TRUE(animA->pending()); @@ -2141,8 +2421,8 @@ TEST_F(AnimationPendingAnimationsTest, SetBodyInnerHTML( "<div id='foo'></div><div id='bar'></div><div id='baz'></div>"); - Persistent<Animation> animA = MakeAnimation("foo", kComposited); - Persistent<Animation> animB = MakeAnimation("bar", kNonComposited); + Animation* animA = MakeAnimation("foo", kComposited); + Animation* animB = MakeAnimation("bar", kNonComposited); // This test simulates the conditions in crbug.com/666710. The start of a // non-composited animation is deferred in order to synchronize with a @@ -2156,8 +2436,8 @@ TEST_F(AnimationPendingAnimationsTest, EXPECT_TRUE(animB->pending()); animA->cancel(); - Persistent<Animation> animC = MakeAnimation("baz", kComposited); - Persistent<Animation> animD = MakeAnimation("bar", kNonComposited); + Animation* animC = MakeAnimation("baz", kComposited); + Animation* animD = MakeAnimation("bar", kNonComposited); EXPECT_TRUE(Update()); // B's is unblocked despite newly created composited animation. @@ -2206,13 +2486,11 @@ TEST_F(AnimationAnimationTestCompositing, Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); - Persistent<StringKeyframe> start_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>(); start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr); - Persistent<StringKeyframe> end_keyframe = - MakeGarbageCollected<StringKeyframe>(); + StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>(); end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr); diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc index 4cdbb44581a..081611af432 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc @@ -25,6 +25,8 @@ void SetV8ObjectPropertyAsString(v8::Isolate* isolate, v8::Local<v8::Object> object, const StringView& name, const StringView& value) { + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); object ->Set(isolate->GetCurrentContext(), V8String(isolate, name), V8String(isolate, value)) @@ -35,6 +37,8 @@ void SetV8ObjectPropertyAsNumber(v8::Isolate* isolate, v8::Local<v8::Object> object, const StringView& name, double value) { + v8::MicrotasksScope microtasks_scope( + isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); object ->Set(isolate->GetCurrentContext(), V8String(isolate, name), v8::Number::New(isolate, value)) diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h index b7ab9757fcd..83d0364413e 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h @@ -94,6 +94,11 @@ class CORE_EXPORT AnimationTimeDelta { AnimationTimeDelta& operator/=(T a) { return *this = (*this / a); } + double operator/(AnimationTimeDelta a) const { + CHECK(!a.is_zero()); + CHECK(!is_inf() || !a.is_inf()); + return delta_ / a.delta_; + } protected: constexpr explicit AnimationTimeDelta(double delta) : delta_(delta) {} diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc index 627b9b164aa..69683b64e20 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc @@ -88,4 +88,48 @@ TEST(AnimationTimeDeltaTest, Comparison) { AnimationTimeDelta::FromSecondsD(100)); } +TEST(AnimationTimeDeltaTest, Division) { + double inf = std::numeric_limits<double>::infinity(); + AnimationTimeDelta inf_time_delta = AnimationTimeDelta::Max(); + AnimationTimeDelta zero = AnimationTimeDelta(); + AnimationTimeDelta num = AnimationTimeDelta::FromSecondsD(5); + + // 0 / 0 = undefined + EXPECT_DEATH_IF_SUPPORTED(zero / zero, ""); + // 0 / inf = 0 + EXPECT_EQ(0, zero / inf_time_delta); + // 0 / -inf = 0 + EXPECT_EQ(0, zero / -inf_time_delta); + // 0 / 5 = 0 + EXPECT_EQ(0, zero / num); + // inf / 0 = undefined + EXPECT_DEATH_IF_SUPPORTED(inf_time_delta / zero, ""); + // -inf / 0 = undefined + EXPECT_DEATH_IF_SUPPORTED(-inf_time_delta / zero, ""); + // inf / inf = undefined + EXPECT_DEATH_IF_SUPPORTED(inf_time_delta / inf_time_delta, ""); + // inf / -inf = undefined + EXPECT_DEATH_IF_SUPPORTED(inf_time_delta / -inf_time_delta, ""); + // -inf / inf = undefined + EXPECT_DEATH_IF_SUPPORTED(-inf_time_delta / inf_time_delta, ""); + // -inf / -inf = undefined + EXPECT_DEATH_IF_SUPPORTED(-inf_time_delta / -inf_time_delta, ""); + // inf / 5 = inf + EXPECT_EQ(inf, inf_time_delta / num); + // inf / -5 = -inf + EXPECT_EQ(-inf, inf_time_delta / -num); + // -inf / 5 = -inf + EXPECT_EQ(-inf, -inf_time_delta / num); + // -inf / -5 = inf + EXPECT_EQ(inf, -inf_time_delta / -num); + // 5 / 0 = undefined + EXPECT_DEATH_IF_SUPPORTED(num / zero, ""); + // 5 / inf = 0 + EXPECT_EQ(0, num / inf_time_delta); + // 5 / -inf = 0 + EXPECT_EQ(0, num / -inf_time_delta); + // 5 / 2 = 2.5 + EXPECT_EQ(2.5, num / AnimationTimeDelta::FromSecondsD(2)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc index e6a822b50c8..26237576c55 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "base/trace_event/trace_event.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/document_animations.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -40,32 +41,47 @@ bool CompareAnimations(const Member<Animation>& left, Animation::CompareAnimationsOrdering::kPointerOrder); } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* AnimationTimeline::currentTime() { + const absl::optional<base::TimeDelta>& result = CurrentPhaseAndTime().time; + if (result) + return MakeGarbageCollected<V8CSSNumberish>(result->InMillisecondsF()); + return nullptr; +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void AnimationTimeline::currentTime(CSSNumberish& currentTime) { - base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time; + absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; currentTime = result ? CSSNumberish::FromDouble(result->InMillisecondsF()) : CSSNumberish(); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -base::Optional<AnimationTimeDelta> AnimationTimeline::CurrentTime() { - base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time; - return result ? base::make_optional(AnimationTimeDelta(result.value())) - : base::nullopt; +absl::optional<AnimationTimeDelta> AnimationTimeline::CurrentTime() { + absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; + return result ? absl::make_optional(AnimationTimeDelta(result.value())) + : absl::nullopt; } -base::Optional<double> AnimationTimeline::CurrentTimeMilliseconds() { - base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time; - return result ? base::make_optional(result->InMillisecondsF()) - : base::nullopt; +absl::optional<double> AnimationTimeline::CurrentTimeMilliseconds() { + absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; + return result ? absl::make_optional(result->InMillisecondsF()) + : absl::nullopt; } -base::Optional<double> AnimationTimeline::CurrentTimeSeconds() { - base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time; - return result ? base::make_optional(result->InSecondsF()) : base::nullopt; +absl::optional<double> AnimationTimeline::CurrentTimeSeconds() { + absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; + return result ? absl::make_optional(result->InSecondsF()) : absl::nullopt; } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* AnimationTimeline::duration() { + return nullptr; +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void AnimationTimeline::duration(CSSNumberish& duration) { duration = CSSNumberish(); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) String AnimationTimeline::phase() { switch (CurrentPhaseAndTime().phase) { diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h index 8cc0a6252e8..0ab43c1998f 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h @@ -23,7 +23,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { public: struct PhaseAndTime { TimelinePhase phase; - base::Optional<base::TimeDelta> time; + absl::optional<base::TimeDelta> time; bool operator==(const PhaseAndTime& other) const { return phase == other.phase && time == other.time; } @@ -35,12 +35,20 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { AnimationTimeline(Document*); ~AnimationTimeline() override = default; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + virtual V8CSSNumberish* currentTime(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) virtual void currentTime(CSSNumberish&); - base::Optional<AnimationTimeDelta> CurrentTime(); - base::Optional<double> CurrentTimeMilliseconds(); - base::Optional<double> CurrentTimeSeconds(); - +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + absl::optional<AnimationTimeDelta> CurrentTime(); + absl::optional<double> CurrentTimeMilliseconds(); + absl::optional<double> CurrentTimeSeconds(); + +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + virtual V8CSSNumberish* duration(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) virtual void duration(CSSNumberish&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) String phase(); TimelinePhase Phase() { return CurrentPhaseAndTime().phase; } @@ -62,7 +70,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { // // Changing scroll-linked animation start_time initialization is under // consideration here: https://github.com/w3c/csswg-drafts/issues/2075. - virtual base::Optional<base::TimeDelta> InitialStartTimeForAnimations() = 0; + virtual absl::optional<base::TimeDelta> InitialStartTimeForAnimations() = 0; Document* GetDocument() { return document_; } virtual void AnimationAttached(Animation*); virtual void AnimationDetached(Animation*); @@ -119,9 +127,9 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { std::unique_ptr<CompositorAnimationTimeline> compositor_timeline_; - base::Optional<PhaseAndTime> last_current_phase_and_time_; + absl::optional<PhaseAndTime> last_current_phase_and_time_; }; } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIMELINE_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/color_property_functions.cc b/chromium/third_party/blink/renderer/core/animation/color_property_functions.cc index 0975b09fa67..b1a4d4a448f 100644 --- a/chromium/third_party/blink/renderer/core/animation/color_property_functions.cc +++ b/chromium/third_party/blink/renderer/core/animation/color_property_functions.cc @@ -18,6 +18,10 @@ OptionalStyleColor ColorPropertyFunctions::GetUnvisitedColor( const CSSProperty& property, const ComputedStyle& style) { switch (property.PropertyID()) { + case CSSPropertyID::kAccentColor: + if (style.AccentColor().IsAutoColor()) + return nullptr; + return style.AccentColor().ToStyleColor(); case CSSPropertyID::kBackgroundColor: return style.BackgroundColor(); case CSSPropertyID::kBorderLeftColor: @@ -64,6 +68,8 @@ OptionalStyleColor ColorPropertyFunctions::GetVisitedColor( const CSSProperty& property, const ComputedStyle& style) { switch (property.PropertyID()) { + case CSSPropertyID::kAccentColor: + return style.AccentColor(); case CSSPropertyID::kBackgroundColor: return style.InternalVisitedBackgroundColor(); case CSSPropertyID::kBorderLeftColor: @@ -113,6 +119,9 @@ void ColorPropertyFunctions::SetUnvisitedColor(const CSSProperty& property, const Color& color) { StyleColor style_color(color); switch (property.PropertyID()) { + case CSSPropertyID::kAccentColor: + style.SetAccentColor(StyleAutoColor(color)); + return; case CSSPropertyID::kBackgroundColor: style.SetBackgroundColor(style_color); return; @@ -166,6 +175,9 @@ void ColorPropertyFunctions::SetVisitedColor(const CSSProperty& property, const Color& color) { StyleColor style_color(color); switch (property.PropertyID()) { + case CSSPropertyID::kAccentColor: + // The accent-color property is not valid for :visited. + return; case CSSPropertyID::kBackgroundColor: style.SetInternalVisitedBackgroundColor(style_color); return; diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc index 5baba636192..4da41e05724 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc @@ -33,6 +33,7 @@ #include <algorithm> #include <cmath> #include <memory> + #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h" @@ -42,9 +43,11 @@ #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h" #include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" +#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h" #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" @@ -163,6 +166,43 @@ void DefaultToUnsupportedProperty( } } +// True if it is either a no-op background-color animation, or a no-op custom +// property animation. +bool IsNoOpBGColorOrVariableAnimation(const PropertyHandle& property, + const LayoutObject* layout_object) { + // If the background color paint worklet was painted, a unique id will be + // generated. See BackgroundColorPaintWorklet::GetBGColorPaintWorkletParams + // for details. + // Similar to that, if a CSS paint worklet was painted, a unique id will be + // generated. See CSSPaintValue::GetImage for details. + bool has_unique_id = layout_object->FirstFragment().HasUniqueId(); + if (has_unique_id) + return false; + // Now the |has_unique_id| == false. + bool is_no_op_bgcolor_anim = + RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled() && + property.GetCSSProperty().PropertyID() == CSSPropertyID::kBackgroundColor; + bool is_no_op_variable_anim = + property.GetCSSProperty().PropertyID() == CSSPropertyID::kVariable; + return is_no_op_variable_anim || is_no_op_bgcolor_anim; +} + +bool CompositedAnimationRequiresProperties(CSSPropertyID property) { + switch (property) { + case CSSPropertyID::kOpacity: + case CSSPropertyID::kBackdropFilter: + case CSSPropertyID::kRotate: + case CSSPropertyID::kScale: + case CSSPropertyID::kTranslate: + case CSSPropertyID::kTransform: + case CSSPropertyID::kFilter: + return true; + default: + return false; + } + return false; +} + } // namespace CompositorElementIdNamespace @@ -284,22 +324,33 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( // like regular filters do, so they can still be composited. break; case CSSPropertyID::kBackgroundColor: { - // When this is true, we have a background-color animation in the body - // element, while the view is responsible for painting the body's - // background. In this case, we need to let the background-color - // animation run on the main thread because the body is not painted - // with BackgroundColorPaintWorklet. - bool background_transfers_to_view = - target_element.GetLayoutBoxModelObject() && - target_element.GetLayoutBoxModelObject() - ->BackgroundTransfersToView(); + bool background_transfers_to_view = false; + Animation* compositable_animation = nullptr; + if (RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled()) { + BackgroundColorPaintImageGenerator* generator = + target_element.GetDocument() + .GetFrame() + ->GetBackgroundColorPaintImageGenerator(); + compositable_animation = + generator->GetAnimationIfCompositable(&target_element); + // When this is true, we have a background-color animation in the + // body element, while the view is responsible for painting the + // body's background. In this case, we need to let the + // background-color animation run on the main thread because the + // wbody is not painted ith BackgroundColorPaintWorklet. + background_transfers_to_view = + target_element.GetLayoutBoxModelObject() && + target_element.GetLayoutBoxModelObject() + ->BackgroundTransfersToView(); + } // The table rows and table cols are painted into table cells, which // means their background is never painted using // BackgroundColorPaintWorklet, as a result, we should not composite // the background color animation on the table rows or cols. if (!RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled() || - layout_object->IsLayoutTableCol() || - layout_object->IsTableRow() || background_transfers_to_view) { + !layout_object || layout_object->IsLayoutTableCol() || + layout_object->IsTableRow() || background_transfers_to_view || + !compositable_animation) { DefaultToUnsupportedProperty(unsupported_properties, property, &reasons); } @@ -356,24 +407,26 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( reasons |= kInvalidAnimationOrEffect; } - if (paint_artifact_compositor) { - // If we don't have paint properties, we won't have a UniqueId to use - // for checking here. - if (!target_element.GetLayoutObject() || - !target_element.GetLayoutObject() - ->FirstFragment() - .PaintProperties()) { + if (CompositedAnimationRequiresProperties( + property.GetCSSProperty().PropertyID())) { + if (!paint_artifact_compositor) { + // TODO(pdr): We should return |kTargetHasInvalidCompositingState|. continue; - } - - CompositorElementId target_element_id = - CompositorElementIdFromUniqueObjectId( - layout_object->UniqueId(), - CompositorElementNamespaceForProperty( - property.GetCSSProperty().PropertyID())); - DCHECK(target_element_id); - if (!paint_artifact_compositor->HasComposited(target_element_id)) + } else if (!target_element.GetLayoutObject() || + !target_element.GetLayoutObject() + ->FirstFragment() + .PaintProperties()) { reasons |= kTargetHasInvalidCompositingState; + } else { + CompositorElementId target_element_id = + CompositorElementIdFromUniqueObjectId( + layout_object->UniqueId(), + CompositorElementNamespaceForProperty( + property.GetCSSProperty().PropertyID())); + DCHECK(target_element_id); + if (!paint_artifact_compositor->HasComposited(target_element_id)) + reasons |= kTargetHasInvalidCompositingState; + } } } } @@ -508,7 +561,7 @@ void CompositorAnimations::CancelIncompatibleAnimationsOnCompositor( void CompositorAnimations::StartAnimationOnCompositor( const Element& element, int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, const Timing& timing, const Animation* animation, @@ -598,7 +651,7 @@ bool CompositorAnimations::ConvertTimingForCompositor( return false; // FIXME: Compositor does not know anything about endDelay. - if (timing.end_delay != 0) + if (!timing.end_delay.is_zero()) return false; if (!timing.iteration_duration || !timing.iteration_count || @@ -608,7 +661,8 @@ bool CompositorAnimations::ConvertTimingForCompositor( // Compositor's time offset is positive for seeking into the animation. DCHECK(animation_playback_rate); - double delay = animation_playback_rate > 0 ? timing.start_delay : 0; + double delay = + animation_playback_rate > 0 ? timing.start_delay.InSecondsF() : 0; out.scaled_time_offset = -base::TimeDelta::FromSecondsD(delay / animation_playback_rate) + time_offset; @@ -714,7 +768,7 @@ void CompositorAnimations::GetAnimationOnCompositor( const Element& target_element, const Timing& timing, int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, const KeyframeEffectModelBase& effect, Vector<std::unique_ptr<CompositorKeyframeModel>>& keyframe_models, @@ -838,10 +892,16 @@ void CompositorAnimations::GetAnimationOnCompositor( if (start_time) keyframe_model->SetStartTime(start_time.value()); - keyframe_model->SetElementId(CompositorElementIdFromUniqueObjectId( - target_element.GetLayoutObject()->UniqueId(), - CompositorElementNamespaceForProperty( - property.GetCSSProperty().PropertyID()))); + // By default, it is a kInvalidElementId. + CompositorElementId id; + if (!IsNoOpBGColorOrVariableAnimation(property, + target_element.GetLayoutObject())) { + id = CompositorElementIdFromUniqueObjectId( + target_element.GetLayoutObject()->UniqueId(), + CompositorElementNamespaceForProperty( + property.GetCSSProperty().PropertyID())); + } + keyframe_model->SetElementId(id); keyframe_model->SetIterations(compositor_timing.adjusted_iteration_count); keyframe_model->SetIterationStart(compositor_timing.iteration_start); keyframe_model->SetTimeOffset(compositor_timing.scaled_time_offset); diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h index c107d8b8fed..678215237a4 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h @@ -119,7 +119,7 @@ class CORE_EXPORT CompositorAnimations { static void StartAnimationOnCompositor( const Element&, int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, const Timing&, const Animation*, @@ -158,7 +158,7 @@ class CORE_EXPORT CompositorAnimations { const Element&, const Timing&, int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, const KeyframeEffectModelBase&, Vector<std::unique_ptr<CompositorKeyframeModel>>& animations, @@ -193,4 +193,4 @@ class CORE_EXPORT CompositorAnimations { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_COMPOSITOR_ANIMATIONS_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 4c5fa9d5378..45174540cfe 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc @@ -57,7 +57,6 @@ #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/layout/layout_object.h" -#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/object_paint_properties.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -75,6 +74,7 @@ #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/testing/find_cc_layer.h" #include "third_party/blink/renderer/platform/testing/histogram_tester.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -160,13 +160,18 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations, // Having an animation would normally ensure this but these tests don't // explicitly construct a full animation on the element. SetBodyInnerHTML(R"HTML( - <div id='test' style='will-change: opacity,filter,transform; height:100px; background: green;'></div> - <span id='inline' style='will-change: opacity,filter,transform;'>text</div> + <div id='test' style='will-change: opacity,filter,transform; + height:100px; background: green;'> + </div> + <span id='inline' style='will-change: opacity,filter,transform;'> + text + </span> )HTML"); element_ = GetDocument().getElementById("test"); inline_ = GetDocument().getElementById("inline"); helper_.Initialize(nullptr, nullptr, nullptr); + helper_.Resize(gfx::Size(800, 600)); base_url_ = "http://www.test.com/"; } @@ -215,7 +220,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations, Vector<std::unique_ptr<CompositorKeyframeModel>>& keyframe_models, double animation_playback_rate) { CompositorAnimations::GetAnimationOnCompositor( - *element_, timing, 0, base::nullopt, base::TimeDelta(), effect, + *element_, timing, 0, absl::nullopt, base::TimeDelta(), effect, keyframe_models, animation_playback_rate); } @@ -235,7 +240,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations, Timing CreateCompositableTiming() { Timing timing; - timing.start_delay = 0; + timing.start_delay = AnimationTimeDelta(); timing.fill_mode = Timing::FillMode::NONE; timing.iteration_start = 0; timing.iteration_count = 1; @@ -734,7 +739,7 @@ TEST_P(AnimationCompositorAnimationsTest, const double play_reverse = -1; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(20); - timing_.start_delay = 2.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(2.0); EXPECT_TRUE( ConvertTimingForCompositor(timing_, compositor_timing_, play_forward)); EXPECT_DOUBLE_EQ(-2.0, compositor_timing_.scaled_time_offset.InSecondsF()); @@ -742,7 +747,7 @@ TEST_P(AnimationCompositorAnimationsTest, ConvertTimingForCompositor(timing_, compositor_timing_, play_reverse)); EXPECT_DOUBLE_EQ(0.0, compositor_timing_.scaled_time_offset.InSecondsF()); - timing_.start_delay = -2.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-2.0); EXPECT_TRUE( ConvertTimingForCompositor(timing_, compositor_timing_, play_forward)); EXPECT_DOUBLE_EQ(2.0, compositor_timing_.scaled_time_offset.InSecondsF()); @@ -774,7 +779,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.iteration_count = std::numeric_limits<double>::infinity(); timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = -6.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-6.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_EQ(std::numeric_limits<double>::infinity(), @@ -786,17 +791,17 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.iteration_count = 4.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = 6.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(6.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(-6.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_DOUBLE_EQ(4.0, compositor_timing_.adjusted_iteration_count); - timing_.start_delay = -6.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-6.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_DOUBLE_EQ(4.0, compositor_timing_.adjusted_iteration_count); - timing_.start_delay = 21.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(21.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); } @@ -825,7 +830,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.direction = Timing::PlaybackDirection::ALTERNATE_NORMAL; timing_.iteration_count = 4.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = -6.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-6.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count); @@ -835,7 +840,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.direction = Timing::PlaybackDirection::ALTERNATE_NORMAL; timing_.iteration_count = 4.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = -11.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-11.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count); @@ -845,7 +850,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.direction = Timing::PlaybackDirection::ALTERNATE_REVERSE; timing_.iteration_count = 4.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = -6.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-6.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count); @@ -855,7 +860,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.direction = Timing::PlaybackDirection::ALTERNATE_REVERSE; timing_.iteration_count = 4.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5); - timing_.start_delay = -11.0; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(-11.0); EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_)); EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset.InSecondsF()); EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count); @@ -958,7 +963,7 @@ TEST_P(AnimationCompositorAnimationsTest, EXPECT_EQ(CheckCanStartEffectOnCompositor(timing, *element_.Get(), animation, *animation_effect), CompositorAnimations::kNoFailure); - timing.end_delay = 1.0; + timing.end_delay = AnimationTimeDelta::FromSecondsD(1.0); EXPECT_TRUE(CheckCanStartEffectOnCompositor(timing, *element_.Get(), animation, *animation_effect) & CompositorAnimations::kEffectHasUnsupportedTimingParameters); @@ -1047,12 +1052,6 @@ TEST_P(AnimationCompositorAnimationsTest, TEST_P(AnimationCompositorAnimationsTest, CanStartElementOnCompositorEffectFilter) { - // TODO(https://crbug.com/960953): Create a filter effect node when - // will-change: filter is specified so that filter effects can be tested - // without compositing changes. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - // Filter Properties use a different ID namespace StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel( CreateReplaceOpKeyframe(CSSPropertyID::kFilter, "none", 0), @@ -1461,7 +1460,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.iteration_count = 5.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1.75); - timing_.start_delay = kStartDelay; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(kStartDelay); std::unique_ptr<CompositorKeyframeModel> keyframe_model = ConvertToCompositorAnimation(*effect); @@ -1620,7 +1619,7 @@ TEST_P(AnimationCompositorAnimationsTest, timing_.iteration_count = 5.0; timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1.5); - timing_.start_delay = kNegativeStartDelay; + timing_.start_delay = AnimationTimeDelta::FromSecondsD(kNegativeStartDelay); timing_.direction = Timing::PlaybackDirection::ALTERNATE_REVERSE; std::unique_ptr<CompositorKeyframeModel> keyframe_model = @@ -2009,6 +2008,15 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimationTimeout) { EXPECT_FALSE(host->NextFrameHasPendingRAF()); } +TEST_P(AnimationCompositorAnimationsTest, TrackSVGAnimation) { + LoadTestData("svg-smil-animation.html"); + + cc::AnimationHost* host = GetFrame()->View()->GetCompositorAnimationHost(); + + BeginFrame(); + EXPECT_TRUE(host->HasSmilAnimation()); +} + TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimationNoneRegistered) { SetBodyInnerHTML("<div id='box'></div>"); @@ -2043,10 +2051,6 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedCustomProperty) { } TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) { - // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - LoadTestData("transform-animation.html"); Document* document = GetFrame()->GetDocument(); Element* target = document->getElementById("target"); @@ -2077,10 +2081,6 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) { } TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) { - // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - LoadTestData("scale-animation.html"); Document* document = GetFrame()->GetDocument(); Element* target = document->getElementById("target"); @@ -2112,10 +2112,6 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) { TEST_P(AnimationCompositorAnimationsTest, NonAnimatedTransformPropertyChangeGetsUpdated) { - // TODO(wangxianzhu): Fix this test for CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - LoadTestData("transform-animation-update.html"); Document* document = GetFrame()->GetDocument(); Element* target = document->getElementById("target"); @@ -2146,10 +2142,8 @@ TEST_P(AnimationCompositorAnimationsTest, EXPECT_FALSE(transform->Matrix().IsIdentity()); // Rotated EXPECT_EQ(transform->GetBackfaceVisibilityForTesting(), TransformPaintPropertyNode::BackfaceVisibility::kVisible); - const CompositedLayerMapping* composited_layer_mapping = - target->GetLayoutBoxModelObject()->Layer()->GetCompositedLayerMapping(); - ASSERT_NE(nullptr, composited_layer_mapping); - const auto& layer = composited_layer_mapping->MainGraphicsLayer()->CcLayer(); + const auto& layer = + *CcLayersByDOMElementId(document->View()->RootCcLayer(), "target")[0]; EXPECT_FALSE(layer.should_check_backface_visibility()); // Change the backface visibility, while the compositor animation is diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc index 9e637788e15..34f54d30029 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc @@ -60,11 +60,19 @@ void CSSAnimation::setTimeline(AnimationTimeline* timeline) { ignore_css_timeline_ = true; } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +void CSSAnimation::setStartTime(const V8CSSNumberish* start_time, + ExceptionState& exception_state) { + PlayStateTransitionScope scope(*this); + Animation::setStartTime(start_time, exception_state); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void CSSAnimation::setStartTime(CSSNumberish start_time_ms, ExceptionState& exception_state) { PlayStateTransitionScope scope(*this); Animation::setStartTime(start_time_ms, exception_state); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) AnimationEffect::EventDelegate* CSSAnimation::CreateEventDelegate( Element* target, diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h index 32bfc8a162c..ad68b5b8c37 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h @@ -51,7 +51,12 @@ class CORE_EXPORT CSSAnimation : public Animation { void play(ExceptionState& = ASSERT_NO_EXCEPTION) override; void reverse(ExceptionState& = ASSERT_NO_EXCEPTION) override; void setTimeline(AnimationTimeline*) override; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + void setStartTime(const V8CSSNumberish* start_time, + ExceptionState& exception_state) override; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void setStartTime(CSSNumberish, ExceptionState&) override; +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // When set, subsequent changes to animation-play-state no longer affect the // play state. diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h index 7efb7955c4a..d2143017e86 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h @@ -303,4 +303,4 @@ class CORE_EXPORT CSSAnimationUpdate final { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATION_UPDATE_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc index c29ba003d61..37c670acca9 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc @@ -35,6 +35,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h" @@ -156,7 +157,7 @@ StringKeyframeVector ProcessKeyframesRule( } // Finds the index of a keyframe with matching offset and easing. -base::Optional<int> FindIndexOfMatchingKeyframe( +absl::optional<int> FindIndexOfMatchingKeyframe( const StringKeyframeVector& keyframes, wtf_size_t start_index, double offset, @@ -172,7 +173,7 @@ base::Optional<int> FindIndexOfMatchingKeyframe( if (easing.ToString() == keyframe->Easing().ToString()) return i; } - return base::nullopt; + return absl::nullopt; } // Tests conditions for inserting a bounding keyframe, which are outlined in @@ -197,7 +198,6 @@ bool NeedsBoundaryKeyframe(StringKeyframe* candidate, StringKeyframeEffectModel* CreateKeyframeEffectModel( StyleResolver* resolver, - const Element* animating_element, Element& element, const ComputedStyle* style, const ComputedStyle* parent_style, @@ -280,7 +280,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( // Avoid unnecessary creation of extra keyframes by merging into // existing keyframes. - base::Optional<int> existing_keyframe_index = FindIndexOfMatchingKeyframe( + absl::optional<int> existing_keyframe_index = FindIndexOfMatchingKeyframe( keyframes, source_index + merged_frame_count + 1, keyframe_offset, easing); int target_index; @@ -397,27 +397,33 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( // Returns the start time of an animation given the start delay. A negative // start delay results in the animation starting with non-zero progress. -AnimationTimeDelta StartTimeFromDelay(double start_delay) { - return AnimationTimeDelta::FromSecondsD(start_delay < 0 ? -start_delay : 0); +AnimationTimeDelta StartTimeFromDelay(AnimationTimeDelta start_delay) { + return start_delay < AnimationTimeDelta() ? -start_delay + : AnimationTimeDelta(); } // Timing functions for computing elapsed time of an event. AnimationTimeDelta IntervalStart(const AnimationEffect& effect) { - const double start_delay = effect.SpecifiedTiming().start_delay; - const double active_duration = effect.SpecifiedTiming().ActiveDuration(); - return AnimationTimeDelta::FromSecondsD( - std::fmax(std::fmin(-start_delay, active_duration), 0.0)); + AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; + const AnimationTimeDelta active_duration = + effect.SpecifiedTiming().ActiveDuration(); + // This fixes a problem where start_delay could be -0 + if (!start_delay.is_zero()) { + start_delay = -start_delay; + } + return std::max(std::min(start_delay, active_duration), AnimationTimeDelta()); } AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) { - const double start_delay = effect.SpecifiedTiming().start_delay; - const double end_delay = effect.SpecifiedTiming().end_delay; - const double active_duration = effect.SpecifiedTiming().ActiveDuration(); - const double target_effect_end = - std::max(start_delay + active_duration + end_delay, 0.0); - return AnimationTimeDelta::FromSecondsD(std::max( - std::min(target_effect_end - start_delay, active_duration), 0.0)); + const AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; + const AnimationTimeDelta end_delay = effect.SpecifiedTiming().end_delay; + const AnimationTimeDelta active_duration = + effect.SpecifiedTiming().ActiveDuration(); + const AnimationTimeDelta target_effect_end = + std::max(start_delay + active_duration + end_delay, AnimationTimeDelta()); + return std::max(std::min(target_effect_end - start_delay, active_duration), + AnimationTimeDelta()); } AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect, @@ -433,12 +439,12 @@ AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect, } CSSScrollTimeline* CreateCSSScrollTimeline( - Element* element, + Document& document, CSSScrollTimeline::Options&& options) { if (!options.IsValid()) return nullptr; - auto* scroll_timeline = MakeGarbageCollected<CSSScrollTimeline>( - &element->GetDocument(), std::move(options)); + auto* scroll_timeline = + MakeGarbageCollected<CSSScrollTimeline>(&document, std::move(options)); // It's is not allowed for a style resolve to create timelines that // needs timing updates (i.e. AnimationTimeline::NeedsAnimationTimingUpdate() // must return false). Servicing animations after creation preserves this @@ -471,7 +477,7 @@ AnimationTimeline* ComputeTimeline(Element* element, return nullptr; } if (rule) { - CSSScrollTimeline::Options options(element, *rule); + CSSScrollTimeline::Options options(document, *rule); const AtomicString& name = timeline_name.GetName().GetValue(); // When multiple animations refer to the same @scroll-timeline, the same @@ -486,8 +492,11 @@ AnimationTimeline* ComputeTimeline(Element* element, if (timeline->Matches(options)) return existing_timeline; } - if (auto* timeline = CreateCSSScrollTimeline(element, std::move(options))) + if (auto* timeline = + CreateCSSScrollTimeline(document, std::move(options))) { + document.GetDocumentAnimations().CacheCSSScrollTimeline(*timeline); return timeline; + } } return nullptr; } @@ -556,13 +565,13 @@ bool ComputedValuesEqual(const PropertyHandle& property, void CSSAnimations::CalculateCompositorAnimationUpdate( CSSAnimationUpdate& update, - const Element* animating_element, + const Element& animating_element, Element& element, const ComputedStyle& style, const ComputedStyle* parent_style, bool was_viewport_resized) { ElementAnimations* element_animations = - animating_element ? animating_element->GetElementAnimations() : nullptr; + animating_element.GetElementAnimations(); // If the change in style is only due to the Blink-side animation update, we // do not need to update the compositor-side animations. The compositor is @@ -571,7 +580,7 @@ void CSSAnimations::CalculateCompositorAnimationUpdate( if (!element_animations || element_animations->IsAnimationStyleChange()) return; - const ComputedStyle* old_style = animating_element->GetComputedStyle(); + const ComputedStyle* old_style = animating_element.GetComputedStyle(); if (!old_style || old_style->IsEnsuredInDisplayNone() || !old_style->ShouldCompositeForCurrentAnimations()) { return; @@ -617,13 +626,13 @@ void CSSAnimations::CalculateCompositorAnimationUpdate( } void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, - const Element* animating_element, + const Element& animating_element, Element& element, const ComputedStyle& style, const ComputedStyle* parent_style, StyleResolver* resolver) { ElementAnimations* element_animations = - animating_element ? animating_element->GetElementAnimations() : nullptr; + animating_element.GetElementAnimations(); bool is_animation_style_change = element_animations && element_animations->IsAnimationStyleChange(); @@ -640,8 +649,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, // Rebuild the keyframe model for a CSS animation if it may have been // invalidated by a change to the text direction or writing mode. - const ComputedStyle* old_style = - animating_element ? animating_element->GetComputedStyle() : nullptr; + const ComputedStyle* old_style = animating_element.GetComputedStyle(); bool logical_property_mapping_change = !old_style || old_style->Direction() != style.Direction() || old_style->GetWritingMode() != style.GetWritingMode(); @@ -758,11 +766,11 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, timeline != existing_animation->Timeline()) { DCHECK(!is_animation_style_change); - base::Optional<TimelinePhase> inherited_phase; - base::Optional<AnimationTimeDelta> inherited_time; + absl::optional<TimelinePhase> inherited_phase; + absl::optional<AnimationTimeDelta> inherited_time; if (timeline) { - inherited_phase = base::make_optional(timeline->Phase()); + inherited_phase = absl::make_optional(timeline->Phase()); inherited_time = animation->UnlimitedCurrentTime(); if (will_be_playing && @@ -776,8 +784,8 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, update.UpdateAnimation( existing_animation_index, animation, *MakeGarbageCollected<InertEffect>( - CreateKeyframeEffectModel(resolver, animating_element, - element, &style, parent_style, name, + CreateKeyframeEffectModel(resolver, element, &style, + parent_style, name, keyframe_timing_function.get(), i), timing, is_paused, inherited_time, inherited_phase), specified_timing, keyframes_rule, timeline, @@ -790,21 +798,19 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, AnimationTimeline* timeline = ComputeTimeline(&element, timeline_name, scroll_timeline_rule, nullptr /* existing_timeline */); - base::Optional<TimelinePhase> inherited_phase; - base::Optional<AnimationTimeDelta> inherited_time; - if (timeline) { - if (timeline->IsMonotonicallyIncreasing()) { - inherited_time = AnimationTimeDelta(); - } else { - inherited_phase = base::make_optional(timeline->Phase()); - inherited_time = timeline->CurrentTime(); - } + absl::optional<TimelinePhase> inherited_phase; + absl::optional<AnimationTimeDelta> inherited_time = + AnimationTimeDelta(); + + if (timeline && !timeline->IsMonotonicallyIncreasing()) { + inherited_phase = absl::make_optional(timeline->Phase()); + inherited_time = timeline->CurrentTime(); } update.StartAnimation( name, name_index, i, *MakeGarbageCollected<InertEffect>( - CreateKeyframeEffectModel(resolver, animating_element, element, - &style, parent_style, name, + CreateKeyframeEffectModel(resolver, element, &style, + parent_style, name, keyframe_timing_function.get(), i), timing, is_paused, inherited_time, inherited_phase), specified_timing, keyframes_rule, timeline, @@ -846,9 +852,9 @@ AnimationEffect::EventDelegate* CSSAnimations::CreateEventDelegate( Timing::Phase previous_phase = old_animation_delegate ? old_animation_delegate->getPreviousPhase() : Timing::kPhaseNone; - base::Optional<double> previous_iteration = + absl::optional<double> previous_iteration = old_animation_delegate ? old_animation_delegate->getPreviousIteration() - : base::nullopt; + : absl::nullopt; return MakeGarbageCollected<AnimationEventDelegate>( element, animation_name, previous_phase, previous_iteration); } @@ -1038,9 +1044,14 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { // Set the current time as the start time for retargeted transitions if (retargeted_compositor_transitions.Contains(property)) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(element->GetDocument().Timeline().currentTime(), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time; element->GetDocument().Timeline().currentTime(current_time); animation->setStartTime(current_time); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } animation->Update(kTimingUpdateOnDemand); running_transition->animation = animation; @@ -1061,8 +1072,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( if (property.IsCSSCustomProperty()) { if (state.update.ActiveInterpolationsForCustomAnimations().Contains( property) || - (state.animating_element->GetElementAnimations() && - state.animating_element->GetElementAnimations() + (state.animating_element.GetElementAnimations() && + state.animating_element.GetElementAnimations() ->CssAnimations() .previous_active_interpolations_for_custom_animations_.Contains( property))) { @@ -1070,8 +1081,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( } } else if (state.update.ActiveInterpolationsForStandardAnimations().Contains( property) || - (state.animating_element->GetElementAnimations() && - state.animating_element->GetElementAnimations() + (state.animating_element.GetElementAnimations() && + state.animating_element.GetElementAnimations() ->CssAnimations() .previous_active_interpolations_for_standard_animations_ .Contains(property))) { @@ -1089,7 +1100,7 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( if (!state.transition_data) { if (!running_transition->animation->FinishedInternal()) { UseCounter::Count( - state.animating_element->GetDocument(), + state.animating_element.GetDocument(), WebFeature::kCSSTransitionCancelledByRemovingStyle); } // TODO(crbug.com/934700): Add a return to this branch to correctly @@ -1100,8 +1111,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( } } state.update.CancelTransition(property); - DCHECK(!state.animating_element->GetElementAnimations() || - !state.animating_element->GetElementAnimations() + DCHECK(!state.animating_element.GetElementAnimations() || + !state.animating_element.GetElementAnimations() ->IsAnimationStyleChange()); if (ComputedValuesEqual( @@ -1112,13 +1123,13 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( } } - // In the default configutation (transition: all 0s) we continue and cancel + // In the default configuration (transition: all 0s) we continue and cancel // transitions but do not start them. if (!state.transition_data) return; const PropertyRegistry* registry = - state.animating_element->GetDocument().GetPropertyRegistry(); + state.animating_element.GetDocument().GetPropertyRegistry(); if (property.IsCSSCustomProperty()) { if (!registry || !registry->Registration(property.CustomPropertyName())) { return; @@ -1129,7 +1140,7 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( // we are transitioning from if the final destination is changing. if (!state.before_change_style) { ElementAnimations* element_animations = - state.animating_element->GetElementAnimations(); + state.animating_element.GetElementAnimations(); if (element_animations) { const ComputedStyle* base_style = element_animations->BaseComputedStyle(); if (base_style) { @@ -1152,8 +1163,7 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( return; } - CSSInterpolationTypesMap map(registry, - state.animating_element->GetDocument()); + CSSInterpolationTypesMap map(registry, state.animating_element.GetDocument()); CSSInterpolationEnvironment old_environment(map, *state.before_change_style); CSSInterpolationEnvironment new_environment(map, state.style); const InterpolationType* transition_type = nullptr; @@ -1188,7 +1198,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( Timing timing = state.transition_data->ConvertToTiming(transition_index); // CSS Transitions always have a valid duration (i.e. the value 'auto' is not // supported), so iteration_duration will always be set. - if (timing.start_delay + timing.iteration_duration->InSecondsF() <= 0) { + if (timing.start_delay + timing.iteration_duration.value() <= + AnimationTimeDelta()) { // We may have started a transition in a prior CSSTransitionData update, // this CSSTransitionData update needs to override them. // TODO(alancutter): Just iterate over the CSSTransitionDatas in reverse and @@ -1203,8 +1214,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( double reversing_shortening_factor = 1; if (interrupted_transition) { AnimationEffect* effect = interrupted_transition->animation->effect(); - const base::Optional<double> interrupted_progress = - effect ? effect->Progress() : base::nullopt; + const absl::optional<double> interrupted_progress = + effect ? effect->Progress() : absl::nullopt; if (interrupted_progress) { reversing_adjusted_start_value = interrupted_transition->to.get(); reversing_shortening_factor = @@ -1213,7 +1224,7 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( (1 - interrupted_transition->reversing_shortening_factor), 0.0, 1.0); timing.iteration_duration.value() *= reversing_shortening_factor; - if (timing.start_delay < 0) { + if (timing.start_delay < AnimationTimeDelta()) { timing.start_delay *= reversing_shortening_factor; } } @@ -1254,9 +1265,9 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( property, state.before_change_style, state.cloned_style, reversing_adjusted_start_value, reversing_shortening_factor, *MakeGarbageCollected<InertEffect>(model, timing, false, - AnimationTimeDelta(), base::nullopt)); - DCHECK(!state.animating_element->GetElementAnimations() || - !state.animating_element->GetElementAnimations() + AnimationTimeDelta(), absl::nullopt)); + DCHECK(!state.animating_element.GetElementAnimations() || + !state.animating_element.GetElementAnimations() ->IsAnimationStyleChange()); } @@ -1317,16 +1328,13 @@ void CSSAnimations::CalculateTransitionUpdateForStandardProperty( void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, PropertyPass property_pass, - Element* animating_element, + Element& animating_element, const ComputedStyle& style) { - if (!animating_element) - return; - - if (animating_element->GetDocument().FinishingOrIsPrinting()) + if (animating_element.GetDocument().FinishingOrIsPrinting()) return; ElementAnimations* element_animations = - animating_element->GetElementAnimations(); + animating_element.GetElementAnimations(); const TransitionMap* active_transitions = element_animations ? &element_animations->CssAnimations().transitions_ : nullptr; @@ -1337,7 +1345,7 @@ void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, HashSet<PropertyHandle> listed_properties; bool any_transition_had_transition_all = false; - const ComputedStyle* old_style = animating_element->GetComputedStyle(); + const ComputedStyle* old_style = animating_element.GetComputedStyle(); if (!animation_style_recalc && style.Display() != EDisplay::kNone && old_style && !old_style->IsEnsuredInDisplayNone()) { TransitionUpdateState state = {update, @@ -1401,11 +1409,11 @@ void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, } scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( - Element* animating_element, + Element& animating_element, const ComputedStyle& base_style) { ActiveInterpolationsMap interpolations_map; ElementAnimations* element_animations = - animating_element->GetElementAnimations(); + animating_element.GetElementAnimations(); if (element_animations) { const TransitionMap& transition_map = element_animations->CssAnimations().transitions_; @@ -1427,17 +1435,32 @@ scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( // Sample animations and add to the interpolatzions map. for (Animation* animation : animations) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* current_time_numberish = animation->currentTime(); + if (!current_time_numberish) + continue; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time_numberish; animation->currentTime(current_time_numberish); if (current_time_numberish.IsNull()) continue; +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - // CSSNumericValue is not yet supported, verify that it is not used + // CSSNumericValue is not yet supported, verify that it is not used +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + DCHECK(!current_time_numberish->IsCSSNumericValue()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DCHECK(!current_time_numberish.IsCSSNumericValue()); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - base::Optional<AnimationTimeDelta> current_time = + absl::optional<AnimationTimeDelta> current_time = AnimationTimeDelta::FromMillisecondsD( - current_time_numberish.GetAsDouble()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + current_time_numberish->GetAsDouble() +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + current_time_numberish.GetAsDouble() +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + ); auto* effect = DynamicTo<KeyframeEffect>(animation->effect()); if (!effect) @@ -1445,7 +1468,7 @@ scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( auto* inert_animation_for_sampling = MakeGarbageCollected<InertEffect>( effect->Model(), effect->SpecifiedTiming(), false, current_time, - base::nullopt); + absl::nullopt); HeapVector<Member<Interpolation>> sample; inert_animation_for_sampling->Sample(sample); @@ -1463,9 +1486,9 @@ scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( } } - StyleResolver& resolver = animating_element->GetDocument().GetStyleResolver(); + StyleResolver& resolver = animating_element.GetDocument().GetStyleResolver(); return resolver.BeforeChangeStyleForTransitionUpdate( - *animating_element, base_style, interpolations_map); + animating_element, base_style, interpolations_map); } void CSSAnimations::Cancel() { @@ -1531,9 +1554,9 @@ void AdoptActiveAnimationInterpolations( void CSSAnimations::CalculateAnimationActiveInterpolations( CSSAnimationUpdate& update, - const Element* animating_element) { + const Element& animating_element) { ElementAnimations* element_animations = - animating_element ? animating_element->GetElementAnimations() : nullptr; + animating_element.GetElementAnimations(); EffectStack* effect_stack = element_animations ? &element_animations->GetEffectStack() : nullptr; @@ -1571,9 +1594,9 @@ EffectStack::PropertyHandleFilter PropertyFilter( void CSSAnimations::CalculateTransitionActiveInterpolations( CSSAnimationUpdate& update, PropertyPass property_pass, - const Element* animating_element) { + const Element& animating_element) { ElementAnimations* element_animations = - animating_element ? animating_element->GetElementAnimations() : nullptr; + animating_element.GetElementAnimations(); EffectStack* effect_stack = element_animations ? &element_animations->GetEffectStack() : nullptr; @@ -1653,7 +1676,7 @@ bool CSSAnimations::AnimationEventDelegate::RequiresIterationEvents( void CSSAnimations::AnimationEventDelegate::OnEventCondition( const AnimationEffect& animation_node, Timing::Phase current_phase) { - const base::Optional<double> current_iteration = + const absl::optional<double> current_iteration = animation_node.CurrentIteration(); // See http://drafts.csswg.org/css-animations-2/#event-dispatch @@ -1787,7 +1810,7 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( // Per the css-transitions-2 spec, transitioncancel is fired with the // "active time of the animation at the moment it was cancelled, // calculated using a fill mode of both". - base::Optional<AnimationTimeDelta> cancel_active_time = + absl::optional<AnimationTimeDelta> cancel_active_time = CalculateActiveTime(animation_node.SpecifiedTiming().ActiveDuration(), Timing::FillMode::BOTH, animation_node.LocalTime(), previous_phase_, diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h index 2bc75e6aee3..cf367221edc 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h @@ -68,14 +68,14 @@ class CORE_EXPORT CSSAnimations final { static bool IsAnimatingFontAffectingProperties(const ElementAnimations*); static bool IsAnimatingRevert(const ElementAnimations*); static void CalculateAnimationUpdate(CSSAnimationUpdate&, - const Element* animating_element, + const Element& animating_element, Element&, const ComputedStyle&, const ComputedStyle* parent_style, StyleResolver*); static void CalculateCompositorAnimationUpdate( CSSAnimationUpdate&, - const Element* animating_element, + const Element& animating_element, Element&, const ComputedStyle&, const ComputedStyle* parent_style, @@ -95,7 +95,7 @@ class CORE_EXPORT CSSAnimations final { enum class PropertyPass { kCustom, kStandard }; static void CalculateTransitionUpdate(CSSAnimationUpdate&, PropertyPass, - Element* animating_element, + Element& animating_element, const ComputedStyle&); static void SnapshotCompositorKeyframes(Element&, @@ -182,7 +182,7 @@ class CORE_EXPORT CSSAnimations final { public: CSSAnimationUpdate& update; - Element* animating_element = nullptr; + Element& animating_element; const ComputedStyle& old_style; const ComputedStyle& style; scoped_refptr<const ComputedStyle> before_change_style; @@ -209,18 +209,18 @@ class CORE_EXPORT CSSAnimations final { static void CalculateAnimationActiveInterpolations( CSSAnimationUpdate&, - const Element* animating_element); + const Element& animating_element); static void CalculateTransitionActiveInterpolations( CSSAnimationUpdate&, PropertyPass, - const Element* animating_element); + const Element& animating_element); // The before-change style is defined as the computed values of all properties // on the element as of the previous style change event, except with any // styles derived from declarative animations updated to the current time. // https://drafts.csswg.org/css-transitions-1/#before-change-style static scoped_refptr<const ComputedStyle> CalculateBeforeChangeStyle( - Element* animating_element, + Element& animating_element, const ComputedStyle& base_style); class AnimationEventDelegate final : public AnimationEffect::EventDelegate { @@ -229,7 +229,7 @@ class CORE_EXPORT CSSAnimations final { Element* animation_target, const AtomicString& name, Timing::Phase previous_phase = Timing::kPhaseNone, - base::Optional<double> previous_iteration = base::nullopt) + absl::optional<double> previous_iteration = absl::nullopt) : animation_target_(animation_target), name_(name), previous_phase_(previous_phase), @@ -239,7 +239,7 @@ class CORE_EXPORT CSSAnimations final { bool IsAnimationEventDelegate() const override { return true; } Timing::Phase getPreviousPhase() const { return previous_phase_; } - base::Optional<double> getPreviousIteration() const { + absl::optional<double> getPreviousIteration() const { return previous_iteration_; } @@ -256,7 +256,7 @@ class CORE_EXPORT CSSAnimations final { Member<Element> animation_target_; const AtomicString name_; Timing::Phase previous_phase_; - base::Optional<double> previous_iteration_; + absl::optional<double> previous_iteration_; }; class TransitionEventDelegate final : public AnimationEffect::EventDelegate { @@ -309,4 +309,4 @@ struct DowncastTraits<CSSAnimations::TransitionEventDelegate> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATIONS_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc index 9982f48ab31..1e2f5ab8eb8 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc @@ -6,6 +6,7 @@ #include "cc/animation/animation.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" #include "third_party/blink/renderer/core/animation/element_animations.h" @@ -349,21 +350,37 @@ TEST_F(CSSAnimationsCompositorSyncTest, SetStartTime) { Animation* animation = GetAnimation(); int compositor_group = animation->CompositorGroup(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* start_time = animation->startTime(); + V8CSSNumberish* current_time = animation->currentTime(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish start_time, current_time; animation->startTime(start_time); animation->currentTime(current_time); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Partially rewind the animation via setStartTime. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* new_start_time = MakeGarbageCollected<V8CSSNumberish>( + start_time->GetAsDouble() + (current_time->GetAsDouble() / 2)); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish new_start_time = CSSNumberish::FromDouble( start_time.GetAsDouble() + (current_time.GetAsDouble() / 2)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(new_start_time, ASSERT_NO_EXCEPTION); UpdateAllLifecyclePhasesForTest(); // Verify blink updates. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + current_time = animation->currentTime(); + EXPECT_TRUE(current_time->IsDouble()); + EXPECT_NEAR(250, current_time->GetAsDouble(), kTimeToleranceMilliseconds); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->currentTime(current_time); EXPECT_TRUE(current_time.IsDouble()); EXPECT_NEAR(250, current_time.GetAsDouble(), kTimeToleranceMilliseconds); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_NEAR(0.75, element_->GetComputedStyle()->Opacity(), kTolerance); // Compositor animation needs to restart and will have a new compositor group. @@ -394,14 +411,25 @@ TEST_F(CSSAnimationsCompositorSyncTest, SetCurrentTime) { int compositor_group = animation->CompositorGroup(); // Advance current time. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(750), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(750), ASSERT_NO_EXCEPTION); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UpdateAllLifecyclePhasesForTest(); // Verify blink updates. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* current_time = animation->currentTime(); + EXPECT_TRUE(current_time->IsDouble()); + EXPECT_NEAR(750, current_time->GetAsDouble(), kTimeToleranceMilliseconds); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time; animation->currentTime(current_time); EXPECT_TRUE(current_time.IsDouble()); EXPECT_NEAR(750, current_time.GetAsDouble(), kTimeToleranceMilliseconds); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_NEAR(0.25, element_->GetComputedStyle()->Opacity(), kTolerance); // Compositor animation needs to restart and will have a new compositor group. diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc index 0ea72a8421c..854e05f9707 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc @@ -144,11 +144,11 @@ HeapVector<Member<ScrollTimelineOffset>> ComputeScrollOffsets( return offsets; } -base::Optional<double> ComputeTimeRange(const CSSValue* value) { +absl::optional<double> ComputeTimeRange(const CSSValue* value) { if (auto* primitive = DynamicTo<CSSPrimitiveValue>(value)) return primitive->ComputeSeconds() * 1000.0; // TODO(crbug.com/1097041): Support 'auto' value. - return base::nullopt; + return absl::nullopt; } class ElementReferenceObserver : public IdTargetObserver { @@ -204,13 +204,11 @@ HeapVector<Member<IdTargetObserver>> CreateElementReferenceObservers( } // anonymous namespace -CSSScrollTimeline::Options::Options(Element* element, +CSSScrollTimeline::Options::Options(Document& document, StyleRuleScrollTimeline& rule) - : source_(ComputeScrollSource(element->GetDocument(), rule.GetSource())), + : source_(ComputeScrollSource(document, rule.GetSource())), direction_(ComputeScrollDirection(rule.GetOrientation())), - offsets_(ComputeScrollOffsets(element->GetDocument(), - rule.GetStart(), - rule.GetEnd())), + offsets_(ComputeScrollOffsets(document, rule.GetStart(), rule.GetEnd())), time_range_(ComputeTimeRange(rule.GetTimeRange())), rule_(&rule) {} @@ -223,7 +221,6 @@ CSSScrollTimeline::CSSScrollTimeline(Document* document, Options&& options) rule_(options.rule_) { DCHECK(options.IsValid()); DCHECK(rule_); - document->GetDocumentAnimations().CacheCSSScrollTimeline(*this); } const AtomicString& CSSScrollTimeline::Name() const { @@ -238,14 +235,14 @@ bool CSSScrollTimeline::Matches(const Options& options) const { } void CSSScrollTimeline::AnimationAttached(Animation* animation) { - ScrollTimeline::AnimationAttached(animation); - if (AttachedAnimationsCount() == 1) + if (!HasAnimations()) SetObservers(CreateElementReferenceObservers(GetDocument(), rule_, this)); + ScrollTimeline::AnimationAttached(animation); } void CSSScrollTimeline::AnimationDetached(Animation* animation) { ScrollTimeline::AnimationDetached(animation); - if (AttachedAnimationsCount() == 0) + if (!HasAnimations()) SetObservers(HeapVector<Member<IdTargetObserver>>()); } diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h index ef6811a5c33..013b7f5cc43 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_SCROLL_TIMELINE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_SCROLL_TIMELINE_H_ -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/dom/id_target_observer.h" @@ -23,7 +23,7 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { STACK_ALLOCATED(); public: - Options(Element*, StyleRuleScrollTimeline&); + Options(Document&, StyleRuleScrollTimeline&); // TODO(crbug.com/1097041): Support 'auto' value. bool IsValid() const { return time_range_.has_value(); } @@ -34,7 +34,7 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { Element* source_; ScrollTimeline::ScrollDirection direction_; HeapVector<Member<ScrollTimelineOffset>> offsets_; - base::Optional<double> time_range_; + absl::optional<double> time_range_; StyleRuleScrollTimeline* rule_; }; diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_timing_data.cc b/chromium/third_party/blink/renderer/core/animation/css/css_timing_data.cc index 635e5e74558..0ecfe2bf23f 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_timing_data.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_timing_data.cc @@ -18,12 +18,13 @@ CSSTimingData::CSSTimingData(const CSSTimingData& other) = default; Timing CSSTimingData::ConvertToTiming(size_t index) const { Timing timing; - timing.start_delay = GetRepeated(delay_list_, index); + timing.start_delay = + AnimationTimeDelta::FromSecondsD(GetRepeated(delay_list_, index)); double duration = GetRepeated(duration_list_, index); timing.iteration_duration = std::isnan(duration) - ? base::nullopt - : base::make_optional(AnimationTimeDelta::FromSecondsD(duration)); + ? absl::nullopt + : absl::make_optional(AnimationTimeDelta::FromSecondsD(duration)); timing.timing_function = GetRepeated(timing_function_list_, index); timing.AssertValid(); return timing; diff --git a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc index 509839e11f3..bfe74bd5d21 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc @@ -27,8 +27,8 @@ InterpolationValue CSSCustomListInterpolationType::MaybeConvertNeutral( ConversionCheckers null_checkers; auto convert_inner = [this, &null_underlying, &null_checkers](size_t) { - return this->inner_interpolation_type_->MaybeConvertNeutral(null_underlying, - null_checkers); + return inner_interpolation_type_->MaybeConvertNeutral(null_underlying, + null_checkers); }; return ListInterpolationFunctions::CreateList(underlying_length, @@ -47,7 +47,7 @@ InterpolationValue CSSCustomListInterpolationType::MaybeConvertValue( return ListInterpolationFunctions::CreateList( list->length(), [this, list, state, &null_checkers](size_t index) { - return this->inner_interpolation_type_->MaybeConvertValue( + return inner_interpolation_type_->MaybeConvertValue( list->Item(index), state, null_checkers); }); } diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc index 122375ec801..9281ca47be8 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc @@ -100,7 +100,7 @@ class ResolvedRegisteredCustomPropertyChecker const auto& css_environment = To<CSSInterpolationEnvironment>(environment); const CSSValue* resolved = css_environment.Resolve( PropertyHandle(declaration_->GetName()), declaration_); - scoped_refptr<CSSVariableData> resolved_tokens = nullptr; + scoped_refptr<CSSVariableData> resolved_tokens; if (const auto* decl = DynamicTo<CSSCustomPropertyDeclaration>(resolved)) resolved_tokens = decl->Value(); diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc index 4caf781ba70..5e248b03987 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc @@ -204,6 +204,7 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get( applicable_types->push_back( std::make_unique<CSSNumberInterpolationType>(used_property)); break; + case CSSPropertyID::kAccentColor: case CSSPropertyID::kBackgroundColor: case CSSPropertyID::kBorderBottomColor: case CSSPropertyID::kBorderLeftColor: diff --git a/chromium/third_party/blink/renderer/core/animation/css_length_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_length_interpolation_type.h index edf28aa004d..25b3570af66 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_length_interpolation_type.h +++ b/chromium/third_party/blink/renderer/core/animation/css_length_interpolation_type.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_LENGTH_INTERPOLATION_TYPE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_LENGTH_INTERPOLATION_TYPE_H_ -#include <memory> #include "third_party/blink/renderer/core/animation/css_interpolation_type.h" #include "third_party/blink/renderer/core/animation/length_property_functions.h" #include "third_party/blink/renderer/core/core_export.h" diff --git a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc index 8f387ec8528..d38c2150c27 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc @@ -7,7 +7,7 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/number_property_functions.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" @@ -21,19 +21,19 @@ class InheritedNumberChecker : public CSSInterpolationType::CSSConversionChecker { public: InheritedNumberChecker(const CSSProperty& property, - base::Optional<double> number) + absl::optional<double> number) : property_(property), number_(number) {} private: bool IsValid(const StyleResolverState& state, const InterpolationValue& underlying) const final { - base::Optional<double> parent_number = + absl::optional<double> parent_number = NumberPropertyFunctions::GetNumber(property_, *state.ParentStyle()); return number_ == parent_number; } const CSSProperty& property_; - const base::Optional<double> number_; + const absl::optional<double> number_; }; const CSSValue* CSSNumberInterpolationType::CreateCSSValue( @@ -60,7 +60,7 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertNeutral( InterpolationValue CSSNumberInterpolationType::MaybeConvertInitial( const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - base::Optional<double> initial_number = + absl::optional<double> initial_number = NumberPropertyFunctions::GetInitialNumber( CssProperty(), state.GetDocument().GetStyleResolver().InitialStyle()); if (!initial_number) @@ -73,7 +73,7 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertInherit( ConversionCheckers& conversion_checkers) const { if (!state.ParentStyle()) return nullptr; - base::Optional<double> inherited = + absl::optional<double> inherited = NumberPropertyFunctions::GetNumber(CssProperty(), *state.ParentStyle()); conversion_checkers.push_back( std::make_unique<InheritedNumberChecker>(CssProperty(), inherited)); @@ -96,7 +96,7 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertValue( InterpolationValue CSSNumberInterpolationType::MaybeConvertStandardPropertyUnderlyingValue( const ComputedStyle& style) const { - base::Optional<double> underlying_number = + absl::optional<double> underlying_number = NumberPropertyFunctions::GetNumber(CssProperty(), style); if (!underlying_number) return nullptr; diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations.h b/chromium/third_party/blink/renderer/core/animation/document_animations.h index 759d9f34600..5c74f71615f 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/document_animations.h @@ -123,4 +123,4 @@ class CORE_EXPORT DocumentAnimations final } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc index 75ab69b5cea..7dabd7cb713 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc @@ -26,7 +26,7 @@ class MockAnimationTimeline : public AnimationTimeline { MOCK_CONST_METHOD0(IsActive, bool()); MOCK_METHOD0(ZeroTime, AnimationTimeDelta()); MOCK_METHOD0(InitialStartTimeForAnimations, - base::Optional<base::TimeDelta>()); + absl::optional<base::TimeDelta>()); MOCK_METHOD0(NeedsAnimationTimingUpdate, bool()); MOCK_CONST_METHOD0(HasOutdatedAnimation, bool()); MOCK_CONST_METHOD0(HasAnimations, bool()); diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc index 6abfb137535..7fb6b0982f4 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc @@ -98,21 +98,21 @@ bool DocumentTimeline::IsActive() const { // Document-linked animations are initialized with start time of the document // timeline current time. -base::Optional<base::TimeDelta> +absl::optional<base::TimeDelta> DocumentTimeline::InitialStartTimeForAnimations() { - base::Optional<double> current_time_ms = CurrentTimeMilliseconds(); + absl::optional<double> current_time_ms = CurrentTimeMilliseconds(); if (current_time_ms.has_value()) { return base::TimeDelta::FromMillisecondsD(current_time_ms.value()); } - return base::nullopt; + return absl::nullopt; } void DocumentTimeline::ScheduleNextService() { DCHECK_EQ(outdated_animation_count_, 0U); - base::Optional<AnimationTimeDelta> time_to_next_effect; + absl::optional<AnimationTimeDelta> time_to_next_effect; for (const auto& animation : animations_needing_update_) { - base::Optional<AnimationTimeDelta> time_to_effect_change = + absl::optional<AnimationTimeDelta> time_to_effect_change = animation->TimeToEffectChange(); if (!time_to_effect_change) continue; @@ -169,10 +169,10 @@ void DocumentTimeline::SetTimingForTesting(PlatformTiming* timing) { AnimationTimeline::PhaseAndTime DocumentTimeline::CurrentPhaseAndTime() { if (!IsActive()) { - return {TimelinePhase::kInactive, /*current_time*/ base::nullopt}; + return {TimelinePhase::kInactive, /*current_time*/ absl::nullopt}; } - base::Optional<base::TimeDelta> result = + absl::optional<base::TimeDelta> result = playback_rate_ == 0 ? CalculateZeroTime().since_origin() : (CurrentAnimationTime(GetDocument()) - CalculateZeroTime()) * diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline.h b/chromium/third_party/blink/renderer/core/animation/document_timeline.h index 87ae16853da..62e4bed7a21 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.h @@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_TIMELINE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_TIMELINE_H_ -#include <memory> #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" @@ -70,7 +69,7 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline { void ScheduleNextService() override; bool IsActive() const override; - base::Optional<base::TimeDelta> InitialStartTimeForAnimations() override; + absl::optional<base::TimeDelta> InitialStartTimeForAnimations() override; bool HasPendingUpdates() const { return !animations_needing_update_.IsEmpty(); } @@ -155,4 +154,4 @@ struct DowncastTraits<DocumentTimeline> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_TIMELINE_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc index 6df9206afa0..d42c89dbb3d 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc @@ -33,6 +33,7 @@ #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" @@ -370,6 +371,14 @@ TEST_F(AnimationDocumentTimelineTest, PauseForTesting) { Animation* animation2 = timeline->Play(anim2); timeline->PauseAnimationsForTesting(seek_time); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* current_time = animation1->currentTime(); + EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(), + Animation::kTimeToleranceMs); + current_time = animation2->currentTime(); + EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(), + Animation::kTimeToleranceMs); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) CSSNumberish current_time; animation1->currentTime(current_time); EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(), @@ -377,11 +386,12 @@ TEST_F(AnimationDocumentTimelineTest, PauseForTesting) { animation2->currentTime(current_time); EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(), Animation::kTimeToleranceMs); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) { timing.iteration_duration = AnimationTimeDelta::FromSecondsD(2); - timing.start_delay = 5; + timing.start_delay = AnimationTimeDelta::FromSecondsD(5); auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>( element.Get(), CreateEmptyEffectModel(), timing); @@ -390,13 +400,14 @@ TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) { // TODO: Put the animation startTime in the future when we add the capability // to change animation startTime - EXPECT_CALL(*platform_timing, WakeAfter(base::TimeDelta::FromSecondsD( - timing.start_delay - MinimumDelay()))); + EXPECT_CALL(*platform_timing, + WakeAfter(base::TimeDelta::FromSecondsD( + timing.start_delay.InSecondsF() - MinimumDelay()))); UpdateClockAndService(0); EXPECT_CALL(*platform_timing, - WakeAfter(base::TimeDelta::FromSecondsD(timing.start_delay - - MinimumDelay() - 1.5))); + WakeAfter(base::TimeDelta::FromSecondsD( + timing.start_delay.InSecondsF() - MinimumDelay() - 1.5))); UpdateClockAndService(1500); timeline->ScheduleServiceOnNextFrame(); @@ -410,12 +421,17 @@ TEST_F(AnimationDocumentTimelineTest, UseAnimationAfterTimelineDeref) { Animation* animation = timeline->Play(nullptr); timeline.Clear(); // Test passes if this does not crash. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(0)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref) { timing.iteration_duration = AnimationTimeDelta::FromSecondsD(2); - timing.start_delay = 5; + timing.start_delay = AnimationTimeDelta::FromSecondsD(5); DocumentTimeline* timeline = &document->Timeline(); document = nullptr; diff --git a/chromium/third_party/blink/renderer/core/animation/effect_input.cc b/chromium/third_party/blink/renderer/core/animation/effect_input.cc index ad548951c33..be3c8bca7d5 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_input.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_input.cc @@ -62,8 +62,8 @@ namespace blink { namespace { // Converts the composite property of a BasePropertyIndexedKeyframe into a -// vector of base::Optional<EffectModel::CompositeOperation> enums. -Vector<base::Optional<EffectModel::CompositeOperation>> ParseCompositeProperty( +// vector of absl::optional<EffectModel::CompositeOperation> enums. +Vector<absl::optional<EffectModel::CompositeOperation>> ParseCompositeProperty( const BasePropertyIndexedKeyframe* keyframe) { const CompositeOperationOrAutoOrCompositeOperationOrAutoSequence& composite = keyframe->composite(); @@ -73,7 +73,7 @@ Vector<base::Optional<EffectModel::CompositeOperation>> ParseCompositeProperty( composite.GetAsCompositeOperationOrAuto())}; } - Vector<base::Optional<EffectModel::CompositeOperation>> result; + Vector<absl::optional<EffectModel::CompositeOperation>> result; for (const String& composite_operation_string : composite.GetAsCompositeOperationOrAutoSequence()) { result.push_back( @@ -366,7 +366,7 @@ StringKeyframeVector ConvertArrayForm(Element* element, execution_context); } - base::Optional<EffectModel::CompositeOperation> composite = + absl::optional<EffectModel::CompositeOperation> composite = EffectModel::StringToCompositeOperation(base_keyframe->composite()); if (composite) { keyframe->SetComposite( @@ -450,9 +450,9 @@ StringKeyframeVector ConvertObjectForm(Element* element, if (exception_state.HadException()) return {}; - Vector<base::Optional<double>> offsets; + Vector<absl::optional<double>> offsets; if (property_indexed_keyframe->offset().IsNull()) - offsets.push_back(base::nullopt); + offsets.push_back(absl::nullopt); else if (property_indexed_keyframe->offset().IsDouble()) offsets.push_back(property_indexed_keyframe->offset().GetAsDouble()); else @@ -466,7 +466,7 @@ StringKeyframeVector ConvertObjectForm(Element* element, else easings = property_indexed_keyframe->easing().GetAsStringSequence(); - Vector<base::Optional<EffectModel::CompositeOperation>> composite_operations = + Vector<absl::optional<EffectModel::CompositeOperation>> composite_operations = ParseCompositeProperty(property_indexed_keyframe); // Next extract all animatable properties from the input argument and iterate @@ -557,7 +557,7 @@ StringKeyframeVector ConvertObjectForm(Element* element, auto* keyframe = keyframes.at(keys[i]); if (i < offsets.size()) { - base::Optional<double> offset = offsets[i]; + absl::optional<double> offset = offsets[i]; // 6. If processed keyframes is not loosely sorted by offset, throw a // TypeError and abort these steps. if (offset.has_value()) { @@ -610,7 +610,7 @@ StringKeyframeVector ConvertObjectForm(Element* element, // property keyframes, repeat the elements in composite modes successively // starting from the beginning of the list until composite modes has as // many items as property keyframes. - base::Optional<EffectModel::CompositeOperation> composite = + absl::optional<EffectModel::CompositeOperation> composite = composite_operations[i % composite_operations.size()]; if (composite) { keyframe->SetComposite( diff --git a/chromium/third_party/blink/renderer/core/animation/effect_input.h b/chromium/third_party/blink/renderer/core/animation/effect_input.h index 29141e9ddf3..42347ca9593 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_input.h +++ b/chromium/third_party/blink/renderer/core/animation/effect_input.h @@ -48,4 +48,4 @@ class CORE_EXPORT EffectInput { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_EFFECT_INPUT_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/effect_model.cc b/chromium/third_party/blink/renderer/core/animation/effect_model.cc index a876304d633..798b1eee7d5 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_model.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_model.cc @@ -6,15 +6,14 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -base::Optional<EffectModel::CompositeOperation> +absl::optional<EffectModel::CompositeOperation> EffectModel::StringToCompositeOperation(const String& composite_string) { DCHECK(composite_string == "replace" || composite_string == "add" || composite_string == "accumulate" || composite_string == "auto"); if (composite_string == "auto") - return base::nullopt; + return absl::nullopt; if (composite_string == "add") return kCompositeAdd; if (composite_string == "accumulate") @@ -23,7 +22,7 @@ EffectModel::StringToCompositeOperation(const String& composite_string) { } String EffectModel::CompositeOperationToString( - base::Optional<CompositeOperation> composite) { + absl::optional<CompositeOperation> composite) { if (!composite) return "auto"; switch (composite.value()) { diff --git a/chromium/third_party/blink/renderer/core/animation/effect_model.h b/chromium/third_party/blink/renderer/core/animation/effect_model.h index 8775f8742dc..30ca0846f47 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_model.h +++ b/chromium/third_party/blink/renderer/core/animation/effect_model.h @@ -52,9 +52,9 @@ class CORE_EXPORT EffectModel : public GarbageCollected<EffectModel> { kCompositeAdd, kCompositeAccumulate, }; - static base::Optional<CompositeOperation> StringToCompositeOperation( + static absl::optional<CompositeOperation> StringToCompositeOperation( const String&); - static String CompositeOperationToString(base::Optional<CompositeOperation>); + static String CompositeOperationToString(absl::optional<CompositeOperation>); EffectModel() = default; virtual ~EffectModel() = default; diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc index bf4f93ecf76..13a728cafc9 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc @@ -5,7 +5,9 @@ #include "third_party/blink/renderer/core/animation/effect_stack.h" #include <memory> + #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" @@ -34,7 +36,13 @@ class AnimationEffectStackTest : public PageTestBase { Animation* Play(KeyframeEffect* effect, double start_time) { Animation* animation = timeline->Play(effect); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setStartTime( + MakeGarbageCollected<V8CSSNumberish>(start_time * 1000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(CSSNumberish::FromDouble(start_time * 1000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->Update(kTimingUpdateOnDemand); return animation; } @@ -69,7 +77,7 @@ class AnimationEffectStackTest : public PageTestBase { Timing timing; timing.fill_mode = Timing::FillMode::BOTH; return MakeGarbageCollected<InertEffect>( - effect, timing, false, AnimationTimeDelta(), base::nullopt); + effect, timing, false, AnimationTimeDelta(), absl::nullopt); } KeyframeEffect* MakeKeyframeEffect(KeyframeEffectModelBase* effect, diff --git a/chromium/third_party/blink/renderer/core/animation/element_animations.cc b/chromium/third_party/blink/renderer/core/animation/element_animations.cc index afad6b763cf..fa1b98062d0 100644 --- a/chromium/third_party/blink/renderer/core/animation/element_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/element_animations.cc @@ -71,6 +71,15 @@ void ElementAnimations::UpdateAnimationFlags(ComputedStyle& style) { if (!effect.IsCurrent()) continue; UpdateAnimationFlagsForEffect(effect, style); + + // This animation animates background-color and some input of the animation + // is changed compared with the previous frame, so trigger a repaint. + if (RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled() && + animation.CalculateAnimationPlayState() != Animation::kIdle && + effect.Affects(PropertyHandle(GetCSSPropertyBackgroundColor())) && + animation.CompositorPending()) { + style.SetCompositablePaintAnimationChanged(true); + } } for (const auto& entry : worklet_animations_) { diff --git a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc index 210a2dfced5..94a09d84855 100644 --- a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc @@ -37,8 +37,8 @@ namespace blink { InertEffect::InertEffect(KeyframeEffectModelBase* model, const Timing& timing, bool paused, - base::Optional<AnimationTimeDelta> inherited_time, - base::Optional<TimelinePhase> inherited_phase) + absl::optional<AnimationTimeDelta> inherited_time, + absl::optional<TimelinePhase> inherited_phase) : AnimationEffect(timing), model_(model), paused_(paused), @@ -52,7 +52,7 @@ void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const { return; } - base::Optional<double> iteration = CurrentIteration(); + absl::optional<double> iteration = CurrentIteration(); DCHECK(iteration); DCHECK_GE(iteration.value(), 0); model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), @@ -61,7 +61,7 @@ void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const { AnimationTimeDelta InertEffect::CalculateTimeToEffectChange( bool, - base::Optional<double>, + absl::optional<AnimationTimeDelta>, AnimationTimeDelta) const { return AnimationTimeDelta::Max(); } diff --git a/chromium/third_party/blink/renderer/core/animation/inert_effect.h b/chromium/third_party/blink/renderer/core/animation/inert_effect.h index 76e785839a5..984208d4db5 100644 --- a/chromium/third_party/blink/renderer/core/animation/inert_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.h @@ -45,8 +45,8 @@ class CORE_EXPORT InertEffect final : public AnimationEffect { InertEffect(KeyframeEffectModelBase*, const Timing&, bool paused, - base::Optional<AnimationTimeDelta> inherited_time, - base::Optional<TimelinePhase> inherited_phase); + absl::optional<AnimationTimeDelta> inherited_time, + absl::optional<TimelinePhase> inherited_phase); void Sample(HeapVector<Member<Interpolation>>&) const; KeyframeEffectModelBase* Model() const { return model_.Get(); } @@ -60,14 +60,14 @@ class CORE_EXPORT InertEffect final : public AnimationEffect { void UpdateChildrenAndEffects() const override {} AnimationTimeDelta CalculateTimeToEffectChange( bool forwards, - base::Optional<double> inherited_time, + absl::optional<AnimationTimeDelta> inherited_time, AnimationTimeDelta time_to_next_iteration) const override; private: Member<KeyframeEffectModelBase> model_; bool paused_; - base::Optional<AnimationTimeDelta> inherited_time_; - base::Optional<TimelinePhase> inherited_phase_; + absl::optional<AnimationTimeDelta> inherited_time_; + absl::optional<TimelinePhase> inherited_phase_; }; template <> @@ -79,4 +79,4 @@ struct DowncastTraits<InertEffect> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INERT_EFFECT_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc index 91a602f957e..c347a99f02b 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc @@ -41,7 +41,7 @@ double ClampParameter(double value, FilterOperation::OperationType type) { std::unique_ptr<InterpolableFilter> InterpolableFilter::MaybeCreate( const FilterOperation& filter, double zoom) { - std::unique_ptr<InterpolableValue> value = nullptr; + std::unique_ptr<InterpolableValue> value; FilterOperation::OperationType type = filter.GetType(); switch (type) { case FilterOperation::GRAYSCALE: @@ -92,7 +92,7 @@ std::unique_ptr<InterpolableFilter> InterpolableFilter::MaybeConvertCSSValue( const auto& filter = To<CSSFunctionValue>(css_value); DCHECK_LE(filter.length(), 1u); - std::unique_ptr<InterpolableValue> value = nullptr; + std::unique_ptr<InterpolableValue> value; FilterOperation::OperationType type = FilterOperationResolver::FilterOperationForType(filter.FunctionType()); switch (type) { @@ -133,7 +133,7 @@ std::unique_ptr<InterpolableFilter> InterpolableFilter::CreateInitialValue( FilterOperation::OperationType type) { // See https://drafts.fxtf.org/filter-effects-1/#filter-functions for the // mapping of OperationType to initial value. - std::unique_ptr<InterpolableValue> value = nullptr; + std::unique_ptr<InterpolableValue> value; switch (type) { case FilterOperation::GRAYSCALE: case FilterOperation::INVERT: diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h index 21428f41228..0fe3e2eb890 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h @@ -168,4 +168,4 @@ struct DowncastTraits<InterpolableList> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_VALUE_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation.h b/chromium/third_party/blink/renderer/core/animation/interpolation.h index f70e08fbfc2..228bab31669 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolation.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolation.h @@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATION_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATION_H_ -#include <memory> - #include "base/macros.h" #include "third_party/blink/renderer/core/animation/interpolable_value.h" #include "third_party/blink/renderer/core/animation/property_handle.h" diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.h b/chromium/third_party/blink/renderer/core/animation/keyframe.h index fe695abdd47..a70ac6cd969 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe.h +++ b/chromium/third_party/blink/renderer/core/animation/keyframe.h @@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/effect_model.h" #include "third_party/blink/renderer/core/animation/property_handle.h" @@ -65,8 +65,8 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { virtual ~Keyframe() = default; // TODO(smcgruer): The keyframe offset should be immutable. - void SetOffset(base::Optional<double> offset) { offset_ = offset; } - base::Optional<double> Offset() const { return offset_; } + void SetOffset(absl::optional<double> offset) { offset_ = offset; } + absl::optional<double> Offset() const { return offset_; } double CheckedOffset() const { return offset_.value(); } // TODO(smcgruer): The keyframe composite operation should be immutable. @@ -188,19 +188,19 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { protected: Keyframe() : offset_(), composite_(), easing_(LinearTimingFunction::Shared()) {} - Keyframe(base::Optional<double> offset, - base::Optional<EffectModel::CompositeOperation> composite, + Keyframe(absl::optional<double> offset, + absl::optional<EffectModel::CompositeOperation> composite, scoped_refptr<TimingFunction> easing) : offset_(offset), composite_(composite), easing_(std::move(easing)) { if (!easing_) easing_ = LinearTimingFunction::Shared(); } - base::Optional<double> offset_; + absl::optional<double> offset_; // To avoid having multiple CompositeOperation enums internally (one with - // 'auto' and one without), we use a base::Optional for composite_. A - // base::nullopt value represents 'auto'. - base::Optional<EffectModel::CompositeOperation> composite_; + // 'auto' and one without), we use a absl::optional for composite_. A + // absl::nullopt value represents 'auto'. + absl::optional<EffectModel::CompositeOperation> composite_; scoped_refptr<TimingFunction> easing_; DISALLOW_COPY_AND_ASSIGN(Keyframe); }; diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc index 3cc8831033b..68f1663432f 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/core/animation/animation_utils.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" @@ -40,6 +41,7 @@ #include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/sampled_effect.h" #include "third_party/blink/renderer/core/animation/timing_input.h" +#include "third_party/blink/renderer/core/css/parser/css_selector_parser.h" #include "third_party/blink/renderer/core/css/properties/css_property_ref.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -86,7 +88,11 @@ KeyframeEffect* KeyframeEffect::Create( ScriptState* script_state, Element* element, const ScriptValue& keyframes, +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const UnrestrictedDoubleOrKeyframeEffectOptions& options, +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ExceptionState& exception_state) { Document* document = element ? &element->GetDocument() : nullptr; Timing timing = TimingInput::Convert(options, document, exception_state); @@ -95,8 +101,18 @@ KeyframeEffect* KeyframeEffect::Create( EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace; String pseudo = String(); - if (options.IsKeyframeEffectOptions()) { + if ( +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + options->IsKeyframeEffectOptions() +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + options.IsKeyframeEffectOptions() +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + ) { +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* effect_options = options->GetAsKeyframeEffectOptions(); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* effect_options = options.GetAsKeyframeEffectOptions(); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) composite = EffectModel::StringToCompositeOperation(effect_options->composite()) .value(); @@ -125,7 +141,7 @@ KeyframeEffect* KeyframeEffect::Create( if (element) { element->GetDocument().UpdateStyleAndLayoutTreeForNode(element); effect->effect_target_ = element->GetPseudoElement( - CSSSelector::ParsePseudoId(pseudo, element)); + CSSSelectorParser::ParsePseudoElement(pseudo, element)); } } return effect; @@ -213,7 +229,7 @@ void KeyframeEffect::RefreshTarget() { target_element_->GetDocument().UpdateStyleAndLayoutTreeForNode( target_element_); PseudoId pseudoId = - CSSSelector::ParsePseudoId(target_pseudo_, target_element_); + CSSSelectorParser::ParsePseudoElement(target_pseudo_, target_element_); new_target = target_element_->GetPseudoElement(pseudoId); } @@ -349,7 +365,7 @@ KeyframeEffect::CheckCanStartAnimationOnCompositor( void KeyframeEffect::StartAnimationOnCompositor( int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, double animation_playback_rate, CompositorAnimation* compositor_animation) { @@ -562,7 +578,7 @@ void KeyframeEffect::ApplyEffects() { GetAnimation()->CancelAnimationOnCompositor(); } - base::Optional<double> iteration = CurrentIteration(); + absl::optional<double> iteration = CurrentIteration(); DCHECK(iteration); DCHECK_GE(iteration.value(), 0); bool changed = false; @@ -654,14 +670,15 @@ void KeyframeEffect::DetachTarget(Animation* animation) { AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange( bool forwards, - base::Optional<double> local_time, + absl::optional<AnimationTimeDelta> local_time, AnimationTimeDelta time_to_next_iteration) const { - const double start_time = SpecifiedTiming().start_delay; - const double end_time_minus_end_delay = + const AnimationTimeDelta start_time = SpecifiedTiming().start_delay; + const AnimationTimeDelta end_time_minus_end_delay = start_time + SpecifiedTiming().ActiveDuration(); - const double end_time = + const AnimationTimeDelta end_time = end_time_minus_end_delay + SpecifiedTiming().end_delay; - const double after_time = std::min(end_time_minus_end_delay, end_time); + const AnimationTimeDelta after_time = + std::min(end_time_minus_end_delay, end_time); Timing::Phase phase = GetPhase(); DCHECK(local_time || phase == Timing::kPhaseNone); @@ -671,18 +688,17 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange( case Timing::kPhaseBefore: // Return value is clamped at 0 to prevent unexpected results that could // be caused by returning negative values. - return forwards ? AnimationTimeDelta::FromSecondsD(std::max<double>( - start_time - local_time.value(), 0)) + return forwards ? std::max(start_time - local_time.value(), + AnimationTimeDelta()) : AnimationTimeDelta::Max(); case Timing::kPhaseActive: if (forwards) { // Need service to apply fill / fire events. - const double time_to_end = after_time - local_time.value(); + const AnimationTimeDelta time_to_end = after_time - local_time.value(); if (RequiresIterationEvents()) { - return std::min(AnimationTimeDelta::FromSecondsD(time_to_end), - time_to_next_iteration); + return std::min(time_to_end, time_to_next_iteration); } - return AnimationTimeDelta::FromSecondsD(time_to_end); + return time_to_end; } return {}; case Timing::kPhaseAfter: @@ -691,11 +707,10 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange( // If an animation has a positive-valued end delay, we need an // additional tick at the end time to ensure that the finished event is // delivered. - return end_time > local_time ? AnimationTimeDelta::FromSecondsD( - end_time - local_time.value()) + return end_time > local_time ? end_time - local_time.value() : AnimationTimeDelta::Max(); } - return AnimationTimeDelta::FromSecondsD(local_time.value() - after_time); + return local_time.value() - after_time; default: NOTREACHED(); return AnimationTimeDelta::Max(); diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h index 7e880f50f65..ea23ee7f945 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_KEYFRAME_EFFECT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_KEYFRAME_EFFECT_H_ -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" @@ -47,6 +47,7 @@ class KeyframeEffectModelBase; class PaintArtifactCompositor; class SampledEffect; class UnrestrictedDoubleOrKeyframeEffectOptions; +class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble; // Represents the effect of an Animation on an Element's properties. // https://drafts.csswg.org/web-animations/#keyframe-effect @@ -57,12 +58,21 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { enum Priority { kDefaultPriority, kTransitionPriority }; // Web Animations API Bindings constructors. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + static KeyframeEffect* Create( + ScriptState* script_state, + Element* element, + const ScriptValue& keyframes, + const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, + ExceptionState& exception_state); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static KeyframeEffect* Create( ScriptState*, Element*, const ScriptValue&, const UnrestrictedDoubleOrKeyframeEffectOptions&, ExceptionState&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static KeyframeEffect* Create(ScriptState*, Element*, const ScriptValue&, @@ -116,7 +126,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { PropertyHandleSet* unsupported_properties = nullptr) const; // Must only be called once. void StartAnimationOnCompositor(int group, - base::Optional<double> start_time, + absl::optional<double> start_time, base::TimeDelta time_offset, double animation_playback_rate, CompositorAnimation* = nullptr); @@ -162,7 +172,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { void CountAnimatedProperties() const; AnimationTimeDelta CalculateTimeToEffectChange( bool forwards, - base::Optional<double> inherited_time, + absl::optional<AnimationTimeDelta> inherited_time, AnimationTimeDelta time_to_next_iteration) const override; bool HasIncompatibleStyle() const; bool HasMultipleTransformProperties() const; @@ -180,7 +190,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { bool ignore_css_keyframes_; - base::Optional<FloatSize> effect_target_size_; + absl::optional<FloatSize> effect_target_size_; }; template <> diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc index 5eea620d145..88ec4bdb326 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc @@ -238,7 +238,7 @@ Vector<double> KeyframeEffectModelBase::GetComputedOffsets( result.ReserveCapacity(keyframes.size()); for (const auto& keyframe : keyframes) { - base::Optional<double> offset = keyframe->Offset(); + absl::optional<double> offset = keyframe->Offset(); if (offset) { DCHECK_GE(offset.value(), 0); DCHECK_LE(offset.value(), 1); diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc index c7d170c625a..990602e28c8 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc @@ -14,6 +14,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" @@ -88,8 +90,13 @@ class AnimationKeyframeEffectV8Test : public KeyframeEffectTest { NonThrowableExceptionState exception_state; return KeyframeEffect::Create( script_state, element, keyframe_object, +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + timing_input), +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions::FromUnrestrictedDouble( timing_input), +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) exception_state); } static KeyframeEffect* CreateAnimationFromOption( @@ -100,8 +107,13 @@ class AnimationKeyframeEffectV8Test : public KeyframeEffectTest { NonThrowableExceptionState exception_state; return KeyframeEffect::Create( script_state, element, keyframe_object, +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + const_cast<KeyframeEffectOptions*>(timing_input)), +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( const_cast<KeyframeEffectOptions*>(timing_input)), +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) exception_state); } static KeyframeEffect* CreateAnimation(ScriptState* script_state, @@ -364,8 +376,8 @@ TEST_F(AnimationKeyframeEffectV8Test, SetKeyframesAdditiveCompositeOperation) { TEST_F(KeyframeEffectTest, TimeToEffectChange) { Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(100); - timing.start_delay = 100; - timing.end_delay = 100; + timing.start_delay = AnimationTimeDelta::FromSecondsD(100); + timing.end_delay = AnimationTimeDelta::FromSecondsD(100); timing.fill_mode = Timing::FillMode::NONE; auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>( nullptr, CreateEmptyEffectModel(), timing); @@ -378,28 +390,48 @@ TEST_F(KeyframeEffectTest, TimeToEffectChange) { keyframe_effect->TimeToReverseEffectChange()); // End of the before phase. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(100000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // Nearing the end of the active phase. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(199000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(199000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // End of the active phase. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(200000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(200000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // End of the animation. +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(300000), + ASSERT_NO_EXCEPTION); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(CSSNumberish::FromDouble(300000)); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ(AnimationTimeDelta::Max(), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), diff --git a/chromium/third_party/blink/renderer/core/animation/number_property_functions.cc b/chromium/third_party/blink/renderer/core/animation/number_property_functions.cc index 07206d9fb87..05dc9a0fe0c 100644 --- a/chromium/third_party/blink/renderer/core/animation/number_property_functions.cc +++ b/chromium/third_party/blink/renderer/core/animation/number_property_functions.cc @@ -8,13 +8,13 @@ namespace blink { -base::Optional<double> NumberPropertyFunctions::GetInitialNumber( +absl::optional<double> NumberPropertyFunctions::GetInitialNumber( const CSSProperty& property, const ComputedStyle& initial_style) { return GetNumber(property, initial_style); } -base::Optional<double> NumberPropertyFunctions::GetNumber( +absl::optional<double> NumberPropertyFunctions::GetNumber( const CSSProperty& property, const ComputedStyle& style) { switch (property.PropertyID()) { @@ -45,21 +45,21 @@ base::Optional<double> NumberPropertyFunctions::GetNumber( case CSSPropertyID::kFontSizeAdjust: if (!style.HasFontSizeAdjust()) - return base::Optional<double>(); + return absl::optional<double>(); return style.FontSizeAdjust(); case CSSPropertyID::kColumnCount: if (style.HasAutoColumnCount()) - return base::Optional<double>(); + return absl::optional<double>(); return style.ColumnCount(); case CSSPropertyID::kZIndex: if (style.HasAutoZIndex()) - return base::Optional<double>(); + return absl::optional<double>(); return style.ZIndex(); case CSSPropertyID::kTextSizeAdjust: { const TextSizeAdjust& text_size_adjust = style.GetTextSizeAdjust(); if (text_size_adjust.IsAuto()) - return base::Optional<double>(); + return absl::optional<double>(); return text_size_adjust.Multiplier() * 100; } @@ -67,22 +67,22 @@ base::Optional<double> NumberPropertyFunctions::GetNumber( const Length& length = style.SpecifiedLineHeight(); // Numbers are represented by percentages. if (!length.IsPercent()) - return base::Optional<double>(); + return absl::optional<double>(); double value = length.Value(); // -100% represents the keyword "normal". if (value == -100) - return base::Optional<double>(); + return absl::optional<double>(); return value / 100; } case CSSPropertyID::kTabSize: { if (!style.GetTabSize().IsSpaces()) - return base::nullopt; + return absl::nullopt; return style.GetTabSize().float_value_; } default: - return base::Optional<double>(); + return absl::optional<double>(); } } diff --git a/chromium/third_party/blink/renderer/core/animation/number_property_functions.h b/chromium/third_party/blink/renderer/core/animation/number_property_functions.h index cc73f2c7d8a..35f867d3404 100644 --- a/chromium/third_party/blink/renderer/core/animation/number_property_functions.h +++ b/chromium/third_party/blink/renderer/core/animation/number_property_functions.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_NUMBER_PROPERTY_FUNCTIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_NUMBER_PROPERTY_FUNCTIONS_H_ -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -18,10 +18,10 @@ class NumberPropertyFunctions { STATIC_ONLY(NumberPropertyFunctions); public: - static base::Optional<double> GetInitialNumber( + static absl::optional<double> GetInitialNumber( const CSSProperty&, const ComputedStyle& initial_style); - static base::Optional<double> GetNumber(const CSSProperty&, + static absl::optional<double> GetNumber(const CSSProperty&, const ComputedStyle&); static double ClampNumber(const CSSProperty&, double); static bool SetNumber(const CSSProperty&, ComputedStyle&, double); diff --git a/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.h b/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.h index dddce787d78..ec6647559bd 100644 --- a/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.h +++ b/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PATH_INTERPOLATION_FUNCTIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PATH_INTERPOLATION_FUNCTIONS_H_ -#include <memory> #include "third_party/blink/renderer/core/animation/interpolation_type.h" #include "third_party/blink/renderer/core/svg/svg_path_byte_stream.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/core/animation/pending_animations.h b/chromium/third_party/blink/renderer/core/animation/pending_animations.h index 5a7c0f7deda..ff8a6fe2f0d 100644 --- a/chromium/third_party/blink/renderer/core/animation/pending_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PENDING_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PENDING_ANIMATIONS_H_ -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/core_export.h" @@ -110,4 +110,4 @@ class CORE_EXPORT PendingAnimations final } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PENDING_ANIMATIONS_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/property_handle.h b/chromium/third_party/blink/renderer/core/animation/property_handle.h index 2bace91f7d2..d540ad6e044 100644 --- a/chromium/third_party/blink/renderer/core/animation/property_handle.h +++ b/chromium/third_party/blink/renderer/core/animation/property_handle.h @@ -140,7 +140,7 @@ struct HashTraits<blink::PropertyHandle> : SimpleClassHashTraits<blink::PropertyHandle> { static const bool kNeedsDestruction = true; static void ConstructDeletedValue(blink::PropertyHandle& slot, bool) { - new (NotNull, &slot) blink::PropertyHandle( + new (NotNullTag::kNotNull, &slot) blink::PropertyHandle( blink::PropertyHandle::DeletedValueForHashTraits()); } static bool IsDeletedValue(const blink::PropertyHandle& value) { diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc index 259917a785b..f5b2ce5a0e0 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc @@ -6,8 +6,11 @@ #include <tuple> -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -114,63 +117,30 @@ ScrollTimeline* ScrollTimeline::Create(Document& document, return nullptr; } - ScrollTimelineOffset* start_scroll_offset = - ScrollTimelineOffset::Create(options->startScrollOffset()); - if (!start_scroll_offset) { - exception_state.ThrowTypeError("Invalid start offset."); - return nullptr; - } - - ScrollTimelineOffset* end_scroll_offset = - ScrollTimelineOffset::Create(options->endScrollOffset()); - if (!end_scroll_offset) { - exception_state.ThrowTypeError("Invalid end offset"); - return nullptr; - } - - // TODO(crbug.com/1094014): Either scroll offsets or start/end offsets can - // be specified. - if (!options->scrollOffsets().IsEmpty() && - (!start_scroll_offset->IsDefaultValue() || - !end_scroll_offset->IsDefaultValue())) { - exception_state.ThrowTypeError( - "Either scrollOffsets or start/end offsets can be specified."); - return nullptr; - } - HeapVector<Member<ScrollTimelineOffset>> scroll_offsets; - if (options->scrollOffsets().IsEmpty()) { - // TODO(crbug.com/1094014): scroll_offsets will replace start and end - // offsets once spec decision on multiple scroll offsets is finalized. - // https://github.com/w3c/csswg-drafts/issues/4912 - if (!start_scroll_offset->IsDefaultValue()) - scroll_offsets.push_back(start_scroll_offset); - if (!end_scroll_offset->IsDefaultValue() || - !start_scroll_offset->IsDefaultValue()) - scroll_offsets.push_back(end_scroll_offset); - } else { - for (auto& offset : options->scrollOffsets()) { - ScrollTimelineOffset* scroll_offset = - ScrollTimelineOffset::Create(offset); - if (!scroll_offset) { - exception_state.ThrowTypeError("Invalid scroll offset"); - return nullptr; - } - if (scroll_offset->IsDefaultValue() && - (options->scrollOffsets().size() == 1 || - (scroll_offsets.size() + 1) < options->scrollOffsets().size())) { - exception_state.ThrowTypeError( - "Invalid scrollOffsets: 'auto' can only be set as an end " - "offset when start offset presents."); - return nullptr; - } - scroll_offsets.push_back(scroll_offset); + // https://drafts.csswg.org/scroll-animations-1/#set-the-offset-value + for (auto& offset : options->scrollOffsets()) { + ScrollTimelineOffset* scroll_offset = ScrollTimelineOffset::Create(offset); + if (!scroll_offset) { + exception_state.ThrowTypeError("Invalid scroll offset"); + return nullptr; } + // 2.1 If val is a CSSKeywordValue and matches the grammar auto and pos + // equals to 0 or size - 1: Return val. + unsigned int pos = scroll_offsets.size(); + if (scroll_offset->IsDefaultValue() && + !(pos == 0 || pos == (options->scrollOffsets().size() - 1))) { + exception_state.ThrowTypeError( + "Invalid scrollOffsets: 'auto' can only be set as start or end " + "offset"); + return nullptr; + } + scroll_offsets.push_back(scroll_offset); } - base::Optional<double> time_range; + absl::optional<double> time_range; if (options->timeRange().IsDouble()) { - time_range = base::make_optional(options->timeRange().GetAsDouble()); + time_range = absl::make_optional(options->timeRange().GetAsDouble()); } return MakeGarbageCollected<ScrollTimeline>( @@ -182,7 +152,7 @@ ScrollTimeline::ScrollTimeline( Element* scroll_source, ScrollDirection orientation, HeapVector<Member<ScrollTimelineOffset>> scroll_offsets, - base::Optional<double> time_range) + absl::optional<double> time_range) : AnimationTimeline(document), scroll_source_(scroll_source), resolved_scroll_source_(ResolveScrollSource(scroll_source_)), @@ -238,8 +208,11 @@ const std::vector<double> ScrollTimeline::GetResolvedScrollOffsets() const { // Resolves scroll offsets and stores them into resolved_offsets argument. // Returns true if the offsets are resolved. +// https://drafts.csswg.org/scroll-animations-1/#effective-scroll-offsets-algorithm bool ScrollTimeline::ResolveScrollOffsets( WTF::Vector<double>& resolved_offsets) const { + // 1. Let effective scroll offsets be an empty list of effective scroll + // offsets. DCHECK(resolved_offsets.IsEmpty()); DCHECK(ComputeIsActive()); LayoutBox* layout_box = resolved_scroll_source_->GetLayoutBox(); @@ -251,26 +224,59 @@ bool ScrollTimeline::ResolveScrollOffsets( auto orientation = ToPhysicalScrollOrientation(orientation_, *layout_box); + // 2. Let first offset be true. + // first_offset signifies weather min or max scroll offset is pushed to + // effective scroll offsets. + bool first_offset = true; + + // 3. If scrollOffsets is empty if (scroll_offsets_.size() == 0) { // Start and end offsets resolve to 'auto'. + // 3.1 Run the procedure to resolve a scroll timeline offset for auto with + // the is first flag set to first offset and add the resulted value into + // effective scroll offsets. resolved_offsets.push_back(0); + // 3.2 Set first offset to false. + // 3.3 Run the procedure to resolve a scroll timeline offset for auto with + // the is first flag set to first offset and add the resulted value into + // effective scroll offsets. resolved_offsets.push_back(max_offset); return true; } // Single entry offset in scrollOffsets is considered as 'end'. - if (scroll_offsets_.size() == 1) + // 4. If scrollOffsets has exactly one element + if (scroll_offsets_.size() == 1) { + // 4.1 Run the procedure to resolve a scroll timeline offset for auto with + // the is first flag set to first offset and add the resulted value into + // effective scroll offsets. resolved_offsets.push_back(0); + // 4.2 Set first offset to false. + first_offset = false; + } + + // 5. For each scroll offset in the list of scrollOffsets, perform the + // following steps: for (auto& offset : scroll_offsets_) { - auto resolved_offset = offset->ResolveOffset( - resolved_scroll_source_, orientation, max_offset, max_offset); + // 5.1 Let effective offset be the result of applying the procedure to + // resolve a scroll timeline offset for scroll offset with the is first flag + // set to first offset. + auto resolved_offset = + offset->ResolveOffset(resolved_scroll_source_, orientation, max_offset, + first_offset ? 0 : max_offset); if (!resolved_offset) { - // Empty resolved offset if any of the offsets cannot be resolved. + // 5.2 If effective offset is null, the effective scroll offsets is empty + // and abort the remaining steps. resolved_offsets.clear(); return false; } + // 5.3 Add effective offset into effective scroll offsets. resolved_offsets.push_back(resolved_offset.value()); + + // 5.4 Set first offset to false. + first_offset = false; } DCHECK_GE(resolved_offsets.size(), 2u); + // 6. Return effective scroll offsets. return true; } @@ -291,6 +297,33 @@ bool ScrollTimeline::ScrollOffsetsEqual( return true; } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* ScrollTimeline::currentTime() { + // time returns either in milliseconds or a 0 to 100 value representing the + // progress of the timeline + auto current_time = timeline_state_snapshotted_.current_time; + + // TODO(crbug.com/1140602): Support progress based animations + // We are currently abusing the intended use of the "auto" keyword. We are + // using it here as a signal to use progress based timeline instead of having + // a range based current time. + // We are doing this maintain backwards compatibility with existing tests. + if (time_range_) { + // not using progress based, return time as double + if (current_time) { + return MakeGarbageCollected<V8CSSNumberish>( + current_time->InMillisecondsF()); + } + return nullptr; + } else { + if (current_time) { + return MakeGarbageCollected<V8CSSNumberish>( + CSSUnitValues::percent(current_time->InSecondsF())); + } + return nullptr; + } +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void ScrollTimeline::currentTime(CSSNumberish& currentTime) { // time returns either in milliseconds or a 0 to 100 value representing the // progress of the timeline @@ -313,7 +346,17 @@ void ScrollTimeline::currentTime(CSSNumberish& currentTime) { : CSSNumberish(); } } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* ScrollTimeline::duration() { + if (time_range_) { + return MakeGarbageCollected<V8CSSNumberish>(time_range_.value()); + } + return MakeGarbageCollected<V8CSSNumberish>( + CSSUnitValues::percent(kScrollTimelineDuration)); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void ScrollTimeline::duration(CSSNumberish& duration) { if (time_range_) { duration = CSSNumberish::FromDouble(time_range_.value()); @@ -322,14 +365,16 @@ void ScrollTimeline::duration(CSSNumberish& duration) { CSSUnitValues::percent(kScrollTimelineDuration)); } } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +// https://drafts.csswg.org/scroll-animations-1/#current-time-algorithm ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { // 1. If scroll timeline is inactive, return an unresolved time value. // https://github.com/WICG/scroll-animations/issues/31 // https://wicg.github.io/scroll-animations/#current-time-algorithm WTF::Vector<double> resolved_offsets; if (!ComputeIsActive()) { - return {TimelinePhase::kInactive, /*current_time*/ base::nullopt, + return {TimelinePhase::kInactive, /*current_time*/ absl::nullopt, resolved_offsets}; } LayoutBox* layout_box = resolved_scroll_source_->GetLayoutBox(); @@ -344,7 +389,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { if (!resolved) { DCHECK(resolved_offsets.IsEmpty()); - return {TimelinePhase::kInactive, /*current_time*/ base::nullopt, + return {TimelinePhase::kInactive, /*current_time*/ absl::nullopt, resolved_offsets}; } @@ -356,7 +401,10 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { // to add a special case here. See // https://github.com/WICG/scroll-animations/issues/20 - // 3. If current scroll offset is less than startScrollOffset: + // 3. The current time is the result corresponding to the first matching + // condition from below: + // 3.1 If current scroll offset is less than effective start offset: + // The current time is 0. if (current_offset < start_offset) { return {TimelinePhase::kBefore, base::TimeDelta(), resolved_offsets}; } @@ -364,7 +412,9 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { double duration = time_range_ ? time_range_.value() : kScrollTimelineDurationMs; - // 4. If current scroll offset is greater than or equal to endScrollOffset: + // 3.2 If current scroll offset is greater than or equal to effective end + // offset: + // The current time is the effective time range. if (current_offset >= end_offset) { // If end_offset is greater than or equal to the maximum scroll offset of // scrollSource in orientation then return active phase, otherwise return @@ -375,10 +425,13 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { resolved_offsets}; } - // 5. Return the result of evaluating the following expression: - // ((current scroll offset - startScrollOffset) / - // (endScrollOffset - startScrollOffset)) * effective time range - base::Optional<base::TimeDelta> calculated_current_time = + // 3.3 Otherwise, + // 3.3.1 Let progress be a result of applying calculate scroll timeline + // progress procedure for current scroll offset. + // 3.3.2 The current time is the result of evaluating the following + // expression: + // progress × effective time range + absl::optional<base::TimeDelta> calculated_current_time = base::TimeDelta::FromMillisecondsD(scroll_timeline_util::ComputeProgress( current_offset, resolved_offsets) * duration); @@ -386,7 +439,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { } // Scroll-linked animations are initialized with the start time of zero. -base::Optional<base::TimeDelta> +absl::optional<base::TimeDelta> ScrollTimeline::InitialStartTimeForAnimations() { return base::TimeDelta(); } @@ -447,27 +500,18 @@ String ScrollTimeline::orientation() { } } -// TODO(crbug.com/1094014): scrollOffsets will replace start and end -// offsets once spec decision on multiple scroll offsets is finalized. -// https://github.com/w3c/csswg-drafts/issues/4912 -void ScrollTimeline::startScrollOffset(ScrollTimelineOffsetValue& out) const { - if (StartScrollOffset()) { - out = StartScrollOffset()->ToScrollTimelineOffsetValue(); - } else { - ScrollTimelineOffset scrollOffset; - out = scrollOffset.ToScrollTimelineOffsetValue(); - } -} - -void ScrollTimeline::endScrollOffset(ScrollTimelineOffsetValue& out) const { - if (EndScrollOffset()) { - out = EndScrollOffset()->ToScrollTimelineOffsetValue(); - } else { - ScrollTimelineOffset scrollOffset; - out = scrollOffset.ToScrollTimelineOffsetValue(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +const HeapVector<Member<V8ScrollTimelineOffset>> ScrollTimeline::scrollOffsets() + const { + HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets; + for (auto& offset : scroll_offsets_) { + scroll_offsets.push_back(offset->ToV8ScrollTimelineOffset()); + // 'auto' can only be the end offset. + DCHECK(!offset->IsDefaultValue() || scroll_offsets.size() == 2); } + return scroll_offsets; } - +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets() const { HeapVector<ScrollTimelineOffsetValue> scroll_offsets; @@ -478,7 +522,23 @@ const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets() } return scroll_offsets; } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8UnionDoubleOrScrollTimelineAutoKeyword* ScrollTimeline::timeRange() const { + // TODO(crbug.com/1140602): Support progress based animations + // We are currently abusing the intended use of the "auto" keyword. We are + // using it here as a signal to use progress based timeline instead of having + // a range based current time. + // We are doing this maintain backwards compatibility with existing tests. + if (time_range_) { + return MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + time_range_.value()); + } + return MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + V8ScrollTimelineAutoKeyword(V8ScrollTimelineAutoKeyword::Enum::kAuto)); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) { // TODO(crbug.com/1140602): Support progress based animations // We are currently abusing the intended use of the "auto" keyword. We are @@ -491,6 +551,7 @@ void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) { result.SetScrollTimelineAutoKeyword("auto"); } } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box, double& current_offset, @@ -533,17 +594,16 @@ void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box, } void ScrollTimeline::AnimationAttached(Animation* animation) { - AnimationTimeline::AnimationAttached(animation); - if (resolved_scroll_source_ && scroll_animations_.IsEmpty()) + if (resolved_scroll_source_ && !HasAnimations()) resolved_scroll_source_->RegisterScrollTimeline(this); - scroll_animations_.insert(animation); + AnimationTimeline::AnimationAttached(animation); } void ScrollTimeline::AnimationDetached(Animation* animation) { AnimationTimeline::AnimationDetached(animation); - scroll_animations_.erase(animation); - if (resolved_scroll_source_ && scroll_animations_.IsEmpty()) + + if (resolved_scroll_source_ && !HasAnimations()) resolved_scroll_source_->UnregisterScrollTimeline(this); } @@ -560,7 +620,6 @@ void ScrollTimeline::WorkletAnimationDetached() { } void ScrollTimeline::Trace(Visitor* visitor) const { - visitor->Trace(scroll_animations_); visitor->Trace(scroll_source_); visitor->Trace(resolved_scroll_source_); visitor->Trace(scroll_offsets_); @@ -600,7 +659,7 @@ void ScrollTimeline::Invalidate(Node* node) { } void ScrollTimeline::InvalidateEffectTargetStyle() { - for (Animation* animation : scroll_animations_) + for (Animation* animation : GetAnimations()) animation->InvalidateEffectTargetStyle(); } diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h index 445af19f636..7c5a2fc7c72 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_ +#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/blink/renderer/core/animation/timing.h" @@ -16,6 +17,7 @@ namespace blink { class DoubleOrScrollTimelineAutoKeyword; class ScrollTimelineOptions; +class V8UnionDoubleOrScrollTimelineAutoKeyword; // Implements the ScrollTimeline concept from the Scroll-linked Animations spec. // @@ -45,14 +47,14 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { Element*, ScrollDirection, HeapVector<Member<ScrollTimelineOffset>>, - base::Optional<double>); + absl::optional<double>); bool IsScrollTimeline() const override { return true; } // ScrollTimeline is not active if scrollSource is null, does not currently // have a CSS layout box, or if its layout box is not a scroll container. // https://github.com/WICG/scroll-animations/issues/31 bool IsActive() const override; - base::Optional<base::TimeDelta> InitialStartTimeForAnimations() override; + absl::optional<base::TimeDelta> InitialStartTimeForAnimations() override; AnimationTimeDelta ZeroTime() override { return AnimationTimeDelta(); } void ServiceAnimations(TimingUpdateReason) override; @@ -61,16 +63,21 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { // IDL API implementation. Element* scrollSource() const; String orientation(); - // TODO(crbug.com/1094014): scrollOffsets will replace start and end - // offsets once spec decision on multiple scroll offsets is finalized. - // https://github.com/w3c/csswg-drafts/issues/4912 - void startScrollOffset(ScrollTimelineOffsetValue& result) const; - void endScrollOffset(ScrollTimelineOffsetValue& result) const; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + const HeapVector<Member<V8ScrollTimelineOffset>> scrollOffsets() const; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const HeapVector<ScrollTimelineOffsetValue> scrollOffsets() const; +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* currentTime() override; + V8CSSNumberish* duration() override; + V8UnionDoubleOrScrollTimelineAutoKeyword* timeRange() const; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void currentTime(CSSNumberish&) override; void duration(CSSNumberish&) override; void timeRange(DoubleOrScrollTimelineAutoKeyword&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Returns the Node that should actually have the ScrollableArea (if one // exists). This can differ from |scrollSource| when |scroll_source_| is the @@ -126,10 +133,10 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { double GetTimeRange() const { return time_range_ ? time_range_.value() : 0; } bool ScrollOffsetsEqual( const HeapVector<Member<ScrollTimelineOffset>>& other) const; - size_t AttachedAnimationsCount() const { return scroll_animations_.size(); } private: FRIEND_TEST_ALL_PREFIXES(ScrollTimelineTest, MultipleScrollOffsetsClamping); + FRIEND_TEST_ALL_PREFIXES(ScrollTimelineTest, ResolveScrollOffsets); // https://wicg.github.io/scroll-animations/#avoiding-cycles // Snapshots scroll timeline current time and phase. // Called once per animation frame. @@ -146,7 +153,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { struct TimelineState { TimelinePhase phase; - base::Optional<base::TimeDelta> current_time; + absl::optional<base::TimeDelta> current_time; // The resolved version of scroll offset. The vector is empty // when timeline is inactive (e.g., when source does not overflow). WTF::Vector<double> scroll_offsets; @@ -172,16 +179,10 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ScrollDirection orientation_; HeapVector<Member<ScrollTimelineOffset>> scroll_offsets_; - base::Optional<double> time_range_; + absl::optional<double> time_range_; // Snapshotted value produced by the last SnapshotState call. TimelineState timeline_state_snapshotted_; - - // The only purpose of scroll_animations_ is keeping strong references to - // attached animations. This is required to keep attached animations alive - // as long as the timeline is alive. Scroll timeline is alive as long as its - // scroller is alive. - HeapHashSet<Member<Animation>> scroll_animations_; }; template <> @@ -193,4 +194,4 @@ struct DowncastTraits<ScrollTimeline> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl index 1f5eebf17c8..382fbd1b64e 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl @@ -13,8 +13,6 @@ typedef (ScrollTimelineContainerBasedOffset or ScrollTimelineElementBasedOffset) [CallWith=Document, RaisesException, MeasureAs=ScrollTimelineConstructor] constructor(optional ScrollTimelineOptions options = {}); readonly attribute Element? scrollSource; readonly attribute ScrollDirection orientation; - readonly attribute ScrollTimelineOffset startScrollOffset; - readonly attribute ScrollTimelineOffset endScrollOffset; readonly attribute FrozenArray<ScrollTimelineOffset> scrollOffsets; readonly attribute (double or ScrollTimelineAutoKeyword) timeRange; }; diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc index 6631be00e8e..4e4d8405464 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc @@ -4,9 +4,10 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/css_numeric_value_or_string_or_css_keyword_value_or_scroll_timeline_element_based_offset.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" #include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h" #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" @@ -107,7 +108,7 @@ ScrollTimelineOffset* ScrollTimelineOffset::Create( return nullptr; } -base::Optional<double> ScrollTimelineOffset::ResolveOffset( +absl::optional<double> ScrollTimelineOffset::ResolveOffset( Node* scroll_source, ScrollOrientation orientation, double max_offset, @@ -133,7 +134,7 @@ base::Optional<double> ScrollTimelineOffset::ResolveOffset( return resolved; } else if (element_based_offset_) { if (!element_based_offset_->hasTarget()) - return base::nullopt; + return absl::nullopt; Element* target = element_based_offset_->target(); const LayoutBox* target_box = target->GetLayoutBox(); @@ -143,10 +144,10 @@ base::Optional<double> ScrollTimelineOffset::ResolveOffset( // See the spec discussion here: // https://github.com/w3c/csswg-drafts/issues/4337#issuecomment-610997231 if (!target_box) - return base::nullopt; + return absl::nullopt; if (!IsContainingBlockChainDescendant(target_box, root_box)) - return base::nullopt; + return absl::nullopt; PhysicalRect target_rect = target_box->PhysicalBorderBoxRect(); target_rect = target_box->LocalToAncestorRect( @@ -209,6 +210,19 @@ base::Optional<double> ScrollTimelineOffset::ResolveOffset( } } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8ScrollTimelineOffset* ScrollTimelineOffset::ToV8ScrollTimelineOffset() const { + if (length_based_offset_) { + return MakeGarbageCollected<V8ScrollTimelineOffset>( + CSSNumericValue::FromCSSValue(*length_based_offset_.Get())); + } else if (element_based_offset_) { + return MakeGarbageCollected<V8ScrollTimelineOffset>(element_based_offset_); + } + // This is the default value (i.e., 'auto' value) + return MakeGarbageCollected<V8ScrollTimelineOffset>( + CSSKeywordValue::Create("auto")); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ScrollTimelineOffsetValue ScrollTimelineOffset::ToScrollTimelineOffsetValue() const { ScrollTimelineOffsetValue result; @@ -224,6 +238,7 @@ ScrollTimelineOffsetValue ScrollTimelineOffset::ToScrollTimelineOffsetValue() return result; } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool ScrollTimelineOffset::operator==(const ScrollTimelineOffset& o) const { return DataEquivalent(length_based_offset_, o.length_based_offset_) && diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h index 067e7b11b6c..5cf0c9e4611 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_OFFSET_H_ #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/core/css/css_style_sheet.h" #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" @@ -47,12 +48,16 @@ class CORE_EXPORT ScrollTimelineOffset final // orientation. // // Returns nullopt if the offset cannot be resolved. - base::Optional<double> ResolveOffset(Node* scroll_source, + absl::optional<double> ResolveOffset(Node* scroll_source, ScrollOrientation, double max_offset, double default_offset); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8ScrollTimelineOffset* ToV8ScrollTimelineOffset() const; +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ScrollTimelineOffsetValue ToScrollTimelineOffsetValue() const; +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool IsDefaultValue() const { return !length_based_offset_ && !element_based_offset_; } diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl index 4456b97feb7..c02d9db29c9 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl @@ -16,8 +16,6 @@ enum ScrollTimelineAutoKeyword { "auto" }; dictionary ScrollTimelineOptions { Element? scrollSource; ScrollDirection orientation = "block"; - ScrollTimelineOffset startScrollOffset = "auto"; - ScrollTimelineOffset endScrollOffset = "auto"; sequence<ScrollTimelineOffset> scrollOffsets = []; (double or ScrollTimelineAutoKeyword) timeRange = "auto"; }; diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc index ac3d1cd6811..bdc9d1c9dd8 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc @@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" +#include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" @@ -30,6 +31,13 @@ static constexpr double time_error_ms = 0.001 + 1e-13; #define EXPECT_TIME_NEAR(expected, value) \ EXPECT_NEAR(expected, value, time_error_ms) +void ExpectVectorDoubleEqual(const WTF::Vector<double>& expected, + const WTF::Vector<double>& value) { + EXPECT_EQ(expected.size(), value.size()); + for (unsigned int i = 0; i < expected.size(); i++) + EXPECT_DOUBLE_EQ(expected[i], value[i]); +} + HeapVector<Member<ScrollTimelineOffset>> CreateScrollOffsets( ScrollTimelineOffset* start_scroll_offset = MakeGarbageCollected<ScrollTimelineOffset>( @@ -47,6 +55,17 @@ HeapVector<Member<ScrollTimelineOffset>> CreateScrollOffsets( return scroll_offsets; } +Animation* CreateTestAnimation(AnimationTimeline* timeline) { + Timing timing; + timing.iteration_duration = AnimationTimeDelta::FromSecondsD(0.1); + return Animation::Create(MakeGarbageCollected<KeyframeEffect>( + nullptr, + MakeGarbageCollected<StringKeyframeEffectModel>( + StringKeyframeVector()), + timing), + timeline, ASSERT_NO_EXCEPTION); +} + } // namespace class ScrollTimelineTest : public RenderingTest { @@ -149,8 +168,8 @@ TEST_F(ScrollTimelineTest, DoubleOrScrollTimelineAutoKeyword::FromDouble(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); - options->setStartScrollOffset(OffsetFromString("10px")); - options->setEndScrollOffset(OffsetFromString("90px")); + options->setScrollOffsets( + {OffsetFromString("10px"), OffsetFromString("90px")}); ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); @@ -218,8 +237,8 @@ TEST_F(ScrollTimelineTest, DoubleOrScrollTimelineAutoKeyword::FromDouble(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); - options->setStartScrollOffset(OffsetFromString("80px")); - options->setEndScrollOffset(OffsetFromString("40px")); + options->setScrollOffsets( + {OffsetFromString("80px"), OffsetFromString("40px")}); ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); @@ -271,8 +290,8 @@ TEST_F(ScrollTimelineTest, PhasesAreCorrectWhenUsingOffsets) { DoubleOrScrollTimelineAutoKeyword::FromDouble(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); - options->setStartScrollOffset(OffsetFromString("10px")); - options->setEndScrollOffset(OffsetFromString("90px")); + options->setScrollOffsets( + {OffsetFromString("10px"), OffsetFromString("90px")}); ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); @@ -435,6 +454,116 @@ TEST_F(ScrollTimelineTest, AnimationIsGarbageCollectedWhenScrollerIsRemoved) { EXPECT_EQ(0u, AnimationsCount()); } +TEST_F(ScrollTimelineTest, AnimationPersistsWhenFinished) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 100px; height: 100px; } + #spacer { width: 200px; height: 200px; } + </style> + <div id='scroller'> + <div id ='spacer'></div> + </div> + )HTML"); + + auto* scroller = + To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); + Persistent<TestScrollTimeline> scroll_timeline = + MakeGarbageCollected<TestScrollTimeline>(&GetDocument(), + GetElementById("scroller")); + Animation* animation = CreateTestAnimation(scroll_timeline); + animation->play(); + SimulateFrame(); + + // Scroll to finished: + scrollable_area->SetScrollOffset(ScrollOffset(0, 91), + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ("finished", animation->playState()); + + // Animation should still persist after GC. + animation = nullptr; + ThreadState::Current()->CollectAllGarbageForTesting(); + ASSERT_EQ(1u, scroll_timeline->GetAnimations().size()); + animation = *scroll_timeline->GetAnimations().begin(); + + // Scroll back to 50%. The animation should update, even though it was + // previously in a finished state. + ScrollOffset offset(0, 50); // 10 + (90 - 10) * 0.5 = 50 + scrollable_area->SetScrollOffset(offset, + mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_EQ("running", animation->playState()); + EXPECT_TIME_NEAR(50.0, animation->CurrentTimeInternal() + .value_or(AnimationTimeDelta()) + .InMillisecondsF()); +} + +TEST_F(ScrollTimelineTest, AnimationPersistsWhenSourceBecomesNonScrollable) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { width: 100px; height: 100px; } + #spacer { width: 200px; height: 200px; } + .scroll { overflow: scroll; } + </style> + <div id='scroller' class='scroll'> + <div id ='spacer'></div> + </div> + )HTML"); + + auto* scroller = + To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + Persistent<TestScrollTimeline> scroll_timeline = + MakeGarbageCollected<TestScrollTimeline>(&GetDocument(), + GetElementById("scroller")); + Animation* animation = CreateTestAnimation(scroll_timeline); + animation->play(); + SimulateFrame(); + + // Scroll to 50%: + ASSERT_TRUE(scroller->GetScrollableArea()); + ScrollOffset offset_50(0, 50); // 10 + (90 - 10) * 0.5 = 50 + scroller->GetScrollableArea()->SetScrollOffset( + offset_50, mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_TIME_NEAR(50.0, animation->CurrentTimeInternal() + .value_or(AnimationTimeDelta()) + .InMillisecondsF()); + + // Make #scroller non-scrollable. + GetElementById("scroller")->classList().Remove("scroll"); + UpdateAllLifecyclePhasesForTest(); + scroller = To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + ASSERT_TRUE(scroller); + EXPECT_FALSE(scroller->GetScrollableArea()); + + // ScrollTimeline should now have an unresolved current time. + SimulateFrame(); + EXPECT_FALSE(scroll_timeline->CurrentTimeMilliseconds().has_value()); + + // Animation should still persist after GC. + animation = nullptr; + ThreadState::Current()->CollectAllGarbageForTesting(); + ASSERT_EQ(1u, scroll_timeline->GetAnimations().size()); + animation = *scroll_timeline->GetAnimations().begin(); + + // Make #scroller scrollable again. + GetElementById("scroller")->classList().Add("scroll"); + UpdateAllLifecyclePhasesForTest(); + scroller = To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + ASSERT_TRUE(scroller); + ASSERT_TRUE(scroller->GetScrollableArea()); + + // Scroll to 40%: + ScrollOffset offset_42(0, 42); // 10 + (90 - 10) * 0.4 = 42 + scroller->GetScrollableArea()->SetScrollOffset( + offset_42, mojom::blink::ScrollType::kProgrammatic); + SimulateFrame(); + EXPECT_TIME_NEAR(40.0, animation->CurrentTimeInternal() + .value_or(AnimationTimeDelta()) + .InMillisecondsF()); +} + TEST_F(ScrollTimelineTest, ScheduleFrameOnlyWhenScrollOffsetChanges) { SetBodyInnerHTML(R"HTML( <style> @@ -786,6 +915,72 @@ TEST_F(ScrollTimelineTest, EXPECT_FALSE(event_listener->EventReceived()); } +TEST_F(ScrollTimelineTest, ResolveScrollOffsets) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 100px; height: 100px; } + #spacer { height: 1000px; } + </style> + <div id='scroller'> + <div id ='spacer'></div> + </div> + )HTML"); + + auto* scroller = + To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller")); + ASSERT_TRUE(scroller); + PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); + ASSERT_TRUE(scrollable_area); + double time_range = 100.0; + ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); + options->setTimeRange( + DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + options->setScrollSource(GetElementById("scroller")); + // Empty scroll offsets resolve into [0, 100%]. + HeapVector<ScrollTimelineOffsetValue> scroll_offsets = {}; + options->setScrollOffsets(scroll_offsets); + + ScrollTimeline* scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + + WTF::Vector<double> resolved_offsets; + WTF::Vector<double> expected_offsets = {0, 900.0}; + scroll_timeline->ResolveScrollOffsets(resolved_offsets); + ExpectVectorDoubleEqual(expected_offsets, resolved_offsets); + + // Single 'auto' offset resolve into [0, 100%]. + scroll_offsets = {OffsetFromString("auto")}; + options->setScrollOffsets(scroll_offsets); + scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + resolved_offsets.clear(); + scroll_timeline->ResolveScrollOffsets(resolved_offsets); + expected_offsets = {0, 900.0}; + ExpectVectorDoubleEqual(expected_offsets, resolved_offsets); + + // Start and end 'auto' offsets resolve into [0, 100%]. + scroll_offsets = {OffsetFromString("auto"), OffsetFromString("auto")}; + options->setScrollOffsets(scroll_offsets); + scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + resolved_offsets.clear(); + scroll_timeline->ResolveScrollOffsets(resolved_offsets); + expected_offsets = {0, 900.0}; + ExpectVectorDoubleEqual(expected_offsets, resolved_offsets); + + // Three offsets, start and end are 'auto' resolve into [0, middle offset, + // 100%]. + scroll_offsets = {OffsetFromString("auto"), OffsetFromString("500px"), + OffsetFromString("auto")}; + options->setScrollOffsets(scroll_offsets); + scroll_timeline = + ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); + resolved_offsets.clear(); + scroll_timeline->ResolveScrollOffsets(resolved_offsets); + expected_offsets = {0, 500.0, 900.0}; + ExpectVectorDoubleEqual(expected_offsets, resolved_offsets); +} + TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { SetBodyInnerHTML(R"HTML( <style> @@ -942,4 +1137,51 @@ TEST_F(ScrollTimelineTest, OverlappingScrollOffsets) { EXPECT_EQ(80, scroll_timeline->CurrentTimeMilliseconds().value()); } +TEST_F(ScrollTimelineTest, WeakReferences) { + SetBodyInnerHTML(R"HTML( + <style> + #scroller { overflow: scroll; width: 100px; height: 100px; } + #spacer { width: 200px; height: 200px; } + </style> + <div id='scroller'> + <div id ='spacer'></div> + </div> + )HTML"); + + Persistent<TestScrollTimeline> scroll_timeline = + MakeGarbageCollected<TestScrollTimeline>(&GetDocument(), + GetElementById("scroller")); + + EXPECT_EQ(0u, scroll_timeline->GetAnimations().size()); + + // Attaching an animation to a ScrollTimeline, and never playing it: + Animation* animation = CreateTestAnimation(scroll_timeline); + DCHECK(animation); + animation = nullptr; + EXPECT_EQ(1u, scroll_timeline->GetAnimations().size()); + + ThreadState::Current()->CollectAllGarbageForTesting(); + EXPECT_EQ(0u, scroll_timeline->GetAnimations().size()); + + // Playing, then canceling an animation: + animation = CreateTestAnimation(scroll_timeline); + EXPECT_EQ(1u, scroll_timeline->GetAnimations().size()); + + animation->play(); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(1u, scroll_timeline->GetAnimations().size()); + + animation->cancel(); + // UpdateAllLifecyclePhasesForTest does not call Animation::Update with + // reason=kTimingUpdateForAnimationFrame, which is required in order to lose + // all strong references to the animation. Hence the explicit call to + // SimulateFrame(). + SimulateFrame(); + UpdateAllLifecyclePhasesForTest(); + animation = nullptr; + + ThreadState::Current()->CollectAllGarbageForTesting(); + EXPECT_EQ(0u, scroll_timeline->GetAnimations().size()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc index f6719a131b7..714034716e1 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h" #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" #include "third_party/blink/renderer/core/dom/node.h" @@ -22,13 +23,18 @@ scoped_refptr<CompositorScrollTimeline> ToCompositorScrollTimeline( auto* scroll_timeline = To<ScrollTimeline>(timeline); Node* scroll_source = scroll_timeline->ResolvedScrollSource(); - base::Optional<CompositorElementId> element_id = + absl::optional<CompositorElementId> element_id = GetCompositorScrollElementId(scroll_source); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* time_range = scroll_timeline->timeRange(); + DCHECK(time_range); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DoubleOrScrollTimelineAutoKeyword time_range; scroll_timeline->timeRange(time_range); // TODO(smcgruer): Handle 'auto' time range value. DCHECK(time_range.IsDouble()); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) LayoutBox* box = scroll_timeline->IsActive() ? scroll_source->GetLayoutBox() : nullptr; @@ -38,14 +44,19 @@ scoped_refptr<CompositorScrollTimeline> ToCompositorScrollTimeline( return CompositorScrollTimeline::Create( element_id, orientation, scroll_timeline->GetResolvedScrollOffsets(), - time_range.GetAsDouble()); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + time_range->GetAsDouble() +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + time_range.GetAsDouble() +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + ); } -base::Optional<CompositorElementId> GetCompositorScrollElementId( +absl::optional<CompositorElementId> GetCompositorScrollElementId( const Node* node) { if (!node || !node->GetLayoutObject() || !node->GetLayoutObject()->FirstFragment().PaintProperties()) { - return base::nullopt; + return absl::nullopt; } return CompositorElementIdFromUniqueObjectId( node->GetLayoutObject()->UniqueId(), diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h index 7c66719e6c0..d53c61f8d48 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h @@ -5,10 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_UTIL_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_UTIL_H_ -#include <memory> - -#include "base/optional.h" #include "cc/animation/scroll_timeline.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/animation/compositor_animation.h" @@ -29,8 +27,8 @@ scoped_refptr<CompositorScrollTimeline> CORE_EXPORT ToCompositorScrollTimeline(AnimationTimeline*); // Retrieves the 'scroll' compositor element id for the input node, or -// base::nullopt if it does not exist. -base::Optional<CompositorElementId> CORE_EXPORT +// absl::nullopt if it does not exist. +absl::optional<CompositorElementId> CORE_EXPORT GetCompositorScrollElementId(const Node*); // Convert the blink concept of a ScrollTimeline orientation into the cc one. diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc index 1eeb2bdf298..223443d5116 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc @@ -53,7 +53,7 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimeline) { )HTML"); Element* scroller = GetElementById("scroller"); - base::Optional<CompositorElementId> element_id = + absl::optional<CompositorElementId> element_id = GetCompositorScrollElementId(scroller); ASSERT_TRUE(element_id.has_value()); @@ -63,14 +63,14 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimeline) { options->setTimeRange( DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); options->setOrientation("block"); - options->setStartScrollOffset(OffsetFromString(GetDocument(), "50px")); - options->setEndScrollOffset(OffsetFromString(GetDocument(), "auto")); + options->setScrollOffsets({OffsetFromString(GetDocument(), "50px"), + OffsetFromString(GetDocument(), "auto")}); ScrollTimeline* timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); scoped_refptr<CompositorScrollTimeline> compositor_timeline = ToCompositorScrollTimeline(timeline); - EXPECT_EQ(compositor_timeline->GetActiveIdForTest(), base::nullopt); + EXPECT_EQ(compositor_timeline->GetActiveIdForTest(), absl::nullopt); EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), element_id); EXPECT_EQ(compositor_timeline->GetTimeRangeForTest(), time_range); EXPECT_EQ(compositor_timeline->GetDirectionForTest(), @@ -107,7 +107,7 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullScrollSource) { scoped_refptr<CompositorScrollTimeline> compositor_timeline = ToCompositorScrollTimeline(timeline); ASSERT_TRUE(compositor_timeline.get()); - EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), base::nullopt); + EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), absl::nullopt); } TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullLayoutBox) { @@ -128,8 +128,8 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullLayoutBox) { // Here we just want to test the start/end scroll offset. // ToCompositorScrollTimelineNullScrollSource covers the expected pending id // and ConvertOrientationNullStyle covers the orientation conversion. - EXPECT_EQ(compositor_timeline->GetStartScrollOffsetForTest(), base::nullopt); - EXPECT_EQ(compositor_timeline->GetEndScrollOffsetForTest(), base::nullopt); + EXPECT_EQ(compositor_timeline->GetStartScrollOffsetForTest(), absl::nullopt); + EXPECT_EQ(compositor_timeline->GetEndScrollOffsetForTest(), absl::nullopt); } TEST_F(ScrollTimelineUtilTest, ConvertOrientationPhysicalCases) { @@ -221,20 +221,20 @@ TEST_F(ScrollTimelineUtilTest, ConvertOrientationNullStyle) { } TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNullNode) { - EXPECT_EQ(GetCompositorScrollElementId(nullptr), base::nullopt); + EXPECT_EQ(GetCompositorScrollElementId(nullptr), absl::nullopt); } TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNullLayoutObject) { auto* div = MakeGarbageCollected<HTMLDivElement>(GetDocument()); ASSERT_FALSE(div->GetLayoutObject()); - EXPECT_EQ(GetCompositorScrollElementId(nullptr), base::nullopt); + EXPECT_EQ(GetCompositorScrollElementId(nullptr), absl::nullopt); } TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNoUniqueId) { SetBodyInnerHTML("<div id='test'></div>"); Element* test = GetElementById("test"); ASSERT_TRUE(test->GetLayoutObject()); - EXPECT_EQ(GetCompositorScrollElementId(test), base::nullopt); + EXPECT_EQ(GetCompositorScrollElementId(test), absl::nullopt); } } // namespace scroll_timeline_util diff --git a/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.h b/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.h index a4cad011f2a..32f2064d74d 100644 --- a/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.h +++ b/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SIZE_INTERPOLATION_FUNCTIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SIZE_INTERPOLATION_FUNCTIONS_H_ -#include <memory> #include "third_party/blink/renderer/core/animation/interpolation_value.h" #include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h" #include "third_party/blink/renderer/core/style/fill_layer.h" diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h index f8793aac72c..a46dbc5e87a 100644 --- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h +++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h @@ -285,4 +285,4 @@ struct DowncastTraits<SVGPropertySpecificKeyframe> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_STRING_KEYFRAME_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h index bc588f791b8..529ef70c711 100644 --- a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h +++ b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h @@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SVG_INTERPOLATION_ENVIRONMENT_H_ #include "third_party/blink/renderer/core/animation/interpolation_environment.h" -#include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html b/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html index e92917a95ea..22e197dc79d 100644 --- a/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html +++ b/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html @@ -10,4 +10,4 @@ animation-duration: 1s; } </style> -<div id="target" class="animate"></div> +<div id="target" class="animate">TARGET</div> diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/svg-smil-animation.html b/chromium/third_party/blink/renderer/core/animation/test_data/svg-smil-animation.html new file mode 100644 index 00000000000..e4160da44f2 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/animation/test_data/svg-smil-animation.html @@ -0,0 +1,5 @@ +<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> + <rect width="10" height="10"> + <animate attributeName="rx" values="0;5;0" dur="1s"/> + </rect> +</svg> diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html index 600e84010cf..9bfccc43f9a 100644 --- a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html +++ b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html @@ -10,4 +10,4 @@ animation-duration: 1s; } </style> -<div id="target" class="animate"></div>; +<div id="target" class="animate">TARGET</div> diff --git a/chromium/third_party/blink/renderer/core/animation/timing.cc b/chromium/third_party/blink/renderer/core/animation/timing.cc index 8d57548ca6c..c1cec54438f 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing.cc @@ -72,24 +72,25 @@ AnimationTimeDelta Timing::IterationDuration() const { return result; } -double Timing::ActiveDuration() const { - const double result = +AnimationTimeDelta Timing::ActiveDuration() const { + const AnimationTimeDelta result = MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_count); - DCHECK_GE(result, 0); + DCHECK_GE(result, AnimationTimeDelta()); return result; } -double Timing::EndTimeInternal() const { +AnimationTimeDelta Timing::EndTimeInternal() const { // Per the spec, the end time has a lower bound of 0.0: // https://drafts.csswg.org/web-animations-1/#end-time - return std::max(start_delay + ActiveDuration() + end_delay, 0.0); + return std::max(start_delay + ActiveDuration() + end_delay, + AnimationTimeDelta()); } EffectTiming* Timing::ConvertToEffectTiming() const { EffectTiming* effect_timing = EffectTiming::Create(); - effect_timing->setDelay(start_delay * 1000); - effect_timing->setEndDelay(end_delay * 1000); + effect_timing->setDelay(start_delay.InMillisecondsF()); + effect_timing->setEndDelay(end_delay.InMillisecondsF()); effect_timing->setFill(FillModeString(fill_mode)); effect_timing->setIterationStart(iteration_start); effect_timing->setIterations(iteration_count); @@ -113,13 +114,13 @@ ComputedEffectTiming* Timing::getComputedTiming( // ComputedEffectTiming members. computed_timing->setEndTime( - CSSNumberish::FromDouble(EndTimeInternal() * 1000)); + CSSNumberish::FromDouble(EndTimeInternal().InMillisecondsF())); computed_timing->setActiveDuration( - CSSNumberish::FromDouble(ActiveDuration() * 1000)); + CSSNumberish::FromDouble(ActiveDuration().InMillisecondsF())); if (calculated_timing.local_time) { - computed_timing->setLocalTime( - CSSNumberish::FromDouble(calculated_timing.local_time.value() * 1000)); + computed_timing->setLocalTime(CSSNumberish::FromDouble( + calculated_timing.local_time->InMillisecondsF())); } else { computed_timing->setLocalTime(CSSNumberish()); } @@ -139,8 +140,8 @@ ComputedEffectTiming* Timing::getComputedTiming( // except that the fill and duration must be resolved. // // https://drafts.csswg.org/web-animations-1/#dom-animationeffect-getcomputedtiming - computed_timing->setDelay(start_delay * 1000); - computed_timing->setEndDelay(end_delay * 1000); + computed_timing->setDelay(start_delay.InMillisecondsF()); + computed_timing->setEndDelay(end_delay.InMillisecondsF()); computed_timing->setFill( Timing::FillModeString(ResolvedFillMode(is_keyframe_effect))); computed_timing->setIterationStart(iteration_start); @@ -157,36 +158,35 @@ ComputedEffectTiming* Timing::getComputedTiming( } Timing::CalculatedTiming Timing::CalculateTimings( - base::Optional<double> local_time, - base::Optional<Phase> timeline_phase, + absl::optional<AnimationTimeDelta> local_time, + absl::optional<Phase> timeline_phase, AnimationDirection animation_direction, bool is_keyframe_effect, - base::Optional<double> playback_rate) const { - const double active_duration = ActiveDuration(); + absl::optional<double> playback_rate) const { + const AnimationTimeDelta active_duration = ActiveDuration(); Timing::Phase current_phase = CalculatePhase( active_duration, local_time, timeline_phase, animation_direction, *this); - const base::Optional<AnimationTimeDelta> active_time = + const absl::optional<AnimationTimeDelta> active_time = CalculateActiveTime(active_duration, ResolvedFillMode(is_keyframe_effect), local_time, current_phase, *this); - base::Optional<double> progress; - const double local_iteration_duration = IterationDuration().InSecondsF(); + absl::optional<double> progress; - const base::Optional<double> overall_progress = CalculateOverallProgress( - current_phase, active_time, local_iteration_duration, iteration_count, - iteration_start); - const base::Optional<double> simple_iteration_progress = + const absl::optional<double> overall_progress = + CalculateOverallProgress(current_phase, active_time, IterationDuration(), + iteration_count, iteration_start); + const absl::optional<double> simple_iteration_progress = CalculateSimpleIterationProgress(current_phase, overall_progress, iteration_start, active_time, active_duration, iteration_count); - const base::Optional<double> current_iteration = + const absl::optional<double> current_iteration = CalculateCurrentIteration(current_phase, active_time, iteration_count, overall_progress, simple_iteration_progress); const bool current_direction_is_forwards = IsCurrentDirectionForwards(current_iteration, direction); - const base::Optional<double> directed_progress = CalculateDirectedProgress( + const absl::optional<double> directed_progress = CalculateDirectedProgress( simple_iteration_progress, current_iteration, direction); progress = CalculateTransformedProgress(current_phase, directed_progress, @@ -196,25 +196,21 @@ Timing::CalculatedTiming Timing::CalculateTimings( AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); // Conditionally compute the time to next iteration, which is only // applicable if the iteration duration is non-zero. - if (local_iteration_duration) { - const double start_offset = - MultiplyZeroAlwaysGivesZero(iteration_start, local_iteration_duration); - DCHECK_GE(start_offset, 0); - const base::Optional<AnimationTimeDelta> offset_active_time = + if (!IterationDuration().is_zero()) { + const AnimationTimeDelta start_offset = + MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_start); + DCHECK_GE(start_offset, AnimationTimeDelta()); + const absl::optional<AnimationTimeDelta> offset_active_time = CalculateOffsetActiveTime(active_duration, active_time, start_offset); - const base::Optional<AnimationTimeDelta> iteration_time = - CalculateIterationTime(local_iteration_duration, active_duration, + const absl::optional<AnimationTimeDelta> iteration_time = + CalculateIterationTime(IterationDuration(), active_duration, offset_active_time, start_offset, current_phase, *this); if (iteration_time) { // active_time cannot be null if iteration_time is not null. DCHECK(active_time); - time_to_next_iteration = - AnimationTimeDelta::FromSecondsD(local_iteration_duration) - - iteration_time.value(); - if (AnimationTimeDelta::FromSecondsD(active_duration) - - active_time.value() < - time_to_next_iteration) + time_to_next_iteration = IterationDuration() - iteration_time.value(); + if (active_duration - active_time.value() < time_to_next_iteration) time_to_next_iteration = AnimationTimeDelta::Max(); } } diff --git a/chromium/third_party/blink/renderer/core/animation/timing.h b/chromium/third_party/blink/renderer/core/animation/timing.h index a20382c5181..cb00ec731ed 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing.h +++ b/chromium/third_party/blink/renderer/core/animation/timing.h @@ -32,7 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_H_ #include "base/memory/scoped_refptr.h" -#include "base/optional.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_time_delta.h" #include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" @@ -88,20 +88,11 @@ struct CORE_EXPORT Timing { static FillMode StringToFillMode(const String&); static String PlaybackDirectionString(PlaybackDirection); - Timing() - : start_delay(0), - end_delay(0), - fill_mode(FillMode::AUTO), - iteration_start(0), - iteration_count(1), - iteration_duration(base::nullopt), - direction(PlaybackDirection::NORMAL), - timing_function(LinearTimingFunction::Shared()), - timing_overrides(kOverrideNode) {} + Timing() = default; void AssertValid() const { - DCHECK(std::isfinite(start_delay)); - DCHECK(std::isfinite(end_delay)); + DCHECK(!start_delay.is_inf()); + DCHECK(!end_delay.is_inf()); DCHECK(std::isfinite(iteration_start)); DCHECK_GE(iteration_start, 0); DCHECK_GE(iteration_count, 0); @@ -114,8 +105,8 @@ struct CORE_EXPORT Timing { AnimationTimeDelta IterationDuration() const; // https://drafts.csswg.org/web-animations-1/#active-duration - double ActiveDuration() const; - double EndTimeInternal() const; + AnimationTimeDelta ActiveDuration() const; + AnimationTimeDelta EndTimeInternal() const; Timing::FillMode ResolvedFillMode(bool is_animation) const; EffectTiming* ConvertToEffectTiming() const; @@ -142,30 +133,31 @@ struct CORE_EXPORT Timing { } bool HasTimingOverrides() { return timing_overrides != kOverrideNode; } - double start_delay; - double end_delay; - FillMode fill_mode; - double iteration_start; - double iteration_count; + AnimationTimeDelta start_delay; + AnimationTimeDelta end_delay; + FillMode fill_mode = FillMode::AUTO; + double iteration_start = 0; + double iteration_count = 1; // If empty, indicates the 'auto' value. - base::Optional<AnimationTimeDelta> iteration_duration; + absl::optional<AnimationTimeDelta> iteration_duration = absl::nullopt; - PlaybackDirection direction; - scoped_refptr<TimingFunction> timing_function; + PlaybackDirection direction = PlaybackDirection::NORMAL; + scoped_refptr<TimingFunction> timing_function = + LinearTimingFunction::Shared(); // Mask of timing attributes that are set by calls to // AnimationEffect.updateTiming. Once set, these attributes ignore changes // based on the CSS style. - uint16_t timing_overrides; + uint16_t timing_overrides = kOverrideNode; struct CalculatedTiming { DISALLOW_NEW(); Phase phase = Phase::kPhaseNone; - base::Optional<double> current_iteration = 0; - base::Optional<double> progress = 0; + absl::optional<double> current_iteration = 0; + absl::optional<double> progress = 0; bool is_current = false; bool is_in_effect = false; bool is_in_play = false; - base::Optional<double> local_time; + absl::optional<AnimationTimeDelta> local_time; AnimationTimeDelta time_to_forwards_effect_change = AnimationTimeDelta::Max(); AnimationTimeDelta time_to_reverse_effect_change = @@ -173,15 +165,16 @@ struct CORE_EXPORT Timing { AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); }; - CalculatedTiming CalculateTimings(base::Optional<double> local_time, - base::Optional<Phase> timeline_phase, - AnimationDirection animation_direction, - bool is_keyframe_effect, - base::Optional<double> playback_rate) const; + CalculatedTiming CalculateTimings( + absl::optional<AnimationTimeDelta> local_time, + absl::optional<Phase> timeline_phase, + AnimationDirection animation_direction, + bool is_keyframe_effect, + absl::optional<double> playback_rate) const; ComputedEffectTiming* getComputedTiming(const CalculatedTiming& calculated, bool is_keyframe_effect) const; }; } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h index 2173cc75e7a..56966564ed1 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h +++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h @@ -52,44 +52,76 @@ static inline double TimingCalculationEpsilon() { return 2.0 * std::numeric_limits<double>::epsilon(); } +static inline AnimationTimeDelta TimeTolerance() { + return AnimationTimeDelta::FromSecondsD(0.000001 /*one microsecond*/); +} + static inline bool IsWithinAnimationTimeEpsilon(double a, double b) { return std::abs(a - b) <= TimingCalculationEpsilon(); } +static inline bool IsWithinAnimationTimeTolerance(AnimationTimeDelta a, + AnimationTimeDelta b) { + if (a.is_inf() || b.is_inf()) { + return a == b; + } + AnimationTimeDelta difference = a >= b ? a - b : b - a; + return difference <= TimeTolerance(); +} + static inline bool LessThanOrEqualToWithinEpsilon(double a, double b) { return a <= b + TimingCalculationEpsilon(); } +static inline bool LessThanOrEqualToWithinTimeTolerance(AnimationTimeDelta a, + AnimationTimeDelta b) { + return a <= b + TimeTolerance(); +} + static inline bool GreaterThanOrEqualToWithinEpsilon(double a, double b) { return a >= b - TimingCalculationEpsilon(); } +static inline bool GreaterThanOrEqualToWithinTimeTolerance( + AnimationTimeDelta a, + AnimationTimeDelta b) { + return a >= b - TimeTolerance(); +} + +static inline bool GreaterThanWithinTimeTolerance(AnimationTimeDelta a, + AnimationTimeDelta b) { + return a > b - TimeTolerance(); +} + static inline double MultiplyZeroAlwaysGivesZero(double x, double y) { DCHECK(!std::isnan(x)); DCHECK(!std::isnan(y)); return x && y ? x * y : 0; } -static inline double MultiplyZeroAlwaysGivesZero(AnimationTimeDelta x, - double y) { +static inline AnimationTimeDelta MultiplyZeroAlwaysGivesZero( + AnimationTimeDelta x, + double y) { DCHECK(!std::isnan(y)); - return x.is_zero() || y == 0 ? 0 : (x * y).InSecondsF(); + return x.is_zero() || y == 0 ? AnimationTimeDelta() : (x * y); } // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states static inline Timing::Phase CalculatePhase( - double active_duration, - base::Optional<double> local_time, - base::Optional<Timing::Phase> timeline_phase, + AnimationTimeDelta active_duration, + absl::optional<AnimationTimeDelta> local_time, + absl::optional<Timing::Phase> timeline_phase, Timing::AnimationDirection direction, const Timing& specified) { - DCHECK_GE(active_duration, 0); + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + AnimationTimeDelta())); if (!local_time) return Timing::kPhaseNone; - double end_time = std::max( - specified.start_delay + active_duration + specified.end_delay, 0.0); - double before_active_boundary_time = - std::max(std::min(specified.start_delay, end_time), 0.0); + AnimationTimeDelta end_time = + std::max(specified.start_delay + active_duration + specified.end_delay, + AnimationTimeDelta()); + AnimationTimeDelta before_active_boundary_time = + std::max(std::min(specified.start_delay, end_time), AnimationTimeDelta()); if (local_time.value() < before_active_boundary_time || (local_time.value() == before_active_boundary_time && timeline_phase && timeline_phase.value() == Timing::kPhaseBefore) || @@ -97,8 +129,9 @@ static inline Timing::Phase CalculatePhase( direction == Timing::AnimationDirection::kBackwards)) { return Timing::kPhaseBefore; } - double active_after_boundary_time = std::max( - std::min(specified.start_delay + active_duration, end_time), 0.0); + AnimationTimeDelta active_after_boundary_time = + std::max(std::min(specified.start_delay + active_duration, end_time), + AnimationTimeDelta()); if (local_time > active_after_boundary_time || (local_time.value() == active_after_boundary_time && timeline_phase && timeline_phase.value() == Timing::kPhaseAfter) || @@ -110,65 +143,66 @@ static inline Timing::Phase CalculatePhase( } // https://drafts.csswg.org/web-animations/#calculating-the-active-time -static inline base::Optional<AnimationTimeDelta> CalculateActiveTime( - double active_duration, +static inline absl::optional<AnimationTimeDelta> CalculateActiveTime( + AnimationTimeDelta active_duration, Timing::FillMode fill_mode, - base::Optional<double> local_time, + absl::optional<AnimationTimeDelta> local_time, Timing::Phase phase, const Timing& specified) { - DCHECK_GE(active_duration, 0); + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + AnimationTimeDelta())); switch (phase) { case Timing::kPhaseBefore: if (fill_mode == Timing::FillMode::BACKWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); - return AnimationTimeDelta::FromSecondsD( - std::max(local_time.value() - specified.start_delay, 0.0)); + return std::max(local_time.value() - specified.start_delay, + AnimationTimeDelta()); } - return base::nullopt; + return absl::nullopt; case Timing::kPhaseActive: DCHECK(local_time.has_value()); - return AnimationTimeDelta::FromSecondsD(local_time.value() - - specified.start_delay); + return local_time.value() - specified.start_delay; case Timing::kPhaseAfter: if (fill_mode == Timing::FillMode::FORWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); - return AnimationTimeDelta::FromSecondsD(std::max( - 0.0, std::min(active_duration, - local_time.value() - specified.start_delay))); + return std::max(AnimationTimeDelta(), + std::min(active_duration, + local_time.value() - specified.start_delay)); } - return base::nullopt; + return absl::nullopt; case Timing::kPhaseNone: DCHECK(!local_time.has_value()); - return base::nullopt; + return absl::nullopt; default: NOTREACHED(); - return base::nullopt; + return absl::nullopt; } } // Calculates the overall progress, which describes the number of iterations // that have completed (including partial iterations). // https://drafts.csswg.org/web-animations/#calculating-the-overall-progress -static inline base::Optional<double> CalculateOverallProgress( +static inline absl::optional<double> CalculateOverallProgress( Timing::Phase phase, - base::Optional<AnimationTimeDelta> active_time, - double iteration_duration, + absl::optional<AnimationTimeDelta> active_time, + AnimationTimeDelta iteration_duration, double iteration_count, double iteration_start) { // 1. If the active time is unresolved, return unresolved. if (!active_time) - return base::nullopt; + return absl::nullopt; // 2. Calculate an initial value for overall progress. double overall_progress = 0; - if (IsWithinAnimationTimeEpsilon(iteration_duration, 0)) { + if (IsWithinAnimationTimeTolerance(iteration_duration, + AnimationTimeDelta())) { if (phase != Timing::kPhaseBefore) overall_progress = iteration_count; } else { - overall_progress = active_time->InSecondsF() / iteration_duration; + overall_progress = (active_time.value() / iteration_duration); } return overall_progress + iteration_start; @@ -179,16 +213,16 @@ static inline base::Optional<double> CalculateOverallProgress( // introduced by the playback direction or timing functions applied to the // effect. // https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration-progress -static inline base::Optional<double> CalculateSimpleIterationProgress( +static inline absl::optional<double> CalculateSimpleIterationProgress( Timing::Phase phase, - base::Optional<double> overall_progress, + absl::optional<double> overall_progress, double iteration_start, - base::Optional<AnimationTimeDelta> active_time, - double active_duration, + absl::optional<AnimationTimeDelta> active_time, + AnimationTimeDelta active_duration, double iteration_count) { // 1. If the overall progress is unresolved, return unresolved. if (!overall_progress) - return base::nullopt; + return absl::nullopt; // 2. If overall progress is infinity, let the simple iteration progress be // iteration start % 1.0, otherwise, let the simple iteration progress be @@ -209,8 +243,7 @@ static inline base::Optional<double> CalculateSimpleIterationProgress( // let the simple iteration progress be 1.0. if (IsWithinAnimationTimeEpsilon(simple_iteration_progress, 0.0) && (phase == Timing::kPhaseActive || phase == Timing::kPhaseAfter) && - IsWithinAnimationTimeEpsilon(active_time->InSecondsF(), - active_duration) && + IsWithinAnimationTimeTolerance(active_time.value(), active_duration) && !IsWithinAnimationTimeEpsilon(iteration_count, 0.0)) { simple_iteration_progress = 1.0; } @@ -220,15 +253,15 @@ static inline base::Optional<double> CalculateSimpleIterationProgress( } // https://drafts.csswg.org/web-animations/#calculating-the-current-iteration -static inline base::Optional<double> CalculateCurrentIteration( +static inline absl::optional<double> CalculateCurrentIteration( Timing::Phase phase, - base::Optional<AnimationTimeDelta> active_time, + absl::optional<AnimationTimeDelta> active_time, double iteration_count, - base::Optional<double> overall_progress, - base::Optional<double> simple_iteration_progress) { + absl::optional<double> overall_progress, + absl::optional<double> simple_iteration_progress) { // 1. If the active time is unresolved, return unresolved. if (!active_time) - return base::nullopt; + return absl::nullopt; // 2. If the animation effect is in the after phase and the iteration count // is infinity, return infinity. @@ -237,7 +270,7 @@ static inline base::Optional<double> CalculateCurrentIteration( } if (!overall_progress) - return base::nullopt; + return absl::nullopt; // simple iteration progress can only be null if overall progress is null. DCHECK(simple_iteration_progress); @@ -255,7 +288,7 @@ static inline base::Optional<double> CalculateCurrentIteration( // https://drafts.csswg.org/web-animations/#calculating-the-directed-progress static inline bool IsCurrentDirectionForwards( - base::Optional<double> current_iteration, + absl::optional<double> current_iteration, Timing::PlaybackDirection direction) { const bool current_iteration_is_even = !current_iteration ? false @@ -280,13 +313,13 @@ static inline bool IsCurrentDirectionForwards( } // https://drafts.csswg.org/web-animations/#calculating-the-directed-progress -static inline base::Optional<double> CalculateDirectedProgress( - base::Optional<double> simple_iteration_progress, - base::Optional<double> current_iteration, +static inline absl::optional<double> CalculateDirectedProgress( + absl::optional<double> simple_iteration_progress, + absl::optional<double> current_iteration, Timing::PlaybackDirection direction) { // 1. If the simple progress is unresolved, return unresolved. if (!simple_iteration_progress) - return base::nullopt; + return absl::nullopt; // 2. Calculate the current direction. bool current_direction_is_forwards = @@ -299,13 +332,13 @@ static inline base::Optional<double> CalculateDirectedProgress( } // https://drafts.csswg.org/web-animations/#calculating-the-transformed-progress -static inline base::Optional<double> CalculateTransformedProgress( +static inline absl::optional<double> CalculateTransformedProgress( Timing::Phase phase, - base::Optional<double> directed_progress, + absl::optional<double> directed_progress, bool is_current_direction_forward, scoped_refptr<TimingFunction> timing_function) { if (!directed_progress) - return base::nullopt; + return absl::nullopt; // Set the before flag to indicate if at the leading edge of an iteration. // This is used to determine if the left or right limit should be used if at a @@ -337,24 +370,27 @@ static inline base::Optional<double> CalculateTransformedProgress( // product of the iteration start and iteration duration). This is not part of // the Web Animations spec; it is used for calculating the time until the next // iteration to optimize scheduling. -static inline base::Optional<AnimationTimeDelta> CalculateOffsetActiveTime( - double active_duration, - base::Optional<AnimationTimeDelta> active_time, - double start_offset) { - DCHECK_GE(active_duration, 0); - DCHECK_GE(start_offset, 0); +static inline absl::optional<AnimationTimeDelta> CalculateOffsetActiveTime( + AnimationTimeDelta active_duration, + absl::optional<AnimationTimeDelta> active_time, + AnimationTimeDelta start_offset) { + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + AnimationTimeDelta())); + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(start_offset, + AnimationTimeDelta())); if (!active_time) - return base::nullopt; + return absl::nullopt; - DCHECK(active_time.value() >= AnimationTimeDelta() && - LessThanOrEqualToWithinEpsilon(active_time->InSecondsF(), - active_duration)); + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_time.value(), + AnimationTimeDelta()) && + LessThanOrEqualToWithinTimeTolerance(active_time.value(), + active_duration)); if (active_time->is_max()) return AnimationTimeDelta::Max(); - return active_time.value() + AnimationTimeDelta::FromSecondsD(start_offset); + return active_time.value() + start_offset; } // Maps the offset active time into 'iteration time space'[0], aka the offset @@ -363,46 +399,48 @@ static inline base::Optional<AnimationTimeDelta> CalculateOffsetActiveTime( // the time until the next iteration to optimize scheduling. // // [0] https://drafts.csswg.org/web-animations-1/#iteration-time-space -static inline base::Optional<AnimationTimeDelta> CalculateIterationTime( - double iteration_duration, - double active_duration, - base::Optional<AnimationTimeDelta> offset_active_time, - double start_offset, +static inline absl::optional<AnimationTimeDelta> CalculateIterationTime( + AnimationTimeDelta iteration_duration, + AnimationTimeDelta active_duration, + absl::optional<AnimationTimeDelta> offset_active_time, + AnimationTimeDelta start_offset, Timing::Phase phase, const Timing& specified) { - DCHECK_GT(iteration_duration, 0); - DCHECK_EQ(active_duration, - MultiplyZeroAlwaysGivesZero(iteration_duration, - specified.iteration_count)); + DCHECK( + GreaterThanWithinTimeTolerance(iteration_duration, AnimationTimeDelta())); + DCHECK(IsWithinAnimationTimeTolerance( + active_duration, MultiplyZeroAlwaysGivesZero(iteration_duration, + specified.iteration_count))); if (!offset_active_time) - return base::nullopt; + return absl::nullopt; - DCHECK_GE(offset_active_time.value(), AnimationTimeDelta()); - DCHECK(LessThanOrEqualToWithinEpsilon(offset_active_time->InSecondsF(), - active_duration + start_offset)); + DCHECK(GreaterThanWithinTimeTolerance(offset_active_time.value(), + AnimationTimeDelta())); + DCHECK(LessThanOrEqualToWithinTimeTolerance( + offset_active_time.value(), (active_duration + start_offset))); if (offset_active_time->is_max() || - (offset_active_time->InSecondsF() - start_offset == active_duration && + (IsWithinAnimationTimeTolerance(offset_active_time.value() - start_offset, + active_duration) && specified.iteration_count && EndsOnIterationBoundary(specified.iteration_count, specified.iteration_start))) - return AnimationTimeDelta::FromSecondsD(iteration_duration); + return absl::make_optional(iteration_duration); DCHECK(!offset_active_time->is_max()); - double iteration_time = - fmod(offset_active_time->InSecondsF(), iteration_duration); + AnimationTimeDelta iteration_time = AnimationTimeDelta::FromSecondsD( + fmod(offset_active_time->InSecondsF(), iteration_duration.InSecondsF())); // This implements step 3 of // https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration-progress - if (iteration_time == 0 && phase == Timing::kPhaseAfter && - active_duration != 0 && - offset_active_time.value() != AnimationTimeDelta()) - return AnimationTimeDelta::FromSecondsD(iteration_duration); + if (iteration_time.is_zero() && phase == Timing::kPhaseAfter && + !active_duration.is_zero() && !offset_active_time.value().is_zero()) + return absl::make_optional(iteration_duration); - return AnimationTimeDelta::FromSecondsD(iteration_time); + return iteration_time; } } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_CALCULATIONS_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc index fe459606c6e..f07595c0f1f 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc @@ -42,66 +42,87 @@ TEST(AnimationTimingCalculationsTest, ActiveTime) { // activeDuration, fillMode, localTime, parentPhase, phase, timing) // Before Phase - timing.start_delay = 10; - EXPECT_FALSE(CalculateActiveTime(20, Timing::FillMode::FORWARDS, 0, + timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + EXPECT_FALSE(CalculateActiveTime( + AnimationTimeDelta::FromSecondsD(20), Timing::FillMode::FORWARDS, + AnimationTimeDelta(), Timing::kPhaseBefore, timing)); + EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), + Timing::FillMode::NONE, AnimationTimeDelta(), Timing::kPhaseBefore, timing)); - EXPECT_FALSE(CalculateActiveTime(20, Timing::FillMode::NONE, 0, - Timing::kPhaseBefore, timing)); - EXPECT_EQ(AnimationTimeDelta(), - CalculateActiveTime(20, Timing::FillMode::BACKWARDS, 0, - Timing::kPhaseBefore, timing)); + EXPECT_EQ( + AnimationTimeDelta(), + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), + Timing::FillMode::BACKWARDS, AnimationTimeDelta(), + Timing::kPhaseBefore, timing)); EXPECT_EQ(AnimationTimeDelta(), - CalculateActiveTime(20, Timing::FillMode::BOTH, 0, + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), + Timing::FillMode::BOTH, AnimationTimeDelta(), Timing::kPhaseBefore, timing)); - timing.start_delay = -10; + timing.start_delay = AnimationTimeDelta::FromSecondsD(-10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(20, Timing::FillMode::BACKWARDS, -5, + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), + Timing::FillMode::BACKWARDS, + AnimationTimeDelta::FromSecondsD(-5), Timing::kPhaseBefore, timing)); // Active Phase - timing.start_delay = 10; + timing.start_delay = AnimationTimeDelta::FromSecondsD(10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(20, Timing::FillMode::FORWARDS, 15, + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), + Timing::FillMode::FORWARDS, + AnimationTimeDelta::FromSecondsD(15), Timing::kPhaseActive, timing)); // After Phase - timing.start_delay = 10; + timing.start_delay = AnimationTimeDelta::FromSecondsD(10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(21, Timing::FillMode::FORWARDS, 45, + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), + Timing::FillMode::FORWARDS, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(21, Timing::FillMode::BOTH, 45, + CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), + Timing::FillMode::BOTH, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); - EXPECT_FALSE(CalculateActiveTime(21, Timing::FillMode::BACKWARDS, 45, - Timing::kPhaseAfter, timing)); - EXPECT_FALSE(CalculateActiveTime(21, Timing::FillMode::NONE, 45, - Timing::kPhaseAfter, timing)); + EXPECT_FALSE(CalculateActiveTime( + AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::BACKWARDS, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); + EXPECT_FALSE(CalculateActiveTime( + AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::NONE, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); // None - EXPECT_FALSE(CalculateActiveTime(32, Timing::FillMode::NONE, base::nullopt, + EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(32), + Timing::FillMode::NONE, absl::nullopt, Timing::kPhaseNone, timing)); } TEST(AnimationTimingCalculationsTest, OffsetActiveTime) { // if the active time is null - EXPECT_FALSE(CalculateOffsetActiveTime(4, base::nullopt, 5)); + EXPECT_FALSE(CalculateOffsetActiveTime(AnimationTimeDelta::FromSecondsD(4), + absl::nullopt, + AnimationTimeDelta::FromSecondsD(5))); // normal case - EXPECT_EQ( - AnimationTimeDelta::FromSecondsD(15), - CalculateOffsetActiveTime(40, AnimationTimeDelta::FromSecondsD(10), 5)); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(15), + CalculateOffsetActiveTime(AnimationTimeDelta::FromSecondsD(40), + AnimationTimeDelta::FromSecondsD(10), + AnimationTimeDelta::FromSecondsD(5))); // infinite activeTime - EXPECT_TRUE(CalculateOffsetActiveTime(std::numeric_limits<double>::infinity(), - AnimationTimeDelta::Max(), 0) + EXPECT_TRUE(CalculateOffsetActiveTime(AnimationTimeDelta::Max(), + AnimationTimeDelta::Max(), + AnimationTimeDelta()) ->is_max()); // Edge case for active_time being within epsilon of active_duration. // https://crbug.com/962138 auto active_time = AnimationTimeDelta::FromSecondsD(1.3435713716800004); - const double active_duration = 1.3435713716800002; - EXPECT_EQ(active_time, - CalculateOffsetActiveTime(active_duration, active_time, 0)); + const auto active_duration = + AnimationTimeDelta::FromSecondsD(1.3435713716800002); + EXPECT_EQ(active_time, CalculateOffsetActiveTime(active_duration, active_time, + AnimationTimeDelta())); } TEST(AnimationTimingCalculationsTest, IterationTime) { @@ -112,94 +133,110 @@ TEST(AnimationTimingCalculationsTest, IterationTime) { // phase, timing) // if the scaled active time is null - EXPECT_FALSE(CalculateIterationTime(1, 1, base::nullopt, 1, - Timing::kPhaseActive, timing)); + EXPECT_FALSE(CalculateIterationTime( + AnimationTimeDelta::FromSecondsD(1), AnimationTimeDelta::FromSecondsD(1), + absl::nullopt, AnimationTimeDelta::FromSecondsD(1), Timing::kPhaseActive, + timing)); // if (complex-conditions)... EXPECT_EQ(AnimationTimeDelta::FromSecondsD(12), - CalculateIterationTime(12, 12, AnimationTimeDelta::FromSecondsD(12), - 0, Timing::kPhaseActive, timing)); + CalculateIterationTime(AnimationTimeDelta::FromSecondsD(12), + AnimationTimeDelta::FromSecondsD(12), + AnimationTimeDelta::FromSecondsD(12), + AnimationTimeDelta(), Timing::kPhaseActive, + timing)); // otherwise timing.iteration_count = 10; - EXPECT_EQ( - AnimationTimeDelta::FromSecondsD(5), - CalculateIterationTime(10, 100, AnimationTimeDelta::FromSecondsD(25), 4, - Timing::kPhaseActive, timing)); - EXPECT_EQ( - AnimationTimeDelta::FromSecondsD(7), - CalculateIterationTime(11, 110, AnimationTimeDelta::FromSecondsD(29), 1, - Timing::kPhaseActive, timing)); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), + CalculateIterationTime(AnimationTimeDelta::FromSecondsD(10), + AnimationTimeDelta::FromSecondsD(100), + AnimationTimeDelta::FromSecondsD(25), + AnimationTimeDelta::FromSecondsD(4), + Timing::kPhaseActive, timing)); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(7), + CalculateIterationTime(AnimationTimeDelta::FromSecondsD(11), + AnimationTimeDelta::FromSecondsD(110), + AnimationTimeDelta::FromSecondsD(29), + AnimationTimeDelta::FromSecondsD(1), + Timing::kPhaseActive, timing)); timing.iteration_start = 1.1; - EXPECT_EQ( - AnimationTimeDelta::FromSecondsD(8), - CalculateIterationTime(12, 120, AnimationTimeDelta::FromSecondsD(20), 7, - Timing::kPhaseActive, timing)); + EXPECT_EQ(AnimationTimeDelta::FromSecondsD(8), + CalculateIterationTime(AnimationTimeDelta::FromSecondsD(12), + AnimationTimeDelta::FromSecondsD(120), + AnimationTimeDelta::FromSecondsD(20), + AnimationTimeDelta::FromSecondsD(7), + Timing::kPhaseActive, timing)); // Edge case for offset_active_time being within epsilon of (active_duration // + start_offset). https://crbug.com/962138 timing.iteration_count = 1; - const double offset_active_time = 1.3435713716800004; - const double iteration_duration = 1.3435713716800002; - const double active_duration = 1.3435713716800002; + const AnimationTimeDelta offset_active_time = + AnimationTimeDelta::FromSecondsD(1.3435713716800004); + const AnimationTimeDelta iteration_duration = + AnimationTimeDelta::FromSecondsD(1.3435713716800002); + const AnimationTimeDelta active_duration = + AnimationTimeDelta::FromSecondsD(1.3435713716800002); EXPECT_NEAR(2.22045e-16, - CalculateIterationTime( - iteration_duration, active_duration, - AnimationTimeDelta::FromSecondsD(offset_active_time), 0, - Timing::kPhaseActive, timing) + CalculateIterationTime(iteration_duration, active_duration, + offset_active_time, AnimationTimeDelta(), + Timing::kPhaseActive, timing) ->InSecondsF(), std::numeric_limits<float>::epsilon()); } TEST(AnimationTimingCalculationsTest, OverallProgress) { // If the active time is null. - EXPECT_FALSE(CalculateOverallProgress(Timing::kPhaseAfter, - /*active_time=*/base::nullopt, - /*iteration_duration=*/1.0, - /*iteration_count=*/1.0, - /*iteration_start=*/1.0)); + EXPECT_FALSE(CalculateOverallProgress( + Timing::kPhaseAfter, + /*active_time=*/absl::nullopt, + /*iteration_duration=*/AnimationTimeDelta::FromSecondsD(1.0), + /*iteration_count=*/1.0, + /*iteration_start=*/1.0)); // If iteration duration is zero, calculate progress based on iteration count. EXPECT_EQ(3, CalculateOverallProgress( Timing::kPhaseActive, /*active_time=*/AnimationTimeDelta::FromSecondsD(3.0), - /*iteration_duration=*/0.0, + /*iteration_duration=*/AnimationTimeDelta(), /*iteration_count=*/3.0, /*iteration_start=*/0.0)); // ...unless in before phase, in which case progress is zero. EXPECT_EQ(0, CalculateOverallProgress( Timing::kPhaseBefore, /*active_time=*/AnimationTimeDelta::FromSecondsD(3.0), - /*iteration_duration=*/0.0, + /*iteration_duration=*/AnimationTimeDelta(), /*iteration_count=*/3.0, /*iteration_start=*/0.0)); // Edge case for duration being within Epsilon of zero. // crbug.com/954558 - EXPECT_EQ(1, CalculateOverallProgress( - Timing::kPhaseActive, - /*active_time=*/AnimationTimeDelta::FromSecondsD(3.0), - /*iteration_duration=*/1e-18, - /*iteration_count=*/1.0, - /*iteration_start=*/0.0)); + EXPECT_EQ(1, + CalculateOverallProgress( + Timing::kPhaseActive, + /*active_time=*/AnimationTimeDelta::FromSecondsD(3.0), + /*iteration_duration=*/AnimationTimeDelta::FromSecondsD(1e-18), + /*iteration_count=*/1.0, + /*iteration_start=*/0.0)); // Otherwise. - EXPECT_EQ(3.0, CalculateOverallProgress( - Timing::kPhaseAfter, - /*active_time=*/AnimationTimeDelta::FromSecondsD(2.5), - /*iteration_duration=*/1.0, - /*iteration_count=*/0.0, - /*iteration_start=*/0.5)); + EXPECT_EQ(3.0, + CalculateOverallProgress( + Timing::kPhaseAfter, + /*active_time=*/AnimationTimeDelta::FromSecondsD(2.5), + /*iteration_duration=*/AnimationTimeDelta::FromSecondsD(1.0), + /*iteration_count=*/0.0, + /*iteration_start=*/0.5)); } TEST(AnimationTimingCalculationsTest, CalculateSimpleIterationProgress) { // If the overall progress is null. - EXPECT_FALSE( - CalculateSimpleIterationProgress(Timing::kPhaseAfter, - /*overall_progress=*/base::nullopt, - /*iteration_start=*/1.0, - /*active_time=*/base::nullopt, - /*active_duration=*/1.0, - /*iteration_count=*/1.0)); + EXPECT_FALSE(CalculateSimpleIterationProgress( + Timing::kPhaseAfter, + /*overall_progress=*/absl::nullopt, + /*iteration_start=*/1.0, + /*active_time=*/absl::nullopt, + /*active_duration=*/AnimationTimeDelta::FromSecondsD(1.0), + /*iteration_count=*/1.0)); // If the overall progress is infinite. const double inf = std::numeric_limits<double>::infinity(); @@ -208,7 +245,7 @@ TEST(AnimationTimingCalculationsTest, CalculateSimpleIterationProgress) { /*overall_progress=*/inf, /*iteration_start=*/1.5, /*active_time=*/AnimationTimeDelta(), - /*active_duration=*/0.0, + /*active_duration=*/AnimationTimeDelta(), /*iteration_count=*/inf)); // Precisely on an iteration boundary. @@ -217,7 +254,7 @@ TEST(AnimationTimingCalculationsTest, CalculateSimpleIterationProgress) { /*overall_progress=*/3.0, /*iteration_start=*/0.0, /*active_time=*/AnimationTimeDelta::FromSecondsD(3.0), - /*active_duration=*/3.0, + /*active_duration=*/AnimationTimeDelta::FromSecondsD(3.0), /*iteration_count=*/3.0)); // Otherwise. @@ -226,16 +263,16 @@ TEST(AnimationTimingCalculationsTest, CalculateSimpleIterationProgress) { /*overall_progress=*/2.5, /*iteration_start=*/0.0, /*active_time=*/AnimationTimeDelta::FromSecondsD(2.5), - /*active_duration=*/0.0, + /*active_duration=*/AnimationTimeDelta(), /*iteration_count=*/0.0)); } TEST(AnimationTimingCalculationsTest, CurrentIteration) { // If the active time is null. EXPECT_FALSE(CalculateCurrentIteration(Timing::kPhaseAfter, - /*active_time=*/base::nullopt, + /*active_time=*/absl::nullopt, /*iteration_count=*/1.0, - /*overall_progress=*/base::nullopt, + /*overall_progress=*/absl::nullopt, /*simple_iteration_progress=*/0)); // If the iteration count is infinite. @@ -300,7 +337,7 @@ TEST(AnimationTimingCalculationsTest, CalculateDirectedProgress) { // direction); // if the simple iteration progress is null - EXPECT_FALSE(CalculateDirectedProgress(base::nullopt, base::nullopt, + EXPECT_FALSE(CalculateDirectedProgress(absl::nullopt, absl::nullopt, Timing::PlaybackDirection::NORMAL)); // forwards @@ -349,7 +386,7 @@ TEST(AnimationTimingCalculationsTest, TransformedProgress) { StepsTimingFunction::Create(4, StepsTimingFunction::StepPosition::END); // directed_progress is null. - EXPECT_FALSE(CalculateTransformedProgress(Timing::kPhaseActive, base::nullopt, + EXPECT_FALSE(CalculateTransformedProgress(Timing::kPhaseActive, absl::nullopt, true, timing_function)); // At step boundaries. diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input.cc b/chromium/third_party/blink/renderer/core/animation/timing_input.cc index f98e49ecb4a..90ed70bd569 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_input.cc @@ -9,6 +9,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -26,13 +28,13 @@ Timing::PlaybackDirection ConvertPlaybackDirection(const String& direction) { return Timing::PlaybackDirection::NORMAL; } -base::Optional<AnimationTimeDelta> ConvertIterationDuration( +absl::optional<AnimationTimeDelta> ConvertIterationDuration( const UnrestrictedDoubleOrString& duration) { if (duration.IsUnrestrictedDouble()) { return AnimationTimeDelta::FromMillisecondsD( duration.GetAsUnrestrictedDouble()); } - return base::nullopt; + return absl::nullopt; } Timing ConvertEffectTiming(const EffectTiming* timing_input, @@ -57,6 +59,37 @@ bool UpdateValueIfChanged(V& lhs, const V& rhs) { } // namespace +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +Timing TimingInput::Convert( + const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, + Document* document, + ExceptionState& exception_state) { + if (!options) { + return Timing(); + } + + switch (options->GetContentType()) { + case V8UnionKeyframeEffectOptionsOrUnrestrictedDouble::ContentType:: + kKeyframeEffectOptions: + return ConvertEffectTiming(options->GetAsKeyframeEffectOptions(), + document, exception_state); + case V8UnionKeyframeEffectOptionsOrUnrestrictedDouble::ContentType:: + kUnrestrictedDouble: { + // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect + // If options is a double, + // Let timing input be a new EffectTiming object with all members set to + // their default values and duration set to options. + EffectTiming* timing_input = EffectTiming::Create(); + timing_input->setDuration( + UnrestrictedDoubleOrString::FromUnrestrictedDouble( + options->GetAsUnrestrictedDouble())); + return ConvertEffectTiming(timing_input, document, exception_state); + } + } + NOTREACHED(); + return Timing(); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing TimingInput::Convert( const UnrestrictedDoubleOrKeyframeEffectOptions& options, Document* document, @@ -81,7 +114,39 @@ Timing TimingInput::Convert( options.GetAsUnrestrictedDouble())); return ConvertEffectTiming(timing_input, document, exception_state); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +Timing TimingInput::Convert( + const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, + Document* document, + ExceptionState& exception_state) { + if (!options) { + return Timing(); + } + switch (options->GetContentType()) { + case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType:: + kKeyframeAnimationOptions: + return ConvertEffectTiming(options->GetAsKeyframeAnimationOptions(), + document, exception_state); + case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType:: + kUnrestrictedDouble: { + // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect + // If options is a double, + // Let timing input be a new EffectTiming object with all members set to + // their default values and duration set to options. + EffectTiming* timing_input = EffectTiming::Create(); + timing_input->setDuration( + UnrestrictedDoubleOrString::FromUnrestrictedDouble( + options->GetAsUnrestrictedDouble())); + return ConvertEffectTiming(timing_input, document, exception_state); + } + } + NOTREACHED(); + return Timing(); +} +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing TimingInput::Convert( const UnrestrictedDoubleOrKeyframeAnimationOptions& options, Document* document, @@ -105,6 +170,7 @@ Timing TimingInput::Convert( options.GetAsUnrestrictedDouble())); return ConvertEffectTiming(timing_input, document, exception_state); } +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) template <class InputTiming> bool TimingInput::Update(Timing& timing, @@ -163,12 +229,16 @@ bool TimingInput::Update(Timing& timing, bool changed = false; if (input->hasDelay()) { DCHECK(std::isfinite(input->delay())); - changed |= UpdateValueIfChanged(timing.start_delay, input->delay() / 1000); + changed |= UpdateValueIfChanged( + timing.start_delay, + AnimationTimeDelta::FromMillisecondsD(input->delay())); timing.SetTimingOverride(Timing::kOverrideStartDelay); } if (input->hasEndDelay()) { DCHECK(std::isfinite(input->endDelay())); - changed |= UpdateValueIfChanged(timing.end_delay, input->endDelay() / 1000); + changed |= UpdateValueIfChanged( + timing.end_delay, + AnimationTimeDelta::FromMillisecondsD(input->endDelay())); timing.SetTimingOverride(Timing::kOverrideEndDelay); } if (input->hasFill()) { diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input.h b/chromium/third_party/blink/renderer/core/animation/timing_input.h index 0df7f407b0e..6a30531d57f 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input.h +++ b/chromium/third_party/blink/renderer/core/animation/timing_input.h @@ -15,6 +15,8 @@ class Document; class ExceptionState; class UnrestrictedDoubleOrKeyframeAnimationOptions; class UnrestrictedDoubleOrKeyframeEffectOptions; +class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble; +class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble; class CORE_EXPORT TimingInput { STATIC_ONLY(TimingInput); @@ -24,17 +26,31 @@ class CORE_EXPORT TimingInput { // the 'options' parameter into timing information. // // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + static Timing Convert( + const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, + Document* document, + ExceptionState& exception_state); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static Timing Convert(const UnrestrictedDoubleOrKeyframeEffectOptions&, Document*, ExceptionState&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Implements step 2 of the Animatable::animate() method, converting the // 'options' parameter into timing information. // // https://drafts.csswg.org/web-animations-1/#dom-animatable-animate +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + static Timing Convert( + const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, + Document* document, + ExceptionState& exception_state); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static Timing Convert(const UnrestrictedDoubleOrKeyframeAnimationOptions&, Document*, ExceptionState&); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Implements the procedure to 'update the timing properties of an animation // effect'. @@ -49,4 +65,4 @@ class CORE_EXPORT TimingInput { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_INPUT_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc index 98834571a87..4a7b2bbacc1 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc @@ -11,6 +11,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "v8/include/v8.h" @@ -62,9 +64,15 @@ Timing AnimationTimingInputTest::ApplyTimingInputNumber( return Timing(); } +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* timing_input = + MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + timing_input_dictionary); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions timing_input = UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( timing_input_dictionary); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -75,9 +83,15 @@ Timing AnimationTimingInputTest::ApplyTimingInputNumber( if (exception_state.HadException()) return Timing(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* timing_input = MakeGarbageCollected< + V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( + timing_input_dictionary); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeAnimationOptions timing_input = UnrestrictedDoubleOrKeyframeAnimationOptions:: FromKeyframeAnimationOptions(timing_input_dictionary); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -106,9 +120,15 @@ Timing AnimationTimingInputTest::ApplyTimingInputString( if (exception_state.HadException()) return Timing(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* timing_input = + MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + timing_input_dictionary); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions timing_input = UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( timing_input_dictionary); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -119,9 +139,15 @@ Timing AnimationTimingInputTest::ApplyTimingInputString( if (exception_state.HadException()) return Timing(); +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* timing_input = MakeGarbageCollected< + V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( + timing_input_dictionary); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeAnimationOptions timing_input = UnrestrictedDoubleOrKeyframeAnimationOptions:: FromKeyframeAnimationOptions(timing_input_dictionary); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -135,35 +161,35 @@ TEST_F(AnimationTimingInputTest, TimingInputStartDelay) { bool did_success; EXPECT_EQ(1.1, ApplyTimingInputNumber(scope.GetIsolate(), "delay", 1100, did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_TRUE(did_success); EXPECT_EQ(-1, ApplyTimingInputNumber(scope.GetIsolate(), "delay", -1000, did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_TRUE(did_success); EXPECT_EQ(1, ApplyTimingInputString(scope.GetIsolate(), "delay", "1000", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_TRUE(did_success); EXPECT_EQ( 0, ApplyTimingInputString(scope.GetIsolate(), "delay", "1s", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_FALSE(did_success); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "Infinity", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_FALSE(did_success); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "-Infinity", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_FALSE(did_success); EXPECT_EQ( 0, ApplyTimingInputString(scope.GetIsolate(), "delay", "NaN", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_FALSE(did_success); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "rubbish", did_success) - .start_delay); + .start_delay.InSecondsF()); EXPECT_FALSE(did_success); } @@ -173,28 +199,28 @@ TEST_F(AnimationTimingInputTest, bool ignored_success; EXPECT_EQ(1.1, ApplyTimingInputNumber(scope.GetIsolate(), "delay", 1100, ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(-1, ApplyTimingInputNumber(scope.GetIsolate(), "delay", -1000, ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(1, ApplyTimingInputString(scope.GetIsolate(), "delay", "1000", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "1s", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "Infinity", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "-Infinity", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "NaN", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); EXPECT_EQ(0, ApplyTimingInputString(scope.GetIsolate(), "delay", "rubbish", ignored_success, false) - .start_delay); + .start_delay.InSecondsF()); } TEST_F(AnimationTimingInputTest, TimingInputEndDelay) { @@ -202,10 +228,10 @@ TEST_F(AnimationTimingInputTest, TimingInputEndDelay) { bool ignored_success; EXPECT_EQ(10, ApplyTimingInputNumber(scope.GetIsolate(), "endDelay", 10000, ignored_success) - .end_delay); + .end_delay.InSecondsF()); EXPECT_EQ(-2.5, ApplyTimingInputNumber(scope.GetIsolate(), "endDelay", -2500, ignored_success) - .end_delay); + .end_delay.InSecondsF()); } TEST_F(AnimationTimingInputTest, TimingInputFillMode) { @@ -453,9 +479,15 @@ TEST_F(AnimationTimingInputTest, TimingInputTimingFunction) { TEST_F(AnimationTimingInputTest, TimingInputEmpty) { DummyExceptionStateForTesting exception_state; Timing control_timing; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* timing_input = + MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( + KeyframeEffectOptions::Create()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeEffectOptions timing_input = UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( KeyframeEffectOptions::Create()); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing updated_timing = TimingInput::Convert(timing_input, nullptr, exception_state); EXPECT_FALSE(exception_state.HadException()); @@ -472,9 +504,15 @@ TEST_F(AnimationTimingInputTest, TimingInputEmpty) { TEST_F(AnimationTimingInputTest, TimingInputEmptyKeyframeAnimationOptions) { DummyExceptionStateForTesting exception_state; Timing control_timing; +#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + auto* input_timing = + MakeGarbageCollected<V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( + KeyframeAnimationOptions::Create()); +#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UnrestrictedDoubleOrKeyframeAnimationOptions input_timing = UnrestrictedDoubleOrKeyframeAnimationOptions:: FromKeyframeAnimationOptions(KeyframeAnimationOptions::Create()); +#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing updated_timing = TimingInput::Convert(input_timing, nullptr, exception_state); EXPECT_FALSE(exception_state.HadException()); diff --git a/chromium/third_party/blink/renderer/core/animation/timing_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_test.cc index 84e0d7fc267..9ce6f35240d 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_test.cc @@ -10,18 +10,24 @@ namespace blink { class AnimationTimingTest : public testing::Test { public: - Timing::CalculatedTiming CalculateTimings(base::Optional<double> local_time, - double playback_rate) { + Timing::CalculatedTiming CalculateTimings( + absl::optional<AnimationTimeDelta> local_time, + double playback_rate) { const bool is_keyframe_effect = false; Timing::AnimationDirection animation_direction = playback_rate < 0 ? Timing::AnimationDirection::kBackwards : Timing::AnimationDirection::kForwards; return timing_.CalculateTimings( - local_time, /*timeline_phase*/ base::nullopt, animation_direction, + local_time, /*timeline_phase*/ absl::nullopt, animation_direction, is_keyframe_effect, playback_rate); } - bool IsCurrent(base::Optional<double> local_time, double playback_rate) { - return CalculateTimings(local_time, playback_rate).is_current; + bool IsCurrent(absl::optional<double> local_time, double playback_rate) { + absl::optional<AnimationTimeDelta> local_time_delta; + if (local_time) { + local_time_delta = absl::make_optional( + AnimationTimeDelta::FromSecondsD(local_time.value())); + } + return CalculateTimings(local_time_delta, playback_rate).is_current; } private: @@ -85,11 +91,11 @@ TEST_F(AnimationTimingTest, IsCurrent) { EXPECT_TRUE(IsCurrent(2, -1)) << "Expected 'current' with a negative playback rate in the after phase"; - EXPECT_FALSE(IsCurrent(base::nullopt, 1)) + EXPECT_FALSE(IsCurrent(absl::nullopt, 1)) << "Expected 'not current' when time is unresolved"; - EXPECT_FALSE(IsCurrent(base::nullopt, 0)) + EXPECT_FALSE(IsCurrent(absl::nullopt, 0)) << "Expected 'not current' when time is unresolved"; - EXPECT_FALSE(IsCurrent(base::nullopt, -1)) + EXPECT_FALSE(IsCurrent(absl::nullopt, -1)) << "Expected 'not current' when time is unresolved"; } diff --git a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc index caf0b907a1d..a7e3ce4732d 100644 --- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc +++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc @@ -8,7 +8,6 @@ #include "third_party/blink/renderer/core/animation/interpolation_environment.h" #include "third_party/blink/renderer/core/animation/interpolation_type.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h index 49f9fa8a535..20881621221 100644 --- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h +++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h @@ -107,4 +107,4 @@ struct DowncastTraits<TransitionInterpolation> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TRANSITION_INTERPOLATION_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h index a5b39a1c6a0..066831e1502 100644 --- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h +++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h @@ -128,4 +128,4 @@ struct DowncastTraits<TransitionPropertySpecificKeyframe> { } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TRANSITION_KEYFRAME_H_ diff --git a/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h b/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h index badae96ef7c..69de9c5d786 100644 --- a/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h +++ b/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h @@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_UNDERLYING_LENGTH_CHECKER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_UNDERLYING_LENGTH_CHECKER_H_ -#include <memory> - #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/animation/interpolable_value.h" #include "third_party/blink/renderer/core/animation/interpolation_type.h" |