For us, that's KeywordStyleValue and CustomIdentStyleValue.
CustomIdentStyleValue now has a .cpp file to reduce the number of
includes in its header file.
When serializing the "style" attribute, we were incorrectly assuming
that some of the grid-related CSS properties would never contain var()
substitution functions.
With this fixed, we can now book appointments on https://cal.com/ :^)
When no better reification form is available, we produce an opaque
CSSStyleValue with a serialized value. For starters, this will be the
only way to reify, and then we'll add others later.
We now clamp the values returned from calc into the allowed range (where
we know it) and censor any `NaN`s to `0` both when we resolve and when
we serialize.
Gains us 76 WPT passes.
Returning this struct will allow us to modify the underlying value of
the `CalculationResult` without requiring us to go through the process
of constructing a whole new `CalculationResult` to return.
This currently only applies to property-level calculation contexts, more
work to be done to generate accepted ranges for other calculation
contexts (e.g. within transformation functions, color functions, etc)
CSSUnitValue is a typed-om type which we will implement separately in
the future. However, it still seems useful to give our dimension values
a base class. (Maybe they could be templated in the future?) So instead
of deleting it entirely, rename it to DimensionStyleValue and make its
API match our style better.
This reverts 0e3487b9ab.
Back when I made that change, I thought we could make our StyleValue
classes match the typed-om definitions directly. However, they have
different requirements. Typed-om types need to be mutable and GCed,
whereas StyleValues are immutable and ideally wouldn't require a JS VM.
While I was already making such a cataclysmic change, I've moved it into
the StyleValues directory, because it *not* being there has bothered me
for a long time. 😅
- Omit calcs that are resolved to `0px` from the serialized value
- Allow CSV to be the 'Z' component in interpolated value.
- Allow calcs with mixed percentages in the first two arguments.
To achieve the third item above the concept of a "special" value parsing
context has been added - this will also be useful for instance for
different arguments of color functions having different contexts.
Gains us 23 WPT tests
These will be used for the mask-repeat property as well in an upcoming
commit, hence the more generic names. Also, this more closely matches
the names used in the spec.
Previously we were converting lengths to CSSPixels values when we didn't
need to, this had a couple of effects in that:
- We rounded to CSSPixel resolution prematurely (sometimes giving
incorrect results)
- We converted NaN to 0 when we shouldn't have.
We now avoid prematurely converting lengths to CSSPixels values in two
places:
- `CalculationResult::from_value`
- `CalculatedStyleValue::resolve_length_deprecated` (the new method
already avoided rounding).
Gains us 16 WPT tests.
Without this, any relative url()s in the `content` property don't know
what style sheet they are in, which makes them load relative to the
document instead.
Using a generic context argument will allow us to resolve colors in
places where we have all the required information but not in the form of
a layout node as was expected previously.
PaintContext dates back to a time when display lists didn't exist and it
truly represented "paint context". Renaming it to better align with its
current role.
This parses `anchor-size(..)` functions in CSS, but does not yet result
in a useful `Size`: we need style & layout interleaving similar to
container queries for this, since the resulting value depends on layout
results.
Not supported yet: `anchor-size()` appearing inside a `calc()` node.
Adds 4280 WPT subtest passes in `css/css-anchor-position`.
Before this change, whenever element's attributes changed, we would add
a flag to "pending invalidation", indicating that all descendants whose
style uses CSS custom properties needed to be recomputed. This resulted
in severe overinvalidation, because we would run invalidation regardless
of whether any custom property on affected element actually changed.
This change takes another approach, and now we decide whether
descendant's style needs to be recomputed based on whether ancestor's
style recomputation results in a change of custom properties, though
this approach adds a little overhead to style computation as now we have
to compare old vs new hashmap of custom properties.
This brings substantial improvement on discord and x.com where, before
this change, advantage of using invalidation sets was lost and we had
to recompute all descendants, because almost all of them use custom
properties.
Compare `Vector<Parser::ComponentValue>` directly instead of
serializing them into strings first.
This is required for the upcoming changes where we would compare
previous and new sets of custom properties to figure out whether we need
to invalidate descendant elements. Without this change `equals()` would
show up being hot in profiles.
This patch expands our generated content support beyond single strings
to lists of strings and/or images.
Pseudo-elements like ::before and ::after can now use content:url(...)
to insert anonymous image boxes into the layout tree.
This is heavily used in Google Docs for UI elements.
Having a setter for `device_pixels_per_css_pixel` was confusing because
display lists are immutable, so it doesn't make sense to override this
value after the display list has been created.
6507d23 introduced a bug when snapshot for iframe is saved in
`PaintNestedDisplayList` and, since display lists are immutable, it's
not possible to update before the next repaint.
This change fixes the issue by moving `ScrollStateSnapshot` for
nested display lists from `PaintNestedDisplayList` to
`HashMap<NonnullRefPtr<DisplayList>, ScrollStateSnapshot>` that is
placed into pending rendering task, making it possible to update
snapshots for all display lists before the next repaint.
This change doesn't have a test because it's really hard to make a ref
test that will specifically check scenario when scroll offset of an
iframe is advanced after display list is cached. We already have
`Tests/LibWeb/Ref/input/scroll-iframe.html` but unfortunately it did
not catch this bug.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/5486
At some point `hue-rotate` was changed to use `AngleOrCalculated`
rather than `Angle`, but `Angle` was still being used in a `visit`,
which otherwise defaulted to zero. This caused all `hue-rotate` angles
to serialize to zero.
UnresolvedStyleValue::create() has one user where we know if there are
any arbitrary substitution functions in the list of CVs, and two users
where we don't know and just hope there aren't any. I'm about to add
another user that also doesn't know, and so it seems worth just making
UnresolvedStyleValue::create() do that work instead.
We keep the parameter, now Optional<>, so that we save some redundant
work in that one place where we do already know.
A couple of arbitrary substitution functions require us to get or
produce some style value, and then substitute its ComponentValues into
the original ComponentValue list. So this commit gives CSSStyleValue a
tokenize() method that does so.
Apart from a couple of unusual cases like the guaranteed-invalid value,
style values can all be converted into ComponentValues by serializing
them as a string, and then parsing that as a list of component values.
That feels unnecessarily inefficient in most cases though, so I've
implemented faster overrides for a lot of the basic style value
classes, but left that serialize-and-reparse method as the fallback.
`CSSColorValue`s which have unresolved `calc` components should be able
to be resolved. Previously we would always resolve them but with
incorrect values.
This is useful as we will now be able to now whether we should serialize
colors in their normalized form or not.
Slight regression in that we now serialize (RGB, HSL and HWB) colors
with components that rely on compute-time information as an empty
string, but that will be fixed in the next commit.
These new methods are built on top of the spec's
`simplify_a_calculation_tree` algorithm where the old methods were
ad-hoc.
These methods are not used anywhere yet as callers will need to be
migrated over from the deprecated methods one-by-one to account for
differences in behaviour.
No functionality changes.
The existing resolve methods are not to spec and we are working to
replace them with new ones based on the `simplify_a_calculation_tree`
method.
These are marked as deprecated rather than replaced outright as work
will need to be done on the caller side to be made compatible with the
new methods, for instance the new methods can fail to resolve (e.g.
if we are missing required context), where the existing methods will
always resolve (albeit sometimes with an incorrect value).
No functionality changes.
When parsing values in `process_a_keyframes_argument` we don't expand
properties using `StyleComputer::for_each_property_expanding_shorthands`
unlike most other places - this means that if we parse a `border` we end
up with the `border`'s sub-properties (`border-width`, `border-style`,
`border-color`) still in their unexpanded forms (`CSSKeywordValue`,
`LengthStyleValue`, `StyleValueList`, etc) rather than
`ShorthandStyleValue`s which causes a crash when serializing the
`border` value in `KeyframeEffect::get_keyframes`.
The proper fix here is to parse `border`'s sub-properties directly to
`ShorthandStyleValue`s instead of relying on
`StyleComputer::for_each_property_expanding_shorthand` to do this
conversion for us but this may be a while off.
This commit also imports the previously crashing tests.
We were previously handling this ad-hoc via logic in
`get_property_internal` but this didn't cover all contexts (for
instance `CSSStyleProperties::serialized`.
Gains us 9 more WPT tests as we now cover properties which weren't
included in the previous ad-hoc approach.
Previously we would never get a valid `consistent_type` as we were
trying to make the node types consistent with the initial empty type
which isn't possible.
Gains us 7 WPT tests.
There are multiple things happening here which are interconnected:
- We now use AbstractElement to refer to the source of a counter, which
means we also need to pass that around to compute `content`.
- Give AbstractElement new helper methods that are needed by
CountersSet, so it doesn't have to care whether it's dealing with a
true Element or PseudoElement.
- The CountersSet algorithms now walk the layout tree instead of DOM
tree, so TreeBuilder needs to wait until the layout node exists
before it resolves counters for it.
- Resolve counters when creating a pseudo-element's layout node. We
awkwardly compute the `content` value up to twice: Once to figure out
what kind of node we need to make, and then if it's a string, we do
so again after counters are resolved so we can get the true value of
any `counter()` functions. This will need adjusting in the future but
it works for now.
The "longhands" array is populated in the code generator to avoid the
overhead of manually maintaining the list in Properties.json
There is one subtest that still fails in
'cssstyledeclaration-csstext-all-shorthand', this is related to
us not maintaining the relative order of CSS declarations for custom vs
non-custom properties.
For getComputedStyle(), we must return an absolute URL for image style
values. We currently return the raw parsed URL.
This fixes loading the marker icons on https://usermap.serenityos.org.
This exposed a few bugs which caused the following tests to behave
incorrectly:
- `tab-size-text-wrap.html`: This previously relied on a bug where we
incorrectly treated `white-space: pre` as allowing text wrapping. The
fix here is to implement the text-wrap CSS shorthand property.
- `execCommand-preserveWhitespace.html`: We don't correctly serialize
shorthand properties. This is covered by an existing FIXME in
`CSSStyleProperties::serialized()`
- `white-space-shorthand.html`: The last 5 subtests here fail as we
don't correctly handle shorthand properties in
`CSSStyleProperties::remove_property()`. This is covered by an
existing FIXME in said function.
This function attempts to resolve `lighter` and `bolder`, which we don't
want to do when serializing - that should happen in style computation.
This has the unexpected bonus of 37 more WPT passes!
This is very hacky and wrong, but it means there's one place to fix,
instead of one for UnresolvedStyleValue, and one for invalid
MediaFeatureValues which I'm about to implement.
Some dimensions would always serialize in a canonical unit, others never
did, and others we manually would do so in their StyleValue. This
commit moves all of that into the dimension types, which means for
example that Length can apply its special rounding.
Our local serialization test now produces the same output as other
browsers. :^)
ParsedFontFace and FontLoader now both keep track of which
CSSStyleSheet (if any) was the source of the font-face, so the URLs can
be completed correctly.
We now don't absolutize the URL during parsing, keeping it as a CSS::URL
object which we then pass to the "fetch an external image for a
stylesheet" algorithm. Our version of this algorithm is a bit ad-hoc,
in order to make use of SharedResourceRequest. To try and reduce
duplication, I've pulled all of fetch_a_style_resource() into a static
function, apart from the "actually do the fetch" step.
The CSS `fetch_foo()` functions resolve the URL relative to the
CSSStyleSheet if one is provided. So, style values that do so need to
know what CSSStyleSheet they are part of so that, for example, `url
(foo.png)` is loaded relative to the style sheet's URL instead of the
document's one.
That all works without this change because we currently absolutize URLs
during parsing, but we're in the process of stopping that.
This commit adds the infrastructure for telling style values what their
CSSStyleSheet is.
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
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.
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.
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.
Deleteing set_surface() makes DisplayListPlayer API a bit more intuitive
because now caller doesn't have to think whether it's necessary to
restore previous surface after execution, instead DisplayListPlayer
takes care of it by maintaining a stack of surfaces.
Having this hidden away in ImageStyleValue meant that
CSSStyleProperties (and anyone else who holds style values) had to know
exactly which types need visiting. This is a footgun waiting to happen,
so make this a virtual method on CSSStyleValue instead.
The `transform` property supports transform functions that sometimes
need their `calc(percentage)` values to be converted to a number instead
of a length. Currently this only applies to the `scale*` family of
functions, which are marked as such in `TransformFunctions.json`.
We were not consistently applying the `NumberPercentage` type to these
functions though, and in addition, any `NumberPercentage` value would
not consider calculated values.
Previously, when serializing an angle value, we would always convert it
to degrees. We now canonicalize the angle value only when serializing
its computed value.
Previously, when serializing a time value, we would always convert it
to seconds. We now canonicalize the time value only when serializing
its computed value.
This implementation also fixes an issue where the individual components
of the `border-radius` shorthand were always assumed to be of type
`BorderRadiusStyleValue`, which could lead to a crash when CSS-wide
keywords were used.
Instead of trying to manually determine which parts of a bitmap fall
within the box of the `<img>` element, just draw the whole bitmap and
let Skia clip the draw-area to the correct rectangle.
This fixes a bug where the entire bitmap was squashed into the rectangle
of the image box instead of being clipped.
With this change, image rendering is now correct enough to import some
of the WPT tests for object-fit and object-position. To get some good
coverage I have imported all tests for the `<img>` tag. I also wanted to
import a subset of the tests for the `<object>` tag, since those are
passing as well now. Unfortunately, they are flaky for unknown reasons.
This is the second attempt at this bugfix. The prior one was e055927ead
and broke image rendering whenever the page was scrolled. It has
subsequently been reverted in 16b14273d1. Hopefully this time it is not
horribly broken.
Instead of trying to manually determine which parts of a bitmap fall
within the box of the `<img>` element, just draw the whole bitmap and
let Skia clip the draw-area to the correct rectangle.
This fixes a bug where the entire bitmap was squashed into the rectangle
of the image box instead of being clipped.
With this change, image rendering is now correct enough to import some
of the WPT tests for object-fit and object-position. To get some good
coverage I have imported all tests for the `<img>` tag. I also wanted to
import a subset of the tests for the `<object>` tag, since those are
passing as well now. Unfortunately, they are flaky for unknown reasons.
A cursor is an image, with an optional x,y hotspot.
We know that a CursorStyleValue's bitmap never needs to change size, so
we create the ShareableBitmap once and then cache it, so that we don't
have to repeatedly create an FD for it or do the work of painting.
To avoid repainting that bitmap, we cache the values that were used to
create it - what currentColor is and its length resolution context -
and only repaint when those change.
None of the code here actually needs a NodeWithStyleAndBoxModelMetrics,
and we'll need to be able to resolve images from inside
NodeWithStyle::apply_style().
We previously only invalidated the cached color-stop data when the
painted area's size changed. However, multiple elements can use the
same gradient and be the same size, but have different parameters that
affect the gradient stop positions, for example if a stop has an em
position. This can also change for the same element over time.
The new cache instead uses these parameters as the cache key. So we
recompute the cache if lengths would resolve differently, or the area's
size is different.
The included test fails without this change.
The main users were the `dump()` functions, which now dump their
children instead, which is more correct anyway.
The others are for serializing numeric values, so
NumericCalculationNode's to_string() is renamed to value_to_string
() and used for those for convenience.
This gets us 37 new subtest passes in css/css-values, and 13 passes in
our other in-tree tests (and probably some random other ones!)
As noted in comments, a few parts of this algorithm have ad-hoc
behaviour to handle some issues in the spec.
Having multiple kinds of node that hold numeric values made things more
complicated than they needed to be, and we were already converting
ConstantCalculationNodes to NumericCalculationNodes in the first
simplification pass that happens at parse-time, so they didn't exist
after that.
As noted, the spec allows for other contexts to introduce their own
numeric keywords, which might be resolved later than parse-time. We'll
need a different mechanism to support those, but
ConstantCalculationNode could not have done so anyway.
Before this change, we only parsed fit-content as a standalone keyword,
but CSS-SIZING-3 added it as a function as well. I don't know of
anything else in CSS that is overloaded like this, so it ends up looking
a little awkward in the implementation.
Note that a lot of code had already been prepped for fit-content values
to have an argument, we just weren't parsing it.
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:
Painting/Command.h: 1030 -> 61
Painting/DisplayList.h: 1030 -> 60
Painting/DisplayListRecorder.h: 557 -> 59
We've long claimed to support this, but then silently ignored string
values, until 4cb2063577 which would
not-so-silently crash instead. (Oops)
So, actually pass the string value along and use it in the list marker.
As part of this, rename our `list-style-type` enum to
`counter-style-name-keyword`. This is an awkward name, attempting to be
spec-based. (The spec says `<counter-style>`, which is either a
`<counter-style-name>` or a function, and the `<counter-style-name>` is
a `<custom-ident>` that also has a few predefined values. So this is the
best I could come up with.)
Unfortunately only one WPT test for this passes - the others fail
because we produce a different layout when text is in `::before` than
when it's in `::marker`, and similar issues.
The Web::CSS::Parser's GradientParsing ignores color-stops if
it is only a single one. This change allows to have color-stops
with double positions against a single color.
Further, also allows for `linear-gradient(black)` and similar
other gradient functions
If a calculation was simplified down to a single numeric node, then most
of the time we can instead return a regular StyleValue, for example
`calc(2px + 3px)` would be simplified down to a `5px` LengthStyleValue.
This means that parse_calculated_value() can't return a
CalculatedStyleValue directly, and its callers all have to handle
non-calculated values as well as calculated ones.
This simplification is reflected in the new test results. Serialization
is not yet correct in all cases but we're closer than we were. :^)
Calc simplification eventually produces a single style-value as its
output. This extra context data will let us know whether a calculated
number should be treated as a `<number>` or an `<integer>`, so that for
example, `z-index: 12` and `z-index: calc(12)` both produce an
`IntegerStyleValue` containing 12.
The goal of this VERIFY was to ensure that we didn't mess up the logic
for calculating the correct type. However, it's now unable to do so
because it doesn't have access to the CalculationContext, which
determines what type percentages are. This makes it crash when running
the simplification algorithm. The benefits of this check are small, and
it meant doing extra work, so let's just remove it.
Calc simplification (which I'm working towards) involves repeatedly
deriving a new calculation tree from an existing one, and in many
cases, either the whole result or a portion of it will be identical to
that of the original. Using RefPtr lets us avoid making unnecessary
copies. As a bonus it will also make it easier to return either `this`
or a new node.
In future we could also cache commonly-used nodes, similar to how we do
so for 1px and 0px LengthStyleValues and various keywords.
To be properly compatible with calc(), the resolved() methods all need:
- A length resolution context
- To return an Optional, as the calculation might not be resolvable
A bonus of this is that we can get rid of the overloads of `resolved()`
as they now all behave the same way.
A downside is a scattering of `value_or()` wherever these are used. It
might be the case that all unresolvable calculations have been rejected
before this point, but I'm not confident, and so I'll leave it like
this for now.
Initially I added this to the existing CalculationContext, but in
reality, we have some data at parse-time and different data at
resolve-time, so it made more sense to keep those separate.
Instead of needing a variety of methods for resolving a Foo, depending
on whether we have a Layout::Node available, or a percentage basis, or
a length resolution context... put those in a
CalculationResolutionContext, and just pass that one thing to these
methods. This also removes the need for separate resolve_*_percentage()
methods, because we can just pass the percentage basis in to the regular
resolve_foo() method.
This also corrects the issue that *any* calculation may need to resolve
lengths, but we previously only passed a length resolution context to
specific types in some situations. Now, they can all have one available,
though it's up to the caller to provide it.
Same again, although rotation is more complicated: `rotate`
is "equivalent to" multiple different transform function depending on
its arguments. So we can parse as one of those instead of the full
`rotate3d()`, but then need to handle this when serializing.
The only ways this varies from the `scale()` function is with parsing
and serialization. Parsing stays separate, and serialization is done by
telling `TransformationStyleValue` which property it is, and overriding
its normal `to_string()` code for properties other than `transform`.
Various places in the spec allow for `<number> | <percentage>`, but this
is either/or, and they are not allowed to be combined like dimensions
and percentages are. (For example, `calc(12 + 50%)` is never valid.)
User code generally doesn't need to care about this distinction, but it
does now need to check if a calculation resolves to a number, or to a
percentage, instead of a single call.
The existing parse_number_percentage[_value]() methods have been kept
for simplicity, but updated to check for number/percentage separately.
Previously, `percentage_of` would be called on the previous value,
potentially changing its numeric type, yet this potential change
was never reflected as the old numeric type was always used. Now,
the numeric type will be re-calculated every time after the
percentage is resolved. As well, VERIFY checks have been placed to
uphold the requirements for the numeric types to match what the
actual values are.
Unfortunately, there is no explicit and step-by-step spec to perform
the serialization of `color()` declared values, so while being
spec-informed, this is quite ad-hoc.
Fixes 81 subtests in:
- css/css-color/parsing/color-valid-color-function.html
When we originally implemented calc(), the result of a calculation was
guaranteed to be a single CSS type like a Length or Angle. However, CSS
Values 4 now allows more complex type arithmetic, which is represented
by the CSSNumericType class. Using that directly makes us more correct,
and allows us to remove a large amount of now ad-hoc code.
Unfortunately this is a large commit but the changes it makes are
interconnected enough that doing one at a time causes test
regressions.
In no particular order:
- Update our "determine the type of a calculation" code to match the
newest spec, which sets percent hints in a couple more cases. (One of
these we're skipping for now, I think it fails because of the FIXMEs
in CSSNumericType::matches_foo().)
- Make the generated math-function-parsing code aware of the difference
between arguments being the same type, and being "consistent" types,
for each function. Otherwise those extra percent hints would cause
them to fail validation incorrectly.
- Use the CSSNumericType as the type for the CalculationResult.
- Calculate and assign each math function's type in its constructor,
instead of calculating it repeatedly on-demand.
The `CalculationNode::resolved_type()` method is now entirely unused and
has been removed.
This reverts commit 76daba3069.
We're going to need separate types for the JS-exposed style values, so
it doesn't make sense for us to match their names with our internal
types.
CSS filters work similarly to canvas filters, so it makes sense to have
Gfx::Filter that can be used by both libraries in an analogous way
as Gfx::Color.
Previously we created a tree of CalculationNodes with dummy
UnparsedCalculationNode children, and then swapped those with the real
children. This matched the spec closely but had the unfortunate
downside that CalculationNodes couldn't be immutable, and couldn't know
their properties at construct-time. UnparsedCalculationNode is also a
footgun, as if it gets left in the tree accidentally we would VERIFY().
So instead, let's parse the calc() tree into an intermediate format, and
then convert each node in that tree, depth-first, into its
corresponding CalculationNode. This means each CalculationNode knows
what its children are when it is constructed, and they never change.
Apart from deleting UnparsedCalculationNode, we can also get rid of the
for_each_child_node() method that was only used by this "replace the
children" code.
With all the plumbing in place, we can handle this quirk at the
serialization layer.
This allows us to remove the pass where StyleComputer would loop over
all computed values and replace any color values with new values
stripped of their original name strings.
Fixes the crash in css/css-color/parsing/color-valid-hwb.html.
The crash was probably introduced in 248e4bb5, as it was the first
commit to VERIFY that the value given to `Color::with_opacity` were in
the correct range. As the values in color-valid-hwb.html were resolved
as NaN, the check never passed.
The length resolution context might be needed even when resolving an
integer value, since it might contain a sign() function with length
values inside. This fixes a WPT subtest.
Regardless of what the shorthand property is, if all its longhands are
the same CSS-wide keyword such as "initial" or "inherit", then it's the
same as the shorthand being that value.
This gets us 2 WPT subtest passes.
When serializing an sRGB color value that originated from a named color,
it should return the color name converted to ASCII lowercase. This
requires storing the color name (if it has one).
This change also requires explicitly removing the color names when
computing style, because computed color values do not retain their name.
It also requires removing a caching optimization in create_from_color(),
because adding the name means that the cached value might be wrong.
This fixes some WPT subtests, and also required updating some of our own
tests.
See previous the commit description for more details about the floating
points operations.
The hwb test cases in `css-color-functions` are now rendered identically
to what firefox does (I haven't checked the others tests, but they
aren't affected by this commit).
Without this change the math in `CSSHWB::to_color()` is lacking some
precision to generate the correct value to hand to `Color::from_hsv()`.
More precisely, when converting `hwb(120 20 30)`, the HSV's value would
be calculated as `1 - .3`. However, it turns out that `1 - .3f != .7f`
and `1 - .3f` gives bad results down the road in `Color::from_hsv()`.
This example actually only requires `resolve_with_reference_value()` to
return a double. I changed the two others for symmetry.
This color space is often used as a reference in WPT tests, having
support for it makes us pass 15 new tests:
- css/css-color/rec2020-001.html
- css/css-color/rec2020-002.html
- css/css-color/rec2020-003.html
- css/css-color/rec2020-004.html
- css/css-color/rec2020-005.html
- css/css-color/predefined-011.html
- css/css-color/predefined-012.html
That makes us pass the following WPT tests:
- css/css-color/prophoto-rgb-001.html
- css/css-color/prophoto-rgb-002.html
- css/css-color/prophoto-rgb-003.html
- css/css-color/prophoto-rgb-004.html
- css/css-color/prophoto-rgb-005.html
- css/css-color/predefined-009.html
- css/css-color/predefined-010.html
This color space is often used as a reference in WPT tests, having
support for it makes us pass 15 new tests:
- css/css-color/display-p3-001.html
- css/css-color/display-p3-002.html
- css/css-color/display-p3-003.html
- css/css-color/display-p3-004.html
- css/css-color/display-p3-005.html
- css/css-color/display-p3-006.html
- css/css-color/lab-008.html
- css/css-color/lch-008.html
- css/css-color/oklab-008.html
- css/css-color/oklch-008.html
- css/css-color/predefined-005.html
- css/css-color/predefined-006.html
- css/css-color/xyz-005.html
- css/css-color/xyz-d50-005.html
- css/css-color/xyz-d65-005.html
This makes us pass the following WPT tests:
- css/css-color/a98rgb-001.html
- css/css-color/a98rgb-002.html
- css/css-color/a98rgb-003.html
- css/css-color/a98rgb-004.html
- css/css-color/predefined-007.html
- css/css-color/predefined-008.html
That makes us pass the following WPT tests:
- css/css-color/srgb-linear-001.html
- css/css-color/srgb-linear-002.html
- css/css-color/srgb-linear-003.html
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
This was a silly mistake on my end and percentages values are not
covered by device-independent color space, so I had to add support for
srgb to run a WPT test that made me realize the mistake.
This makes the following test pass:
- css/css-color/predefined-002.html
It makes the following WPT tests pass:
- css/css-color/predefined-001.html
- css/css-color/xyz-003.html
- css/css-color/xyz-d50-003.html
- css/css-color/xyz-d50-004.html
- css/css-color/xyz-d65-003.html
Also we now render the reference of color-mix-currentcolor-nested-for-
color-property.html properly. Which means that it's now different from
the actual test, that is still rendered incorrectly. In other word, the
false positive for this test is now turned into a true negative.