From 65b2df47e0b1001a4f113f2ec323509bd27b77ca Mon Sep 17 00:00:00 2001 From: Jordan Taylor Date: Wed, 11 Nov 2020 23:35:27 +0000 Subject: [PATCH] Initial implementation of progress based ScrollTimelines This work is the first step in implementing upcoming spec change in: https://github.com/w3c/csswg-drafts/issues/4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor Reviewed-by: Robert Flack Cr-Commit-Position: refs/heads/master@{#826533} --- .../renderer/core/animation/animation.cc | 20 +- .../renderer/core/animation/animation_test.cc | 2 +- .../core/animation/animation_timeline.cc | 12 +- .../core/animation/animation_timeline.h | 6 +- .../core/animation/animation_timeline.idl | 3 +- .../core/animation/computed_effect_timing.idl | 10 +- .../core/animation/css/css_animations.cc | 3 +- .../core/animation/document_timeline.cc | 2 +- .../core/animation/document_timeline_test.cc | 66 +-- .../core/animation/scroll_timeline.cc | 72 ++- .../renderer/core/animation/scroll_timeline.h | 9 +- .../core/animation/scroll_timeline_test.cc | 45 +- .../blink/renderer/core/animation/timing.cc | 17 +- .../inspector/inspector_animation_agent.cc | 13 +- .../animationworklet/worklet_animation.cc | 8 +- .../constructor-expected.txt | 71 --- .../progress-based-current-time.tenative.html | 501 ++++++++++++++++++ .../wpt/scroll-animations/testcommon.js | 8 + .../scrolltimeline-creation.html | 29 - .../global-interface-listing-expected.txt | 1 + 20 files changed, 702 insertions(+), 196 deletions(-) delete mode 100644 third_party/blink/web_tests/external/wpt/scroll-animations/constructor-expected.txt create mode 100644 third_party/blink/web_tests/external/wpt/scroll-animations/progress-based-current-time.tenative.html delete mode 100644 third_party/blink/web_tests/fast/animation/scroll-animations/scrolltimeline-creation.html diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index 9d2b3991803486..3cd250acb320b8 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc @@ -36,6 +36,7 @@ #include "base/metrics/histogram_macros.h" #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/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" @@ -193,6 +194,23 @@ Animation* Animation::Create(AnimationEffect* effect, } DCHECK(IsA(timeline) || timeline->IsScrollTimeline()); + // TODO(crbug.com/1097041): Support 'auto' value. + if (timeline->IsScrollTimeline()) { + DoubleOrScrollTimelineAutoKeyword time_range; + To(timeline)->timeRange(time_range); + // 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()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "progress based animations are not supported"); + return nullptr; + } + } + auto* context = timeline->GetDocument()->GetExecutionContext(); return MakeGarbageCollected(context, timeline, effect); } @@ -290,7 +308,7 @@ Document* Animation::GetDocument() const { } base::Optional Animation::TimelineTime() const { - return timeline_ ? timeline_->currentTime() : base::nullopt; + return timeline_ ? timeline_->CurrentTimeMilliseconds() : base::nullopt; } // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation. diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc index 4f77224cdaa05d..151f3417187c4a 100644 --- a/third_party/blink/renderer/core/animation/animation_test.cc +++ b/third_party/blink/renderer/core/animation/animation_test.cc @@ -258,7 +258,7 @@ TEST_F(AnimationAnimationTestNoCompositing, InitialState) { StartTimeline(); EXPECT_EQ("finished", animation->playState()); - EXPECT_EQ(0, timeline->currentTime()); + EXPECT_EQ(0, timeline->CurrentTimeMilliseconds()); EXPECT_EQ(0, animation->currentTime()); EXPECT_FALSE(animation->Paused()); EXPECT_FALSE(animation->pending()); diff --git a/third_party/blink/renderer/core/animation/animation_timeline.cc b/third_party/blink/renderer/core/animation/animation_timeline.cc index 40554363c928aa..3a3859f3f1caaf 100644 --- a/third_party/blink/renderer/core/animation/animation_timeline.cc +++ b/third_party/blink/renderer/core/animation/animation_timeline.cc @@ -40,7 +40,13 @@ bool CompareAnimations(const Member& left, Animation::CompareAnimationsOrdering::kPointerOrder); } -base::Optional AnimationTimeline::currentTime() { +void AnimationTimeline::currentTime(CSSNumberish& currentTime) { + base::Optional result = CurrentPhaseAndTime().time; + currentTime = result ? CSSNumberish::FromDouble(result->InMillisecondsF()) + : CSSNumberish(); +} + +base::Optional AnimationTimeline::CurrentTimeMilliseconds() { base::Optional result = CurrentPhaseAndTime().time; return result ? base::make_optional(result->InMillisecondsF()) : base::nullopt; @@ -51,6 +57,10 @@ base::Optional AnimationTimeline::CurrentTimeSeconds() { return result ? base::make_optional(result->InSecondsF()) : base::nullopt; } +void AnimationTimeline::duration(CSSNumberish& duration) { + duration = CSSNumberish(); +} + String AnimationTimeline::phase() { switch (CurrentPhaseAndTime().phase) { case TimelinePhase::kInactive: diff --git a/third_party/blink/renderer/core/animation/animation_timeline.h b/third_party/blink/renderer/core/animation/animation_timeline.h index dbbe8d5eb4bd95..6c16a91fd4e092 100644 --- a/third_party/blink/renderer/core/animation/animation_timeline.h +++ b/third_party/blink/renderer/core/animation/animation_timeline.h @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -34,9 +35,12 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { AnimationTimeline(Document*); ~AnimationTimeline() override = default; - base::Optional currentTime(); + virtual void currentTime(CSSNumberish&); + base::Optional CurrentTimeMilliseconds(); base::Optional CurrentTimeSeconds(); + virtual void duration(CSSNumberish&); + String phase(); TimelinePhase Phase() { return CurrentPhaseAndTime().phase; } diff --git a/third_party/blink/renderer/core/animation/animation_timeline.idl b/third_party/blink/renderer/core/animation/animation_timeline.idl index 0c36488ff89822..336d122d360c30 100644 --- a/third_party/blink/renderer/core/animation/animation_timeline.idl +++ b/third_party/blink/renderer/core/animation/animation_timeline.idl @@ -9,6 +9,7 @@ enum TimelinePhase { "inactive", "before", "active", "after" }; RuntimeEnabled=WebAnimationsAPI, Exposed=Window ] interface AnimationTimeline { - readonly attribute double? currentTime; + readonly attribute CSSNumberish? currentTime; + [RuntimeEnabled=ScrollTimeline] readonly attribute CSSNumberish? duration; [RuntimeEnabled=ScrollTimeline] readonly attribute TimelinePhase phase; }; diff --git a/third_party/blink/renderer/core/animation/computed_effect_timing.idl b/third_party/blink/renderer/core/animation/computed_effect_timing.idl index a77ac17f01bac1..603a8accda2dba 100644 --- a/third_party/blink/renderer/core/animation/computed_effect_timing.idl +++ b/third_party/blink/renderer/core/animation/computed_effect_timing.idl @@ -5,9 +5,9 @@ // https://drafts.csswg.org/web-animations/#the-computedeffecttiming-dictionary dictionary ComputedEffectTiming : EffectTiming { - unrestricted double endTime; - unrestricted double activeDuration; - double? localTime; - double? progress; - unrestricted double? currentIteration; + CSSNumberish endTime; + CSSNumberish activeDuration; + CSSNumberish? localTime; + double? progress; + unrestricted double? currentIteration; }; diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index 80c55f69ba8da3..601832605c766f 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc @@ -1039,7 +1039,8 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { // Set the current time as the start time for retargeted transitions if (retargeted_compositor_transitions.Contains(property)) { - animation->setStartTime(element->GetDocument().Timeline().currentTime()); + animation->setStartTime( + element->GetDocument().Timeline().CurrentTimeMilliseconds()); } animation->Update(kTimingUpdateOnDemand); running_transition->animation = animation; diff --git a/third_party/blink/renderer/core/animation/document_timeline.cc b/third_party/blink/renderer/core/animation/document_timeline.cc index ce2592b9b9d983..c05b1f14b81574 100644 --- a/third_party/blink/renderer/core/animation/document_timeline.cc +++ b/third_party/blink/renderer/core/animation/document_timeline.cc @@ -99,7 +99,7 @@ bool DocumentTimeline::IsActive() const { // timeline current time. base::Optional DocumentTimeline::InitialStartTimeForAnimations() { - base::Optional current_time_ms = currentTime(); + base::Optional current_time_ms = CurrentTimeMilliseconds(); if (current_time_ms.has_value()) { return base::TimeDelta::FromMillisecondsD(current_time_ms.value()); } diff --git a/third_party/blink/renderer/core/animation/document_timeline_test.cc b/third_party/blink/renderer/core/animation/document_timeline_test.cc index e29cbf4ef7230a..f165b142f00ac2 100644 --- a/third_party/blink/renderer/core/animation/document_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/document_timeline_test.cc @@ -104,7 +104,7 @@ class AnimationDocumentTimelineTest : public PageTestBase { timeline->SetTimingForTesting(platform_timing); timeline->ResetForTesting(); - ASSERT_EQ(0, timeline->currentTime()); + ASSERT_EQ(0, timeline->CurrentTimeMilliseconds()); } void TearDown() override { @@ -163,11 +163,11 @@ TEST_F(AnimationDocumentTimelineTest, EmptyKeyframeAnimation) { timeline->Play(keyframe_effect); UpdateClockAndService(0); - EXPECT_FLOAT_EQ(0, timeline->currentTime().value()); + EXPECT_FLOAT_EQ(0, timeline->CurrentTimeMilliseconds().value()); EXPECT_FALSE(keyframe_effect->IsInEffect()); UpdateClockAndService(1000); - EXPECT_FLOAT_EQ(1000, timeline->currentTime().value()); + EXPECT_FLOAT_EQ(1000, timeline->CurrentTimeMilliseconds().value()); } TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation) { @@ -180,32 +180,32 @@ TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation) { timeline->Play(keyframe_effect); UpdateClockAndService(0); - EXPECT_EQ(0, timeline->currentTime()); + EXPECT_EQ(0, timeline->CurrentTimeMilliseconds()); EXPECT_TRUE(keyframe_effect->IsInEffect()); UpdateClockAndService(1000); - EXPECT_FLOAT_EQ(1000, timeline->currentTime().value()); + EXPECT_FLOAT_EQ(1000, timeline->CurrentTimeMilliseconds().value()); } TEST_F(AnimationDocumentTimelineTest, ZeroTime) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); - EXPECT_EQ(2000, timeline->currentTime()); + EXPECT_EQ(2000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, CurrentTimeSeconds) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); EXPECT_EQ(2, timeline->CurrentTimeSeconds()); - EXPECT_EQ(2000, timeline->currentTime()); + EXPECT_EQ(2000, timeline->CurrentTimeMilliseconds()); auto* document_without_frame = Document::CreateForTest(); auto* inactive_timeline = MakeGarbageCollected( document_without_frame, base::TimeDelta(), platform_timing); EXPECT_FALSE(inactive_timeline->CurrentTimeSeconds()); - EXPECT_FALSE(inactive_timeline->currentTime()); + EXPECT_FALSE(inactive_timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormal) { @@ -215,11 +215,11 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormal) { EXPECT_EQ(1.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(zero_time, timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); EXPECT_EQ(zero_time, timeline->ZeroTime()); - EXPECT_EQ(2000, timeline->currentTime()); + EXPECT_EQ(2000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormalWithOriginTime) { @@ -230,33 +230,33 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormalWithOriginTime) { EXPECT_EQ(1.0, timeline->PlaybackRate()); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(1100, timeline->currentTime()); + EXPECT_EQ(1100, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(200)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(1200, timeline->currentTime()); + EXPECT_EQ(1200, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRatePause) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(0.0); EXPECT_EQ(0.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000)); EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); - EXPECT_EQ(3000, timeline->currentTime()); + EXPECT_EQ(3000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRatePauseWithOriginTime) { @@ -266,61 +266,61 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRatePauseWithOriginTime) { timeline->ResetForTesting(); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100)); EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime()); - EXPECT_EQ(1100, timeline->currentTime()); + EXPECT_EQ(1100, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(0.0); EXPECT_EQ(0.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(200)); EXPECT_EQ(TimeTicksFromMillisecondsD(1100), timeline->ZeroTime()); - EXPECT_EQ(1100, timeline->currentTime()); + EXPECT_EQ(1100, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); EXPECT_EQ(TimeTicksFromMillisecondsD(-900), timeline->ZeroTime()); - EXPECT_EQ(1100, timeline->currentTime()); + EXPECT_EQ(1100, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(400)); EXPECT_EQ(TimeTicksFromMillisecondsD(-900), timeline->ZeroTime()); - EXPECT_EQ(1300, timeline->currentTime()); + EXPECT_EQ(1300, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateSlow) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(0.5); EXPECT_EQ(0.5, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(3000)); EXPECT_EQ(TimeTicksFromMillisecondsD(-1000), timeline->ZeroTime()); - EXPECT_EQ(2000, timeline->currentTime()); + EXPECT_EQ(2000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); EXPECT_EQ(TimeTicksFromMillisecondsD(1000), timeline->ZeroTime()); - EXPECT_EQ(3000, timeline->currentTime()); + EXPECT_EQ(3000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateFast) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(1000)); EXPECT_EQ(base::TimeTicks(), timeline->ZeroTime()); - EXPECT_EQ(1000, timeline->currentTime()); + EXPECT_EQ(1000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(2.0); EXPECT_EQ(2.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(3000)); EXPECT_EQ(TimeTicksFromMillisecondsD(500), timeline->ZeroTime()); - EXPECT_EQ(5000, timeline->currentTime()); + EXPECT_EQ(5000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(4000)); EXPECT_EQ(TimeTicksFromMillisecondsD(-2000), timeline->ZeroTime()); - EXPECT_EQ(6000, timeline->currentTime()); + EXPECT_EQ(6000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PlaybackRateFastWithOriginTime) { @@ -330,25 +330,25 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRateFastWithOriginTime) { GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(100000)); EXPECT_EQ(TimeTicksFromMillisecondsD(-1000000), timeline->ZeroTime()); - EXPECT_EQ(1100000, timeline->currentTime()); + EXPECT_EQ(1100000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(2.0); EXPECT_EQ(2.0, timeline->PlaybackRate()); EXPECT_EQ(TimeTicksFromMillisecondsD(-450000), timeline->ZeroTime()); - EXPECT_EQ(1100000, timeline->currentTime()); + EXPECT_EQ(1100000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(300000)); EXPECT_EQ(TimeTicksFromMillisecondsD(-450000), timeline->ZeroTime()); - EXPECT_EQ(1500000, timeline->currentTime()); + EXPECT_EQ(1500000, timeline->CurrentTimeMilliseconds()); timeline->SetPlaybackRate(1.0); EXPECT_EQ(1.0, timeline->PlaybackRate()); EXPECT_EQ(TimeTicksFromMillisecondsD(-1200000), timeline->ZeroTime()); - EXPECT_EQ(1500000, timeline->currentTime()); + EXPECT_EQ(1500000, timeline->CurrentTimeMilliseconds()); GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(400000)); EXPECT_EQ(TimeTicksFromMillisecondsD(-1200000), timeline->ZeroTime()); - EXPECT_EQ(1600000, timeline->currentTime()); + EXPECT_EQ(1600000, timeline->CurrentTimeMilliseconds()); } TEST_F(AnimationDocumentTimelineTest, PauseForTesting) { diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index c5fd4f0c4701ab..b260ad3797019f 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc @@ -11,6 +11,7 @@ #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" +#include "third_party/blink/renderer/core/css/cssom/css_unit_values.h" #include "third_party/blink/renderer/core/css/parser/css_parser_context.h" #include "third_party/blink/renderer/core/css/parser/css_tokenizer.h" #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" @@ -26,6 +27,13 @@ namespace blink { namespace { + +constexpr double kScrollTimelineDuration = 100.0; +// Animation times are tracked as TimeDeltas which are stored internally as an +// integer number of microseconds. Multiplying by 1000 converts this into a +// value equivalent to Milliseconds. +constexpr double kScrollTimelineDurationMs = kScrollTimelineDuration * 1000.0; + using ScrollTimelineSet = HeapHashMap, Member>>>; @@ -161,17 +169,13 @@ ScrollTimeline* ScrollTimeline::Create(Document& document, } } - // TODO(crbug.com/1097041): Support 'auto' value. - if (options->timeRange().IsScrollTimelineAutoKeyword()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "'auto' value for timeRange not yet supported"); - return nullptr; + base::Optional time_range; + if (options->timeRange().IsDouble()) { + time_range = base::make_optional(options->timeRange().GetAsDouble()); } return MakeGarbageCollected( - &document, scroll_source, orientation, scroll_offsets, - options->timeRange().GetAsDouble()); + &document, scroll_source, orientation, scroll_offsets, time_range); } ScrollTimeline::ScrollTimeline( @@ -179,7 +183,7 @@ ScrollTimeline::ScrollTimeline( Element* scroll_source, ScrollDirection orientation, HeapVector>* scroll_offsets, - double time_range) + base::Optional time_range) : AnimationTimeline(document), scroll_source_(scroll_source), resolved_scroll_source_(ResolveScrollSource(scroll_source_)), @@ -293,6 +297,38 @@ bool ScrollTimeline::ScrollOffsetsEqual( return true; } +void ScrollTimeline::currentTime(CSSNumberish& 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 + currentTime = + current_time ? CSSNumberish::FromDouble(current_time->InMillisecondsF()) + : CSSNumberish(); + } else { + currentTime = current_time + ? CSSNumberish::FromCSSNumericValue( + CSSUnitValues::percent(current_time->InSecondsF())) + : CSSNumberish(); + } +} + +void ScrollTimeline::duration(CSSNumberish& duration) { + if (time_range_) { + duration = CSSNumberish::FromDouble(time_range_.value()); + } else { + duration = CSSNumberish::FromCSSNumericValue( + CSSUnitValues::percent(kScrollTimelineDuration)); + } +} + ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { // 1. If scroll timeline is inactive, return an unresolved time value. // https://github.com/WICG/scroll-animations/issues/31 @@ -331,6 +367,9 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { return {TimelinePhase::kBefore, base::TimeDelta(), resolved_offsets}; } + double duration = + time_range_ ? time_range_.value() : kScrollTimelineDurationMs; + // 4. If current scroll offset is greater than or equal to endScrollOffset: if (current_offset >= end_offset) { // If end_offset is greater than or equal to the maximum scroll offset of @@ -338,7 +377,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { // after phase. TimelinePhase phase = end_offset >= max_offset ? TimelinePhase::kActive : TimelinePhase::kAfter; - return {phase, base::TimeDelta::FromMillisecondsD(time_range_), + return {phase, base::TimeDelta::FromMillisecondsD(duration), resolved_offsets}; } @@ -348,7 +387,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { base::Optional calculated_current_time = base::TimeDelta::FromMillisecondsD(scroll_timeline_util::ComputeProgress( current_offset, resolved_offsets) * - time_range_); + duration); return {TimelinePhase::kActive, calculated_current_time, resolved_offsets}; } @@ -451,7 +490,16 @@ const HeapVector ScrollTimeline::scrollOffsets() } void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) { - result.SetDouble(time_range_); + // 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_) { + result.SetDouble(time_range_.value()); + } else { + result.SetScrollTimelineAutoKeyword("auto"); + } } void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box, diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.h b/third_party/blink/renderer/core/animation/scroll_timeline.h index fc15021c205a74..019885d471d86d 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/third_party/blink/renderer/core/animation/scroll_timeline.h @@ -45,9 +45,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { Element*, ScrollDirection, HeapVector>*, - double); + base::Optional); - // AnimationTimeline implementation. 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. @@ -69,6 +68,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { void endScrollOffset(ScrollTimelineOffsetValue& result) const; const HeapVector scrollOffsets() const; + void currentTime(CSSNumberish&) override; + void duration(CSSNumberish&) override; void timeRange(DoubleOrScrollTimelineAutoKeyword&); // Returns the Node that should actually have the ScrollableArea (if one @@ -119,7 +120,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { protected: PhaseAndTime CurrentPhaseAndTime() override; - double GetTimeRange() const { return time_range_; } + double GetTimeRange() const { return time_range_ ? time_range_.value() : 0; } bool ScrollOffsetsEqual( const HeapVector>& other) const; size_t AttachedAnimationsCount() const { return scroll_animations_.size(); } @@ -167,7 +168,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ScrollDirection orientation_; Member>> scroll_offsets_; - double time_range_; + base::Optional time_range_; // Snapshotted value produced by the last SnapshotState call. TimelineState timeline_state_snapshotted_; diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc index de09a1f5e8b8bf..5321591f55a2a8 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc @@ -123,7 +123,7 @@ TEST_F(ScrollTimelineTest, CurrentTimeIsNullIfScrollSourceIsNotScrollable) { ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - EXPECT_FALSE(scroll_timeline->currentTime().has_value()); + EXPECT_FALSE(scroll_timeline->CurrentTimeMilliseconds().has_value()); EXPECT_FALSE(scroll_timeline->IsActive()); } @@ -161,35 +161,37 @@ TEST_F(ScrollTimelineTest, // Simulate a new animation frame which allows the timeline to compute new // current time. SimulateFrame(); - EXPECT_EQ(scroll_timeline->currentTime(), 0); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 0); EXPECT_EQ("before", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 10), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(scroll_timeline->currentTime(), 0); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 0); EXPECT_EQ("active", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(scroll_timeline->currentTime(), 50); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 50); EXPECT_EQ("active", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 90), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(scroll_timeline->currentTime(), time_range.GetAsDouble()); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), + time_range.GetAsDouble()); EXPECT_EQ("after", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(scroll_timeline->currentTime(), time_range.GetAsDouble()); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), + time_range.GetAsDouble()); EXPECT_EQ("after", scroll_timeline->phase()); EXPECT_TRUE(scroll_timeline->IsActive()); } @@ -228,21 +230,22 @@ TEST_F(ScrollTimelineTest, // Simulate a new animation frame which allows the timeline to compute new // current time. SimulateFrame(); - EXPECT_EQ(0, scroll_timeline->currentTime()); + EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("before", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 60), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(0, scroll_timeline->currentTime()); + EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("before", scroll_timeline->phase()); current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(time_range.GetAsDouble(), scroll_timeline->currentTime()); + EXPECT_EQ(time_range.GetAsDouble(), + scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("after", scroll_timeline->phase()); EXPECT_TRUE(scroll_timeline->IsActive()); } @@ -604,20 +607,20 @@ TEST_F(ScrollTimelineTest, CurrentTimeUpdateAfterNewAnimationFrame) { ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - double time_before = scroll_timeline->currentTime().value(); + double time_before = scroll_timeline->CurrentTimeMilliseconds().value(); scrollable_area->SetScrollOffset(ScrollOffset(0, 10), mojom::blink::ScrollType::kProgrammatic); // Verify that the current time didn't change before there is a new animation // frame. - EXPECT_EQ(time_before, scroll_timeline->currentTime().value()); + EXPECT_EQ(time_before, scroll_timeline->CurrentTimeMilliseconds().value()); // Simulate a new animation frame which allows the timeline to compute a new // current time. SimulateFrame(); // Verify that current time did change in the new animation frame. - EXPECT_NE(time_before, scroll_timeline->currentTime().value()); + EXPECT_NE(time_before, scroll_timeline->CurrentTimeMilliseconds().value()); } TEST_F(ScrollTimelineTest, FinishedAnimationPlaysOnReversedScrolling) { @@ -816,14 +819,14 @@ TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - EXPECT_EQ(scroll_timeline->currentTime(), 0); + EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 0); scrollable_area->SetScrollOffset(ScrollOffset(0, 10), mojom::blink::ScrollType::kProgrammatic); // Simulate a new animation frame which allows the timeline to compute new // current phase and time. SimulateFrame(); - EXPECT_EQ(0, scroll_timeline->currentTime().value()); + EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 12), mojom::blink::ScrollType::kProgrammatic); @@ -833,7 +836,7 @@ TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { double w = 1.0 / 3.0; // offset weight double p = (12.0 - 10.0) / (20.0 - 10.0); // progress within the offset EXPECT_TIME_NEAR((offset + p) * w * time_range, - scroll_timeline->currentTime().value()); + scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic); @@ -841,14 +844,14 @@ TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { offset = 1; p = 0; EXPECT_TIME_NEAR((offset + p) * w * time_range, - scroll_timeline->currentTime().value()); + scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 30), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); p = (30.0 - 20.0) / (40.0 - 20.0); EXPECT_TIME_NEAR((offset + p) * w * time_range, - scroll_timeline->currentTime().value()); + scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 40), mojom::blink::ScrollType::kProgrammatic); @@ -856,24 +859,24 @@ TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { offset = 2; p = 0; EXPECT_TIME_NEAR((offset + p) * w * time_range, - scroll_timeline->currentTime().value()); + scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 80), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); p = (80.0 - 40.0) / (90.0 - 40.0); EXPECT_TIME_NEAR((offset + p) * w * time_range, - scroll_timeline->currentTime().value()); + scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 90), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(100, scroll_timeline->currentTime().value()); + EXPECT_EQ(100, scroll_timeline->CurrentTimeMilliseconds().value()); scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(100, scroll_timeline->currentTime().value()); + EXPECT_EQ(100, scroll_timeline->CurrentTimeMilliseconds().value()); } } // namespace blink diff --git a/third_party/blink/renderer/core/animation/timing.cc b/third_party/blink/renderer/core/animation/timing.cc index f8609307a54da9..5a6d39467f4067 100644 --- a/third_party/blink/renderer/core/animation/timing.cc +++ b/third_party/blink/renderer/core/animation/timing.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h" #include "third_party/blink/renderer/core/animation/timing_calculations.h" +#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" namespace blink { @@ -111,13 +112,17 @@ ComputedEffectTiming* Timing::getComputedTiming( ComputedEffectTiming* computed_timing = ComputedEffectTiming::Create(); // ComputedEffectTiming members. - computed_timing->setEndTime(EndTimeInternal() * 1000); - computed_timing->setActiveDuration(ActiveDuration() * 1000); - - if (calculated_timing.local_time) - computed_timing->setLocalTime(calculated_timing.local_time.value() * 1000); - else + computed_timing->setEndTime( + CSSNumberish::FromDouble(EndTimeInternal() * 1000)); + computed_timing->setActiveDuration( + CSSNumberish::FromDouble(ActiveDuration() * 1000)); + + if (calculated_timing.local_time) { + computed_timing->setLocalTime( + CSSNumberish::FromDouble(calculated_timing.local_time.value() * 1000)); + } else { computed_timing->setLocalTimeToNull(); + } if (calculated_timing.is_in_effect) { DCHECK(calculated_timing.current_iteration); diff --git a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc index 917896ec77543c..e54b1ce1d13588 100644 --- a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc @@ -228,7 +228,8 @@ Response InspectorAnimationAgent::getCurrentTime(const String& id, *current_time = animation->currentTime().value_or(Timing::NullValue()); } else { // Use startTime where possible since currentTime is limited. - base::Optional timeline_time = animation->timeline()->currentTime(); + base::Optional timeline_time = + animation->timeline()->CurrentTimeMilliseconds(); // TODO(crbug.com/916117): Handle NaN values for scroll linked animations. *current_time = timeline_time ? timeline_time.value() - @@ -255,7 +256,8 @@ Response InspectorAnimationAgent::setPaused( if (!clone->timeline()->IsActive()) { current_time = clone->currentTime().value_or(Timing::NullValue()); } else { - base::Optional timeline_time = clone->timeline()->currentTime(); + base::Optional timeline_time = + clone->timeline()->CurrentTimeMilliseconds(); // TODO(crbug.com/916117): Handle NaN values. current_time = timeline_time ? timeline_time.value() - @@ -514,9 +516,10 @@ double InspectorAnimationAgent::NormalizedStartTime( auto* document_timeline = DynamicTo(animation.timeline()); if (document_timeline) { if (ReferenceTimeline().PlaybackRate() == 0) { - time_ms += - ReferenceTimeline().currentTime().value_or(Timing::NullValue()) - - document_timeline->currentTime().value_or(Timing::NullValue()); + time_ms += ReferenceTimeline().CurrentTimeMilliseconds().value_or( + Timing::NullValue()) - + document_timeline->CurrentTimeMilliseconds().value_or( + Timing::NullValue()); } else { time_ms += (document_timeline->ZeroTime() - ReferenceTimeline().ZeroTime()) diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index 67436af8cbb743..5f4b5c2378d27f 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc @@ -166,7 +166,8 @@ base::Optional CalculateStartTime( base::TimeDelta current_time, double playback_rate, AnimationTimeline& timeline) { - base::Optional timeline_current_time_ms = timeline.currentTime(); + base::Optional timeline_current_time_ms = + timeline.CurrentTimeMilliseconds(); return base::TimeDelta::FromMillisecondsD(timeline_current_time_ms.value()) - (current_time / playback_rate); } @@ -729,7 +730,7 @@ base::Optional WorkletAnimation::InitialCurrentTime() const { base::Optional starting_time = timeline_->InitialStartTimeForAnimations(); - base::Optional current_time = timeline_->currentTime(); + base::Optional current_time = timeline_->CurrentTimeMilliseconds(); if (!starting_time || !current_time) { return base::nullopt; @@ -791,7 +792,8 @@ base::Optional WorkletAnimation::CurrentTimeInternal() const { // OR // - Current scroll offset is greater than or equal to endScrollOffset and // fill mode is none or backwards. - base::Optional timeline_time_ms = timeline_->currentTime(); + base::Optional timeline_time_ms = + timeline_->CurrentTimeMilliseconds(); if (!timeline_time_ms) return base::nullopt; diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/constructor-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/constructor-expected.txt deleted file mode 100644 index 1a54fc9a648b14..00000000000000 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/constructor-expected.txt +++ /dev/null @@ -1,71 +0,0 @@ -This is a testharness.js-based test. -Found 67 tests; 65 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS A ScrollTimeline can be created with a scrollSource -PASS A ScrollTimeline can be created with a non-scrolling scrollSource -PASS A ScrollTimeline created with a null scrollSource should have no scrollSource -PASS A ScrollTimeline created without a scrollSource should use the document.scrollingElement -PASS A ScrollTimeline created with the default orientation should default to 'block' -PASS 'block' is a valid orientation value -PASS 'inline' is a valid orientation value -PASS 'horizontal' is a valid orientation value -PASS 'vertical' is a valid orientation value -PASS Creating a ScrollTimeline with an invalid orientation value should throw -PASS A ScrollTimeline created with the default startScrollOffset should default to CSSKeywordValue(auto) -PASS A ScrollTimeline created with the default endScrollOffset should default to CSSKeywordValue(auto) -PASS CSSKeywordValue(auto) is a valid scroll offset value -PASS CSSUnitValue(0px) is a valid scroll offset value -PASS CSSMathSum(calc(100% + -80px)) is a valid scroll offset value -PASS 'auto' is a valid scroll offset value -PASS 'em' is a valid scroll offset unit -PASS 'ex' is a valid scroll offset unit -PASS 'ch' is a valid scroll offset unit -PASS 'rem' is a valid scroll offset unit -PASS 'vw' is a valid scroll offset unit -PASS 'vh' is a valid scroll offset unit -PASS 'vmin' is a valid scroll offset unit -PASS 'vmax' is a valid scroll offset unit -PASS 'cm' is a valid scroll offset unit -PASS 'mm' is a valid scroll offset unit -PASS 'q' is a valid scroll offset unit -PASS 'in' is a valid scroll offset unit -PASS 'pc' is a valid scroll offset unit -PASS 'pt' is a valid scroll offset unit -PASS 'px' is a valid scroll offset unit -PASS '%' is a valid scroll offset unit -PASS '' is an invalid scroll offset value -PASS 'calc(360deg / 4)' is an invalid scroll offset value -PASS 'left' is an invalid scroll offset value -PASS '#ff0000' is an invalid scroll offset value -PASS 'rgb(0, 128, 0)' is an invalid scroll offset value -PASS 'url("http://www.example.com/pinkish.gif")' is an invalid scroll offset value -PASS 'this_is_garbage' is an invalid scroll offset value -PASS CSSUnitValue(0) is an invalid scroll offset value -PASS '100px 5%' is an invalid scroll offset value -PASS '0' is an invalid scroll offset value -PASS '10px' is an invalid scroll offset value -PASS '10%' is an invalid scroll offset value -PASS 'calc(100% - 80px)' is an invalid scroll offset value -PASS 'deg' is an invalid scroll offset unit -PASS 's' is an invalid scroll offset unit -PASS 'Hz' is an invalid scroll offset unit -PASS 'dpi' is an invalid scroll offset unit -PASS '{"target":{}}' is a valid scroll offset value -PASS '{"target":{},"threshold":0}' is a valid scroll offset value -PASS '{"target":{},"threshold":0.5}' is a valid scroll offset value -PASS '{"target":{},"threshold":1}' is a valid scroll offset value -PASS '{}' is an invalid scroll offset value -PASS '{"target":{},"threshold":"test"}' is an invalid scroll offset value -PASS '{"target":{},"threshold":2}' is an invalid scroll offset value -PASS '{"target":{},"threshold":-0.2}' is an invalid scroll offset value -FAIL A ScrollTimeline created with the default timeRange should default to 'auto' Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported -FAIL 'auto' is a valid timeRange value Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported -PASS '0' is a valid timeRange value -PASS '-100' is a valid timeRange value -PASS '100' is a valid timeRange value -PASS '1234.5678' is a valid timeRange value -PASS 'invalid' is an invalid timeRange value -PASS 'Infinity' is an invalid timeRange value -PASS '-Infinity' is an invalid timeRange value -PASS 'NaN' is an invalid timeRange value -Harness: the test ran to completion. - diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/progress-based-current-time.tenative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/progress-based-current-time.tenative.html new file mode 100644 index 00000000000000..8a8ccfcff8b2ba --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/progress-based-current-time.tenative.html @@ -0,0 +1,501 @@ + + +ScrollTimeline current time algorithm + + + + + + + + + + diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/testcommon.js b/third_party/blink/web_tests/external/wpt/scroll-animations/testcommon.js index d9fc153887c5fc..9b3e82228fcdb3 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/testcommon.js +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/testcommon.js @@ -55,3 +55,11 @@ function assert_approx_equals_or_null(actual, expected, tolerance, name){ assert_approx_equals(actual, expected, tolerance, name); } } + +// actual should be a CSSUnitValue and expected should be a double value 0-100 +function assert_percent_css_unit_value_approx_equals(actual, expected, tolerance, name){ + assert_true(actual instanceof CSSUnitValue, "'actual' must be of type CSSUnitValue"); + assert_equals(typeof expected, "number", "'expected' should be a number (0-100)"); + assert_equals(actual.unit, "percent", "'actual' unit type must be 'percent'"); + assert_approx_equals(actual.value, expected, tolerance, name); +} \ No newline at end of file diff --git a/third_party/blink/web_tests/fast/animation/scroll-animations/scrolltimeline-creation.html b/third_party/blink/web_tests/fast/animation/scroll-animations/scrolltimeline-creation.html deleted file mode 100644 index 2cf54728d6250b..00000000000000 --- a/third_party/blink/web_tests/fast/animation/scroll-animations/scrolltimeline-creation.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -
-
-
- - - - diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 5e7e5c9ad39596..2ae44ba2221875 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt @@ -218,6 +218,7 @@ interface AnimationPlaybackEvent : Event interface AnimationTimeline attribute @@toStringTag getter currentTime + getter duration getter phase method constructor interface Attr : Node