Commit Graph

2257 Commits

Author SHA1 Message Date
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
Tim Ledbetter
58ce1f9ec4 LibWeb: Absolutize color in ShadowStyleValue
ShadowStyleValue was not absolutizing its color component, which meant
that complex color values like `color-mix()` would retain unresolved
state. This caused a null pointer dereference when `color-mix()` with
omitted percentages was used as a shadow color. We now absolutize the
color component, avoiding this crash.
2026-03-31 21:02:57 +02:00
Shannon Booth
a066ee720e LibWeb/CSS: Remove redundant has_alt_text() from ContentStyleValue
Replace the has_alt_text() / alt_text() calls by directly null
checking on the returned pointer from alt_text().
2026-03-31 13:48:50 +01:00
Jelle Raaijmakers
bff863d6d9 LibGfx+LibWeb: Remove unused code from Gfx::Point/Rect/Size
No functional changes.
2026-03-31 10:37:23 +02:00
Callum Law
847cf74ff8 LibWeb: Remove Length::ResolutionContext::for_window
This didn't work within iframes and all users have been moved over to
use `for_document` instead
2026-03-31 10:06:18 +02:00
Callum Law
90e0e5a0f2 LibWeb: Use correct viewport units for font properties in iframe root el 2026-03-31 10:06:18 +02:00
Callum Law
fec79b62e4 LibWeb: Always pass ASF presence to UnresolvedSV::create()
There was only one place that we weren't passing this where we could
have ASFs so let's just handle that there and explicitly mark the others
as having no ASFs to avoid unnecessary work.

No functional changes
2026-03-30 19:57:36 +01:00
Callum Law
03d479c1da LibWeb: Validate ASF syntax at parse time 2026-03-30 19:57:36 +01:00
Callum Law
04f634eeb2 LibWeb: Disallow ASF in initialValue when calling registerProperty 2026-03-30 19:57:36 +01:00
Callum Law
071b000d9f LibWeb: Only allow ASFs in descriptor values if explicitly supported
`@function` descriptors are the only ones that support ASFs, while most
descriptors enforce this through their syntaxes implicitly disallowing
ASFs, this wasn't the case for `@property/initial-value`.

We now explictly disallow ASFs unless they are marked as allowed within
`Descriptors.json`.
2026-03-30 19:57:36 +01:00
Callum Law
8b66e7f463 LibWeb: Consider semicolon in parse_descriptor_value a SyntaxError
Everywhere we use this expects us to parse the whole value, either
because we are parsing the value of a declaration (in which case there
will be no semicolons), or because it is called from a JS setter which
takes whole values and semicolons make the value invalid.

Previously we would just ignore everything after a semicolon.

This also allows us to avoid creating a new `Vector` and copying all the
component values
2026-03-30 19:57:36 +01:00
Callum Law
7d2f772317 LibWeb: Move ASF presence checking into Parser
We are going to extend this and use it elsewhere in the future so it's a
bit neater here.

No functional changes
2026-03-30 19:57:36 +01:00
Adam Colvin
36c549eba7 LibWeb: Support ::part() pseudo-element chaining
Allow CSS pseudo-element chaining with ::part() so that
selectors like ::part(title)::before can style pseudo-elements
within shadow DOM parts.

Parser changes (SelectorParsing.cpp): The pseudo-element
validation logic now tracks which pseudo-element appears first
and second in a compound selector. When multiple pseudo-elements
are found, the parser permits the selector only if the first is
::part() and the second is NOT ::part(). A maximum of two
pseudo-elements is enforced.

Selector changes (Selector.cpp, Selector.h): The Selector
constructor now stores the last pseudo-element (the styling
target) rather than the first. For ::part(foo)::before, the
selector reports ::before as its target. A new
m_contains_part_pseudo_element flag separately tracks whether
::part() is present for the selector engine.

Fixes 9 WPT tests: 6 in css/selectors/parsing/parse-part.html
for chained selector parsing, and 3 in
css/css-shadow-parts/multiple-scopes.html for correct scoping
of exported, middle-scope, and non-exported part selectors.
2026-03-30 16:47:34 +01:00
Adam Colvin
cf67db5f0d LibWeb: Only match ::part() in direct child shadow trees
When matching ::part(), only consider shadow trees whose host lies in
the same style scope as the rule. Use MatchContext::rule_shadow_root,
which is already set when collecting ::part() rules, as that scope.

For cross-scope rules, accept a candidate shadow root only if its
host's containing_shadow_root() matches the rule's shadow root: the
rule's scope is the document when rule_shadow_root is null, or that
shadow root when the rule comes from its stylesheet.

The one exception is :host::part(): the rule and the part live in the
same shadow root, so its host is outside the rule's scope and the
comparison would never pass. Allow the check to be skipped for this
case by setting MatchContext::for_host_part_matching when the compound
selector contains :host (directly or inside :is(), which is how CSS
nesting resolves &::part() inside a :host rule).

Run that :host pre-scan only when rule_shadow_root is set. Document
rules never use the same-shadow-root exception; scanning would
otherwise set for_host_part_matching whenever :host appears in the
compound and break cross-scope ::part() matching (e.g. multiple-scopes).

Previously the engine walked all ancestor shadow roots without this
cross-scope check.
2026-03-30 16:47:34 +01:00