diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index 1a76a738025..921d02a11b4 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -813,10 +813,6 @@ RefPtr CSSStyleProperties::style_value_for_computed_property(L return get_computed_value(property_id); } - case PropertyID::Opacity: { - auto opacity = layout_node.computed_values().opacity(); - return NumberStyleValue::create(opacity); - } case PropertyID::FillOpacity: { auto opacity = layout_node.computed_values().fill_opacity(); return NumberStyleValue::create(opacity); diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index b5e670f0faa..d14997ecc83 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -474,8 +474,7 @@ float ComputedProperties::resolve_opacity_value(StyleValue const& value) float ComputedProperties::opacity() const { - auto const& value = property(PropertyID::Opacity); - return resolve_opacity_value(value); + return property(PropertyID::Opacity).as_number().number(); } float ComputedProperties::fill_opacity() const diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index d71ad7f9a38..ec14e885a55 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -3283,6 +3283,8 @@ NonnullRefPtr StyleComputer::compute_value_of_property(Propert return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::BorderTopStyle), computation_context); case PropertyID::OutlineWidth: return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::OutlineStyle), computation_context); + case PropertyID::Opacity: + return compute_opacity(specified_value, computation_context); default: // FIXME: We should replace this with a VERIFY_NOT_REACHED() once all properties have their own handling. return specified_value; @@ -3314,6 +3316,30 @@ NonnullRefPtr StyleComputer::compute_border_or_outline_width(N return LengthStyleValue::create(Length::make_px(snap_a_length_as_a_border_width(computation_context.device_pixels_per_css_pixel, absolute_length))); } +NonnullRefPtr StyleComputer::compute_opacity(NonnullRefPtr const& specified_value, PropertyValueComputationContext const& computation_context) +{ + // https://drafts.csswg.org/css-color-4/#transparency + // specified number, clamped to the range [0,1] + + // + if (specified_value->is_number()) + return NumberStyleValue::create(clamp(specified_value->as_number().number(), 0, 1)); + + // 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)); + + // + if (specified_value->is_percentage()) + return NumberStyleValue::create(clamp(specified_value->as_percentage().percentage().as_fraction(), 0, 1)); + + // 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)); + + VERIFY_NOT_REACHED(); +} + void StyleComputer::compute_math_depth(ComputedProperties& style, Optional element) const { // https://w3c.github.io/mathml-core/#propdef-math-depth diff --git a/Libraries/LibWeb/CSS/StyleComputer.h b/Libraries/LibWeb/CSS/StyleComputer.h index 3ca296e4b8c..944c174be70 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Libraries/LibWeb/CSS/StyleComputer.h @@ -204,6 +204,7 @@ public: }; static NonnullRefPtr compute_value_of_property(PropertyID, NonnullRefPtr const& specified_value, Function(PropertyID)> const& get_property_specified_value, PropertyValueComputationContext const&); static NonnullRefPtr compute_border_or_outline_width(NonnullRefPtr const& specified_value, NonnullRefPtr const& style_specified_value, PropertyValueComputationContext const&); + static NonnullRefPtr compute_opacity(NonnullRefPtr const& specified_value, PropertyValueComputationContext const&); private: virtual void visit_edges(Visitor&) override; diff --git a/Libraries/LibWeb/CSS/StyleInvalidation.cpp b/Libraries/LibWeb/CSS/StyleInvalidation.cpp index f4bd5ef063a..2e2ce9e4e50 100644 --- a/Libraries/LibWeb/CSS/StyleInvalidation.cpp +++ b/Libraries/LibWeb/CSS/StyleInvalidation.cpp @@ -5,9 +5,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include +#include namespace Web::CSS { @@ -61,8 +61,8 @@ RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::Property // OPTIMIZATION: An element creates a stacking context when its opacity changes from 1 to less than 1 // and stops to create one when opacity returns to 1. So stacking context tree rebuild is // not required for opacity changes within the range below 1. - auto old_value_opacity = CSS::ComputedProperties::resolve_opacity_value(*old_value); - auto new_value_opacity = CSS::ComputedProperties::resolve_opacity_value(*new_value); + auto old_value_opacity = old_value->as_number().number(); + auto new_value_opacity = new_value->as_number().number(); if (old_value_opacity != new_value_opacity && (old_value_opacity == 1 || new_value_opacity == 1)) { invalidation.rebuild_stacking_context_tree = true; }