mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 02:18:11 +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:
parent
5e3da93f1a
commit
6fd3b39bef
6 changed files with 102 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
|||
#include <LibWeb/CSS/GridTrackSize.h>
|
||||
#include <LibWeb/CSS/LengthBox.h>
|
||||
#include <LibWeb/CSS/PercentageOr.h>
|
||||
#include <LibWeb/CSS/Ratio.h>
|
||||
#include <LibWeb/CSS/Size.h>
|
||||
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
|
||||
|
@ -22,8 +23,14 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
struct AspectRatio {
|
||||
bool use_natural_aspect_ratio_if_available;
|
||||
Optional<Ratio> preferred_ratio;
|
||||
};
|
||||
|
||||
class InitialValues {
|
||||
public:
|
||||
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
|
||||
static float font_size() { return 16; }
|
||||
static int font_weight() { return 400; }
|
||||
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 {
|
||||
public:
|
||||
AspectRatio aspect_ratio() const { return m_noninherited.aspect_ratio; }
|
||||
CSS::Float float_() const { return m_noninherited.float_; }
|
||||
CSS::Clear clear() const { return m_noninherited.clear; }
|
||||
CSS::Clip clip() const { return m_noninherited.clip; }
|
||||
|
@ -344,6 +352,7 @@ protected:
|
|||
} m_inherited;
|
||||
|
||||
struct {
|
||||
AspectRatio aspect_ratio { InitialValues::aspect_ratio() };
|
||||
CSS::Float float_ { InitialValues::float_() };
|
||||
CSS::Clear clear { InitialValues::clear() };
|
||||
CSS::Clip clip { InitialValues::clip() };
|
||||
|
@ -418,6 +427,7 @@ class ImmutableComputedValues final : public ComputedValues {
|
|||
|
||||
class MutableComputedValues final : public ComputedValues {
|
||||
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_weight(int font_weight) { m_inherited.font_weight = font_weight; }
|
||||
void set_font_variant(CSS::FontVariant font_variant) { m_inherited.font_variant = font_variant; }
|
||||
|
|
|
@ -4457,6 +4457,51 @@ static void remove_property(Vector<PropertyID>& properties, PropertyID property_
|
|||
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)
|
||||
{
|
||||
StyleValueVector background_images;
|
||||
|
@ -7307,6 +7352,10 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue>> Parser::parse_css_value(Property
|
|||
|
||||
// Special-case property handling
|
||||
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:
|
||||
if (auto parsed_value = FIXME_TRY(parse_filter_value_list_value(component_values)))
|
||||
return parsed_value.release_nonnull();
|
||||
|
|
|
@ -307,6 +307,7 @@ private:
|
|||
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_aspect_ratio_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_x_or_y_value(TokenStream<ComponentValue>&, PropertyID);
|
||||
|
|
|
@ -138,6 +138,17 @@
|
|||
"appearance"
|
||||
]
|
||||
},
|
||||
"aspect-ratio": {
|
||||
"affects-layout": true,
|
||||
"inherited": false,
|
||||
"initial": "auto",
|
||||
"valid-types": [
|
||||
"ratio"
|
||||
],
|
||||
"valid-identifiers":[
|
||||
"auto"
|
||||
]
|
||||
},
|
||||
"backdrop-filter": {
|
||||
"affects-layout": false,
|
||||
"affects-stacking-context": true,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.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())));
|
||||
case PropertyID::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: {
|
||||
auto maybe_background_color = property(PropertyID::BackgroundColor);
|
||||
auto maybe_background_image = property(PropertyID::BackgroundImage);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -10,9 +11,11 @@
|
|||
#include <LibWeb/CSS/StyleValues/BackgroundSizeStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/IdentifierStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.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())
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue