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.
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.
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.
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.
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.
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.
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.
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>`).
This simplifies handling (particularly around absolutization and
interpolation) and allows us to support calculated flex values (which
will come in a later commit).
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.
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)
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.
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.
We now ignore all animation properties from `css-animations-1` declared
within keyframes, except `animation-timing-function`, which is treated
specially.
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
`@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`.
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
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.
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.
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.