The spec is unclear about when exactly we should parse the style sheet.
Previously we'd do so before calling this algorithm, which was
error-prone, as seen by the bug fixed by the previous commit. The spec
for step 1 of "create a CSS style sheet" says:
1. Create a new CSS style sheet object and set its properties as
specified.
The definitions linked are UA-defined enough that it seems reasonable to
put the parsing here. That simplifies the user code a little and makes
it harder to mess up. It does raise the question of what to do if
parsing fails. I've matched our previous behaviour by just logging and
returning in that case.
While I'm modifying this method, I've also converted the bool params to
enums so they're a little clearer to read.
This fixes one source of flakiness on WPT (of many) where we wouldn't
recompute style after programmatically altering the contents of a style
sheet, but instead had to wait for something else to cause invalidation.
With this change we save a copy of of scroll state at the time of
recording a display list, instead of actual ScrollState pointer that
could be modifed by the main thread while display list is beings
rasterized on the rendering thread, which leads to a frame painted with
inconsistent scroll state.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/4288
See the linked spec issue for more details. The MediaList can be null
internally, and this was upsetting GCC as it meant our bindings code
was dereferencing a null pointer.
The regression in the "conditional-CSSGroupingRule" test is we now fail
the "inserting an `@import`" subtests differently and the subtests
aren't independent. Specifically, we don't yet implement the checks in
`CSSRuleList::insert_a_css_rule()` that reject certain rules from being
inserted. Previously we didn't insert the `@import` rule because we
failed to parse its relative URL. Now we parse it correctly, we end up
inserting it.
When `CSSRuleList::remove_a_css_rule()` is called, the removed rule has
its parent style sheet set to null. We shouldn't try to fetch an import
in this case.
It's possible to parse an `@import` rule that isn't attached to a
document. We only actually need it to have one when fetching the linked
style sheet, and that should only happen when the CSSImportRule is
attached to a document. So, we can just accept a null pointer when
constructing it.
We relied on that Document to get the Realm, so pass that in as a
separate parameter.
Our previous approach to `<url>` had a couple of issues:
- We'd complete the URL during parsing, when we should actually keep it
as the original string until it's used.
- There's nowhere for us to store `<url-modifier>`s on a `URL::URL`.
So, `CSS::URL` is a solution to this. It holds the original URL string,
and later will also hold any modifiers. This commit parses all `<url>`s
as `CSS::URL`, but then converts it into a `URL::URL`, so no user code
is changed. These will be modified in subsequent commits.
For `@namespace`, we were never supposed to complete the URL at all, so
this makes that more correct already. However, in practice all
`@namespace`s are absolute URLs already, so this should have no
observable effects.
To prepare for introducing a CSS::URL type, we need to qualify any use
of LibURL as `::URL::foo` instead of `URL::foo` so the compiler doesn't
get confused.
Many of these uses will be replaced, but I don't want to mix this in
with what will likely already be a large change.
This commit disallows "default" as a font-family name, when the name is
not quoted because unquoted names are treated as custom-idents, for
which the name "default" is not allowed.
Shorthand subproperties that match their initial values are now
excluded from serialization, by default.
Properties where this behavior is not desired, like `gap`, are
special-cased.
This also rearranges the code to follow the spec better: We create an
empty FontFace first and then fill it in, instead of creating it
fully-formed at the end.
Read the descriptor style values instead of producing a ParsedFontFace
first, as this means we know if a descriptor is actually present, or
has been defaulted to an initial value. This lets us correctly skip the
unicode-range if it was not explicitly set.
Firefox and Chromium both serialize using the "font-stretch" name,
(which is an alias for font-width) which follows the outdated cssom
spec, so I've done so too to match them.
The one thing that we still do differently in this test is that those
browsers check explicitly if `font-stretch` was set, and ignore when
`font-width` is.
I've also inlined the `serialize_a_local()` function to the one place
it's used. The style value to_string() method was already wrapping the
string in quotes, so calling serialize_a_string() on it was producing
`local("\this mess\"")`. It's clearer what's happening when the code
isn't split up.