mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-28 20:29:03 +00:00
LibWeb: Ensure all DocumentTimeline objects have the same time value
The DocumentTimeline constructor used the current millisecond time to initialize its currentTime, but that means that a newly created timeline would always have a different time value than other timelines that have been through the update_animations_and_send_events function.
This commit is contained in:
parent
4e9480b719
commit
37322baf54
Notes:
sideshowbarker
2024-07-17 05:02:35 +09:00
Author: https://github.com/mattco98
Commit: 37322baf54
Pull-request: https://github.com/SerenityOS/serenity/pull/24530
5 changed files with 32 additions and 3 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
new timeline time equals document timeline time: true
|
||||||
|
new timeline originTime defaults to 0: true
|
||||||
|
new timeline originTime offsets from document timeline: true
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
function timesAreClose(a, b) {
|
||||||
|
return Math.abs(a - b) <= 1;
|
||||||
|
}
|
||||||
|
let timeline = new DocumentTimeline();
|
||||||
|
println(`new timeline time equals document timeline time: ${timesAreClose(timeline.currentTime, document.timeline.currentTime)}`);
|
||||||
|
|
||||||
|
timeline = new DocumentTimeline({ originTime: 0 });
|
||||||
|
println(`new timeline originTime defaults to 0: ${timesAreClose(timeline.currentTime, document.timeline.currentTime)}`);
|
||||||
|
|
||||||
|
timeline = new DocumentTimeline({ originTime: 1000 });
|
||||||
|
let passed = timesAreClose(timeline.currentTime + 1000, document.timeline.currentTime);
|
||||||
|
println(`new timeline originTime offsets from document timeline: ${passed}`)
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -20,9 +20,14 @@ JS_DEFINE_ALLOCATOR(DocumentTimeline);
|
||||||
JS::NonnullGCPtr<DocumentTimeline> DocumentTimeline::create(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time)
|
JS::NonnullGCPtr<DocumentTimeline> DocumentTimeline::create(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time)
|
||||||
{
|
{
|
||||||
auto timeline = realm.heap().allocate<DocumentTimeline>(realm, realm, document, origin_time);
|
auto timeline = realm.heap().allocate<DocumentTimeline>(realm, realm, document, origin_time);
|
||||||
|
auto current_time = document.last_animation_frame_timestamp();
|
||||||
|
if (!current_time.has_value()) {
|
||||||
|
// The document hasn't processed an animation frame yet, so just use the exact current time
|
||||||
auto* window_or_worker = dynamic_cast<HTML::WindowOrWorkerGlobalScopeMixin*>(&realm.global_object());
|
auto* window_or_worker = dynamic_cast<HTML::WindowOrWorkerGlobalScopeMixin*>(&realm.global_object());
|
||||||
VERIFY(window_or_worker);
|
VERIFY(window_or_worker);
|
||||||
timeline->set_current_time(window_or_worker->performance()->now());
|
current_time = window_or_worker->performance()->now();
|
||||||
|
}
|
||||||
|
timeline->set_current_time(current_time);
|
||||||
return timeline;
|
return timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4233,6 +4233,7 @@ void Document::update_animations_and_send_events(Optional<double> const& timesta
|
||||||
// - Running the update an animation’s finished state procedure for any animations whose current time has been
|
// - Running the update an animation’s finished state procedure for any animations whose current time has been
|
||||||
// updated.
|
// updated.
|
||||||
// - Queueing animation events for any such animations.
|
// - Queueing animation events for any such animations.
|
||||||
|
m_last_animation_frame_timestamp = timestamp;
|
||||||
for (auto const& timeline : m_associated_animation_timelines)
|
for (auto const& timeline : m_associated_animation_timelines)
|
||||||
timeline->set_current_time(timestamp);
|
timeline->set_current_time(timestamp);
|
||||||
|
|
||||||
|
|
|
@ -596,6 +596,7 @@ public:
|
||||||
void restore_the_history_object_state(JS::NonnullGCPtr<HTML::SessionHistoryEntry> entry);
|
void restore_the_history_object_state(JS::NonnullGCPtr<HTML::SessionHistoryEntry> entry);
|
||||||
|
|
||||||
JS::NonnullGCPtr<Animations::DocumentTimeline> timeline();
|
JS::NonnullGCPtr<Animations::DocumentTimeline> timeline();
|
||||||
|
auto const& last_animation_frame_timestamp() const { return m_last_animation_frame_timestamp; }
|
||||||
|
|
||||||
void associate_with_timeline(JS::NonnullGCPtr<Animations::AnimationTimeline>);
|
void associate_with_timeline(JS::NonnullGCPtr<Animations::AnimationTimeline>);
|
||||||
void disassociate_with_timeline(JS::NonnullGCPtr<Animations::AnimationTimeline>);
|
void disassociate_with_timeline(JS::NonnullGCPtr<Animations::AnimationTimeline>);
|
||||||
|
@ -889,6 +890,7 @@ private:
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#document-default-document-timeline
|
// https://www.w3.org/TR/web-animations-1/#document-default-document-timeline
|
||||||
JS::GCPtr<Animations::DocumentTimeline> m_default_timeline;
|
JS::GCPtr<Animations::DocumentTimeline> m_default_timeline;
|
||||||
|
Optional<double> m_last_animation_frame_timestamp;
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#pending-animation-event-queue
|
// https://www.w3.org/TR/web-animations-1/#pending-animation-event-queue
|
||||||
Vector<PendingAnimationEvent> m_pending_animation_event_queue;
|
Vector<PendingAnimationEvent> m_pending_animation_event_queue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue