Commit Graph

125 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
04c3ad669b LibWeb: Rebuild AccumulatedVisualContext on transform changes
Ensure AccumulatedVisualContext stays synchronized when CSS transform
properties change.

AccumulatedVisualContext copies transform and perspective matrices from
the paintable tree at assignment time. When CSS properties that affect
these matrices change (transform, rotate, scale, translate, perspective,
transform-origin, perspective-origin), we must rebuild the
AccumulatedVisualContext tree to reflect the new values.

This adds a rebuild_accumulated_visual_contexts flag to style
invalidation that triggers a full rebuild during the next paint.

Note: The current invalidation strategy is inefficient - it rebuilds
the entire tree even for single-element transform changes. This could
be improved by patching the AccumulatedVisualContext node in-place with
updated matrices, but only when the transform doesn't transition
from/to none (which would change the tree structure). This optimization
is left for future work.
2026-01-15 19:50:53 +01:00
Andreas Kling
2ac363dcba LibGC: Only call finalize() on types that override finalize()
This dramatically cuts down on time spent in the GC's finalizer pass,
since most types don't override finalize().
2026-01-07 20:51:17 +01:00
Andreas Kling
a9cc425cde LibJS+LibWeb: Add missing GC marking visits
This adds visit_edges(Cell::Visitor&) methods to various helper structs
that contain GC pointers, and makes sure they are called from owning
GC-heap-allocated objects as needed.

These were found by our Clang plugin after expanding its capabilities.
The added rules will be enforced by CI going forward.
2026-01-07 12:48:58 +01:00
Tim Ledbetter
e4fb4d7c1a LibWeb: Extract animation-composition value from keyframe at-rules
Previously, we weren't respecting the value of this property, so the
composite operation always defaulted to
`AnimationComposition::Replace`.
2026-01-06 12:58:54 +01:00
Callum Law
558f034007 LibWeb: Consolidate transition computation
Previously the logic to compute transitions was split across
`ComputedProperties`, `StyleComputer`, and `Animatable` - this commit
consolidates it all in `ComputedProperties`
2026-01-05 11:35:26 +00:00
Andreas Kling
ade167ed33 LibWeb: Always return task's ID after adding to a queue (or not)
Now that we don't always honor requests to add tasks to a queue, we
can't rely on "last added task" as the place to find the task's ID.
Fortunately we can just get it from the task itself.
2025-12-27 16:40:34 +01:00
Callum Law
781f961c07 LibWeb: Always use timeline time for animation pending task ready time
It is not guaranteed that an animation is ready to run a pending task
when it is scheduled just because it has a timeline, and even if it is,
the current time when scheduling will not necessarily still be correct
when the task is run (e.g. if the timeline changes in the interim).

We had some tests which relied on the previous behavior which have been
updated to await the pending play task

Fixes a crash in the
/web-animations/interfaces/Animatable/animate-no-browsing-context.html
WPT test but it can't be imported since it relies on a python web server
to be running
2025-12-23 14:54:22 +01:00
Callum Law
1bad8e5a78 LibWeb: Update animations regardless of whether timeline time changed
There are times that we want to update an animation regardless of
whether it's timelines time has changed, for example if an animation
associated with a scroll timeline has a pending task we should run that
on the next update regardless of whether the user has scrolled
2025-12-23 14:54:22 +01:00
Callum Law
f235625670 LibWeb: Don't disassociate animations from timeline when target orphaned
An animation with an orphaned owning element should continue to be
ticked by the timeline.

Reverts c8b574e and instead avoids leaking animations by not visiting
`Animation`s from `AnimationTimeline`s.

Fixes a timeout in the imported test
2025-12-23 14:54:22 +01:00
Callum Law
d62e2e39a3 LibWeb: Avoid running microtasks too early when updating animations
There were a bunch of places that we created
`HTML::TemporaryExecutionContext`s when updating animations in order to
resolve various promises, this worked but as part of the destructor it
would perform a microtask checkpoint which would result in us executing
microtasks earlier than intended, this is solved by instead having a
single temporary execution context for the entire animation update
process which we then destruct at the intended time.
2025-12-23 14:54:22 +01:00
Callum Law
d1e8788d43 LibWeb: Account for pending playback rate changes when playing animation
The spec calls for us to use the effective playback rate (i.e. including
any pending updates) when playing an animation.

Fixes a timeout in the newly imported test.
2025-12-23 14:54:22 +01:00
Callum Law
3ab187fd3c LibWeb: Expose AnimationTimeline::currentTime as CSSNumberish
This also allows us to remove the now redundant
`CSSNumberishTime::as_milliseconds()` method
2025-12-12 10:49:18 +00:00
Callum Law
43b265cd68 LibWeb: Expose applicable effect timing values as CSSNumberish 2025-12-12 10:49:18 +00:00
Callum Law
02adacb84c LibWeb: Expose AnimationEffect::{current,start}Time as CSSNumberish 2025-12-12 10:49:18 +00:00
Callum Law
57b7d0bbe5 LibWeb: Expose AnimationPlaybackEvent time values as CSSNumberish 2025-12-12 10:49:18 +00:00
Callum Law
69f05bd45d LibWeb: Store animation time values in abstract type
In level 2 of the web animations spec, times are no longer always
measures in milliseconds, they can also be percents when dealing with
progress-based (i.e. scroll-based) timelines.

We don't actually support percent times yet but this change will make it
easier to implement when we do.
2025-12-12 10:49:18 +00:00
Callum Law
f9df1c4eea LibWeb: Implement distinct specified timing values for AnimationEffect
Web Animations Level 2 disallows setting some `AnimationEffect` timing
values (start delay, end delay, iteration duration) directly and instead
allows authors to set the specified values which are then normalized
into the actual used values taking into account the type of the
associated timeline (i.e. progress- vs time-based)
2025-12-12 10:49:18 +00:00
Callum Law
435791b754 LibWeb: Implement AnimationTimline::duration property
This was added in Level 2 of the Web Animations spec

In this level of the spec, all time values associated with animations
(including this duration property) are no longer simple numbers but are
instead either percentages or numbers for progress- and time-based
timelines respectively. These values are represented internally by a new
`TimeValue` wrapper struct, and externally (i.e. in JS) as
`CSSNumberish`.
2025-12-12 10:49:18 +00:00
Callum Law
f58339de7f LibWeb: Split AnimationTimeline::set_current_time into two methods
This method did two things:
1) on the base class (`AnimationTimeline`) it was a setter for
   `m_current_time` and;
2) on the child classes (e.g. `DocumentTimeline`) it updated the
   timeline's current time given a document timestamp

It makes more sense for theses to be distinct methods
2025-12-12 10:49:18 +00:00
Andreas Kling
cb23d65625 LibJS: Pass JS::Value directly to string formatting functions
We don't need to call .to_string_without_side_effects() when passing
a JS::Value in for string formatting. The Formatter will do it for us.
2025-12-09 21:44:13 -06:00
Sam Atkins
d717dd64b3 LibWeb: Make Animation's owning element an AbstractElement
From the spec:
> The owning element of a transition refers to the element or
  pseudo-element to which the transition-property property was applied
  that generated the animation.

https://drafts.csswg.org/css-transitions-2/#owning-element

Previously we only stored the element.
2025-12-03 13:29:51 +01:00
Sam Atkins
ba86b81c1a LibWeb/Animations: Make KeyframeEffect work with AbstractElements 2025-12-03 13:29:51 +01:00
Callum Law
e937f5db57 LibWeb: Always parse comma separated value lists as StyleValueList
Previously we would either parse these as `StyleValueList<T>` or `T`
depending on whether or not there was more than one value, this meant we
always had to handle both cases anywhere we used these values.
2025-12-01 10:16:41 +00:00
Callum Law
1af0364cfc LibWeb: Store last_css_animation_play_state on anim instead of effect
Since it is the animation rather than the effect which has a play state
it makes more sense to store it here
2025-12-01 10:16:41 +00:00
Psychpsyo
693dd7b6f6 LibWeb: Avoid unnecessary sorting work when getting animations
This way, the list is not re-sorted on every recursive call.
2025-11-26 22:19:23 +01:00
Callum Law
b2b889e1da LibWeb: Ensure registered transitions are reflective of properties
Previously we would only update these if:
a) We had a cascaded value for `transition-property`
b) The source of that cascaded value had changed since we last
   registered transitions

This meant that there were a lot of changes we didn't apply:
 - Changes exclusively to properties other than `transition-property`
   (e.g. `transition-duration`, `transition-behavior`, etc)
 - Removing the `transition-property` property
 - Updating the `transition-property` property in a way that didn't
   change it's source (e.g. setting it within inline-style)

Unfortunately this does mean that we now register transitions for all
properties on most elements since "all" is the initial value for
"transition-property" which isn't great for performance, but that can be
looked at in later commits.
2025-11-23 09:43:24 +01:00
Callum Law
025274cd86 LibWeb: Don't deassociate animations when deregistering transitions
Also renames the `clear_transitions` function to clarify this doesn't
affect the associated transition animations.

This fixes an issue where transitions weren't being cancelled when the
relevant transition-property entry was no longer present
2025-11-23 09:43:24 +01:00
Callum Law
2f0cd9f739 LibWeb: Add Time::from_style_value
This method takes a `TimeStyleValue`, `PercentageStyleValue` or
fully-simplified `CalculatedStyleValue` with a numeric type of time, as
well as a percentage basis and produces the equivalent `Time` value.

This saves us having to reimplement this logic in multiple places
2025-11-23 09:43:24 +01:00
Callum Law
408bbead31 LibWeb: Don't mangle inherited properties when updating animated style 2025-11-21 09:24:53 +01:00
Psychpsyo
2c4f2a3cb6 LibWeb: Make transition order consider property name
class_specific_composite_order() also has no reason to return an
Optional<int>, since it can just return 0.
2025-11-11 13:46:56 +01:00
Callum Law
55afa9d37e LibWeb: Avoid unnecessary work when element display property changes
`play_or_cancel_animations_after_display_property_change` is called
whenever an element is inserted or removed, or it's display property
changes, but it is only required to run if we actually have animations
to play or cancel.

Reduces time spent in the aforementioned function from ~2% to ~0.03%
when loading https://en.wikipedia.org/wiki/2023_in_American_television
2025-11-11 08:35:39 +00:00
Psychpsyo
b7a71ca950 LibWeb: Correctly sort animations returned by getAnimations() 2025-11-10 18:29:07 +01:00
Callum Law
dd9d6d22ee LibWeb: Iterate over fewer properties in start_needed_transitions
We don't need to iterate every property in start_needed_transitions,
only those that appear in transition-property or have an existing
transition

Reduces the time spent in start_needed_transitions from ~5% to ~0.03%
when loading https://en.wikipedia.org/wiki/2023_in_American_television
2025-11-10 12:11:36 +01:00
Callum Law
fbcef936a9 LibWeb: Update style before getting animation play state
Pending style updates can influence this value
2025-11-02 23:54:00 +01:00
Callum Law
ed0b741a26 LibWeb: Remove special handling of all property for animations
There were a couple places that we had special handling for the `all`
property but since d31a58a was merged we can treat it the same as any
other shorthand
2025-11-02 23:54:00 +01:00
Callum Law
5381146e85 LibWeb: Include PropertyID.h in fewer header files
This reduces the size of the recompile when PropertyID.h is modified
from ~1500 to ~125
2025-10-27 14:50:54 +00:00
Callum Law
84762021b8 LibWeb: Support triggering multiple animations per animation property
We also now use the computed (rather than cascaded) values when
triggering animations.
2025-10-27 09:48:25 +00:00
Callum Law
18477b0d84 LibWeb: Promote animation-composition values to enum
This brings us in line with the other `animation-*` enum properties
(`animation-play-state` and `animation-fill-mode`)
2025-10-27 09:48:25 +00:00
Callum Law
03be70087d LibWeb: Maintain easing keywords as KeywordStyleValue until use-time
This excludes `step-end` and `step-start` which are expected to be
converted to the equivalent function at parse time.

We are expected to serialize these as the explicit keywords - previously
we would parse as `EasingStyleValue` and serialize equivalent functions
as the keywords. This caused issues as we would incorrectly serialize
even explicit functions as the keyword.

This also allows us to move the magic easing functions to
`EasingFunction` rather than `EasingStyleValue` which is a bit tidier
2025-10-20 11:27:44 +01:00
Callum Law
2f83356c0f LibWeb: Support calc within linear() easing function 2025-10-20 11:27:44 +01:00
Callum Law
95e26819d9 LibWeb: Separate use time easing functions from EasingStyleValue
In the future there will be different methods of creating these use-time
easing functions (e.g. from `KeywordStyleValue`s)
2025-10-20 11:27:44 +01:00
Andreas Kling
eff9989aeb LibWeb: Only update paint-only properties in affected subtrees
Before this change, we always updated paint-only properties for every
single paintable after layout or style changes.

This could get very expensive in large documents, so this patch makes
it something we can do partially based on "repaint" invalidations.

This cuts down time spent in paint-only property update when scrolling
https://imdb.com/ from 19% to 5%.
2025-09-24 23:59:41 +02:00
Tim Ledbetter
9b15517052 LibWeb: Apply composite operator to keyframe effects 2025-09-18 16:46:06 +01:00
Sam Atkins
50c0b4549c LibWeb/CSS: Take AbstractElement in collect_animation_into() 2025-09-11 18:45:35 +02:00
Callum Law
3b8c2a97c0 LibWeb: Don't resolve UnresolvedStyleValues in set_keyframes
If the custom property related to this UnresolvedStyleValue changed
we would not reflect the up to date value in the animation.
2025-08-28 09:29:46 +01:00
Callum Law
ede80ccdfb LibWeb: Allow UseInitial in keyframes when updating animated style
This removes the AnimationRefresh argument from `collect_animation_into`
which was added in a9b8840 - it's only effect was disallowing
`UseInitial`s within keyframes when we were doing animated style
updates which I believe is unintentional.

Gains us 214 WPT tests.
2025-08-27 14:50:58 +02:00
Jelle Raaijmakers
84c4eb7aa9 LibWeb: Always update computed properties for finished animations
If an animation got to its finished state before its target's computed
properties could be updated, we would end up with invalid styles. Do not
skip finished animations, but prevent effect invalidation on timeline
updates if the animation is already finished.

This fixes the CI flake on WPT test
`css/css-transitions/inherit-height-transition.html`.
2025-08-26 18:47:57 +02:00
Jelle Raaijmakers
13cba5ecb4 LibWeb: Make KeyframeEffect final 2025-08-26 18:47:57 +02:00
Jelle Raaijmakers
af552856c8 LibWeb: Remove unused TemporaryExecutionContext from Animation
We don't need a temporary execution context to create a promise.
2025-08-26 18:47:57 +02:00
Jelle Raaijmakers
55255586e8 LibWeb: Remove unused include from Animation.cpp 2025-08-26 18:47:57 +02:00