mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-23 01:38:56 +00:00
LibWeb: Initial work to store ComputedProperties in computed form
`StyleValue`s stored within `ComputedProperties` should be in their computed forms, this is for various reasons including: - Inheritance should be of computed values - Animations should work on computed values - Triggering transitions should work on computed values Currently we store `StyleValue`s in an absolutized version of the specified value - this is equivalent to the computed form in many cases which is why this hasn't been causing significant issues but there are some cases - such as `border-*-width` keywords where this is not the case. No functionality change as we are yet to implement any properties
This commit is contained in:
parent
2585f2da0d
commit
f9e5332d16
Notes:
github-actions[bot]
2025-08-28 08:31:40 +00:00
Author: https://github.com/Calme1709
Commit: f9e5332d16
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6007
Reviewed-by: https://github.com/AtkinsSJ ✅
3 changed files with 43 additions and 10 deletions
|
@ -1098,7 +1098,7 @@ void StyleComputer::collect_animation_into(DOM::Element& element, Optional<CSS::
|
||||||
};
|
};
|
||||||
|
|
||||||
compute_font(computed_properties, &element, pseudo_element);
|
compute_font(computed_properties, &element, pseudo_element);
|
||||||
absolutize_values(computed_properties);
|
compute_property_values(computed_properties);
|
||||||
Length::FontMetrics font_metrics {
|
Length::FontMetrics font_metrics {
|
||||||
computed_properties.font_size(),
|
computed_properties.font_size(),
|
||||||
computed_properties.first_available_computed_font().pixel_metrics()
|
computed_properties.first_available_computed_font().pixel_metrics()
|
||||||
|
@ -2149,7 +2149,7 @@ Gfx::Font const& StyleComputer::initial_font() const
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleComputer::absolutize_values(ComputedProperties& style) const
|
void StyleComputer::compute_property_values(ComputedProperties& style) const
|
||||||
{
|
{
|
||||||
Length::FontMetrics font_metrics {
|
Length::FontMetrics font_metrics {
|
||||||
style.font_size(),
|
style.font_size(),
|
||||||
|
@ -2169,9 +2169,26 @@ void StyleComputer::absolutize_values(ComputedProperties& style) const
|
||||||
style.set_property(PropertyID::LineHeight, computed_value, is_inherited);
|
style.set_property(PropertyID::LineHeight, computed_value, is_inherited);
|
||||||
}
|
}
|
||||||
|
|
||||||
style.for_each_property([&](PropertyID property_id, auto& value) {
|
PropertyValueComputationContext computation_context {
|
||||||
auto const& absolutized_value = value.absolutized(viewport_rect(), font_metrics, m_root_element_font_metrics);
|
.length_resolution_context = {
|
||||||
auto is_inherited = style.is_property_inherited(property_id) ? ComputedProperties::Inherited::Yes : ComputedProperties::Inherited::No;
|
.viewport_rect = viewport_rect(),
|
||||||
|
.font_metrics = font_metrics,
|
||||||
|
.root_font_metrics = m_root_element_font_metrics,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: This doesn't necessarily return the specified value if we have already computed this property but that
|
||||||
|
// doesn't matter as a computed value is always valid as a specified value.
|
||||||
|
Function<NonnullRefPtr<StyleValue const>(PropertyID)> const get_property_specified_value = [&](auto property_id) -> NonnullRefPtr<StyleValue const> {
|
||||||
|
return style.property(property_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
style.for_each_property([&](PropertyID property_id, auto& specified_value) {
|
||||||
|
auto const& computed_value = compute_value_of_property(property_id, specified_value, get_property_specified_value, computation_context);
|
||||||
|
|
||||||
|
// FIXME: Any required absolutization should be done within compute_value_of_property() - we can remove this once that's implemented.
|
||||||
|
auto const& absolutized_value = computed_value->absolutized(viewport_rect(), font_metrics, m_root_element_font_metrics);
|
||||||
|
auto const& is_inherited = style.is_property_inherited(property_id) ? ComputedProperties::Inherited::Yes : ComputedProperties::Inherited::No;
|
||||||
|
|
||||||
style.set_property(property_id, absolutized_value, is_inherited);
|
style.set_property(property_id, absolutized_value, is_inherited);
|
||||||
});
|
});
|
||||||
|
@ -2393,7 +2410,7 @@ GC::Ref<ComputedProperties> StyleComputer::create_document_style() const
|
||||||
|
|
||||||
compute_math_depth(style, {});
|
compute_math_depth(style, {});
|
||||||
compute_font(style, nullptr, {});
|
compute_font(style, nullptr, {});
|
||||||
absolutize_values(style);
|
compute_property_values(style);
|
||||||
style->set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().width())));
|
style->set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().width())));
|
||||||
style->set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().height())));
|
style->set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().height())));
|
||||||
style->set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Block)));
|
style->set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Block)));
|
||||||
|
@ -2702,8 +2719,8 @@ GC::Ref<ComputedProperties> StyleComputer::compute_properties(DOM::Element& elem
|
||||||
// 3. Compute the font, since that may be needed for font-relative CSS units
|
// 3. Compute the font, since that may be needed for font-relative CSS units
|
||||||
compute_font(computed_style, &element, pseudo_element);
|
compute_font(computed_style, &element, pseudo_element);
|
||||||
|
|
||||||
// 4. Absolutize values, turning font/viewport relative lengths into absolute lengths
|
// 4. Convert properties into their computed forms
|
||||||
absolutize_values(computed_style);
|
compute_property_values(computed_style);
|
||||||
|
|
||||||
// 5. Run automatic box type transformations
|
// 5. Run automatic box type transformations
|
||||||
transform_box_type_if_needed(computed_style, element, pseudo_element);
|
transform_box_type_if_needed(computed_style, element, pseudo_element);
|
||||||
|
@ -3157,6 +3174,17 @@ void StyleComputer::compute_custom_properties(ComputedProperties&, DOM::Abstract
|
||||||
abstract_element.set_custom_properties(move(resolved_custom_properties));
|
abstract_element.set_custom_properties(move(resolved_custom_properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<StyleValue const> StyleComputer::compute_value_of_property(PropertyID property_id, NonnullRefPtr<StyleValue const> const& specified_value, Function<NonnullRefPtr<StyleValue const>(PropertyID)> const&, PropertyValueComputationContext const&)
|
||||||
|
{
|
||||||
|
switch (property_id) {
|
||||||
|
default:
|
||||||
|
// FIXME: We should replace this with a VERIFY_NOT_REACHED() once all properties have their own handling.
|
||||||
|
return specified_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
void StyleComputer::compute_math_depth(ComputedProperties& style, Optional<DOM::AbstractElement> element) const
|
void StyleComputer::compute_math_depth(ComputedProperties& style, Optional<DOM::AbstractElement> element) const
|
||||||
{
|
{
|
||||||
// https://w3c.github.io/mathml-core/#propdef-math-depth
|
// https://w3c.github.io/mathml-core/#propdef-math-depth
|
||||||
|
|
|
@ -189,13 +189,18 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] GC::Ref<ComputedProperties> compute_properties(DOM::Element&, Optional<PseudoElement>, CascadedProperties&) const;
|
[[nodiscard]] GC::Ref<ComputedProperties> compute_properties(DOM::Element&, Optional<PseudoElement>, CascadedProperties&) const;
|
||||||
|
|
||||||
void absolutize_values(ComputedProperties&) const;
|
void compute_property_values(ComputedProperties&) const;
|
||||||
void compute_font(ComputedProperties&, DOM::Element const*, Optional<CSS::PseudoElement>) const;
|
void compute_font(ComputedProperties&, DOM::Element const*, Optional<CSS::PseudoElement>) const;
|
||||||
|
|
||||||
[[nodiscard]] inline bool should_reject_with_ancestor_filter(Selector const&) const;
|
[[nodiscard]] inline bool should_reject_with_ancestor_filter(Selector const&) const;
|
||||||
|
|
||||||
static NonnullRefPtr<StyleValue const> compute_value_of_custom_property(DOM::AbstractElement, FlyString const& custom_property, Optional<Parser::GuardedSubstitutionContexts&> = {});
|
static NonnullRefPtr<StyleValue const> compute_value_of_custom_property(DOM::AbstractElement, FlyString const& custom_property, Optional<Parser::GuardedSubstitutionContexts&> = {});
|
||||||
|
|
||||||
|
struct PropertyValueComputationContext {
|
||||||
|
Length::ResolutionContext length_resolution_context;
|
||||||
|
};
|
||||||
|
static NonnullRefPtr<StyleValue const> compute_value_of_property(PropertyID, NonnullRefPtr<StyleValue const> const& specified_value, Function<NonnullRefPtr<StyleValue const>(PropertyID)> const& get_property_specified_value, PropertyValueComputationContext const&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
|
|
|
@ -835,7 +835,7 @@ CSS::RequiredInvalidationAfterStyleChange Element::recompute_inherited_style()
|
||||||
return invalidation;
|
return invalidation;
|
||||||
|
|
||||||
document().style_computer().compute_font(*computed_properties, this, {});
|
document().style_computer().compute_font(*computed_properties, this, {});
|
||||||
document().style_computer().absolutize_values(*computed_properties);
|
document().style_computer().compute_property_values(*computed_properties);
|
||||||
|
|
||||||
for (auto [property_id, old_value] : old_values_with_relative_units) {
|
for (auto [property_id, old_value] : old_values_with_relative_units) {
|
||||||
auto const& new_value = computed_properties->property(static_cast<CSS::PropertyID>(property_id));
|
auto const& new_value = computed_properties->property(static_cast<CSS::PropertyID>(property_id));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue