mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 15:07:45 +00:00
LibWeb: Implement Flex and FlexStyleValue types
This commit is contained in:
parent
f1d7ea67c0
commit
b0317bb3a1
15 changed files with 258 additions and 6 deletions
|
@ -21,7 +21,7 @@ void generate_bounds_checking_function(JsonObject& properties, SourceGenerator&
|
||||||
static bool type_name_is_enum(StringView type_name)
|
static bool type_name_is_enum(StringView type_name)
|
||||||
{
|
{
|
||||||
return !AK::first_is_one_of(type_name,
|
return !AK::first_is_one_of(type_name,
|
||||||
"angle"sv, "color"sv, "custom-ident"sv, "easing-function"sv, "frequency"sv, "image"sv,
|
"angle"sv, "color"sv, "custom-ident"sv, "easing-function"sv, "flex"sv, "frequency"sv, "image"sv,
|
||||||
"integer"sv, "length"sv, "number"sv, "paint"sv, "percentage"sv, "ratio"sv, "rect"sv,
|
"integer"sv, "length"sv, "number"sv, "paint"sv, "percentage"sv, "ratio"sv, "rect"sv,
|
||||||
"resolution"sv, "string"sv, "time"sv, "url"sv);
|
"resolution"sv, "string"sv, "time"sv, "url"sv);
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,7 @@ enum class ValueType {
|
||||||
CustomIdent,
|
CustomIdent,
|
||||||
EasingFunction,
|
EasingFunction,
|
||||||
FilterValueList,
|
FilterValueList,
|
||||||
|
Flex,
|
||||||
Frequency,
|
Frequency,
|
||||||
Image,
|
Image,
|
||||||
Integer,
|
Integer,
|
||||||
|
@ -193,6 +194,7 @@ Optional<ValueType> property_resolves_percentages_relative_to(PropertyID);
|
||||||
|
|
||||||
// These perform range-checking, but are also safe to call with properties that don't accept that type. (They'll just return false.)
|
// These perform range-checking, but are also safe to call with properties that don't accept that type. (They'll just return false.)
|
||||||
bool property_accepts_angle(PropertyID, Angle const&);
|
bool property_accepts_angle(PropertyID, Angle const&);
|
||||||
|
bool property_accepts_flex(PropertyID, Flex const&);
|
||||||
bool property_accepts_frequency(PropertyID, Frequency const&);
|
bool property_accepts_frequency(PropertyID, Frequency const&);
|
||||||
bool property_accepts_integer(PropertyID, i64 const&);
|
bool property_accepts_integer(PropertyID, i64 const&);
|
||||||
bool property_accepts_length(PropertyID, Length const&);
|
bool property_accepts_length(PropertyID, Length const&);
|
||||||
|
@ -620,6 +622,8 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type)
|
||||||
property_generator.appendln(" case ValueType::CustomIdent:");
|
property_generator.appendln(" case ValueType::CustomIdent:");
|
||||||
} else if (type_name == "easing-function") {
|
} else if (type_name == "easing-function") {
|
||||||
property_generator.appendln(" case ValueType::EasingFunction:");
|
property_generator.appendln(" case ValueType::EasingFunction:");
|
||||||
|
} else if (type_name == "flex") {
|
||||||
|
property_generator.appendln(" case ValueType::Flex:");
|
||||||
} else if (type_name == "frequency") {
|
} else if (type_name == "frequency") {
|
||||||
property_generator.appendln(" case ValueType::Frequency:");
|
property_generator.appendln(" case ValueType::Frequency:");
|
||||||
} else if (type_name == "image") {
|
} else if (type_name == "image") {
|
||||||
|
@ -774,6 +778,7 @@ size_t property_maximum_value_count(PropertyID property_id)
|
||||||
})~~~");
|
})~~~");
|
||||||
|
|
||||||
generate_bounds_checking_function(properties, generator, "angle"sv, "Angle"sv, "Deg"sv);
|
generate_bounds_checking_function(properties, generator, "angle"sv, "Angle"sv, "Deg"sv);
|
||||||
|
generate_bounds_checking_function(properties, generator, "flex"sv, "Flex"sv, "Fr"sv);
|
||||||
generate_bounds_checking_function(properties, generator, "frequency"sv, "Frequency"sv, "Hertz"sv);
|
generate_bounds_checking_function(properties, generator, "frequency"sv, "Frequency"sv, "Hertz"sv);
|
||||||
generate_bounds_checking_function(properties, generator, "integer"sv, "i64"sv, {}, "value"sv);
|
generate_bounds_checking_function(properties, generator, "integer"sv, "i64"sv, {}, "value"sv);
|
||||||
generate_bounds_checking_function(properties, generator, "length"sv, "Length"sv, {}, "value.raw_value()"sv);
|
generate_bounds_checking_function(properties, generator, "length"sv, "Length"sv, {}, "value.raw_value()"sv);
|
||||||
|
|
|
@ -28,6 +28,7 @@ source_set("CSS") {
|
||||||
"Clip.cpp",
|
"Clip.cpp",
|
||||||
"Display.cpp",
|
"Display.cpp",
|
||||||
"EdgeRect.cpp",
|
"EdgeRect.cpp",
|
||||||
|
"Flex.cpp",
|
||||||
"FontFace.cpp",
|
"FontFace.cpp",
|
||||||
"Frequency.cpp",
|
"Frequency.cpp",
|
||||||
"GridTrackPlacement.cpp",
|
"GridTrackPlacement.cpp",
|
||||||
|
|
|
@ -38,6 +38,7 @@ set(SOURCES
|
||||||
CSS/CSSSupportsRule.cpp
|
CSS/CSSSupportsRule.cpp
|
||||||
CSS/Display.cpp
|
CSS/Display.cpp
|
||||||
CSS/EdgeRect.cpp
|
CSS/EdgeRect.cpp
|
||||||
|
CSS/Flex.cpp
|
||||||
CSS/FontFace.cpp
|
CSS/FontFace.cpp
|
||||||
CSS/Frequency.cpp
|
CSS/Frequency.cpp
|
||||||
CSS/GridTrackPlacement.cpp
|
CSS/GridTrackPlacement.cpp
|
||||||
|
|
|
@ -20,6 +20,8 @@ Optional<CSSNumericType::BaseType> CSSNumericType::base_type_from_value_type(Val
|
||||||
switch (value_type) {
|
switch (value_type) {
|
||||||
case ValueType::Angle:
|
case ValueType::Angle:
|
||||||
return BaseType::Angle;
|
return BaseType::Angle;
|
||||||
|
case ValueType::Flex:
|
||||||
|
return BaseType::Flex;
|
||||||
case ValueType::Frequency:
|
case ValueType::Frequency:
|
||||||
return BaseType::Frequency;
|
return BaseType::Frequency;
|
||||||
case ValueType::Length:
|
case ValueType::Length:
|
||||||
|
|
|
@ -66,7 +66,6 @@ public:
|
||||||
bool matches_angle() const { return matches_dimension(BaseType::Angle); }
|
bool matches_angle() const { return matches_dimension(BaseType::Angle); }
|
||||||
bool matches_angle_percentage() const { return matches_dimension_percentage(BaseType::Angle); }
|
bool matches_angle_percentage() const { return matches_dimension_percentage(BaseType::Angle); }
|
||||||
bool matches_flex() const { return matches_dimension(BaseType::Flex); }
|
bool matches_flex() const { return matches_dimension(BaseType::Flex); }
|
||||||
bool matches_flex_percentage() const { return matches_dimension_percentage(BaseType::Flex); }
|
|
||||||
bool matches_frequency() const { return matches_dimension(BaseType::Frequency); }
|
bool matches_frequency() const { return matches_dimension(BaseType::Frequency); }
|
||||||
bool matches_frequency_percentage() const { return matches_dimension_percentage(BaseType::Frequency); }
|
bool matches_frequency_percentage() const { return matches_dimension_percentage(BaseType::Frequency); }
|
||||||
bool matches_length() const { return matches_dimension(BaseType::Length); }
|
bool matches_length() const { return matches_dimension(BaseType::Length); }
|
||||||
|
|
59
Userland/Libraries/LibWeb/CSS/Flex.cpp
Normal file
59
Userland/Libraries/LibWeb/CSS/Flex.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Flex.h"
|
||||||
|
#include <LibWeb/CSS/Percentage.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
Flex::Flex(double value, Type type)
|
||||||
|
: m_type(type)
|
||||||
|
, m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Flex Flex::make_fr(double value)
|
||||||
|
{
|
||||||
|
return { value, Type::Fr };
|
||||||
|
}
|
||||||
|
|
||||||
|
Flex Flex::percentage_of(Percentage const& percentage) const
|
||||||
|
{
|
||||||
|
return Flex { percentage.as_fraction() * m_value, m_type };
|
||||||
|
}
|
||||||
|
|
||||||
|
String Flex::to_string() const
|
||||||
|
{
|
||||||
|
return MUST(String::formatted("{}fr", to_fr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
double Flex::to_fr() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::Fr:
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView Flex::unit_name() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::Fr:
|
||||||
|
return "fr"sv;
|
||||||
|
}
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Flex::Type> Flex::unit_from_name(StringView name)
|
||||||
|
{
|
||||||
|
if (name.equals_ignoring_ascii_case("fr"sv))
|
||||||
|
return Type::Fr;
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
Userland/Libraries/LibWeb/CSS/Flex.h
Normal file
66
Userland/Libraries/LibWeb/CSS/Flex.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-grid-2/#typedef-flex
|
||||||
|
class Flex {
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
Fr,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Optional<Type> unit_from_name(StringView);
|
||||||
|
|
||||||
|
Flex(double value, Type type);
|
||||||
|
static Flex make_fr(double);
|
||||||
|
Flex percentage_of(Percentage const&) const;
|
||||||
|
|
||||||
|
String to_string() const;
|
||||||
|
double to_fr() const;
|
||||||
|
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
double raw_value() const { return m_value; }
|
||||||
|
|
||||||
|
bool operator==(Flex const& other) const
|
||||||
|
{
|
||||||
|
return m_type == other.m_type && m_value == other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int operator<=>(Flex const& other) const
|
||||||
|
{
|
||||||
|
auto this_fr = to_fr();
|
||||||
|
auto other_fr = other.to_fr();
|
||||||
|
|
||||||
|
if (this_fr < other_fr)
|
||||||
|
return -1;
|
||||||
|
if (this_fr > other_fr)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringView unit_name() const;
|
||||||
|
|
||||||
|
Type m_type;
|
||||||
|
double m_value { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AK::Formatter<Web::CSS::Flex> : Formatter<StringView> {
|
||||||
|
ErrorOr<void> format(FormatBuilder& builder, Web::CSS::Flex const& flex)
|
||||||
|
{
|
||||||
|
return Formatter<StringView>::format(builder, flex.to_string());
|
||||||
|
}
|
||||||
|
};
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
#include <LibWeb/CSS/Angle.h>
|
#include <LibWeb/CSS/Angle.h>
|
||||||
|
#include <LibWeb/CSS/Flex.h>
|
||||||
#include <LibWeb/CSS/Frequency.h>
|
#include <LibWeb/CSS/Frequency.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
#include <LibWeb/CSS/Percentage.h>
|
#include <LibWeb/CSS/Percentage.h>
|
||||||
|
@ -24,6 +25,11 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dimension(Flex&& value)
|
||||||
|
: m_value(move(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Dimension(Frequency&& value)
|
Dimension(Frequency&& value)
|
||||||
: m_value(move(value))
|
: m_value(move(value))
|
||||||
{
|
{
|
||||||
|
@ -59,6 +65,9 @@ public:
|
||||||
return percentage();
|
return percentage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_flex() const { return m_value.has<Flex>(); }
|
||||||
|
Flex flex() const { return m_value.get<Flex>(); }
|
||||||
|
|
||||||
bool is_frequency() const { return m_value.has<Frequency>(); }
|
bool is_frequency() const { return m_value.has<Frequency>(); }
|
||||||
Frequency frequency() const { return m_value.get<Frequency>(); }
|
Frequency frequency() const { return m_value.get<Frequency>(); }
|
||||||
|
|
||||||
|
@ -99,7 +108,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Variant<Angle, Frequency, Length, Percentage, Resolution, Time> m_value;
|
Variant<Angle, Flex, Frequency, Length, Percentage, Resolution, Time> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/FlexStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
|
||||||
|
@ -1757,6 +1758,9 @@ Optional<Dimension> Parser::parse_dimension(ComponentValue const& component_valu
|
||||||
if (auto angle_type = Angle::unit_from_name(unit_string); angle_type.has_value())
|
if (auto angle_type = Angle::unit_from_name(unit_string); angle_type.has_value())
|
||||||
return Angle { numeric_value, angle_type.release_value() };
|
return Angle { numeric_value, angle_type.release_value() };
|
||||||
|
|
||||||
|
if (auto flex_type = Flex::unit_from_name(unit_string); flex_type.has_value())
|
||||||
|
return Flex { numeric_value, flex_type.release_value() };
|
||||||
|
|
||||||
if (auto frequency_type = Frequency::unit_from_name(unit_string); frequency_type.has_value())
|
if (auto frequency_type = Frequency::unit_from_name(unit_string); frequency_type.has_value())
|
||||||
return Frequency { numeric_value, frequency_type.release_value() };
|
return Frequency { numeric_value, frequency_type.release_value() };
|
||||||
|
|
||||||
|
@ -6194,6 +6198,7 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
|
||||||
}
|
}
|
||||||
|
|
||||||
bool property_accepts_dimension = any_property_accepts_type(property_ids, ValueType::Angle).has_value()
|
bool property_accepts_dimension = any_property_accepts_type(property_ids, ValueType::Angle).has_value()
|
||||||
|
|| any_property_accepts_type(property_ids, ValueType::Flex).has_value()
|
||||||
|| any_property_accepts_type(property_ids, ValueType::Frequency).has_value()
|
|| any_property_accepts_type(property_ids, ValueType::Frequency).has_value()
|
||||||
|| any_property_accepts_type(property_ids, ValueType::Length).has_value()
|
|| any_property_accepts_type(property_ids, ValueType::Length).has_value()
|
||||||
|| any_property_accepts_type(property_ids, ValueType::Percentage).has_value()
|
|| any_property_accepts_type(property_ids, ValueType::Percentage).has_value()
|
||||||
|
@ -6231,6 +6236,13 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
|
||||||
return PropertyAndValue { *property, AngleStyleValue::create(angle) };
|
return PropertyAndValue { *property, AngleStyleValue::create(angle) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dimension.is_flex()) {
|
||||||
|
auto flex = dimension.flex();
|
||||||
|
if (auto property = any_property_accepts_type(property_ids, ValueType::Flex); property.has_value() && property_accepts_flex(*property, flex)) {
|
||||||
|
transaction.commit();
|
||||||
|
return PropertyAndValue { *property, FlexStyleValue::create(flex) };
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dimension.is_frequency()) {
|
if (dimension.is_frequency()) {
|
||||||
auto frequency = dimension.frequency();
|
auto frequency = dimension.frequency();
|
||||||
if (auto property = any_property_accepts_type(property_ids, ValueType::Frequency); property.has_value() && property_accepts_frequency(*property, frequency)) {
|
if (auto property = any_property_accepts_type(property_ids, ValueType::Frequency); property.has_value() && property_accepts_frequency(*property, frequency)) {
|
||||||
|
@ -6281,6 +6293,9 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
|
||||||
} else if (calculated.resolves_to_angle_percentage()) {
|
} else if (calculated.resolves_to_angle_percentage()) {
|
||||||
if (auto property = any_property_accepts_type_percentage(property_ids, ValueType::Angle); property.has_value())
|
if (auto property = any_property_accepts_type_percentage(property_ids, ValueType::Angle); property.has_value())
|
||||||
return PropertyAndValue { *property, calculated };
|
return PropertyAndValue { *property, calculated };
|
||||||
|
} else if (calculated.resolves_to_flex()) {
|
||||||
|
if (auto property = any_property_accepts_type(property_ids, ValueType::Flex); property.has_value())
|
||||||
|
return PropertyAndValue { *property, calculated };
|
||||||
} else if (calculated.resolves_to_frequency()) {
|
} else if (calculated.resolves_to_frequency()) {
|
||||||
if (auto property = any_property_accepts_type(property_ids, ValueType::Frequency); property.has_value())
|
if (auto property = any_property_accepts_type(property_ids, ValueType::Frequency); property.has_value())
|
||||||
return PropertyAndValue { *property, calculated };
|
return PropertyAndValue { *property, calculated };
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/FlexStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
|
||||||
|
|
|
@ -96,6 +96,7 @@ using StyleValueVector = Vector<ValueComparingNonnullRefPtr<StyleValue const>>;
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(Easing, easing) \
|
__ENUMERATE_STYLE_VALUE_TYPE(Easing, easing) \
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(Edge, edge) \
|
__ENUMERATE_STYLE_VALUE_TYPE(Edge, edge) \
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(FilterValueList, filter_value_list) \
|
__ENUMERATE_STYLE_VALUE_TYPE(FilterValueList, filter_value_list) \
|
||||||
|
__ENUMERATE_STYLE_VALUE_TYPE(Flex, flex) \
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(Frequency, frequency) \
|
__ENUMERATE_STYLE_VALUE_TYPE(Frequency, frequency) \
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(GridAutoFlow, grid_auto_flow) \
|
__ENUMERATE_STYLE_VALUE_TYPE(GridAutoFlow, grid_auto_flow) \
|
||||||
__ENUMERATE_STYLE_VALUE_TYPE(GridTemplateArea, grid_template_area) \
|
__ENUMERATE_STYLE_VALUE_TYPE(GridTemplateArea, grid_template_area) \
|
||||||
|
|
|
@ -38,6 +38,7 @@ static double resolve_value(CalculatedStyleValue::CalculationResult::Value value
|
||||||
return value.visit(
|
return value.visit(
|
||||||
[](Number const& number) { return number.value(); },
|
[](Number const& number) { return number.value(); },
|
||||||
[](Angle const& angle) { return angle.to_degrees(); },
|
[](Angle const& angle) { return angle.to_degrees(); },
|
||||||
|
[](Flex const& flex) { return flex.to_fr(); },
|
||||||
[](Frequency const& frequency) { return frequency.to_hertz(); },
|
[](Frequency const& frequency) { return frequency.to_hertz(); },
|
||||||
[&context](Length const& length) { return length.to_px(*context).to_double(); },
|
[&context](Length const& length) { return length.to_px(*context).to_double(); },
|
||||||
[](Percentage const& percentage) { return percentage.value(); },
|
[](Percentage const& percentage) { return percentage.value(); },
|
||||||
|
@ -74,6 +75,8 @@ static CalculatedStyleValue::CalculationResult to_resolved_type(CalculatedStyleV
|
||||||
return { Number(Number::Type::Number, value) };
|
return { Number(Number::Type::Number, value) };
|
||||||
case CalculatedStyleValue::ResolvedType::Angle:
|
case CalculatedStyleValue::ResolvedType::Angle:
|
||||||
return { Angle::make_degrees(value) };
|
return { Angle::make_degrees(value) };
|
||||||
|
case CalculatedStyleValue::ResolvedType::Flex:
|
||||||
|
return { Flex::make_fr(value) };
|
||||||
case CalculatedStyleValue::ResolvedType::Frequency:
|
case CalculatedStyleValue::ResolvedType::Frequency:
|
||||||
return { Frequency::make_hertz(value) };
|
return { Frequency::make_hertz(value) };
|
||||||
case CalculatedStyleValue::ResolvedType::Length:
|
case CalculatedStyleValue::ResolvedType::Length:
|
||||||
|
@ -137,6 +140,7 @@ Optional<CalculatedStyleValue::ResolvedType> NumericCalculationNode::resolved_ty
|
||||||
return m_value.visit(
|
return m_value.visit(
|
||||||
[](Number const&) { return CalculatedStyleValue::ResolvedType::Number; },
|
[](Number const&) { return CalculatedStyleValue::ResolvedType::Number; },
|
||||||
[](Angle const&) { return CalculatedStyleValue::ResolvedType::Angle; },
|
[](Angle const&) { return CalculatedStyleValue::ResolvedType::Angle; },
|
||||||
|
[](Flex const&) { return CalculatedStyleValue::ResolvedType::Flex; },
|
||||||
[](Frequency const&) { return CalculatedStyleValue::ResolvedType::Frequency; },
|
[](Frequency const&) { return CalculatedStyleValue::ResolvedType::Frequency; },
|
||||||
[](Length const&) { return CalculatedStyleValue::ResolvedType::Length; },
|
[](Length const&) { return CalculatedStyleValue::ResolvedType::Length; },
|
||||||
[](Percentage const&) { return CalculatedStyleValue::ResolvedType::Percentage; },
|
[](Percentage const&) { return CalculatedStyleValue::ResolvedType::Percentage; },
|
||||||
|
@ -175,7 +179,11 @@ Optional<CSSNumericType> NumericCalculationNode::determine_type(PropertyID prope
|
||||||
return CSSNumericType { CSSNumericType::BaseType::Frequency, 1 };
|
return CSSNumericType { CSSNumericType::BaseType::Frequency, 1 };
|
||||||
},
|
},
|
||||||
// FIXME: <resolution>
|
// FIXME: <resolution>
|
||||||
// FIXME: <flex>
|
[](Flex const&) {
|
||||||
|
// -> <flex>
|
||||||
|
// the type is «[ "flex" → 1 ]»
|
||||||
|
return CSSNumericType { CSSNumericType::BaseType::Flex, 1 };
|
||||||
|
},
|
||||||
// NOTE: <calc-constant> is a separate node type. (FIXME: Should it be?)
|
// NOTE: <calc-constant> is a separate node type. (FIXME: Should it be?)
|
||||||
[property_id](Percentage const&) {
|
[property_id](Percentage const&) {
|
||||||
// -> <percentage>
|
// -> <percentage>
|
||||||
|
@ -2053,6 +2061,24 @@ void CalculatedStyleValue::CalculationResult::add_or_subtract_internal(SumOperat
|
||||||
m_value = Angle::make_degrees(this_degrees - other_degrees);
|
m_value = Angle::make_degrees(this_degrees - other_degrees);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[&](Flex const& flex) {
|
||||||
|
auto this_fr = flex.to_fr();
|
||||||
|
if (other.m_value.has<Flex>()) {
|
||||||
|
auto other_fr = other.m_value.get<Flex>().to_fr();
|
||||||
|
if (op == SumOperation::Add)
|
||||||
|
m_value = Flex::make_fr(this_fr + other_fr);
|
||||||
|
else
|
||||||
|
m_value = Flex::make_fr(this_fr - other_fr);
|
||||||
|
} else {
|
||||||
|
VERIFY(percentage_basis.has<Flex>());
|
||||||
|
|
||||||
|
auto other_fr = percentage_basis.get<Flex>().percentage_of(other.m_value.get<Percentage>()).to_fr();
|
||||||
|
if (op == SumOperation::Add)
|
||||||
|
m_value = Flex::make_fr(this_fr + other_fr);
|
||||||
|
else
|
||||||
|
m_value = Flex::make_fr(this_fr - other_fr);
|
||||||
|
}
|
||||||
|
},
|
||||||
[&](Frequency const& frequency) {
|
[&](Frequency const& frequency) {
|
||||||
auto this_hertz = frequency.to_hertz();
|
auto this_hertz = frequency.to_hertz();
|
||||||
if (other.m_value.has<Frequency>()) {
|
if (other.m_value.has<Frequency>()) {
|
||||||
|
@ -2151,6 +2177,9 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
|
||||||
[&](Angle const& angle) {
|
[&](Angle const& angle) {
|
||||||
m_value = Angle::make_degrees(angle.to_degrees() * other.m_value.get<Number>().value());
|
m_value = Angle::make_degrees(angle.to_degrees() * other.m_value.get<Number>().value());
|
||||||
},
|
},
|
||||||
|
[&](Flex const& flex) {
|
||||||
|
m_value = Flex::make_fr(flex.to_fr() * other.m_value.get<Number>().value());
|
||||||
|
},
|
||||||
[&](Frequency const& frequency) {
|
[&](Frequency const& frequency) {
|
||||||
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value());
|
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value());
|
||||||
},
|
},
|
||||||
|
@ -2183,6 +2212,9 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const&
|
||||||
[&](Angle const& angle) {
|
[&](Angle const& angle) {
|
||||||
m_value = Angle::make_degrees(angle.to_degrees() / denominator);
|
m_value = Angle::make_degrees(angle.to_degrees() / denominator);
|
||||||
},
|
},
|
||||||
|
[&](Flex const& flex) {
|
||||||
|
m_value = Flex::make_fr(flex.to_fr() / denominator);
|
||||||
|
},
|
||||||
[&](Frequency const& frequency) {
|
[&](Frequency const& frequency) {
|
||||||
m_value = Frequency::make_hertz(frequency.to_hertz() / denominator);
|
m_value = Frequency::make_hertz(frequency.to_hertz() / denominator);
|
||||||
},
|
},
|
||||||
|
@ -2206,6 +2238,9 @@ void CalculatedStyleValue::CalculationResult::negate()
|
||||||
[&](Angle const& angle) {
|
[&](Angle const& angle) {
|
||||||
m_value = Angle { 0 - angle.raw_value(), angle.type() };
|
m_value = Angle { 0 - angle.raw_value(), angle.type() };
|
||||||
},
|
},
|
||||||
|
[&](Flex const& flex) {
|
||||||
|
m_value = Flex { 0 - flex.raw_value(), flex.type() };
|
||||||
|
},
|
||||||
[&](Frequency const& frequency) {
|
[&](Frequency const& frequency) {
|
||||||
m_value = Frequency { 0 - frequency.raw_value(), frequency.type() };
|
m_value = Frequency { 0 - frequency.raw_value(), frequency.type() };
|
||||||
},
|
},
|
||||||
|
@ -2230,6 +2265,9 @@ void CalculatedStyleValue::CalculationResult::invert()
|
||||||
[&](Angle const& angle) {
|
[&](Angle const& angle) {
|
||||||
m_value = Angle { 1 / angle.raw_value(), angle.type() };
|
m_value = Angle { 1 / angle.raw_value(), angle.type() };
|
||||||
},
|
},
|
||||||
|
[&](Flex const& flex) {
|
||||||
|
m_value = Flex { 1 / flex.raw_value(), flex.type() };
|
||||||
|
},
|
||||||
[&](Frequency const& frequency) {
|
[&](Frequency const& frequency) {
|
||||||
m_value = Frequency { 1 / frequency.raw_value(), frequency.type() };
|
m_value = Frequency { 1 / frequency.raw_value(), frequency.type() };
|
||||||
},
|
},
|
||||||
|
@ -2283,6 +2321,15 @@ Optional<Angle> CalculatedStyleValue::resolve_angle_percentage(Angle const& perc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<Flex> CalculatedStyleValue::resolve_flex() const
|
||||||
|
{
|
||||||
|
auto result = m_calculation->resolve({}, {});
|
||||||
|
|
||||||
|
if (result.value().has<Flex>())
|
||||||
|
return result.value().get<Flex>();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
Optional<Frequency> CalculatedStyleValue::resolve_frequency() const
|
Optional<Frequency> CalculatedStyleValue::resolve_frequency() const
|
||||||
{
|
{
|
||||||
auto result = m_calculation->resolve({}, {});
|
auto result = m_calculation->resolve({}, {});
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <LibWeb/CSS/Angle.h>
|
#include <LibWeb/CSS/Angle.h>
|
||||||
#include <LibWeb/CSS/CSSNumericType.h>
|
#include <LibWeb/CSS/CSSNumericType.h>
|
||||||
|
#include <LibWeb/CSS/Flex.h>
|
||||||
#include <LibWeb/CSS/Frequency.h>
|
#include <LibWeb/CSS/Frequency.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
#include <LibWeb/CSS/Percentage.h>
|
#include <LibWeb/CSS/Percentage.h>
|
||||||
|
@ -26,6 +27,7 @@ class CalculatedStyleValue : public StyleValue {
|
||||||
public:
|
public:
|
||||||
enum class ResolvedType {
|
enum class ResolvedType {
|
||||||
Angle,
|
Angle,
|
||||||
|
Flex,
|
||||||
Frequency,
|
Frequency,
|
||||||
Integer,
|
Integer,
|
||||||
Length,
|
Length,
|
||||||
|
@ -43,11 +45,11 @@ public:
|
||||||
Divide,
|
Divide,
|
||||||
};
|
};
|
||||||
|
|
||||||
using PercentageBasis = Variant<Empty, Angle, Frequency, Length, Time>;
|
using PercentageBasis = Variant<Empty, Angle, Flex, Frequency, Length, Time>;
|
||||||
|
|
||||||
class CalculationResult {
|
class CalculationResult {
|
||||||
public:
|
public:
|
||||||
using Value = Variant<Number, Angle, Frequency, Length, Percentage, Time>;
|
using Value = Variant<Number, Angle, Flex, Frequency, Length, Percentage, Time>;
|
||||||
CalculationResult(Value value)
|
CalculationResult(Value value)
|
||||||
: m_value(move(value))
|
: m_value(move(value))
|
||||||
{
|
{
|
||||||
|
@ -79,6 +81,9 @@ public:
|
||||||
Optional<Angle> resolve_angle() const;
|
Optional<Angle> resolve_angle() const;
|
||||||
Optional<Angle> resolve_angle_percentage(Angle const& percentage_basis) const;
|
Optional<Angle> resolve_angle_percentage(Angle const& percentage_basis) const;
|
||||||
|
|
||||||
|
bool resolves_to_flex() const { return m_resolved_type.matches_flex(); }
|
||||||
|
Optional<Flex> resolve_flex() const;
|
||||||
|
|
||||||
bool resolves_to_frequency() const { return m_resolved_type.matches_frequency(); }
|
bool resolves_to_frequency() const { return m_resolved_type.matches_frequency(); }
|
||||||
bool resolves_to_frequency_percentage() const { return m_resolved_type.matches_frequency_percentage(); }
|
bool resolves_to_frequency_percentage() const { return m_resolved_type.matches_frequency_percentage(); }
|
||||||
Optional<Frequency> resolve_frequency() const;
|
Optional<Frequency> resolve_frequency() const;
|
||||||
|
|
39
Userland/Libraries/LibWeb/CSS/StyleValues/FlexStyleValue.h
Normal file
39
Userland/Libraries/LibWeb/CSS/StyleValues/FlexStyleValue.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/CSS/Flex.h>
|
||||||
|
#include <LibWeb/CSS/StyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
class FlexStyleValue final : public StyleValueWithDefaultOperators<FlexStyleValue> {
|
||||||
|
public:
|
||||||
|
static ValueComparingNonnullRefPtr<FlexStyleValue> create(Flex flex)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) FlexStyleValue(move(flex)));
|
||||||
|
}
|
||||||
|
virtual ~FlexStyleValue() override = default;
|
||||||
|
|
||||||
|
Flex const& flex() const { return m_flex; }
|
||||||
|
Flex& flex() { return m_flex; }
|
||||||
|
|
||||||
|
virtual String to_string() const override { return m_flex.to_string(); }
|
||||||
|
|
||||||
|
bool properties_equal(FlexStyleValue const& other) const { return m_flex == other.m_flex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FlexStyleValue(Flex&& flex)
|
||||||
|
: StyleValueWithDefaultOperators(Type::Flex)
|
||||||
|
, m_flex(flex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Flex m_flex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -101,6 +101,8 @@ class EdgeStyleValue;
|
||||||
class ElementInlineCSSStyleDeclaration;
|
class ElementInlineCSSStyleDeclaration;
|
||||||
class ExplicitGridTrack;
|
class ExplicitGridTrack;
|
||||||
class FilterValueListStyleValue;
|
class FilterValueListStyleValue;
|
||||||
|
class Flex;
|
||||||
|
class FlexStyleValue;
|
||||||
class FontFace;
|
class FontFace;
|
||||||
class Frequency;
|
class Frequency;
|
||||||
class FrequencyOrCalculated;
|
class FrequencyOrCalculated;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue