LibWeb: Use GC::WeakHashSet for AnimationTimeline associated animations

Replace the unsafe HashTable<GC::Weak<Animation>> with
GC::WeakHashSet<Animation>, and update all callers to use reference
syntax instead of pointer syntax since the iterator now yields T&.
This commit is contained in:
Andreas Kling 2026-02-24 12:36:21 +01:00 committed by Andreas Kling
parent 323e7dd79d
commit 73b0ecd89d
3 changed files with 21 additions and 18 deletions

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibGC/WeakHashSet.h>
#include <LibWeb/Animations/Animation.h>
#include <LibWeb/Animations/TimeValue.h>
#include <LibWeb/Bindings/PlatformObject.h>
@ -42,9 +43,9 @@ public:
virtual Optional<double> convert_a_timeline_time_to_an_origin_relative_time(Optional<TimeValue>) { VERIFY_NOT_REACHED(); }
virtual bool can_convert_a_timeline_time_to_an_origin_relative_time() const { return false; }
void associate_with_animation(GC::Ref<Animation> value) { m_associated_animations.set(value); }
void disassociate_with_animation(GC::Ref<Animation> value) { m_associated_animations.remove(value); }
HashTable<GC::Weak<Animation>> const& associated_animations() const { return m_associated_animations; }
void associate_with_animation(GC::Ref<Animation> value) { m_associated_animations.set(*value); }
void disassociate_with_animation(GC::Ref<Animation> value) { m_associated_animations.remove(*value); }
GC::WeakHashSet<Animation> const& associated_animations() const { return m_associated_animations; }
protected:
AnimationTimeline(JS::Realm&);
@ -64,7 +65,7 @@ protected:
// https://www.w3.org/TR/web-animations-1/#timeline-associated-with-a-document
GC::Ptr<DOM::Document> m_associated_document {};
HashTable<GC::Weak<Animation>> m_associated_animations {};
GC::WeakHashSet<Animation> m_associated_animations;
};
}

View file

@ -1807,9 +1807,9 @@ void Document::update_animated_style_if_needed()
for (auto& timeline : m_associated_animation_timelines) {
for (auto& animation : timeline->associated_animations()) {
if (animation->is_idle())
if (animation.is_idle())
continue;
if (auto effect = animation->effect())
if (auto effect = animation.effect())
effect->update_computed_properties(context);
}
}
@ -5734,12 +5734,14 @@ void Document::update_animations_and_send_events(double timestamp)
for (auto const& timeline : timelines_to_update) {
timeline->update_current_time(timestamp);
for (auto const& animation : timeline->associated_animations())
animation->update();
for (auto& animation : timeline->associated_animations())
animation.update();
auto animations = GC::RootVector { heap(), timeline->associated_animations().values() };
auto animations = GC::RootVector<GC::Ref<Animations::Animation>> { heap() };
for (auto& animation : timeline->associated_animations())
animations.append(animation);
for (auto& animation : animations)
dispatch_events_for_animation_if_necessary(animation.as_nonnull());
dispatch_events_for_animation_if_necessary(animation);
}
// 2. Remove replaced animations for doc.
@ -5810,21 +5812,21 @@ void Document::remove_replaced_animations()
Vector<GC::Ref<Animations::Animation>> replaceable_animations;
for (auto const& timeline : m_associated_animation_timelines) {
for (auto const& animation : timeline->associated_animations()) {
if (!animation->effect() || !animation->effect()->target() || &animation->effect()->target()->document() != this)
for (auto& animation : timeline->associated_animations()) {
if (!animation.effect() || !animation.effect()->target() || &animation.effect()->target()->document() != this)
continue;
if (!animation->is_replaceable())
if (!animation.is_replaceable())
continue;
if (animation->replace_state() != Bindings::AnimationReplaceState::Active)
if (animation.replace_state() != Bindings::AnimationReplaceState::Active)
continue;
// Composite order is only defined for KeyframeEffects
if (!animation->effect()->is_keyframe_effect())
if (!animation.effect()->is_keyframe_effect())
continue;
replaceable_animations.append(animation.as_nonnull());
replaceable_animations.append(animation);
}
}

View file

@ -31,8 +31,8 @@ void InternalAnimationTimeline::set_time(Optional<double> time)
// updated.
// - Queueing animation events for any such animations.
// NB: This mirrors what the event loop does for DocumentTimeline in Document::update_animations_and_send_events().
for (auto const& animation : associated_animations())
animation->update();
for (auto& animation : associated_animations())
animation.update();
}
InternalAnimationTimeline::InternalAnimationTimeline(JS::Realm& realm)