A couple of parts of this:
- Store the source text for Declarations of custom properties.
- Then save that in the UnresolvedStyleValue.
- Serialize UnresolvedStyleValue using the saved source when available -
that is, for custom properties but not for regular properties that
include var() or attr().
(cherry picked from commit bf3e6daedbc8fd0d8e03f5f0eafebf5bbe3abf03)
This requires a little bit of ad-hoc tracking of start/end Tokens for
Function and SimpleBlock.
(cherry picked from commit ea164124de271e511778326280347ebc28d948d8)
CSS Syntax 3 (https://drafts.csswg.org/css-syntax) has changed
significantly since we implemented it a couple of years ago. Just about
every parsing algorithm has been rewritten in terms of the new token
stream concept, and to support nested styles. As all of those
algorithms call into each other, this is an unfortunately chonky diff.
As part of this, the transitory types (Declaration, Function, AtRule...)
have been rewritten. That's both because we have new requirements of
what they should be and contain, and also because the spec asks us to
create and then gradually modify them in place, which is easier if they
are plain structs.
(cherry picked from commit e0be17e4fbf1870f35614d0cde8f63e72f78bd16;
amended to tweak test expectation due to serenity not yet having
LadybirdBrowser/ladybird#1603)
As part of this, we can now fill in the missing serialization steps.
The parsing is a stub for now, and will be filled out in a subsequent
commit.
(cherry picked from commit 77238730165641f2bab7409f5c9fbaf575cbd99f)
When the TokenStream code was originally written, there was no such
concept in the CSS Syntax spec. But since then, it's been officially
added, (https://drafts.csswg.org/css-syntax/#css-token-stream) and the
parsing algorithms are described in terms of it. This patch brings our
implementation in line with the spec. A few deprecated TokenStream
methods are left around until their users are also updated to match the
newer spec.
There are a few differences:
- They name things differently. The main confusing one is we had
`next_token()` which consumed a token and returned it, but the spec
has a `next_token()` which peeks the next token. The spec names are
honestly better than what I'd come up with. (`discard_a_token()` is a
nice addition too!)
- We used to store the index of the token that was just consumed, and
they instead store the index of the token that will be consumed next.
This is a perfect breeding ground for off-by-one errors, so I've
finally added a test suite for TokenStream itself.
- We use a transaction system for rewinding, and the spec uses a stack
of "marks", which can be manually rewound to. These should be able to
coexist as long as we stick with marks in the parser spec algorithms,
and stick with transactions elsewhere.
(cherry picked from commit b645e26e9b29437c0e248b5e43e3ec76aacf960d)
This matches the behavior of other browsers and fixes a WPT test.
(cherry picked from commit 902586a21de3ef8335e447053d82057c4c927d72;
amended expected output because serenity does not yet have
LadybirdBrowser/ladybird#1603)
Before this change we were serializing them in a bogus 8-digit hex color
format that isn't actually recognized by HTML.
This code will need more work when we start supporting color spaces
other than sRGB.
(cherry picked from commit 4590c081c2eb257232463ed660498a02f9bbe7b8;
amended expected output because serenity does not yet have
LadybirdBrowser/ladybird#1603)
With the introduction of the cascade layer, the 5th CSS-wide keyword,
`revert-layer`, has been added.
(cherry picked from commit bea7eec5183a816a100d190e409a622f429d7405)
In order to know whether `calc(2.5)` is a number or an integer, we have
to see what the property will accept. So, add that knowledge to
`Parser::expand_unresolved_values()`.
This makes `counter-increment: foo calc(2 * var(--n));` work correctly,
in a test I'm working on.
(cherry picked from commit 69d064697ad8bbf602eb2dc73fc532b0e1b16716)
This allows us to run the WPT tests under quirks/unitless-length/
without crashing, giving us over 4600 new passing subtests. :^)
(cherry picked from commit 5df6c6eecff678bf2a1fe8960149302d42015439)
(cherry picked from commit 55812aaed20ce8f7aeea233a47bcab73b60edd5e;
amended to include AK/QuickSort.h in Parser.cpp to fix a compile
error, and to update height: in getComputedStyle-print-all.txt)
Multiple font properties are either the `normal` keyword or some
non-keyword value, so this lets us avoid some boilerplate for those, at
the cost of the existing `none` users having marginally more verbose
code.
(cherry picked from commit 1a127c9d37e47b8793057ab68305bf399ad3106f)
This is a special form of `<string>` so doesn't need its own style value
type. It's used in a couple of font-related properties. For completeness
it's included in ValueType.
(cherry picked from commit cd13b30fb871ab521777ce164bff7696aa0fbfca)
CSS Fonts level 4 renames font-stretch to font-width, with font-stretch
being left as a legacy alias. Unfortunately the other specs have not yet
been updated, so both terms are used in different places.
(cherry picked from commit 4a67b28600437901e6d8a366c56a5ddd8665deb1)
This matches the name in the CSS Typed OM spec. There's quite a lot
still to do to make it match the spec behavior, but this is the first
step.
(cherry picked from commit 76daba3069de4c184c6b2317d0c89b50f81a8c00)
When a property is a "legacy name alias", any time it is used in CSS or
via the CSSOM its aliased name is used instead.
(See https://drafts.csswg.org/css-cascade-5/#legacy-name-alias)
This means we only care about the alias when parsing a string as a
PropertyID - and we can just return the PropertyID it is an alias for.
No need for a distinct PropertyID for it, and no need for LibWeb to
care about it at all.
Previously, we had a bunch of these properties, which misused our code
for "logical aliases", some of which I've discovered were not even
fully implemented. But with this change, all that code can go away, and
making a legacy alias is just a case of putting it in the JSON. This
also shrinks `StyleProperties` as it doesn't need to contain data for
these aliases, and removes a whole load of `-webkit-*` spam from the
style inspector.
(cherry picked from commit fdcece2e88b91b9ec6cf63c3466525fb77540316;
amended to:
* resolve a conflict on height: in getComputedStyle-print-all.txt
* run prettier on CSSGeneratedFiles.md)
According to https://www.w3.org/TR/css-grid-2/#placement-shorthands
when setting the 'grid-row' and 'grid-column' shorthand property to a
single <custom-ident> value, both 'grid-row-start'/'grid-column-start'
and 'grid-row-end'/'grid-column-end' should be set to that
<custom_ident>.
(cherry picked from commit 3e92ec80f3873bb81cbc8b0dc93bb3a6a145172c)
Instead of CSSColorValue holding a Gfx::Color, make it an abstract class
with subclasses for each different color function, to match the Typed-OM
spec. This means moving the color calculations from the parsing code to
the `to_color()` method on the style value.
This lets us have calc() inside a color function, instead of having to
fully resolve the color at parse time. The canvas fillStyle tests have
been updated to reflect this.
The other test change is Screenshot/css-color-functions.html: previously
we produced slightly different colors for an alpha of 0.5 and one of
50%, and this incorrect behavior was baked into the test. So now it's
more correct. :^)
(cherry picked from commit 3af6a69f1e13803c64466a9b24b7bd7d75d459df;
amended to:
* resolve a minor conflict in Parser.cpp due to upstream not having
https://github.com/LadybirdBrowser/ladybird/pull/385#issuecomment-2227130015
* rebaseline canvas-fillstyle-rgb.png since the diff didn't apply due to
us not having https://github.com/LadybirdBrowser/ladybird/pull/999
* remove css-color-functions-ref.png and instead update
css-color-functions-ref.html since that file is still a reftest due to us
not having https://github.com/LadybirdBrowser/ladybird/pull/736
Makes it much easier to see what actually changed.
)
"Parse a style value for <foo>", where we don't care if it's a literal
<foo> or a calculated one, is a really common thing that we previously
didn't have methods for.
A couple of methods we had have been extended to parse calc(), and the
others have been filled in.
The method for parsing the `flex` property's value is renamed
`parse_flex_shorthand_value()` as it conflicted.
(cherry picked from commit 27be8678c973da41379f47f07c8b0a9ff692bcd3)
For simplicity in user code, the `parse_foo_value()` methods should
parse anything that is a `<foo>`. In these cases, that means a
number/integer or calculation that resolves to them.
These uses in parse_css_value_for_properties() specifically only want a
literal IntegerStyleValue/NumberStyleValue, as calc-parsing is done
elsewhere. So, do the parsing for them locally.
(cherry picked from commit 79bd942dd1284112db24fd50203ff4f1fe6263b1)
Parsing a `Gfx::Color` no longer makes sense, as CSS has many ways of
defining a color, often in a dynamic way where the color value isn't
known until later. This is a small preparatory change before a much
larger color rewrite.
(cherry picked from commit 9bc71ab1fe6f5207b858bb3681f48871f3e18673)
Soon, CSSColorValue will be an abstract class, and we'll instead create
a CSSRGB, CSSHSL, or other specific color type from the Typed-OM spec.
However, it's still useful to have an easy "just give me a style value
for this color" method. So change the name to distinguish this from the
usual StyleValue::create() methods.
(cherry picked from commit 37ea4e3b5f33464a58ee1260fe3ce5fc0699e29a)
Colors can be specified in a way that `Gfx::Color` can't represent, such
as named system colors, `currentColor`, or functions involving `calc()`.
(cherry picked from commit 4e48afd9a7e32cc97fcec5086afc2d2967ec4360)
This matches the name in the CSS Typed OM spec.
https://drafts.css-houdini.org/css-typed-om-1/#csscolorvalue
This is not (yet) the same as the CSSColorValue, but one step at a time.
(cherry picked from commit 581d00293c184e47015a5d7e9c4230410567db45)
We previously had 4 single-instance StyleValues for these keywords.
CSS-Typed-OM expects them keywords to be exposed as CSSKeywordValue, so
it's simpler to treat them the same. The single-instance behaviour is
kept by having StyleValue::create() use a cached instance for each of
these.
(cherry picked from commit f518811f73539b5ca6631084001d8f517ea292be)
For a long time, we've used two terms, inconsistently:
- "Identifier" is a spec term, but refers to a sequence of alphanumeric
characters, which may or may not be a keyword. (Keywords are a
subset of all identifiers.)
- "ValueID" is entirely non-spec, and is directly called a "keyword" in
the CSS specs.
So to avoid confusion as much as possible, let's align with the spec
terminology. I've attempted to change variable names as well, but
obviously we use Keywords in a lot of places in LibWeb and so I may
have missed some.
One exception is that I've not renamed "valid-identifiers" in
Properties.json... I'd like to combine that and the "valid-types" array
together eventually, so there's no benefit to doing an extra rename
now.
(cherry picked from commit 6a74b0164423d63904cf5a5b594772b595f57600;
very minorly amended to fix conflict in GenerateCSSKeyword.cpp caused
by #22870, and in libweb_generators.cmake due to us not having
https://github.com/LadybirdBrowser/ladybird/pull/741)
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)