Commit graph

2270 commits

Author SHA1 Message Date
Sam Atkins
973b919153 LibWeb/CSS: Only serialize a space before combinators that need it
This has no effect on behaviour now, but means we won't have to adjust
this code when adding the invisible pseudo-element combinator.
2026-04-10 15:00:58 +01:00
Sam Atkins
f32ba2b1a5 LibWeb/CSS: Use Selector's methods to query its pseudo-elements
...instead of iterating through its components. This lets us initialize
the MatchingRule directly, now using designated initializers to
distinguish between the different bool fields.

No behaviour changes.
2026-04-10 15:00:58 +01:00
Sam Atkins
62527c1917 LibWeb/CSS: Separate pseudo-class and pseudo-element parsing code
Apart from making the code a bit easier to follow, we'll need to
distinguish between the two in order to insert a pseudo-element
combinator in front of pseudo-elements (including the single-colon
legacy ones).

next_is_pseudo_element() is its own function because it'll be needed in
a couple of other places, again to support pseudo-element combinators.
2026-04-10 15:00:58 +01:00
Sam Atkins
77308d8a5e LibWeb/CSS: VERIFY() that we don't call is_delim() incorrectly
This has bitten me too many times and it is non-intuitive to debug. So
let's make it very clear that something is wrong!
2026-04-10 15:00:58 +01:00
Sam Atkins
a55fc0f403 LibWeb/CSS: Check for OpenParen token, not '(' Delim
'(' never exists as a Delim token, only as an OpenParen or part of a
Block.
2026-04-10 15:00:58 +01:00
Sam Atkins
a997bb9546 LibWeb/CSS: Remove Optional from parse_compound_selector() return type
We always either return a CompoundSelector or an Error here. This
simplifies the user code.
2026-04-10 15:00:58 +01:00
Callum Law
919dba87b9 LibWeb: Support calculated <flex> values
This spec note reads to me as explicitly disallowing combining
`<length>` and `<flex>` (i.e. `calc(1px + 1fr)`). This behavior is
already implemented (as it is for all other combination of units i.e.
`<length>` and `<time>`).
2026-04-09 21:41:49 +01:00
Callum Law
8d4e1a97cf LibWeb: Remove unused is_computationally_independent methods
`Size` and `LengthPercentage` are no longer stored within any
`StyleValue` classes so these methods are unused
2026-04-09 21:41:49 +01:00
Callum Law
281028944e LibWeb: Store GridTrackSize::m_value as a StyleValue
This simplifies handling (particularly around absolutization and
interpolation) and allows us to support calculated flex values (which
will come in a later commit).
2026-04-09 21:41:49 +01:00
Callum Law
21ffc8e1fe LibWeb: Implement composition for FlexStyleValue
Non-functional change for now but will be required once `GridTrackSize`
stores flex values as `StyleValue`s
2026-04-09 21:41:49 +01:00
Callum Law
e376310a70 LibWeb: Implement interpolation for FlexStyleValue
Non-functional change for now but will be required once `GridTrackSize`
stores flex values as `StyleValue`s
2026-04-09 21:41:49 +01:00
Callum Law
f4e7e193da LibWeb: Implement composition for FitContentStyleValue 2026-04-09 21:41:49 +01:00
Callum Law
af17641b0a LibWeb: Implement interpolation for FitContentStyleValue 2026-04-09 21:41:49 +01:00
Callum Law
c6de8def49 LibWeb: Add Size::from_style_value method 2026-04-09 21:41:49 +01:00
Callum Law
06b22d620d LibWeb: Add Flex::from_style_value method 2026-04-09 21:41:49 +01:00
Callum Law
5807d201b7 LibWeb: Implement absolutization of FitContentStyleValue 2026-04-09 21:41:49 +01:00
Callum Law
aa7c30b7a9 LibWeb: Store fit-content() argument as StyleValue
This brings us in line with other `StyleValue` classes and will make it
easier to implement absolutization in a later commit
2026-04-09 21:41:49 +01:00
Callum Law
2d3c705c17 LibWeb: Split FitContentStyleValue into an implementation file
Brings us in line with the other `StyleValue` classes
2026-04-09 21:41:49 +01:00
R-Goc
d1cd391017 LibWeb: Deduplicate inline_axis functions
This commit deduplicates inline_axis_is_reversed and
block_axis_is_reversed.
2026-04-09 08:33:40 -04:00
Sam Atkins
f993362425 LibWeb/CSS: Reject trailing tokens inside :host() pseudo-class 2026-04-08 15:53:02 +01:00
Sam Atkins
8cd4a19bb0 LibWeb/CSS: Parse combinators and compound-selectors separately
This allows places that want to parse a lone `<compound-selector>` to do
so without also implicitly parsing a combinator before it.

Also add error reporting in a bunch of places that previously failed
silently.
2026-04-08 15:53:02 +01:00
Callum Law
42b93a85fe LibWeb: Remove fallbacks for computing style on disconnected elements
This were introduced in dfe5d00 but only papered over the underlying
issue that we were computing style for element belonging to detached
documents - this underlying fix was implemented in c173a66 so these
fallbacks/guards are no longer needed
2026-04-08 14:31:43 +01:00
Callum Law
8bd1b383ea LibWeb: Use correct inherited font size when canvas is not connected
The default font size for a canvas context is 10px as opposed to 16px
for the document as a whole.
2026-04-08 14:31:43 +01:00
Callum Law
2b0f94fb6f LibWeb: Remove unused method declaration
This method was removed in 1c1476f but this declaration was added back
in 32da7ed, presumably due to a rebase mistake
2026-04-08 14:31:43 +01:00
Callum Law
df73c0e9b5 LibWeb: Don't unnecessarily absolutize style value
We already do this in the caller
2026-04-08 14:31:43 +01:00
Callum Law
4fcb82143b LibWeb: Disallow tree counting functions in most canvas context setters
This matches the behavior of Chrome - tree counting functions are
allowed within on-screen (i.e. not OffscreenCanvas) font values, but
nowhere else.
2026-04-08 14:31:43 +01:00
Callum Law
1fdcea2b7b LibWeb: Disallow random() in canvas context value setters
This introduces two new top-level `ValueParsingContext`s,
`OnScreenCanvasContextFontValue` and `CanvasContextGenericValue`, while
these are handled the same for now, there is a distinction is whether or
not they allow tree counting functions (which will come in a later
commit)
2026-04-08 14:31:43 +01:00
Callum Law
243465391a LibWeb: Cache hardcoded counter styles
This avoids a bunch of string validations reducing time spent in
`CounterStyle::disc()` from ~3% to ~0.01% when loading
https://en.wikipedia.org/wiki/2023_in_American_television
2026-04-08 11:59:57 +01:00
Sam Atkins
67e4633638 LibWeb/CSS: Make SelectorEngine more compatible with AbstractElement
Pass AbstractElement around as the target for match_compound_selector()
and match_simple_selector().

This has no effect yet, as we currently handle the pseudo-element at the
top layer and then pass down an AbstractElement without it, but it'll
matter once we stop doing that.
2026-04-08 10:37:05 +01:00
Sam Atkins
73e602f921 LibWeb/CSS: Rename internal matches() functions
Having 3 different functions named `matches()` that work on different
parts of a selector, all of which take a lot of arguments, makes this
harder to reason about than it needs to be. Rename them like so:
- The public "matches an entire selector" function is still matches()
- matches_compound_selector() for compound selectors
- matches_simple_selector() for simple selectors
2026-04-08 10:37:05 +01:00
Sam Atkins
f11207fee1 LibWeb/CSS: Pass AbstractElement to SelectorEngine::matches
...instead of separate Element and PseudoElement arguments.

As noted, AbstractElement's constness is weird currently, but that's a
tangent I don't want to go on right now.
2026-04-08 10:37:05 +01:00
Sam Atkins
43f0b2845d LibWeb/CSS: Rename Selector::pseudo_element() to target_pseudo_element()
This really represents the final pseudo-element, the one that style
actually applies to. We'll want to know that even once we fully support
having multiple pseudo-elements in a selector.
2026-04-08 10:37:05 +01:00
Sam Atkins
492cfc58d9 LibWeb/CSS: Add flags for element-backed & tree-abiding pseudo-elements
Generate a couple of functions for checking if a pseudo-element fits
these categories.
2026-04-08 10:37:05 +01:00
Andreas Kling
e15b1a33cb LibWeb: Parse sizes media conditions per HTML
The HTML sizes algorithm does not use full media queries. It evaluates
a restricted media-condition grammar and then parses the selected
source size value as a length.

Teach the parser to follow that split more closely: treat sizes
conditions as two-valued booleans, validate MQ5 <general-enclosed>
contents more strictly, accept calc(0) for media feature values, and
reject only source-size math results that are negative or non-finite.

The imported sizes parsing tests then progress from 140/171 to
171/171 in all four cases.
2026-04-05 22:01:18 +02:00
Shannon Booth
bb0f244667 LibWeb: Remove ShadowRealm HTML integration 2026-04-05 13:57:58 +02:00
Andreas Kling
e2e3c7fcdf LibWeb: Rebuild counter style cache lazily
Stop rebuilding the counter style cache from every style update.
That made unrelated restyles pay the full counter-style cost even when
no relevant stylesheet state had changed.

Dirty the cache when stylesheet rule caches are invalidated and rebuild
it on the first counter-style lookup instead. Also make cold cache
rebuilds include user stylesheets.

Add regression tests covering insertRule() and replaceSync() updates
that should make newly defined counter styles take effect.
2026-04-05 12:34:28 +02:00
Andreas Kling
0b5ef8fa22 LibWeb: Invalidate styles after constructable sheet updates
Constructed stylesheets updated their rule lists, but adopted documents
and shadow roots were not restyled when replace(), replaceSync(),
or disabled-state changes modified the sheet.  That left several CSSOM
tests passing stale computed styles.

Invalidate stylesheet owners after those updates so adopted sheets
recompute promptly. Also set replace()-produced rules' parent
stylesheet so non-import rules keep their stylesheet context.

The imported baseURL test assumes a tuple origin, so move it to the
HTTP fixture now that replaceSync() actually triggers a restyle.
2026-04-05 12:34:28 +02:00
Tim Ledbetter
5b584fde1d LibWeb: Register JS-created FontFace objects for font matching
Previously, FontFace objects created via the JS and added to
`document.fonts` were stored in the FontFaceSet but never participated
in font matching during style resolution. We now store both
CSS-connected and JS-created font faces in a unified map on
`FontComputer`, keyed by family name, and include them all as
candidates in the font matching algorithm.
2026-04-05 00:13:35 +02:00
Tim Ledbetter
d0b1482e80 LibWeb: Consolidate OwnFontFaceKey and FontFaceKey into a single type
Previously, `FontComputer` used two key types for its font map: a
non-owning `FontFaceKey` for lookups and an owning `OwnFontFaceKey` for
storage. This change replaces both with a single FontFaceKey that owns
its FlyString.
2026-04-05 00:13:35 +02:00
Tim Ledbetter
333df3b399 LibWeb: Cache parsed font descriptors on FontFace objects 2026-04-05 00:13:35 +02:00
Glenn Skrzypczak
f1d3244b22 LibWeb: Support CSS modules
This adds support for importing CSS stylesheets from CSS files in
javascript.
2026-04-03 21:21:09 +02:00
Jelle Raaijmakers
38342b2ad3 LibWeb: Add valid normal and none keywords for position-anchor
The WPT test was updated from upstream, but still assumes a wrong
initial value of `none`.

Co-authored-by: Rob Ryan <rob@affclicks.com>
2026-04-01 19:41:46 +01:00
Jelle Raaijmakers
4293c841f3 LibWeb: Implement CSS anchor positioning
When `position-anchor` is used, resolve the insets for that absolutely
positioned box.

Co-authored-by: Rob Ryan <rob@affclicks.com>
2026-04-01 19:41:46 +01:00
Jelle Raaijmakers
00397b4808 LibWeb: Keep track of elements with an anchor-name set
We maintain a registry of elements with an anchor-name so once they are
referenced for anchor positioning, we can find them with an O(1) lookup
instead of traversing the entire DOM tree.
2026-04-01 19:41:46 +01:00
Jelle Raaijmakers
1012aad322 LibWeb: Remove bogus discard_a_token() from CSS anchor fallback parsing
This correctly rejects invalid trailing tokens from `anchor()` fallback
values. Also introduces discard_whitespace() to take care of any
whitespace between the fallback value and the closing parenthesis.
2026-04-01 19:41:46 +01:00
Jelle Raaijmakers
6068d94752 LibWeb: Update/remove unused includes
No functional changes.
2026-04-01 19:41:46 +01:00
Tim Ledbetter
5a05909eab LibWeb: Disallow animation properties inside keyframe declarations
We now ignore all animation properties from `css-animations-1` declared
within keyframes, except `animation-timing-function`, which is treated
specially.
2026-04-01 11:38:48 +01:00
Tim Ledbetter
af6bc07c4f LibWeb/CSS: Resolve var() in keyframe animation-timing-function
When a `@keyframes` rule contains `animation-timing-function` with a
`var()`, we cannot eagerly resolve it to an `EasingFunction` at rule
cache build time because there is no element context available. We now
store the unresolved `StyleValue` and defer resolution to
`collect_animation_into()`, where the animated element's custom
properties can be used to substitute the variable. Previously, an
`animation-timing-function` with a `var()` in a `@keyframe` would cause
a crash.
2026-04-01 11:38:48 +01:00
Tim Ledbetter
9640e08646 LibWeb: Normalize color-mix() percentages at resolution time
Previously it was possible to hit a null deference if to_color() was
called on a non-absolutized `ColorMixStyleValue`.
2026-03-31 21:02:57 +02:00
Tim Ledbetter
e8a13b30b6 LibWeb: Absolutize ScrollbarColorStyleValue color values 2026-03-31 21:02:57 +02:00