The ifs below the switch no longer functioned, so let's move everything
into the switch cases. This also means we can replace the StringBuilder
usage with String::formatted().
Dimension tokens don't make use of the m_value string for anything else,
so we can sneak the unit string in there.
- Token goes from 72 to 64 bytes
- StyleComponentValueRule goes from 80 to 72 bytes
These three are all integers - we just repeatedly multiply them by 10
and then add a digit - so using an integer here is both faster and more
accurate. :^)
There's really no reason to use doubles here, except at the time I
wanted to use doubles everywhere in CSS. I now realize that is
excessive, so everything can be floats instead.
There was no real benefit to creating the SimpleSelector early and then
modifying it, and doing so made this code harder to follow than it
needs to be.
We want to return a view to a constant object, not a constant view,
which we can implicitly copy to get a mutable reference to the object.
Clang-Tidy helpfully pointed this out.
The spec says:
> <delim-token> has a value composed of a single code point.
So using StringView is a bit overkill.
This also allows us to use switch statements in the future.
This doesn't have parsing support for multiple languages in the same
selector. Support for language subcodes is not great either. But it
does do the basics.
ID selectors need to be serialized as identifiers in the spec, but other
hash-values do not. This was causing hex colors that start with a
number, like `#54a3ff`, to serialize as `#\35 4a3ff`, which is silly
and unnecessary.
Selector serialization is done elsewhere, so this case in Token is
probably also unnecessary, but there might be situations I haven't
thought of where serializing an ID does need to happen while it's still
a Token.
`static const` variables can be computed and initialized at run-time
during initialization or the first time a function is called. Change
them to `static constexpr` to ensure they are computed at
compile-time.
This allows some removal of `strlen` because the length of the
`StringView` can be used which is pre-computed at compile-time.
In Selectors level 4, `:nth-child()` and `:nth-last-child()` can both
optionally take a selector-list argument. This selector-list acts as a
filter, so that only elements matching the list are counted. For
example, this means that the following are equivalent:
```css
:nth-child(2n+1 of p) {}
p:nth-of-type(2n+1) {}
```
`<forgiving-selector-list>` and `<forgiving-relative-selector-list>` are
the same as regular selector-lists, except that an invalid selector
does not make the whole list invalid. The former is used by the `:is()`
pseudo-class.
For example:
```css
/* This entire selector-list is invalid */
.foo, .bar, !?invalid { }
/* This is valid, but the "!?invalid" selector is removed */
:is(.foo, .bar, !?invalid) { }
```
Also as part of this, I've removed the `parse_a_selector(TokenStream)`
and `parse_a_relative_selector(TokenStream)` methods as they don't add
anything useful.
This resolves the ambiguity between whether a single number is a number
or a ratio. :^)
Also removed the "no more tokens" checks from
deea129b8c - that logic was completely
wrong, since there are always tokens after a value in the `(123 < foo <
456)` syntax.
As noted, the Parser can't handle the `<number>` syntax for this - it
gets parsed instead by the `<number>` branch. We can't actually resolve
the ambiguity without making the Parser aware of what type each
media-feature is, but I will get to that soon. :^)
For now, we only understand `none`, `normal`, `<image>` and `<string>`.
The various other functions and identifiers can be added later.
We can *almost* use a StyleValueList for this, except it's divided into
two parts - the content, and the optional "alt text". So, I've added a
new StyleValue for it.
This is the only dimension type besides `<length>` that is used in any
media queries in levels 4 or 5 right now. Others can be included
if/when they're needed.
This means the units are defined in a single place instead of two.
Also removed the verify that we didn't produce a bogus % dimension token
in the Tokenizer, since this has never happened and the parser is not a
tokenizer test suite. :^)