Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb/CSS: Interpret NaN as 0 when resolving alpha #2724

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ Optional<double> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
{
// <number> | <percentage> | none
auto normalized = [](double number) {
if (isnan(number))
number = 0;
return clamp(number, 0.0, 1.0);
};

Expand Down
2 changes: 2 additions & 0 deletions Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Color CSSRGB::to_color(Optional<Layout::NodeWithStyle const&>) const
auto resolve_rgb_to_u8 = [](CSSStyleValue const& style_value) -> Optional<u8> {
// <number> | <percentage> | none
auto normalized = [](double number) {
if (isnan(number))
number = 0;
return llround(clamp(number, 0.0, 255.0));
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Harness status: OK

Found 38 tests

34 Pass
4 Fail
Pass e.style['color'] = "hwb(120 30% 50%)" should set the property value
Pass e.style['color'] = "hwb(120 30% 50% / 0.5)" should set the property value
Pass e.style['color'] = "hwb(none none none)" should set the property value
Pass e.style['color'] = "hwb(0 0% 0%)" should set the property value
Pass e.style['color'] = "hwb(none none none / none)" should set the property value
Pass e.style['color'] = "hwb(0 0% 0% / 0)" should set the property value
Pass e.style['color'] = "hwb(120 none none)" should set the property value
Pass e.style['color'] = "hwb(120 0% 0%)" should set the property value
Pass e.style['color'] = "hwb(120 80% none)" should set the property value
Pass e.style['color'] = "hwb(120 80% 0%)" should set the property value
Pass e.style['color'] = "hwb(120 none 50%)" should set the property value
Pass e.style['color'] = "hwb(120 0% 50%)" should set the property value
Pass e.style['color'] = "hwb(120 30% 50% / none)" should set the property value
Pass e.style['color'] = "hwb(120 30% 50% / 0)" should set the property value
Pass e.style['color'] = "hwb(none 100% 50% / none)" should set the property value
Pass e.style['color'] = "hwb(0 100% 50% / 0)" should set the property value
Pass e.style['color'] = "hwb(120 30 50)" should set the property value
Pass e.style['color'] = "hwb(120 30 50 / 0.5)" should set the property value
Pass e.style['color'] = "hwb(120 30% 50)" should set the property value
Pass e.style['color'] = "hwb(120 30% 50 / 0.5)" should set the property value
Pass e.style['color'] = "hwb(120 30 50%)" should set the property value
Pass e.style['color'] = "hwb(120 30 50% / 0.5)" should set the property value
Pass e.style['color'] = "hwb(120 none 50)" should set the property value
Pass e.style['color'] = "hwb(120 none 50 / 0.5)" should set the property value
Pass e.style['color'] = "hwb(120 30 none)" should set the property value
Pass e.style['color'] = "hwb(120 30 none / 0.5)" should set the property value
Pass e.style['color'] = "hwb(120 30 50 / none)" should set the property value
Pass e.style['color'] = "hwb(320deg 30% 40%)" should set the property value
Pass e.style['color'] = "hwb(calc(infinity) 20% 10%)" should set the property value
Pass e.style['color'] = "hwb(calc(-infinity) 20% 10%)" should set the property value
Pass e.style['color'] = "hwb(calc(0 / 0) 20% 10%)" should set the property value
Pass e.style['color'] = "hwb(90 20% 10% / calc(infinity))" should set the property value
Pass e.style['color'] = "hwb(90 20% 10% / calc(-infinity))" should set the property value
Pass e.style['color'] = "hwb(90 20% 10% / calc(0 / 0))" should set the property value
Fail e.style['color'] = "hwb(calc(110deg + (sign(1em - 10px) * 10deg)) 30% 50% / 50%)" should set the property value
Fail e.style['color'] = "hwb(calc(110 + (sign(1em - 10px) * 10)) 30 50 / 0.5)" should set the property value
Fail e.style['color'] = "hwb(120deg 30% 50% / calc(50% + (sign(1em - 10px) * 10%)))" should set the property value
Fail e.style['color'] = "hwb(120 30 50 / calc(0.75 + (sign(1em - 10px) * 0.1)))" should set the property value
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Color Level 4: Parsing and serialization of colors using valid HWB notation</title>
<link rel="help" href="https://drafts.csswg.org/css-color-4/#the-hwb-notation">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#resolving-sRGB-values">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#serializing-sRGB-values">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
tests = [
["hwb(120 30% 50%)", "rgb(77, 128, 77)"],
["hwb(120 30% 50% / 0.5)", "rgba(77, 128, 77, 0.5)"],
["hwb(none none none)", "rgb(255, 0, 0)"],
["hwb(0 0% 0%)", "rgb(255, 0, 0)"],
["hwb(none none none / none)", "rgba(255, 0, 0, 0)"],
["hwb(0 0% 0% / 0)", "rgba(255, 0, 0, 0)"],
["hwb(120 none none)", "rgb(0, 255, 0)"],
["hwb(120 0% 0%)", "rgb(0, 255, 0)"],
["hwb(120 80% none)", "rgb(204, 255, 204)"],
["hwb(120 80% 0%)", "rgb(204, 255, 204)"],
["hwb(120 none 50%)", "rgb(0, 128, 0)"],
["hwb(120 0% 50%)", "rgb(0, 128, 0)"],
["hwb(120 30% 50% / none)", "rgba(77, 128, 77, 0)"],
["hwb(120 30% 50% / 0)", "rgba(77, 128, 77, 0)"],
["hwb(none 100% 50% / none)", "rgba(170, 170, 170, 0)"],
["hwb(0 100% 50% / 0)", "rgba(170, 170, 170, 0)"],

// Test with number components.
["hwb(120 30 50)", "rgb(77, 128, 77)"],
["hwb(120 30 50 / 0.5)", "rgba(77, 128, 77, 0.5)"],
["hwb(120 30% 50)", "rgb(77, 128, 77)"],
["hwb(120 30% 50 / 0.5)", "rgba(77, 128, 77, 0.5)"],
["hwb(120 30 50%)", "rgb(77, 128, 77)"],
["hwb(120 30 50% / 0.5)", "rgba(77, 128, 77, 0.5)"],
["hwb(120 none 50)", "rgb(0, 128, 0)"],
["hwb(120 none 50 / 0.5)", "rgba(0, 128, 0, 0.5)"],
["hwb(120 30 none)", "rgb(77, 255, 77)"],
["hwb(120 30 none / 0.5)", "rgba(77, 255, 77, 0.5)"],
["hwb(120 30 50 / none)", "rgba(77, 128, 77, 0)"],

// Test that rounding happens properly. hwb(320deg 30% 40%) in sRGB has a blue
// channel of exactly one-half.
// 0.5 * 255 = 127.5. This value should be rounded UP to 128, not down to 127.
["hwb(320deg 30% 40%)", "rgb(153, 77, 128)"],

// Test non-finite values. calc(infinity) goes to upper bound while calc(-infinity) and NaN go to the lower bound.
// See: https://github.com/w3c/csswg-drafts/issues/8629
["hwb(calc(infinity) 20% 10%)", "rgb(230, 51, 51)"], // hwb(360 20% 10%)
["hwb(calc(-infinity) 20% 10%)", "rgb(230, 51, 51)"], // hwb(0 20% 10%)
["hwb(calc(0 / 0) 20% 10%)", "rgb(230, 51, 51)"], // hwb(0 20% 10%)
["hwb(90 20% 10% / calc(infinity))", "rgb(140, 230, 51)"], // hwb(90 20% 10%)
["hwb(90 20% 10% / calc(-infinity))", "rgba(140, 230, 51, 0)"], // hwb(90 20% 10% / 0)
["hwb(90 20% 10% / calc(0 / 0))", "rgba(140, 230, 51, 0)"], // hwb(90 20% 10% / 0)

// calc(50% + (sign(1em - 10px) * 10%)) cannot be evaluated eagerly because font relative units are not yet known at parse time.
["hwb(calc(110deg + (sign(1em - 10px) * 10deg)) 30% 50% / 50%)", "hwb(calc(110deg + (10deg * sign(1em - 10px))) 30 50 / 0.5)"],
["hwb(calc(110 + (sign(1em - 10px) * 10)) 30 50 / 0.5)", "hwb(calc(110 + (10 * sign(1em - 10px))) 30 50 / 0.5)"],
["hwb(120deg 30% 50% / calc(50% + (sign(1em - 10px) * 10%)))", "hwb(120 30 50 / calc(50% + (10% * sign(1em - 10px))))"],
["hwb(120 30 50 / calc(0.75 + (sign(1em - 10px) * 0.1)))", "hwb(120 30 50 / calc(0.75 + (0.1 * sign(1em - 10px))))"],
];

for (const test of tests) {
test_valid_value("color", test[0], test[1]);
}

</script>
</body>
</html>
Loading