Commit graph

306 commits

Author SHA1 Message Date
Sam Atkins
2994a7532d LibWeb: Make shadow_including_first_ancestor_of_type() use the flat tree
Every user of this actually wants an ancestor in the flat tree - taking
things like `<slot>` into account. So rename it and adjust its behavior
to use that.
2026-02-05 11:21:08 +01:00
Callum Law
2310aaa5b3 LibWeb: Compute font-feature-settings before computing font
In a future commit we will require this to be in it's computed form
before calling `ComputedProperties::computed_font_list()`.

We will also depend on other properties (e.g. `font-kerning`,
`font-variant-*`) but these are unaffected by computation.
2026-02-02 14:11:43 +00:00
Tim Ledbetter
66246a0f3a LibWeb: Implement composition for grid track size lists 2026-01-26 03:20:08 +01:00
Callum Law
2c3ddc294f LibWeb: Compute math-depth in line with other font properties
The main change here is that we now properly absolutize values which
means we now support `random()` and `sibling-{count,index}()`

We are also more consistent with how we handle computation for the other
font properties
2026-01-15 12:03:16 +00:00
Callum Law
27dd77a538 LibWeb: Don't store resolved math depth directly
There's no need to store this twice

We also now use `set_property_without_modifying_flags` to avoid
overwriting inherited/important flags
2026-01-15 12:03:16 +00:00
Callum Law
eb5b73d3b5 LibWeb: Use existing StyleValues for math-depth
Previously we implemented an all encompassing `MathDepthStyleValue`
specifically for the `math-depth` property, this was unnecessary since
we can represent `auto-add` and `<integer>` using existing `StyleValue`
classes.

This brings the values created from parsing in line with those set via
`StylePropertyMap` which allows us to simplify computation
2026-01-15 12:03:16 +00:00
Tim Ledbetter
40d217bde2 LibWeb/CSS: Serialize shorthands with var() to original value 2026-01-15 11:50:45 +00:00
Andreas Kling
5049599594 LibWeb: Use FixedBitmap in StyleComputer to avoid malloc
Replace two uses of heap-allocated Bitmap with stack-allocated
FixedBitmap. The sizes are known at compile time, so there's no need
to hit malloc for these.
2026-01-14 11:46:23 +01:00
Callum Law
9b20fe6902 LibWeb: Promote font-style to ValueType
This means we now allow oblique angles when parsing the `font`
shorthand.

This also required us to rename the existing `FontStyle` enum to
`FontStyleKeyword`
2026-01-13 10:21:26 +00:00
Callum Law
1c1476f728 LibWeb: Don't compute font-feature-settings until compute-time
Previously we applied the computation logic (i.e. deduplication and
sorting of tags) at parse time
2026-01-13 10:21:26 +00:00
Callum Law
99c06675cf LibWeb: Combine cascaded property lookups during computation
Previously we would do two cascaded property lookups per property during
style computation - the first to get the value of the property and the
second to check whether it was marked as important. We now do this as a
single lookup to save some unnecessary work.
2026-01-11 14:10:37 +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
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
Aliaksandr Kalenik
3353ec9663 LibWeb: Add result caching for :has() pseudo-class matching
The `:has()` pseudo-class requires traversing descendants (or siblings)
to find matches.

With this change we cache results keyed by `(Selector*, Element*)`
pairs. The cache is stored in `StyleComputer` and cleared at the start
of each style computation pass in `Document::update_style()`.

When `:has()` uses a descendant combinator and we find a match, we also
cache that all ancestors between the matching descendant and the
anchor match. For example with `div:has(.target)`:

```html
<div id="A">  <!-- checking :has(.target) here -->
  <div id="B">
    <div id="C">
      <span class="target"/>
    </div>
  </div>
</div>
```

When we find `.target` while checking `div#A`, we also cache that
`div#B` and `div#C` match `:has(.target)` since they also contain
`.target`. Later when styling these elements, we get cache hits and skip
traversal.
2026-01-04 19:36:40 +01:00
Sam Atkins
45fc72214f LibWeb/CSS: Set border-widths to 0 at used time, not computed time
...when the style is `none` or `hidden`. `outline-width` is not affected
by `outline-style: none` at all.

In our codebase, that means doing the border-width conversion when
assigning to ComputedValues.

Corresponds to:
2a3d1e4d10
09f11f2ef9
2025-12-15 21:28:19 +01:00
Sam Atkins
4ab9ac86a7 LibWeb/CSS: Implement basic ::part() matching
Matches elements with a `part` attribute, against their parent shadow
host.
2025-12-15 14:12:39 +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
68d07355ed LibWeb: Coordinate border-* longhands at compute time
Updates the `position-serialization.html` test to be 2-valued so that
all cases are covered.
2025-12-08 11:46:50 +00:00
Callum Law
020c4aadff LibWeb: Parse background-position as ShorthandStyleValue
This makes us consistent with how we handle this value within the
`background` shorthand and allows us to remove the special handling in
`StyleComputer::for_each_property_expanding_shorthands`
2025-12-08 11:41:13 +00:00
Callum Law
dca80ad5eb LibWeb: Account for animated values when computing font
Computing the font for an element in `compute_font` is premature since
we are yet to apply animated properties - instead we should compute the
value on the fly (with a cache to avoid unnecessary work) to ensure we
are respecting the latest values
2025-12-05 10:03:15 +00:00
Callum Law
6c236d04d8 LibWeb: Separate font computation logic from StyleComputer
Font computation and loading is distinct enough from style computation
that it makes more sense to have this in it's own class.

This will be useful later when we move the font loading process to
`ComputedProperties` in order to respect animated values.
2025-12-05 10:03:15 +00:00
Callum Law
dfa47d9ed6 LibWeb: Simplify handling of font-variation-settings
Since we resolve any relative lengths at compute time there's no need
for the value to be passed around as a `NumberOrCalculated` and we can
just resolve it within `ComputedProperties::font_variation_settings`.

The only place this is used it is used with value_or so there's no need
to return it is an `Optional`.

This is only used for loading fonts (which occurs during style
computation) so there's no need to store it in `ComputedValues`
2025-12-05 10:03:15 +00: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
b61c857c64 LibWeb/CSS: Use AbstractElement animation helpers 2025-12-03 13:29:51 +01:00
Callum Law
e935dfbf5b LibWeb: Simplify compute_style_value_list 2025-12-02 12:47:10 +00:00
Callum Law
4034ce995a LibWeb: Account for transition-{delay,duration} always being a list
This fixes the optimization implemented in 46acdbd that was no longer
working after e937f5d
2025-12-02 11:45:46 +00:00
Sam Atkins
d9abfdf2ab LibWeb/CSS: Allow non-StyleValueLists in animation properties
Reverts 51f694c6af and
b52beb5105.

The animation-* properties are in an awkward place currently, where
they *should* be lists, and a lot of our code acts as if they are, but
actually we parse them as single values. The above commits caused a few
WPT tests to crash - see link below. I've imported one of them to
prevent future regressions.
https://wpt.fyi/results/css/css-typed-om/the-stylepropertymap/properties?diff&filter=ADC&run_id=6293362870321152&run_id=5123272984494080
2025-12-02 09:48:32 +00:00
Callum Law
51f694c6af LibWeb: Simplify compute_style_value_list 2025-12-01 10:16:41 +00:00
Callum Law
11a9b5a67b LibWeb: Simplify handling of font-family
We know `parse_comma_separated_value_list` always returns a
`StyleValueList`
2025-12-01 10:16:41 +00:00
Callum Law
4c4fa5c9cd LibWeb: Simplify expansion of background-position shorthand
We know that this is always a `StyleValueList`
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
Callum Law
63538c8a75 LibWeb: Prefer transitioned property values over important
CSS transitions have a higher precedence in the cascade than important
properties
2025-11-28 16:15:49 +00:00
Timothy Flynn
3dce6766a3 LibWeb: Extract some CORS and MIME Fetch helpers to their own files
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
2025-11-27 14:57:29 +01: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
46acdbd10a LibWeb: Avoid registering unnecessary transitions
Reduces time spent in `StyleComputer::compute_properties` when loading
https://en.wikipedia.org/wiki/2023_in_American_television from ~37% to
~13%
2025-11-23 09:43:24 +01:00
Callum Law
67a3d0f1aa LibWeb: Consider cancelled (idle) transitions as "completed" 2025-11-23 09:43:24 +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
Hendiadyoin1
bcd01da91d AK: Use Deducing this for OptionalBase
This is taken from and akin to
https://github.com/SerenityOS/serenity/pull/25894
2025-11-20 16:27:07 +01:00
Andreas Kling
66263f142b LibWeb: Add StyleScope to keep style caches per Document/ShadowRoot
Before this change, we've been maintaining various StyleComputer caches
at the document level.

This made sense for old-school documents without shadow trees, since
all the style information was document-wide anyway. However, documents
with many shadow trees ended up suffering since any time you mutated
a style sheet inside a shadow tree, *all* style caches for the entire
document would get invalidated.

This was particularly expensive on Reddit, which has tons of shadow
trees with their own style elements. Every time we'd create one of their
custom elements, we'd invalidate the document-level "rule cache" and
have to rebuild it, taking about ~60ms each time (ouch).

This commit introduces a new object called StyleScope.

Every Document and ShadowRoot has its own StyleScope. Rule caches etc
are moved from StyleComputer to StyleScope.

Rule cache invalidation now happens at StyleScope level. As an example,
rule cache rebuilds now take ~1ms on Reddit instead of ~60ms.

This is largely a mechanical change, moving things around, but there's
one key detail to be aware of: due to the :host selector, which works
across the shadow DOM boundary and reaches from inside a shadow tree out
into the light tree, there are various places where we have to check
both the shadow tree's StyleScope *and* the document-level StyleScope
in order to get all rules that may apply.
2025-11-14 22:05:33 +01:00
Timothy Flynn
d8ec204be8 LibWeb: Do not return an exception from fetching CSS resources
The exception returned here is never used or logged. Let's just return
a null request, to make it clearer that these are not exceptions shown
to the user (thus not observable).
2025-11-12 18:30:16 +01:00
Tim Ledbetter
0ec97eabab LibWeb: Extract device_pixels_per_css_pixel getter from loop
This reduces time spent in StyleComputer::compute_property_values() by
~10% when loading https://html.spec.whatwg.org/
2025-11-12 11:21:17 +01:00
Tim Ledbetter
df23b42b37 LibWeb: Don't store custom name on StyleProperty
This reduces time spent in `~StyleProperty()` from 2.18% to 0.67% on
https://cloudflare.com.
2025-11-12 11:19:37 +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
Callum Law
cfc22a4075 LibWeb: Dont try to transition custom properties
Fixes a crash introduced in dd9d6d2
2025-11-11 07:53:41 +00:00
Tim Ledbetter
61af399b50 LibWeb: Remove unnecessary lowercase name property from Attr 2025-11-10 22:55:38 +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
Timothy Flynn
ac246caa0c LibWeb: Remove now-unused Resource and ResourceClient
And deal with the fallout of transitive includes.
2025-11-05 18:27:36 +01:00
Tim Ledbetter
8d81421526 LibWeb: Cache font matching algorithm results
The majority of time in `compute_font()` was spent in
`font_matching_algorithm()` repeatedly computing the same values. We
now cache these values to avoid unnecessary work.
2025-11-05 09:12:02 +01:00