Commit Graph

2320 Commits

Author SHA1 Message Date
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
Sam Atkins
c2f0d61eb6 LibWeb/CSS: Implement initial parsing for @container rules
The main limitation here are that none of the container-query features
are parsed in a meaningful way; they all become `<general-enclosed>`.
Parsing for them will be added as they are implemented.
2026-03-30 14:49:24 +01:00
Sam Atkins
214d2b5e1f LibWeb/CSS: Implement CSSContainerRule
No parsing yet, just CSSContainerRule and the supporting ContainerQuery
class.

CSSContainerRule is unusual in how it matches, because instead of it
either matching or not matching globally, it instead is matched against
a specific element. But also, some at-rules inside it always apply, as
if they were written outside it. This doesn't fit well with how
CSSConditionRule is implemented, and will likely require some rework
later. For now, `condition_matches()` always returns false, and
`for_each_effective_rule()` is overridden to always process those
global at-rules and nothing else.
2026-03-30 14:49:24 +01:00
Callum Law
0219eb2ef9 LibWeb: Remove FooOrCalculated classes
These are unused since we now store values as `StyleValue`s before
used-value time, and as their resolved type (e.g. CSSPixels) after
2026-03-30 14:05:10 +01:00
Callum Law
cbc2bb7aa7 LibWeb: Don't pass layout node when resolving EdgeRect
We know that these lengths have already been absolutized at computed
value time
2026-03-30 14:05:10 +01:00
Callum Law
3aa71034de LibWeb: Support calc() within clip: rect() 2026-03-30 14:05:10 +01:00
Callum Law
ab6f5b36d2 LibWeb: Add LengthOrAuto::from_style_value 2026-03-30 14:05:10 +01:00
Callum Law
3b3f06bfa3 LibWeb: Support non-literal integers in repeat()
We now support non-literal integers (i.e. `calc()` and tree counting
functions) within `<track-repeat>` and `<fixed-repeat>`
2026-03-30 14:05:10 +01:00
Callum Law
f2a8099d13 LibWeb: Parse sizes attribute as StyleValue
Gets us a step closer to removing the `FooOrCalculated` classes
2026-03-30 14:05:10 +01:00
Callum Law
3e58e15217 LibWeb: Support relative lengths within color-mix percentage calc()s 2026-03-30 14:05:10 +01:00
Callum Law
3c00a13237 LibWeb: Remove redundant normalization of percentages in ColorMixSV
We normalize percentages at computed value time so there's no need to
normalize them again when converting to used value
2026-03-30 14:05:10 +01:00
Callum Law
9b2dd73359 LibWeb: Store ColorMixComponent::percentage as StyleValue
This simplifies handling and gets us closer to removing the
`OrCalculated` classes
2026-03-30 14:05:10 +01:00
Callum Law
149acdd7c5 LibWeb: Add Percentage::from_style_value 2026-03-30 14:05:10 +01:00
Callum Law
fe5d6471f0 LibWeb: Store GridTrackPlacement sub-values as StyleValues
Gets us one step closer to removing the `FooOrCalculated` classes
2026-03-30 14:05:10 +01:00
Dylan Hart
1354eb1ac2 LibWeb: Resolve var() in shorthands before pseudo-element filtering
When a shorthand like `background` containing `var()` is used in
a `::selection` rule, the shorthand was filtered out by the pseudo-
element property whitelist before variable resolution could occur.
This left PendingSubstitutionStyleValue longhands unresolved,
causing either a crash or incorrect computed values.

Allow unresolved shorthands to bypass the pseudo-element filter so
variable resolution can proceed. After resolution and expansion
into longhands, filter out any that the pseudo-element does not
support.

Fixes #8625.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 12:46:20 +01:00
Tim Ledbetter
4c48827ed2 LibWeb: Merge duplicate @keyframe rule selector values
Previously, a keyframe with duplicate selector would cause a crash.
2026-03-30 12:42:57 +01:00
Sam Atkins
fd46ade2a2 LibWeb/CSS: Add the env() function to @supports conditions
This was just added to the spec and doesn't yet have WPT coverage, but
it's also pretty trivial.
2026-03-29 21:27:20 +01:00
Tim Ledbetter
657060ccc2 LibWeb: Implement FontFaceSet.check()
This returns true if the given text can be rendered with the fonts in
the set that are fully loaded.
2026-03-27 15:28:59 +00:00
Callum Law
c7b402eff5 LibWeb: Parse @function rules 2026-03-27 11:19:28 +00:00
Callum Law
01394322ac LibWeb: Propagate media query evaluation into @function rules
`CSSFunctionRule`s can contain `CSSMediaRule`s so we need to propagate
evaluation through `CSSFunctionRule`
2026-03-27 11:19:28 +00:00
Callum Law
7d158c47d1 LibWeb: Implement CSSFunctionDeclarations
We also define it as a valid `NestedDeclarationsRule` for the relevant
functions
2026-03-27 11:19:28 +00:00
Callum Law
7f72b01ed3 LibWeb: Implement CSSFunctionDescriptors 2026-03-27 11:19:28 +00:00
Callum Law
19c8eb4146 LibWeb: Implement CSSFunctionRule
Parsing/using this rule will come in later commits
2026-03-27 11:19:28 +00:00
Callum Law
401b0fb734 LibWeb: Expose parse_syntax_component
This will be used when parsing `@function` rules
2026-03-27 11:19:28 +00:00
Callum Law
cd05e1d039 LibWeb: Allow specifying type of nested declarations rule
When parsing declarations within a nested grouping rule, we don't store
these directly, but within a "nested declarations rule", in most cases
this is `CSSNestedDeclarations`, but this isn't always the case e.g.
`@function` rules and others (e.g. @media) within them should instead
use `CSSFunctionDeclarations`
2026-03-27 11:19:28 +00:00
Callum Law
e7243f0090 LibWeb: Support custom descriptors
Some at-rules (i.e. `@function`) require us to support custom
descriptors (e.g. `--foo`).

We do this by adding `DescriptorID::Custom` and using a new
`DescriptorNameAndID` class in a bunch of places where we previously
just used `DescriptorID`
2026-03-27 11:19:28 +00:00
Jelle Raaijmakers
3d2571b46e LibWeb: Implement text-decoration-skip-ink painting
Use Skia's SkTextBlob::getIntercepts() to find where glyph outlines
cross the underline/overline band, then split the decoration line into
segments with gaps around those intersections.
2026-03-26 12:15:36 +00:00
Jelle Raaijmakers
18f01b2c4b LibWeb: Support parsing text-decoration-skip-ink property 2026-03-26 12:15:36 +00:00
Callum Law
761ccdb5e3 LibWeb: Remove special handling of z-index resolved value
Previously we waited until used-value time to apply handling for the
z-index value that we should have applied at declared or computed-value
time, which was papered over by returning the used rather than computed
value as the resolved value. This is no longer required.

This allows us to unmark z-index as requiring a layout node to get
resolved value.
2026-03-26 12:30:01 +01:00
Callum Law
124b142ae4 LibWeb: Simplify z-index handling in ComputedProperites
We now implement clamping and up-on-half rounding for all <integer>
values generically so this is no longer needed
2026-03-26 12:30:01 +01:00
Callum Law
b86377b9dc LibWeb: Clamp CSS <integer> value to i32 at parse time
This matches the behavior of other browsers. Previously we implemented
this at used-value time for z-index specifically.
2026-03-26 12:30:01 +01:00
Callum Law
0ab06e119e LibWeb: Use i32 max for clamping 'infinite' calculated integers
This required us to change our range values from `float`s to `double`s
since `float` can't exactly represent i32 max
2026-03-26 12:30:01 +01:00
Callum Law
0e8956ee30 LibWeb: Round up on half when rounding to nearest integer in CSS 2026-03-26 12:30:01 +01:00
Callum Law
cdc264a62e LibWeb: Validate nested contents when parsing declaration value
Previously we automatically assumed that contents inside functions and
blocks were valid, now we actually check them.
2026-03-26 01:11:39 +00:00
Callum Law
93bd066639 LibWeb: Ensure <declaration-value>? descriptors are valid
Currently this only applies to the `@property` `syntax` descriptor.

As with custom properties in the previous commit we assumed that any
consumed values were valid but that's not the case.
2026-03-26 01:11:39 +00:00
Callum Law
46bebf44c5 LibWeb: Ensure custom property definition is valid <declaration-value>?
Previously we assumed that consumed declarations were always valid but
that isn't the case
2026-03-26 01:11:39 +00:00
Callum Law
6afe2ff27b LibWeb: Limit <ident> to <custom-ident> in @property/syntax
The definition of syntax in the "css-properties-values-api" spec (which
is used for the `@property/syntax` descriptor) is slightly different
from the definition of `<syntax>` in the "css-values" spec (which we
implement) in that it limits literal idents to exclusively
`<custom-ident>`s (i.e. not CSS-wide keywords or "default").

`<custom-ident>`s are also case-sensitive so that behavior is
implemented for syntax matching here as well
2026-03-26 01:11:39 +00:00
Callum Law
cfc2e64b4b LibWeb: Add is_valid_custom_ident function
We repeat this pattern in a couple of places so let's add a single
helper method
2026-03-26 01:11:39 +00:00