Commit Graph

2027 Commits

Author SHA1 Message Date
Sam Atkins
92897a1dec LibWeb/CSS: Absolutize color KeywordStyleValues
These get computed to an equivalent RGBColorStyleValue.

To support this, we now store the computed color-scheme on the
ComputationContext when computing properties that might contain a color.

This has a nice bonus of correcting the css-accent-color test's result.
2026-02-05 13:48:10 +00:00
Sam Atkins
7ba7377e19 LibWeb/CSS: Absolutize basic color StyleValues
These generally work as you'd expect. The exceptions are that hsl() and
hwb() are expected to compute to rgb(), so absolutization produces an
RGBColorStyleValue where possible.
2026-02-05 13:48:10 +00:00
Sam Atkins
8975fd7d06 LibWeb/CSS: Stop parsing media-features without parentheses
Our parsing code was treating `foo` and `foo: bar` as `<media-feature>`s
when really they need to be `(foo)` and `(foo: bar)` respectively. This
previously worked for the valid case because boolean expressions can
also have arbitrary `()` blocks. However, it meant we'd also allow them
without the parentheses which isn't valid.

So instead, parse and serialize the parentheses as part of the
`<media-feature>`. This gets us some WPT passes and fixes an Acid3
failure.
2026-02-05 12:22:58 +01:00
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
11d524bda4 LibWeb: Support CSS font-optical-sizing property 2026-02-03 11:44:25 +00:00
Callum Law
0c4bab4390 LibWeb: Simplify ComputedProperties::length_box
Value clamping is no longer required since we now do it at interpolation
time (96b628f)
2026-02-03 10:33:04 +00:00
Callum Law
f13e0bb8a5 LibWeb: Replace ComputedProperties::length_percentage
Since we now clamp values as part of interpolation (96b628f) this
function is equivalent to `LengthPercentage::from_style_value`
2026-02-03 10:33:04 +00:00
Callum Law
11654d0d7e LibWeb: Propagate rx/ry auto value in apply_style
We stored and initialized this value as a `LengthPercentageOrAuto` but
didn't propagate a computed `auto` value.
2026-02-03 10:33:04 +00:00
Callum Law
2f90529438 LibWeb: Parse @counter-style speak-as descriptor 2026-02-03 09:58:47 +00:00
Callum Law
85d64a1215 LibWeb: Parse @counter-style additive-symbols descriptor 2026-02-03 09:58:47 +00:00
Callum Law
ecfdf252b8 LibWeb: Parse @counter-style symbols descriptor 2026-02-03 09:58:47 +00:00
Callum Law
1f8c9cf662 LibWeb: Parse @counter-style fallback descriptor 2026-02-03 09:58:47 +00:00
Callum Law
9b376240f9 LibWeb: Parse @counter-style pad descriptor 2026-02-03 09:58:47 +00:00
Callum Law
afca221d47 LibWeb: Parse @counter-style range descriptor 2026-02-03 09:58:47 +00:00
Callum Law
f1e8d54717 LibWeb: Parse @counter-style prefix and suffix descriptors 2026-02-03 09:58:47 +00:00
Callum Law
70c8d8746f LibWeb: Parse @counter-style negative descriptor 2026-02-03 09:58:47 +00:00
Callum Law
f60bfd9e9e LibWeb: Parse @counter-style system descriptor 2026-02-03 09:58:47 +00:00
Callum Law
703259a24c LibWeb: Parse and serialize @counter-style rule
We don't yet parse or serialize any of the descriptors in the rule, just
the rule itself and the name
2026-02-03 09:58:47 +00:00
Callum Law
c7f288bf97 LibWeb: Allow marking StyleValueList as non-collapsible
We already disallow collapsing for comma separated lists but this allows
us to disallow it for space separated lists as well
2026-02-03 09:58:47 +00:00
Andreas Kling
5f434a442a LibWeb: Use targeted style invalidation when adding a new stylesheet
Instead of doing a full document style invalidation when a stylesheet is
dynamically added, we now analyze the new sheet's selectors to determine
which elements could potentially be affected, and only invalidate those.

This works by building an InvalidationSet from the rightmost compound
selector (the "subject") of each rule in the new stylesheet, extracting
class, ID, tag name, attribute, and pseudo-class features. We then walk
the DOM tree and only mark elements matching those features as needing a
style update.

If any selector has a rightmost compound that is purely universal (no
identifying features), or uses a pseudo-class not supported by the
invalidation set matching logic, we fall back to full invalidation.
2026-02-02 21:08:30 +01:00
Aliaksandr Kalenik
ced5dc51c4 LibWeb: Fix fit-content() row clamping with indefinite available height
`grid-template-rows: fit-content(100px)` had no effect when the grid
container lacked an explicit height, because the fit-content growth
limit clamping was gated behind `available_size.is_definite()`.

Fix by normalizing fit-content tracks with unresolvable percentage
arguments to max-content during track initialization, then applying
the fit-content clamp unconditionally.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/7730
2026-02-02 20:33:05 +01:00
Jonathan Gamble
b8ee6ec476 LibWeb: Use SizeWithAspectRatio struct 2026-02-02 14:36:49 +00:00
Vahan Arakelyan
d04b74555b LibWeb/CSS: Make accentColor and accentColorText take accent-color value 2026-02-02 14:19:08 +00:00
Vahan Arakelyan
f280bbdf69 LibWeb/CSS: Fix color-scheme.html test with new accentColorText value 2026-02-02 14:19:08 +00:00
Callum Law
8247bcbf20 LibWeb: Update to_shape_features() FIXMEs to spec
This brings the FIXMEs into line with CSS Fonts Level 4
2026-02-02 14:11:43 +00:00
Callum Law
b55023fad3 LibGfx+LibWeb: Resolve font features per font rather than per element
Previously we would resolve font features
(https://drafts.csswg.org/css-fonts-4/#feature-variation-precedence)
per element, while this works for the current subset of the font feature
resolution algorithm that we support, some as yet unimplemented parts
require us to know whether we are resolving against a CSS @font-face
rule, and if so which one (e.g. applying descriptors from the @font-face
rule, deciding which @font-feature-values rules to apply, etc).

To achieve this we store the data required to resolve font features in a
struct and pass that to `FontComputer` which resolves the font features
and stores them with the computed `Font`.

We no longer need to invalidate the font shaping cache when features
change since the features are defined per font (and therefore won't ever
change).
2026-02-02 14:11:43 +00:00
Callum Law
a76ed0e3a9 LibWeb: Use FlyString for ComputedProperties::font_feature_settings()
We are going to be storing this returned value in a future commit so we
should use `FlyString` rather than `StringView` to avoid use after free
2026-02-02 14:11:43 +00: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
Callum Law
5917a8c1c8 LibGfx+LibWeb: Allow setting FontVariationSettings for default font
While our default font supporting variations is unlikely, this is
nevertheless required for our fallback font to be considered equal to
it's non-default/fallback equivalent (i.e. `font-family: serif`) which
in turn is required for LineBuilder to merge chunks into a single
fragment.
2026-02-02 14:11:43 +00:00
Adam Colvin
994e8123ba LibWeb: Pass scope through pseudo-classes for proper :scope matching
The :scope pseudo-class inside :has(), :is(), :where(), and :not()
selectors was not receiving the scoping root from outer selector
contexts like Element.closest().

This fix passes the scope parameter through matches_has_pseudo_class(),
matches_relative_selector(), and the :is()/:where()/:not() cases so
that :scope correctly refers to the scoping root element.

This fixes WPT tests for Element.closest() with selector
':has(> :scope)' and for comparing :has(:scope) with :is(:scope)
selectors.
2026-02-02 12:47:32 +00:00
Aliaksandr Kalenik
24f6e697d9 LibWeb: Optimize stacking context tree rebuilds
Previously, any change to a property that affects stacking context would
trigger a full stacking context tree rebuild. However, an element only
creates or destroys a stacking context when a property crosses from its
"neutral" value to a "creating" value (or vice versa).

For example, animating `transform: translateX(10px)` to
`transform: translateX(20px)` previously triggered stacking context
rebuilds on every frame, but this is unnecessary because the stacking
context already exists.
2026-01-28 18:05:41 +01:00
Andreas Kling
7bc7e80042 LibWeb: Only invalidate affected elements when @font-face font loads
Previously, when a @font-face font finished loading, we would clear the
entire computed font cache and invalidate style for the whole document.

This was overly conservative since most elements don't use the newly
loaded font. We now take a targeted approach inspired by Firefox:

1. Only clear cache entries that reference the loaded font family
2. Walk the DOM tree (including shadow trees) and only invalidate
   elements whose font-family property (or pseudo-elements' font-family)
   actually references the loaded font

This significantly reduces style invalidation work on pages with many
elements but only some using custom fonts.
2026-01-26 12:40:36 +01:00
Andreas Kling
bcc7be1751 LibWeb: Optimize EdgeStyleValue::absolutize() in same-value case 2026-01-26 12:40:36 +01:00
Andreas Kling
35839af2d2 LibWeb: Optimize getComputedStyle() to avoid layout when possible
Previously, getComputedStyle() would always call update_layout() for
most properties. This was expensive since layout involves a full tree
traversal even when only style information is needed.

This change introduces a more granular approach:
- Properties needing layout computation (used values like width/height)
  still call update_layout()
- Properties needing a layout node for resolved value computation
  (colors, border widths, etc.) also call update_layout()
- All other properties now only call update_style()

The set of properties needing layout node for resolution is now defined
in Properties.json via the "needs-layout-node-for-resolved-value" flag,
rather than being hardcoded. This is generated into a new function
property_needs_layout_node_for_resolved_value().
2026-01-26 12:40:36 +01:00
Tim Ledbetter
66246a0f3a LibWeb: Implement composition for grid track size lists 2026-01-26 03:20:08 +01:00
Callum Law
afdde488c3 LibWeb: Correctly parse logical border-*-*-radius shorthands
Builds on #7609 by parsing these properties correctly in the first place
2026-01-25 10:22:10 +01:00
Tim Ledbetter
191e0e8c18 LibWeb: Support @-webkit-keyframes as an alias for @keyframes
This is listed as mandatory in the compat spec.
2026-01-25 09:33:24 +01:00
Aliaksandr Kalenik
3e54291813 LibWeb: Move VisualViewport transform to AccumulatedVisualContext tree
Move the visual viewport (pinch-to-zoom) transform from a reserved slot
in DisplayList to the AccumulatedVisualContext tree as a root transform
node. Fixed position elements now correctly inherit from this context.

This requires rebuilding the context tree and display list on each zoom
change, but this overhead will be eliminated by future partial context
tree rebuilds.
2026-01-23 18:56:24 +01:00
Sam Atkins
0796418c18 LibWeb/CSS: Use serialize_a_number() for color components 2026-01-23 14:26:11 +01:00
Sam Atkins
d2a76933d5 LibWeb/CSS: Use serialize_a_number() directly in NumberStyleValue 2026-01-23 14:26:11 +01:00
Sam Atkins
a6b7da9b7c LibWeb/CSS: Serialize resolved alpha components with serialize_a_number
This rounds the numbers in the expected way.
2026-01-23 14:26:11 +01:00
Sam Atkins
0f04c6dd3e LibWeb/CSS: Extract ValueComparingRefPtr types into their own header
I originally wanted to move this to prevent a circular dependency, in a
commit that I'm probably not submitting any more. But also, there's
nothing about this type that is CSS or LibWeb-specific, so let's put
this in AK.
2026-01-23 14:26:11 +01:00
Jelle Raaijmakers
c81dd92dab LibWeb: Update UA stylesheet for form controls
This was updated in the spec.
2026-01-22 19:36:09 +01:00
Callum Law
55ce89d513 LibWeb: Support composition of BasicShapeStyleValue
This also required supporting composition for it's constituent types
(`RadialSizeStyleValue` and `BorderRadiusRect`).

The remaining failing subtests in the two affected tests are because we
dont yet support compositing of mixed values
2026-01-22 11:29:41 +00:00
Callum Law
1029bac5fc LibWeb: Support composition of EdgeStyleValue
The remaining failing tests in `background-position-composition.html`
are because we dont yet support compositing of mixed values
2026-01-22 11:29:41 +00:00
Callum Law
51bea3b308 LibWeb: Clamp interpolation of RadialSizeStyleValue 2026-01-22 11:29:41 +00:00
Callum Law
52c09a6e87 LibWeb: Remove unnecessary call to FontDatabase::get()
This method was only called when `font_matching_algorithm` failed to
match a font (i.e. there are no fonts with a matching family name) in
which case this method would also fail to match a font.
2026-01-21 23:49:25 +01:00
Callum Law
73fbe24892 LibWeb: Add early return from font_matching_algorithm
We also add a `VERIFY_NOT_REACHED()` to make it clear that we will
always return a font if there is atleast one font in
`matching_family_fonts`
2026-01-21 23:49:25 +01:00
Callum Law
c35ecc8b1c LibWeb: Respect font-width for variable fonts 2026-01-21 23:49:25 +01:00
Callum Law
2f7848913b LibWeb: Always respect font-variation-settings
Previously we wouldn't respect font-variation-settings for fonts matched
through `font_matching_algorithm` (i.e. any fonts which didn't have an
exact loaded match).
2026-01-21 23:49:25 +01:00