mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb: Properly clamp interpolated opacity values
Opacity values are unique in that the range which calculated and interpolated values should be clamped to [0,1] is different from the range of allowed values [-∞,∞]. This fixes 28 WPT tests that were regressed in #6112
This commit is contained in:
parent
517e3f5f1d
commit
43dd0f2dda
|
|
@ -3514,7 +3514,7 @@ NonnullRefPtr<StyleValue const> StyleComputer::compute_opacity(NonnullRefPtr<Sty
|
|||
|
||||
// NOTE: We also support calc()'d numbers
|
||||
if (specified_value->is_calculated() && specified_value->as_calculated().resolves_to_number())
|
||||
return NumberStyleValue::create(clamp(specified_value->as_calculated().resolve_number({ .length_resolution_context = computation_context.length_resolution_context }).value(), 0, 1));
|
||||
return NumberStyleValue::create(specified_value->as_calculated().resolve_number({ .length_resolution_context = computation_context.length_resolution_context }).value());
|
||||
|
||||
// <percentage>
|
||||
if (specified_value->is_percentage())
|
||||
|
|
@ -3522,7 +3522,7 @@ NonnullRefPtr<StyleValue const> StyleComputer::compute_opacity(NonnullRefPtr<Sty
|
|||
|
||||
// NOTE: We also support calc()'d percentages
|
||||
if (specified_value->is_calculated() && specified_value->as_calculated().resolves_to_percentage())
|
||||
return NumberStyleValue::create(clamp(specified_value->as_calculated().resolve_percentage({ .length_resolution_context = computation_context.length_resolution_context })->as_fraction(), 0, 1));
|
||||
return NumberStyleValue::create(specified_value->as_calculated().resolve_percentage({ .length_resolution_context = computation_context.length_resolution_context })->as_fraction());
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -891,35 +891,44 @@ AcceptedTypeRangeMap property_accepted_type_ranges(PropertyID property_id)
|
|||
|
||||
StringBuilder ranges_builder;
|
||||
|
||||
for (auto& type : valid_types.values()) {
|
||||
VERIFY(type.is_string());
|
||||
// Opacity values are unique in that the range which calculated and interpolated values should be clamped
|
||||
// to [0,1] is different from the range of allowed values [-∞,∞]. To handle this we set the allowed range
|
||||
// in Properties.json to [-∞,∞] but overwrite it to [0,1] here.
|
||||
// FIXME: This is confusing as property_accepts_{number,percentage}() has a different range from this
|
||||
// despite the names sounding similar.
|
||||
if (first_is_one_of(name, "opacity"sv, "fill-opacity"sv, "flood-opacity"sv, "stop-opacity"sv, "stroke-opacity"sv)) {
|
||||
ranges_builder.append("{ ValueType::Number, { 0, 1 } }, { ValueType::Percentage, { 0, 100 } }"sv);
|
||||
} else {
|
||||
for (auto& type : valid_types.values()) {
|
||||
VERIFY(type.is_string());
|
||||
|
||||
Vector<String> type_parts = MUST(type.as_string().split(' '));
|
||||
Vector<String> type_parts = MUST(type.as_string().split(' '));
|
||||
|
||||
if (type_parts.size() < 2)
|
||||
continue;
|
||||
if (type_parts.size() < 2)
|
||||
continue;
|
||||
|
||||
auto type_name = type_parts.first();
|
||||
auto type_name = type_parts.first();
|
||||
|
||||
if (type_name == "custom-ident")
|
||||
continue;
|
||||
if (type_name == "custom-ident")
|
||||
continue;
|
||||
|
||||
// Drop the brackets on the range e.g. "[-∞,∞]" -> "-∞,∞"
|
||||
auto type_range = MUST(type_parts.get(1)->substring_from_byte_offset(1, type_parts.get(1)->byte_count() - 2));
|
||||
// Drop the brackets on the range e.g. "[-∞,∞]" -> "-∞,∞"
|
||||
auto type_range = MUST(type_parts.get(1)->substring_from_byte_offset(1, type_parts.get(1)->byte_count() - 2));
|
||||
|
||||
auto limits = MUST(type_range.split(','));
|
||||
auto limits = MUST(type_range.split(','));
|
||||
|
||||
if (limits.size() != 2)
|
||||
VERIFY_NOT_REACHED();
|
||||
if (limits.size() != 2)
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
// FIXME: Use min and max values for i32 instead of float where applicable (e.g. for "integer")
|
||||
auto min = limits.get(0) == "-∞" ? "AK::NumericLimits<float>::lowest()"_string : *limits.get(0);
|
||||
auto max = limits.get(1) == "∞" ? "AK::NumericLimits<float>::max()"_string : *limits.get(1);
|
||||
// FIXME: Use min and max values for i32 instead of float where applicable (e.g. for "integer")
|
||||
auto min = limits.get(0) == "-∞" ? "AK::NumericLimits<float>::lowest()"_string : *limits.get(0);
|
||||
auto max = limits.get(1) == "∞" ? "AK::NumericLimits<float>::max()"_string : *limits.get(1);
|
||||
|
||||
if (!ranges_builder.is_empty())
|
||||
ranges_builder.appendff(", ");
|
||||
if (!ranges_builder.is_empty())
|
||||
ranges_builder.appendff(", ");
|
||||
|
||||
ranges_builder.appendff("{{ ValueType::{}, {{ {}, {} }} }}", title_casify(type_name), min, max);
|
||||
ranges_builder.appendff("{{ ValueType::{}, {{ {}, {} }} }}", title_casify(type_name), min, max);
|
||||
}
|
||||
}
|
||||
|
||||
property_generator.set("ranges", ranges_builder.to_string_without_validation());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 120 tests
|
||||
|
||||
120 Pass
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (-0.3) should be [0.07]
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (0) should be [0.1]
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (0.3) should be [0.13]
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (0.6) should be [0.16]
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions: property <opacity> from neutral to [0.2] at (1.5) should be [0.25]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (-0.3) should be [0.07]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (0) should be [0.1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (0.3) should be [0.13]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (0.6) should be [0.16]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from neutral to [0.2] at (1.5) should be [0.25]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (-0.3) should be [0.07]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (0) should be [0.1]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (0.3) should be [0.13]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (0.6) should be [0.16]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Animations: property <opacity> from neutral to [0.2] at (1.5) should be [0.25]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (-0.3) should be [0.07]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (0) should be [0.1]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (0.3) should be [0.13]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (0.6) should be [0.16]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (1) should be [0.2]
|
||||
Pass Web Animations: property <opacity> from neutral to [0.2] at (1.5) should be [0.25]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (0) should be [1]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions: property <opacity> from [initial] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (0) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [initial] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (0) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Animations: property <opacity> from [initial] to [0.2] at (1.5) should be [0]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (-0.3) should be [1]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (0) should be [1]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (0.3) should be [0.76]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (0.6) should be [0.52]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (1) should be [0.2]
|
||||
Pass Web Animations: property <opacity> from [initial] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (-0.3) should be [0.98]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (0) should be [0.8]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (0.3) should be [0.62]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (0.6) should be [0.44]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions: property <opacity> from [inherit] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (-0.3) should be [0.98]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (0) should be [0.8]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (0.3) should be [0.62]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (0.6) should be [0.44]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [inherit] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (-0.3) should be [0.98]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (0) should be [0.8]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (0.3) should be [0.62]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (0.6) should be [0.44]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Animations: property <opacity> from [inherit] to [0.2] at (1.5) should be [0]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (-0.3) should be [0.98]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (0) should be [0.8]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (0.3) should be [0.62]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (0.6) should be [0.44]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (1) should be [0.2]
|
||||
Pass Web Animations: property <opacity> from [inherit] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (0) should be [1]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions: property <opacity> from [unset] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (0) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [unset] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (-0.3) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (0) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (0.3) should be [0.76]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (0.6) should be [0.52]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (1) should be [0.2]
|
||||
Pass CSS Animations: property <opacity> from [unset] to [0.2] at (1.5) should be [0]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (-0.3) should be [1]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (0) should be [1]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (0.3) should be [0.76]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (0.6) should be [0.52]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (1) should be [0.2]
|
||||
Pass Web Animations: property <opacity> from [unset] to [0.2] at (1.5) should be [0]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (-0.3) should be [0]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (0) should be [0]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (0.3) should be [0.3]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (0.6) should be [0.6]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (1) should be [1]
|
||||
Pass CSS Transitions: property <opacity> from [0] to [1] at (1.5) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (-0.3) should be [0]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (0) should be [0]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (0.3) should be [0.3]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (0.6) should be [0.6]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (1) should be [1]
|
||||
Pass CSS Transitions with transition: all: property <opacity> from [0] to [1] at (1.5) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (-0.3) should be [0]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (0) should be [0]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (0.3) should be [0.3]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (0.6) should be [0.6]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (1) should be [1]
|
||||
Pass CSS Animations: property <opacity> from [0] to [1] at (1.5) should be [1]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (-0.3) should be [0]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (0) should be [0]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (0.3) should be [0.3]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (0.6) should be [0.6]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (1) should be [1]
|
||||
Pass Web Animations: property <opacity> from [0] to [1] at (1.5) should be [1]
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<title>opacity interpolation</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-color-3/#opacity">
|
||||
<meta name="assert" content="opacity supports animation">
|
||||
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/interpolation-testcommon.js"></script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.target {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: black;
|
||||
display: inline-block;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.expected {
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
test_interpolation({
|
||||
property: 'opacity',
|
||||
from: neutralKeyframe,
|
||||
to: '0.2',
|
||||
}, [
|
||||
{at: -0.3, expect: '0.07'},
|
||||
{at: 0, expect: '0.1'},
|
||||
{at: 0.3, expect: '0.13'},
|
||||
{at: 0.6, expect: '0.16'},
|
||||
{at: 1, expect: '0.2'},
|
||||
{at: 1.5, expect: '0.25'},
|
||||
]);
|
||||
|
||||
test_interpolation({
|
||||
property: 'opacity',
|
||||
from: 'initial',
|
||||
to: '0.2',
|
||||
}, [
|
||||
{at: -0.3, expect: '1'},
|
||||
{at: 0, expect: '1'},
|
||||
{at: 0.3, expect: '0.76'},
|
||||
{at: 0.6, expect: '0.52'},
|
||||
{at: 1, expect: '0.2'},
|
||||
{at: 1.5, expect: '0'},
|
||||
]);
|
||||
|
||||
test_interpolation({
|
||||
property: 'opacity',
|
||||
from: 'inherit',
|
||||
to: '0.2',
|
||||
}, [
|
||||
{at: -0.3, expect: '0.98'},
|
||||
{at: 0, expect: '0.8'},
|
||||
{at: 0.3, expect: '0.62'},
|
||||
{at: 0.6, expect: '0.44'},
|
||||
{at: 1, expect: '0.2'},
|
||||
{at: 1.5, expect: '0'},
|
||||
]);
|
||||
|
||||
test_interpolation({
|
||||
property: 'opacity',
|
||||
from: 'unset',
|
||||
to: '0.2',
|
||||
}, [
|
||||
{at: -0.3, expect: '1'},
|
||||
{at: 0, expect: '1'},
|
||||
{at: 0.3, expect: '0.76'},
|
||||
{at: 0.6, expect: '0.52'},
|
||||
{at: 1, expect: '0.2'},
|
||||
{at: 1.5, expect: '0'},
|
||||
]);
|
||||
|
||||
test_interpolation({
|
||||
property: 'opacity',
|
||||
from: '0',
|
||||
to: '1'
|
||||
}, [
|
||||
{at: -0.3, expect: '0'}, // CSS opacity is [0-1].
|
||||
{at: 0, expect: '0'},
|
||||
{at: 0.3, expect: '0.3'},
|
||||
{at: 0.6, expect: '0.6'},
|
||||
{at: 1, expect: '1'},
|
||||
{at: 1.5, expect: '1'}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
Loading…
Reference in New Issue
Block a user