1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 01:58:12 +00:00

LibWeb: Parse aspect-ratio property

Parse it, store the result in the ComputedValues, and also expose it to
ResolvedCSSStyleDeclaration.
This commit is contained in:
Sam Atkins 2023-06-08 15:25:16 +01:00 committed by Andreas Kling
parent 5e3da93f1a
commit 6fd3b39bef
6 changed files with 102 additions and 0 deletions

View file

@ -15,6 +15,7 @@
#include <LibWeb/CSS/GridTrackSize.h> #include <LibWeb/CSS/GridTrackSize.h>
#include <LibWeb/CSS/LengthBox.h> #include <LibWeb/CSS/LengthBox.h>
#include <LibWeb/CSS/PercentageOr.h> #include <LibWeb/CSS/PercentageOr.h>
#include <LibWeb/CSS/Ratio.h>
#include <LibWeb/CSS/Size.h> #include <LibWeb/CSS/Size.h>
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h> #include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h> #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
@ -22,8 +23,14 @@
namespace Web::CSS { namespace Web::CSS {
struct AspectRatio {
bool use_natural_aspect_ratio_if_available;
Optional<Ratio> preferred_ratio;
};
class InitialValues { class InitialValues {
public: public:
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
static float font_size() { return 16; } static float font_size() { return 16; }
static int font_weight() { return 400; } static int font_weight() { return 400; }
static CSS::FontVariant font_variant() { return CSS::FontVariant::Normal; } static CSS::FontVariant font_variant() { return CSS::FontVariant::Normal; }
@ -211,6 +218,7 @@ inline Gfx::Painter::ScalingMode to_gfx_scaling_mode(CSS::ImageRendering css_val
class ComputedValues { class ComputedValues {
public: public:
AspectRatio aspect_ratio() const { return m_noninherited.aspect_ratio; }
CSS::Float float_() const { return m_noninherited.float_; } CSS::Float float_() const { return m_noninherited.float_; }
CSS::Clear clear() const { return m_noninherited.clear; } CSS::Clear clear() const { return m_noninherited.clear; }
CSS::Clip clip() const { return m_noninherited.clip; } CSS::Clip clip() const { return m_noninherited.clip; }
@ -344,6 +352,7 @@ protected:
} m_inherited; } m_inherited;
struct { struct {
AspectRatio aspect_ratio { InitialValues::aspect_ratio() };
CSS::Float float_ { InitialValues::float_() }; CSS::Float float_ { InitialValues::float_() };
CSS::Clear clear { InitialValues::clear() }; CSS::Clear clear { InitialValues::clear() };
CSS::Clip clip { InitialValues::clip() }; CSS::Clip clip { InitialValues::clip() };
@ -418,6 +427,7 @@ class ImmutableComputedValues final : public ComputedValues {
class MutableComputedValues final : public ComputedValues { class MutableComputedValues final : public ComputedValues {
public: public:
void set_aspect_ratio(AspectRatio aspect_ratio) { m_noninherited.aspect_ratio = aspect_ratio; }
void set_font_size(float font_size) { m_inherited.font_size = font_size; } void set_font_size(float font_size) { m_inherited.font_size = font_size; }
void set_font_weight(int font_weight) { m_inherited.font_weight = font_weight; } void set_font_weight(int font_weight) { m_inherited.font_weight = font_weight; }
void set_font_variant(CSS::FontVariant font_variant) { m_inherited.font_variant = font_variant; } void set_font_variant(CSS::FontVariant font_variant) { m_inherited.font_variant = font_variant; }

View file

@ -4457,6 +4457,51 @@ static void remove_property(Vector<PropertyID>& properties, PropertyID property_
properties.remove_first_matching([&](auto it) { return it == property_to_remove; }); properties.remove_first_matching([&](auto it) { return it == property_to_remove; });
} }
// https://www.w3.org/TR/css-sizing-4/#aspect-ratio
ErrorOr<RefPtr<StyleValue>> Parser::parse_aspect_ratio_value(Vector<ComponentValue> const& component_values)
{
// `auto || <ratio>`
RefPtr<StyleValue> auto_value;
RefPtr<StyleValue> ratio_value;
auto tokens = TokenStream { component_values };
while (tokens.has_next_token()) {
auto maybe_value = TRY(parse_css_value_for_property(PropertyID::AspectRatio, tokens));
if (!maybe_value)
return nullptr;
if (maybe_value->is_ratio()) {
if (ratio_value)
return nullptr;
ratio_value = maybe_value.release_nonnull();
continue;
}
if (maybe_value->is_identifier() && maybe_value->as_identifier().id() == ValueID::Auto) {
if (auto_value)
return nullptr;
auto_value = maybe_value.release_nonnull();
continue;
}
return nullptr;
}
if (auto_value && ratio_value) {
return TRY(StyleValueList::create(
StyleValueVector { auto_value.release_nonnull(), ratio_value.release_nonnull() },
StyleValueList::Separator::Space));
}
if (ratio_value)
return ratio_value.release_nonnull();
if (auto_value)
return auto_value.release_nonnull();
return nullptr;
}
ErrorOr<RefPtr<StyleValue>> Parser::parse_background_value(Vector<ComponentValue> const& component_values) ErrorOr<RefPtr<StyleValue>> Parser::parse_background_value(Vector<ComponentValue> const& component_values)
{ {
StyleValueVector background_images; StyleValueVector background_images;
@ -7307,6 +7352,10 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue>> Parser::parse_css_value(Property
// Special-case property handling // Special-case property handling
switch (property_id) { switch (property_id) {
case PropertyID::AspectRatio:
if (auto parsed_value = FIXME_TRY(parse_aspect_ratio_value(component_values)))
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::BackdropFilter: case PropertyID::BackdropFilter:
if (auto parsed_value = FIXME_TRY(parse_filter_value_list_value(component_values))) if (auto parsed_value = FIXME_TRY(parse_filter_value_list_value(component_values)))
return parsed_value.release_nonnull(); return parsed_value.release_nonnull();

View file

@ -307,6 +307,7 @@ private:
ErrorOr<RefPtr<StyleValue>> parse_simple_comma_separated_value_list(PropertyID, Vector<ComponentValue> const&); ErrorOr<RefPtr<StyleValue>> parse_simple_comma_separated_value_list(PropertyID, Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_filter_value_list_value(Vector<ComponentValue> const&); ErrorOr<RefPtr<StyleValue>> parse_filter_value_list_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_aspect_ratio_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_background_value(Vector<ComponentValue> const&); ErrorOr<RefPtr<StyleValue>> parse_background_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_single_background_position_value(TokenStream<ComponentValue>&); ErrorOr<RefPtr<StyleValue>> parse_single_background_position_value(TokenStream<ComponentValue>&);
ErrorOr<RefPtr<StyleValue>> parse_single_background_position_x_or_y_value(TokenStream<ComponentValue>&, PropertyID); ErrorOr<RefPtr<StyleValue>> parse_single_background_position_x_or_y_value(TokenStream<ComponentValue>&, PropertyID);

View file

@ -138,6 +138,17 @@
"appearance" "appearance"
] ]
}, },
"aspect-ratio": {
"affects-layout": true,
"inherited": false,
"initial": "auto",
"valid-types": [
"ratio"
],
"valid-identifiers":[
"auto"
]
},
"backdrop-filter": { "backdrop-filter": {
"affects-layout": false, "affects-layout": false,
"affects-stacking-context": true, "affects-stacking-context": true,

View file

@ -33,6 +33,7 @@
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h> #include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h> #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h> #include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
#include <LibWeb/CSS/StyleValues/RectStyleValue.h> #include <LibWeb/CSS/StyleValues/RectStyleValue.h>
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h> #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
#include <LibWeb/CSS/StyleValues/StyleValueList.h> #include <LibWeb/CSS/StyleValues/StyleValueList.h>
@ -263,6 +264,19 @@ ErrorOr<RefPtr<StyleValue const>> ResolvedCSSStyleDeclaration::style_value_for_p
return TRY(IdentifierStyleValue::create(to_value_id(layout_node.computed_values().align_self()))); return TRY(IdentifierStyleValue::create(to_value_id(layout_node.computed_values().align_self())));
case PropertyID::Appearance: case PropertyID::Appearance:
return TRY(IdentifierStyleValue::create(to_value_id(layout_node.computed_values().appearance()))); return TRY(IdentifierStyleValue::create(to_value_id(layout_node.computed_values().appearance())));
case PropertyID::AspectRatio: {
auto aspect_ratio = layout_node.computed_values().aspect_ratio();
if (aspect_ratio.use_natural_aspect_ratio_if_available && aspect_ratio.preferred_ratio.has_value()) {
return TRY(StyleValueList::create(
StyleValueVector {
TRY(IdentifierStyleValue::create(ValueID::Auto)),
TRY(RatioStyleValue::create(aspect_ratio.preferred_ratio.value())) },
StyleValueList::Separator::Space));
}
if (aspect_ratio.preferred_ratio.has_value())
return TRY(RatioStyleValue::create(aspect_ratio.preferred_ratio.value()));
return TRY(IdentifierStyleValue::create(ValueID::Auto));
}
case PropertyID::Background: { case PropertyID::Background: {
auto maybe_background_color = property(PropertyID::BackgroundColor); auto maybe_background_color = property(PropertyID::BackgroundColor);
auto maybe_background_image = property(PropertyID::BackgroundImage); auto maybe_background_image = property(PropertyID::BackgroundImage);

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -10,9 +11,11 @@
#include <LibWeb/CSS/StyleValues/BackgroundSizeStyleValue.h> #include <LibWeb/CSS/StyleValues/BackgroundSizeStyleValue.h>
#include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h> #include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h>
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h> #include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
#include <LibWeb/CSS/StyleValues/IdentifierStyleValue.h>
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h> #include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h> #include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h> #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
#include <LibWeb/CSS/StyleValues/StyleValueList.h> #include <LibWeb/CSS/StyleValues/StyleValueList.h>
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h> #include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
#include <LibWeb/CSS/StyleValues/URLStyleValue.h> #include <LibWeb/CSS/StyleValues/URLStyleValue.h>
@ -707,6 +710,20 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
if (auto border_collapse = computed_style.border_collapse(); border_collapse.has_value()) if (auto border_collapse = computed_style.border_collapse(); border_collapse.has_value())
computed_values.set_border_collapse(border_collapse.value()); computed_values.set_border_collapse(border_collapse.value());
auto aspect_ratio = computed_style.property(CSS::PropertyID::AspectRatio);
if (aspect_ratio->is_value_list()) {
auto& values_list = aspect_ratio->as_value_list().values();
if (values_list.size() == 2
&& values_list[0]->is_identifier() && values_list[0]->as_identifier().id() == CSS::ValueID::Auto
&& values_list[1]->is_ratio()) {
computed_values.set_aspect_ratio({ true, values_list[1]->as_ratio().ratio() });
}
} else if (aspect_ratio->is_identifier() && aspect_ratio->as_identifier().id() == CSS::ValueID::Auto) {
computed_values.set_aspect_ratio({ true, {} });
} else if (aspect_ratio->is_ratio()) {
computed_values.set_aspect_ratio({ false, aspect_ratio->as_ratio().ratio() });
}
} }
bool Node::is_root_element() const bool Node::is_root_element() const