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:
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/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; }
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue