As noted, this is hacky because the parser wasn't written to allow
parsing an individual component of a selector. (Fox example, the
convenient-sounding `parse_pseudo_simple_selector()` assumes the first
colon has already been consumed...) So until that changes, this parses
the input as an entire selector-list, and then throws it away if it's
not a single pseudo-element selector.
It's only temporary though, I promise. 😅
(cherry picked from commit dae9c9be40e069989e0079745b7077dd9bab1c26)
They already used TokenStream for parsing the function parameters, but
this makes the `parse_foo_gradient()` functions themselves take a
TokenStream.
(cherry picked from commit 9de73bf89b061d6f168f7c1c3278e8f203959b3a)
These have a few rules that we didn't follow in most cases:
- CSS-wide keywords are not allowed. (inherit, initial, etc)
- `default` is not allowed.
- The above and any other disallowed identifiers must be tested
case-insensitively.
This introduces a `parse_custom_ident_value()` method, which takes a
list of disallowed identifier names, and handles the above rules.
(cherry picked from commit 6ae2b8c3d901d8a7255046a4517fddd8b0fa84c4)
Now that `Tokenizer::tokenize()` just returns a String, there are no
errors to propagate, and we can simplify the user code a bit.
(cherry picked from commit 59778d2b365476ecb5b50218dae4457493ee7bf7)
This is `counter(name, style?)` or `counters(name, link, style?)`. The
difference being, `counter()` matches only the nearest level (eg, "1"),
and `counters()` combines all the levels in the tree (eg, "3.4.1").
(cherry picked from commit 576a4314084e5c3b839006da00dddb16e58b3503)
These control the state of CSS counters.
Parsing code for `reversed(counter-name)` is implemented, but disabled
for now until we are able to resolve values for those.
(cherry picked from commit 017d6c3314d57d4e351764f328c1d25dbc9d033a)
The new method is Parser::parse_all_as_single_none_value(), which has a
few advantages:
1. There's no need for user code to manually create a StyleValue.
2. It consumes tokens so that doesn't have to be done manually.
3. Whitespace before or after the `none` is consumed correctly.
It does mean we create and then discard a `none` StyleValue in a couple
of places, namely parsing for `grid-*` properties. We may or may not
want to migrate those to returning the IdentifierStyleValue instead.
(cherry picked from commit ca10fb412947f6b6080326573418bfa8a3759c12)
This fixes an issue where :host(foo) would parse as if "foo" was the
on the right side of a descendant combinator.
Not testable yet, but will be in the next commit.
(cherry picked from commit 274c46a3c97e1f9969d18b7704ced4c39770e152)
We already have a FlyString of its value from parsing, and most users
also want a FlyString from it, so let's use that instead of converting
backwards and forwards.
The two users that did want a String are:
- Quotes, which make sense as FlyString instead, so I've converted that.
- Animation names, which should probably be FlyString too, but the code
currently also allows for other kinds of StyleValue, and I don't want
to dive into this right now to figure out if that's needed or not.
(cherry picked from commit 9fb44cb05777c6d7a8a1950258edadfcee6d4e09)
When loading a canned version of reddit.com, we end up parsing many many
shadow tree style sheets of roughly ~170 KiB text each.
None of them have '\r' or '\f', yet we spend 2-3 ms for each sheet just
looping over and reconstructing the text to see if we need to normalize
any newlines.
This patch makes the common case faster in two ways:
- We use TextCodec::Decoder::to_utf8() instead of process()
This way, we do a one-shot fast validation and conversion to UTF-8,
instead of using the generic code-point-at-a-time callback API.
- We scan for '\r' and '\f' before filtering, and if neither is present,
we simply use the unfiltered string.
With these changes, we now spend 0 ms in the filtering function for the
vast majority of style sheets I've seen so far.
(cherry picked from commit dba6216caa71796f25831908035cd9eb0fb54715)
This property is now correctly parsed.
Ladybird always uses overlay scrollbars so this property does nothing.
(cherry picked from commit 662317726549cd2dde4c7902b99f0b83397a3396)
The values aren't that complex, so it doesn't make much sense to have a
dedicated generator for them. Parsing them manually also allows us to
have much more control over the produced values, so as a result of this
change, EasingStyleValue becomes much more ergonomic.
(cherry picked from commit 667e313731f06fabf2a3f75893c3e8f15a4172be,
manually amended with the output of `git clang-format master`)
To make this straightforward, CSSKeyframesRule now uses a CSSRuleList
for internal storage.
(cherry picked from commit 7f2c833a39e150c7372299dcfe4d2d5590ae779f)
This lets us remove the color/dimension-parsing lambdas, since these
always forwarded to the same methods. This will make it easier to later
convert those methods to take a TokenStream.
As the parser was trying to directly unwrap an unresolved duration.
Currently we are outputting the wrong results for the serialized
duration, but this is still a step forwards.
Fixes a crash seen on: https://evaparish.com/blog/how-i-edit
Before this change, every CSS @supports rule would keep the containing
JS realm alive via a JS::Handle. This led to a GC reference cycle and
the whole realm leaked.
Since we only need the realm at construction time, we can take it as a
parameter instead, and stop storing it.