Instead of storing these as individual `background-foo` properties, we
combine them together into layers, since that is how they will be
painted. It also makes it more convenient to pass them around.
This now outputs valid CSS representing the background, instead of
confusing debug info.
We can't guarantee that all the longhands have the same number of
values, since while that's always the case when parsing, we also create
BackgroundStyleValues when producing the resolved style, which just
combines the longhands together.
Like the `background-foo` longhand properties (except
`background-color`), `background` allows multiple layers to be defined,
separated by commas. A layer does not necessarily contain something to
actually draw!
This parses as a `BackgroundStyleValue`, holding a `StyleValueList` for
each property. This is mostly to make expansion into longhands simpler -
if we had a list of `BackgroundStyleValue`s instead, one per layer, then
we would have to break it up per-property anyway when computing styles.
We now can parse lists of values for these properties:
- `background-attachment`
- `background-clip`
- `background-image`
- `background-origin`
- `background-position`
- `background-repeat`
- `background-size`
This uses two new Parser methods:
`parse_simple_comma_separated_value_list()` for the simple case when
each value is parsed from a single token; and
`parse_comma_separated_value_list()` which takes a lambda for when
parsing each value is more involved.
This also means that any unconsumed tokens at the end will make the
parsing fail as it should, where previously we just ignored them.
This isn't a complete conversion to ErrorOr<void>, but a good chunk.
The end goal here is to propagate buffer allocation failures to the
caller, and allow the use of TRY() with formatting functions.
It's a little verbose to repeat these in cases like the borders, but if
everything has an initial value, we can guarantee that
`property_initial_value()` will return something! :^)
- `align-items`: `normal` is the initial value in the CSS-ALIGN spec,
but `stretch` is in CSS-FLEXBOX. The FLEXBOX spec is the one we've
actually implemented elsewhere, and ALIGN adds new values with special
syntax, so it's not trivial to add it here.
- `border-spacing`: `0` is equivalent to `0px 0px` and we don't yet
parse the double-value syntax.
- `text-decoration-thickness`: Had the wrong value.
There's nothing really background-size-specific about this, but since
there is no `<size>` value type defined in the CSS spec at this time,
and background-size is the only user of it, I think this name makes more
sense. But I'm not 100% convinced.
...as opposed to storing StyleValues, which we have to later check are
IdentifierStyleValues, which store identifiers that we can convert to
Repeat values later. It's fewer allocations, and we can't end up with
invalid values by mistake. :^)
While right now this doesn't save much complexity, it will do once we
care about multiple background layers per node. Then, having a single
repeat value per layer will simplify things.
It also means we can remove the pseudo-property concept entirely! :^)
This is step 1 in removing the two `background-repeat-x/y`
pseudo-properties. Since adding the concept of compound StyleValues, we
don't need `background-repeat` to be split in two any more.
This is done a bit differently from other properties: using a
TokenStream instead of just a Vector of ComponentValues. The reason for
this is, we can then use call the same function when parsing the
`background` shorthand. Otherwise, we would have to know in advance how
many values to pass down, which basically would involve duplicating the
`background-position` parsing code inside `background`.
The StyleValue is PositionStyleValue, since it represents a
`<position>`: https://www.w3.org/TR/css-values-4/#typedef-position
Unfortunately, background-position's parsing is a bit different from
`<position>`'s, (background-position allows 3-value syntax and
`<position>` doesn't) so we'll need to come back and write a different
parsing function for that later.
This allows supporting websites to use a light or dark theme to match
our desktop theme, without being limited to palette colors. This can be
overridden with the `WebContentServer::set_preferred_color_scheme()` IPC
call.
When using bitmap fonts, the computed *font* that we're using may be
smaller than the font-size property asked for. We can still honor the
font-size value in layout calculations.
This accounts for cases like:
```css
.foo {
color: blue ! important ;
}
```
That's rare now that minifying is so popular, but does appear on some
websites.
I've added spec comments to `consume_a_declaration()` while I was at it.
Noticed this while checking some MediaWiki-based sites. It's not
obvious, but the spec does allow this, by not mentioning it in this list
of places whitespace is forbidden:
https://www.w3.org/TR/selectors-4/#white-space
This works at the Token level, which is quick and easy but has
drawbacks: We don't know when something is a property name or a value,
or if something is part of a selector. But, this works for now.
The only reason it wasn't const before (and why we had a const_cast
hack) was to support ImageStyleValue's constructor taking it, which no
longer applies. `hack_count--;` :^)
This always felt awkward to me, and required a few other hacks to make
it work. Now, the request is only started when `load_bitmap()` is
called, which we do inside `NodeWithStyle::apply_style()`.