Commit graph

689 commits

Author SHA1 Message Date
Sam Atkins
5d965d6d37 LibWeb/CSS: Simplify parse_as_pseudo_element_selector()
Now that we have a method that parses a single pseudo-element selector,
use that. This actually fixes a bug too.
2026-04-18 08:56:25 +02:00
Sam Atkins
2b47098301 LibWeb/CSS: Un-deprecate TokenStream::peek_token()
This is sometimes the best tool for the job. To try and make it less of
a footgun that peek_token() is identical to next_token(), make the
offset required, and note the shared behaviour. Also move them
together, and make the internal code match.
2026-04-16 14:52:22 +01:00
Sam Atkins
1f8a8870c3 LibWeb/CSS: Replace trivial peek_token() users with next_token()
`next_token()` does the same thing as `peek_token()` or `peek_token(0)`,
but is more idiomatic.
2026-04-16 14:52:22 +01:00
Sam Atkins
f938829619 LibWeb/CSS: Remove a couple of deprecated TokenStream methods 2026-04-16 14:52:22 +01:00
Sam Atkins
e7e0a48144 LibWeb/CSS: Stop reconsuming tokens in an+b parsing
The main change is that we now wait to consume the token until we know
we want it, instead of consuming it and then later putting it back.

While I was here, I spec-commented some parts and updated the URL.
2026-04-16 14:52:22 +01:00
Sam Atkins
d7c2524311 LibWeb: Stop reconsuming tokens to parse shorthands
Reconsuming the current token relies on parse_css_value_for_properties()
only consuming a single token, which may be true now but isn't safe to
assume. Wrapping that in a Transaction and reverting it if we need to
run manual parsing, is a much safer pattern.

Ideally we'll get parse_css_value_for_properties() to run the
per-property bespoke parsing code eventually.
2026-04-16 14:52:22 +01:00
Sam Atkins
b661c17117 LibWeb/CSS: Stop reconsuming tokens in parse_simple_selector()
No behaviour change, just a refactor to stop using a deprecated API.
2026-04-16 14:52:22 +01:00
Sam Atkins
7eabbfaa4b LibWeb/CSS: Use Transaction for checking tokens' substitution presence
Equivalent to using mark() and restore_a_mark() from before, except it
runs even if we return a SyntaxError.

Also removes the deprecated reconsume_current_input_token() call - this
never actually did anything useful anyway.
2026-04-16 14:52:22 +01:00
Sam Atkins
1239ebad29 LibWeb/CSS: Use transaction for attribute selector match-type parsing
No behaviour change, just a refactor to stop using a deprecated API -
reconsuming tokens.
2026-04-16 14:52:22 +01:00
Sam Atkins
3681452386 LibWeb/CSS: Stop reconsuming tokens in convert_to_keyframes_rule()
No behaviour change, just a refactor to stop using a deprecated API.
2026-04-16 14:52:22 +01:00
Sam Atkins
3342d880e8 LibWeb/CSS: Use a transaction for simple comma-separated list parsing
No behaviour change, just a refactor to stop using a deprecated API.
2026-04-16 14:52:22 +01:00
Sam Atkins
08dbbf24c2 LibWeb/CSS: Tokenize custom property values when substituting var()
Co-authored-by: Shannon Booth <shannon@serenityos.org>
2026-04-15 16:42:15 +02:00
Sam Atkins
5385d90e3c LibWeb/CSS: Output more details in Token::to_debug_string()
Include all the relevant fields for the type of Token, so that the
upcoming Tokenizer tests can verify that the produced Tokens are
correct.
2026-04-15 10:23:09 +01:00
Sam Atkins
d54305eb06 LibWeb/CSS: Ensure at-keyword name is consumed before input_since()
This relied on input_since() being called after
consume_an_ident_sequence(), which is not at all guaranteed. GCC
evidently evaluates the arguments in the opposite order.

This caused AtKeyword tokens to have their original source text be `@`
instead of the full `@whatever`, which apparently has no consequences
in our current code, but does mess up the debug output introduced in
the following commit.
2026-04-15 10:23:09 +01:00
Callum Law
76f0416b75 LibWeb: Resolve keywords in basic shape position at compute time
Previously we resolved these at parse time since that's what WPT
expected, but WPT was updated in web-platform-tests/wpt#59022 and
web-platform-tests/wpt#59176
2026-04-15 08:04:02 +02:00
Callum Law
1e36ccad0d LibWeb: Remove unused PercentageOr classes
These are only used at used value time (since we store as `StyleValue`s
before) by which time we resolve all percentages except for layout
relative length percentages.
2026-04-13 19:24:43 +02:00
Callum Law
d25f86da66 LibWeb: Remove unused CSS::Parser::Dimension 2026-04-13 19:24:43 +02: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
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
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
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
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
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
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
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
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
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
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
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
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
3aa71034de LibWeb: Support calc() within clip: rect() 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
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
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
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
Callum Law
c7b402eff5 LibWeb: Parse @function rules 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