mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +00:00 
			
		
		
		
	LibWeb: Implement CSS Frequency class
This corresponds to `<frequency>` in the grammar.
This commit is contained in:
		
							parent
							
								
									355d1936f2
								
							
						
					
					
						commit
						bd79c303f6
					
				
					 9 changed files with 267 additions and 5 deletions
				
			
		|  | @ -28,6 +28,7 @@ set(SOURCES | ||||||
|     CSS/CSSSupportsRule.cpp |     CSS/CSSSupportsRule.cpp | ||||||
|     CSS/DefaultStyleSheetSource.cpp |     CSS/DefaultStyleSheetSource.cpp | ||||||
|     CSS/Display.cpp |     CSS/Display.cpp | ||||||
|  |     CSS/Frequency.cpp | ||||||
|     CSS/Length.cpp |     CSS/Length.cpp | ||||||
|     CSS/MediaList.cpp |     CSS/MediaList.cpp | ||||||
|     CSS/MediaQuery.cpp |     CSS/MediaQuery.cpp | ||||||
|  |  | ||||||
							
								
								
									
										86
									
								
								Userland/Libraries/LibWeb/CSS/Frequency.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Userland/Libraries/LibWeb/CSS/Frequency.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "Frequency.h" | ||||||
|  | #include <LibWeb/CSS/StyleValue.h> | ||||||
|  | 
 | ||||||
|  | namespace Web::CSS { | ||||||
|  | 
 | ||||||
|  | Frequency::Frequency(int value, Type type) | ||||||
|  |     : m_type(type) | ||||||
|  |     , m_value(value) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frequency::Frequency(float value, Type type) | ||||||
|  |     : m_type(type) | ||||||
|  |     , m_value(value) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frequency Frequency::make_calculated(NonnullRefPtr<CalculatedStyleValue> calculated_style_value) | ||||||
|  | { | ||||||
|  |     Frequency frequency { 0, Type::Calculated }; | ||||||
|  |     frequency.m_calculated_style = move(calculated_style_value); | ||||||
|  |     return frequency; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frequency Frequency::make_hertz(float value) | ||||||
|  | { | ||||||
|  |     return { value, Type::Hz }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frequency Frequency::percentage_of(Percentage const& percentage) const | ||||||
|  | { | ||||||
|  |     VERIFY(!is_calculated()); | ||||||
|  | 
 | ||||||
|  |     return Frequency { percentage.as_fraction() * m_value, m_type }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | String Frequency::to_string() const | ||||||
|  | { | ||||||
|  |     if (is_calculated()) | ||||||
|  |         return m_calculated_style->to_string(); | ||||||
|  |     return String::formatted("{}{}", m_value, unit_name()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | float Frequency::to_hertz() const | ||||||
|  | { | ||||||
|  |     switch (m_type) { | ||||||
|  |     case Type::Calculated: | ||||||
|  |         return m_calculated_style->resolve_frequency()->to_hertz(); | ||||||
|  |     case Type::Hz: | ||||||
|  |         return m_value; | ||||||
|  |     case Type::kHz: | ||||||
|  |         return m_value * 1000; | ||||||
|  |     } | ||||||
|  |     VERIFY_NOT_REACHED(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | StringView Frequency::unit_name() const | ||||||
|  | { | ||||||
|  |     switch (m_type) { | ||||||
|  |     case Type::Calculated: | ||||||
|  |         return "calculated"sv; | ||||||
|  |     case Type::Hz: | ||||||
|  |         return "hz"sv; | ||||||
|  |     case Type::kHz: | ||||||
|  |         return "khz"sv; | ||||||
|  |     } | ||||||
|  |     VERIFY_NOT_REACHED(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Optional<Frequency::Type> Frequency::unit_from_name(StringView name) | ||||||
|  | { | ||||||
|  |     if (name.equals_ignoring_case("hz"sv)) { | ||||||
|  |         return Type::Hz; | ||||||
|  |     } else if (name.equals_ignoring_case("khz"sv)) { | ||||||
|  |         return Type::kHz; | ||||||
|  |     } | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										53
									
								
								Userland/Libraries/LibWeb/CSS/Frequency.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Userland/Libraries/LibWeb/CSS/Frequency.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <AK/RefPtr.h> | ||||||
|  | #include <LibWeb/Forward.h> | ||||||
|  | 
 | ||||||
|  | namespace Web::CSS { | ||||||
|  | class Frequency { | ||||||
|  | public: | ||||||
|  |     enum class Type { | ||||||
|  |         Calculated, | ||||||
|  |         Hz, | ||||||
|  |         kHz | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     static Optional<Type> unit_from_name(StringView); | ||||||
|  | 
 | ||||||
|  |     Frequency(int value, Type type); | ||||||
|  |     Frequency(float value, Type type); | ||||||
|  |     static Frequency make_calculated(NonnullRefPtr<CalculatedStyleValue>); | ||||||
|  |     static Frequency make_hertz(float); | ||||||
|  |     Frequency percentage_of(Percentage const&) const; | ||||||
|  | 
 | ||||||
|  |     bool is_calculated() const { return m_type == Type::Calculated; } | ||||||
|  | 
 | ||||||
|  |     String to_string() const; | ||||||
|  |     float to_hertz() const; | ||||||
|  | 
 | ||||||
|  |     bool operator==(Frequency const& other) const | ||||||
|  |     { | ||||||
|  |         if (is_calculated()) | ||||||
|  |             return m_calculated_style == other.m_calculated_style; | ||||||
|  |         return m_type == other.m_type && m_value == other.m_value; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator!=(Frequency const& other) const | ||||||
|  |     { | ||||||
|  |         return !(*this == other); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     StringView unit_name() const; | ||||||
|  | 
 | ||||||
|  |     Type m_type; | ||||||
|  |     float m_value { 0 }; | ||||||
|  |     RefPtr<CalculatedStyleValue> m_calculated_style; | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | @ -4300,6 +4300,8 @@ Optional<CalculatedStyleValue::CalcValue> Parser::parse_calc_value(TokenStream<S | ||||||
| 
 | 
 | ||||||
|         if (dimension.is_angle()) |         if (dimension.is_angle()) | ||||||
|             return CalculatedStyleValue::CalcValue { dimension.angle() }; |             return CalculatedStyleValue::CalcValue { dimension.angle() }; | ||||||
|  |         if (dimension.is_frequency()) | ||||||
|  |             return CalculatedStyleValue::CalcValue { dimension.frequency() }; | ||||||
|         if (dimension.is_length()) |         if (dimension.is_length()) | ||||||
|             return CalculatedStyleValue::CalcValue { dimension.length() }; |             return CalculatedStyleValue::CalcValue { dimension.length() }; | ||||||
|         if (dimension.is_percentage()) |         if (dimension.is_percentage()) | ||||||
|  |  | ||||||
|  | @ -14,6 +14,11 @@ Angle AnglePercentage::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> co | ||||||
|     return calculated->resolve_angle_percentage(reference_value)->resolved(layout_node, reference_value); |     return calculated->resolve_angle_percentage(reference_value)->resolved(layout_node, reference_value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Frequency FrequencyPercentage::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const& layout_node, Frequency const& reference_value) const | ||||||
|  | { | ||||||
|  |     return calculated->resolve_frequency_percentage(reference_value)->resolved(layout_node, reference_value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Length LengthPercentage::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const& layout_node, Length const& reference_value) const | Length LengthPercentage::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const& layout_node, Length const& reference_value) const | ||||||
| { | { | ||||||
|     return calculated->resolve_length_percentage(layout_node, reference_value)->resolved(layout_node, reference_value); |     return calculated->resolve_length_percentage(layout_node, reference_value)->resolved(layout_node, reference_value); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include <AK/String.h> | #include <AK/String.h> | ||||||
| #include <AK/Variant.h> | #include <AK/Variant.h> | ||||||
| #include <LibWeb/CSS/Angle.h> | #include <LibWeb/CSS/Angle.h> | ||||||
|  | #include <LibWeb/CSS/Frequency.h> | ||||||
| #include <LibWeb/CSS/Length.h> | #include <LibWeb/CSS/Length.h> | ||||||
| 
 | 
 | ||||||
| namespace Web::CSS { | namespace Web::CSS { | ||||||
|  | @ -160,6 +161,16 @@ public: | ||||||
|     Angle const& angle() const { return get_t(); } |     Angle const& angle() const { return get_t(); } | ||||||
|     virtual Angle resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&, Angle const& reference_value) const override; |     virtual Angle resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&, Angle const& reference_value) const override; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | class FrequencyPercentage : public PercentageOr<Frequency> { | ||||||
|  | public: | ||||||
|  |     using PercentageOr<Frequency>::PercentageOr; | ||||||
|  | 
 | ||||||
|  |     bool is_frequency() const { return is_t(); } | ||||||
|  |     Frequency const& frequency() const { return get_t(); } | ||||||
|  |     virtual Frequency resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&, Frequency const& reference_value) const override; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class LengthPercentage : public PercentageOr<Length> { | class LengthPercentage : public PercentageOr<Length> { | ||||||
| public: | public: | ||||||
|     using PercentageOr<Length>::PercentageOr; |     using PercentageOr<Length>::PercentageOr; | ||||||
|  | @ -187,6 +198,15 @@ struct AK::Formatter<Web::CSS::AnglePercentage> : Formatter<StringView> { | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | template<> | ||||||
|  | struct AK::Formatter<Web::CSS::FrequencyPercentage> : Formatter<StringView> { | ||||||
|  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::FrequencyPercentage const& frequency_percentage) | ||||||
|  |     { | ||||||
|  |         return Formatter<StringView>::format(builder, frequency_percentage.to_string()); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
| struct AK::Formatter<Web::CSS::LengthPercentage> : Formatter<StringView> { | struct AK::Formatter<Web::CSS::LengthPercentage> : Formatter<StringView> { | ||||||
|     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthPercentage const& length_percentage) |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthPercentage const& length_percentage) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -99,6 +99,12 @@ FontStyleValue const& StyleValue::as_font() const | ||||||
|     return static_cast<FontStyleValue const&>(*this); |     return static_cast<FontStyleValue const&>(*this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | FrequencyStyleValue const& StyleValue::as_frequency() const | ||||||
|  | { | ||||||
|  |     VERIFY(is_frequency()); | ||||||
|  |     return static_cast<FrequencyStyleValue const&>(*this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| IdentifierStyleValue const& StyleValue::as_identifier() const | IdentifierStyleValue const& StyleValue::as_identifier() const | ||||||
| { | { | ||||||
|     VERIFY(is_identifier()); |     VERIFY(is_identifier()); | ||||||
|  | @ -333,6 +339,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); | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         [&](Frequency const& frequency) { | ||||||
|  |             auto this_hertz = frequency.to_hertz(); | ||||||
|  |             if (other.m_value.has<Frequency>()) { | ||||||
|  |                 auto other_hertz = other.m_value.get<Frequency>().to_hertz(); | ||||||
|  |                 if (op == SumOperation::Add) | ||||||
|  |                     m_value = Frequency::make_hertz(this_hertz + other_hertz); | ||||||
|  |                 else | ||||||
|  |                     m_value = Frequency::make_hertz(this_hertz - other_hertz); | ||||||
|  |             } else { | ||||||
|  |                 VERIFY(percentage_basis.has<Frequency>()); | ||||||
|  | 
 | ||||||
|  |                 auto other_hertz = percentage_basis.get<Frequency>().percentage_of(other.m_value.get<Percentage>()).to_hertz(); | ||||||
|  |                 if (op == SumOperation::Add) | ||||||
|  |                     m_value = Frequency::make_hertz(this_hertz + other_hertz); | ||||||
|  |                 else | ||||||
|  |                     m_value = Frequency::make_hertz(this_hertz - other_hertz); | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         [&](Length const& length) { |         [&](Length const& length) { | ||||||
|             auto this_px = length.to_px(*layout_node); |             auto this_px = length.to_px(*layout_node); | ||||||
|             if (other.m_value.has<Length>()) { |             if (other.m_value.has<Length>()) { | ||||||
|  | @ -396,6 +420,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); | ||||||
|         }, |         }, | ||||||
|  |         [&](Frequency const& frequency) { | ||||||
|  |             m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value); | ||||||
|  |         }, | ||||||
|         [&](Length const& length) { |         [&](Length const& length) { | ||||||
|             VERIFY(layout_node); |             VERIFY(layout_node); | ||||||
|             m_value = Length::make_px(length.to_px(*layout_node) * other.m_value.get<Number>().value); |             m_value = Length::make_px(length.to_px(*layout_node) * other.m_value.get<Number>().value); | ||||||
|  | @ -423,6 +450,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); | ||||||
|         }, |         }, | ||||||
|  |         [&](Frequency const& frequency) { | ||||||
|  |             m_value = Frequency::make_hertz(frequency.to_hertz() / denominator); | ||||||
|  |         }, | ||||||
|         [&](Length const& length) { |         [&](Length const& length) { | ||||||
|             VERIFY(layout_node); |             VERIFY(layout_node); | ||||||
|             m_value = Length::make_px(length.to_px(*layout_node) / denominator); |             m_value = Length::make_px(length.to_px(*layout_node) / denominator); | ||||||
|  | @ -536,6 +566,31 @@ Optional<AnglePercentage> CalculatedStyleValue::resolve_angle_percentage(Angle c | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Optional<Frequency> CalculatedStyleValue::resolve_frequency() const | ||||||
|  | { | ||||||
|  |     auto result = m_expression->resolve(nullptr, {}); | ||||||
|  | 
 | ||||||
|  |     if (result.value().has<Frequency>()) | ||||||
|  |         return result.value().get<Frequency>(); | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Optional<FrequencyPercentage> CalculatedStyleValue::resolve_frequency_percentage(Frequency const& percentage_basis) const | ||||||
|  | { | ||||||
|  |     auto result = m_expression->resolve(nullptr, percentage_basis); | ||||||
|  | 
 | ||||||
|  |     return result.value().visit( | ||||||
|  |         [&](Frequency const& frequency) -> Optional<FrequencyPercentage> { | ||||||
|  |             return frequency; | ||||||
|  |         }, | ||||||
|  |         [&](Percentage const& percentage) -> Optional<FrequencyPercentage> { | ||||||
|  |             return percentage; | ||||||
|  |         }, | ||||||
|  |         [&](auto const&) -> Optional<FrequencyPercentage> { | ||||||
|  |             return {}; | ||||||
|  |         }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Optional<Length> CalculatedStyleValue::resolve_length(Layout::Node const& layout_node) const | Optional<Length> CalculatedStyleValue::resolve_length(Layout::Node const& layout_node) const | ||||||
| { | { | ||||||
|     auto result = m_expression->resolve(&layout_node, {}); |     auto result = m_expression->resolve(&layout_node, {}); | ||||||
|  | @ -745,6 +800,7 @@ Optional<CalculatedStyleValue::ResolvedType> CalculatedStyleValue::CalcValue::re | ||||||
|             return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number }; |             return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number }; | ||||||
|         }, |         }, | ||||||
|         [](Angle const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Angle }; }, |         [](Angle const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Angle }; }, | ||||||
|  |         [](Frequency const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Frequency }; }, | ||||||
|         [](Length const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Length }; }, |         [](Length const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Length }; }, | ||||||
|         [](Percentage const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Percentage }; }, |         [](Percentage const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Percentage }; }, | ||||||
|         [](NonnullOwnPtr<CalcSum> const& sum) { return sum->resolved_type(); }); |         [](NonnullOwnPtr<CalcSum> const& sum) { return sum->resolved_type(); }); | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <LibGfx/Color.h> | #include <LibGfx/Color.h> | ||||||
| #include <LibWeb/CSS/Angle.h> | #include <LibWeb/CSS/Angle.h> | ||||||
| #include <LibWeb/CSS/Display.h> | #include <LibWeb/CSS/Display.h> | ||||||
|  | #include <LibWeb/CSS/Frequency.h> | ||||||
| #include <LibWeb/CSS/Length.h> | #include <LibWeb/CSS/Length.h> | ||||||
| #include <LibWeb/CSS/Parser/StyleComponentValueRule.h> | #include <LibWeb/CSS/Parser/StyleComponentValueRule.h> | ||||||
| #include <LibWeb/CSS/Percentage.h> | #include <LibWeb/CSS/Percentage.h> | ||||||
|  | @ -297,6 +298,7 @@ public: | ||||||
|         Flex, |         Flex, | ||||||
|         FlexFlow, |         FlexFlow, | ||||||
|         Font, |         Font, | ||||||
|  |         Frequency, | ||||||
|         Identifier, |         Identifier, | ||||||
|         Image, |         Image, | ||||||
|         Inherit, |         Inherit, | ||||||
|  | @ -330,6 +332,7 @@ public: | ||||||
|     bool is_flex() const { return type() == Type::Flex; } |     bool is_flex() const { return type() == Type::Flex; } | ||||||
|     bool is_flex_flow() const { return type() == Type::FlexFlow; } |     bool is_flex_flow() const { return type() == Type::FlexFlow; } | ||||||
|     bool is_font() const { return type() == Type::Font; } |     bool is_font() const { return type() == Type::Font; } | ||||||
|  |     bool is_frequency() const { return type() == Type::Frequency; } | ||||||
|     bool is_identifier() const { return type() == Type::Identifier; } |     bool is_identifier() const { return type() == Type::Identifier; } | ||||||
|     bool is_image() const { return type() == Type::Image; } |     bool is_image() const { return type() == Type::Image; } | ||||||
|     bool is_inherit() const { return type() == Type::Inherit; } |     bool is_inherit() const { return type() == Type::Inherit; } | ||||||
|  | @ -361,6 +364,7 @@ public: | ||||||
|     FlexFlowStyleValue const& as_flex_flow() const; |     FlexFlowStyleValue const& as_flex_flow() const; | ||||||
|     FlexStyleValue const& as_flex() const; |     FlexStyleValue const& as_flex() const; | ||||||
|     FontStyleValue const& as_font() const; |     FontStyleValue const& as_font() const; | ||||||
|  |     FrequencyStyleValue const& as_frequency() const; | ||||||
|     IdentifierStyleValue const& as_identifier() const; |     IdentifierStyleValue const& as_identifier() const; | ||||||
|     ImageStyleValue const& as_image() const; |     ImageStyleValue const& as_image() const; | ||||||
|     InheritStyleValue const& as_inherit() const; |     InheritStyleValue const& as_inherit() const; | ||||||
|  | @ -390,6 +394,7 @@ public: | ||||||
|     FlexFlowStyleValue& as_flex_flow() { return const_cast<FlexFlowStyleValue&>(const_cast<StyleValue const&>(*this).as_flex_flow()); } |     FlexFlowStyleValue& as_flex_flow() { return const_cast<FlexFlowStyleValue&>(const_cast<StyleValue const&>(*this).as_flex_flow()); } | ||||||
|     FlexStyleValue& as_flex() { return const_cast<FlexStyleValue&>(const_cast<StyleValue const&>(*this).as_flex()); } |     FlexStyleValue& as_flex() { return const_cast<FlexStyleValue&>(const_cast<StyleValue const&>(*this).as_flex()); } | ||||||
|     FontStyleValue& as_font() { return const_cast<FontStyleValue&>(const_cast<StyleValue const&>(*this).as_font()); } |     FontStyleValue& as_font() { return const_cast<FontStyleValue&>(const_cast<StyleValue const&>(*this).as_font()); } | ||||||
|  |     FrequencyStyleValue& as_frequency() { return const_cast<FrequencyStyleValue&>(const_cast<StyleValue const&>(*this).as_frequency()); } | ||||||
|     IdentifierStyleValue& as_identifier() { return const_cast<IdentifierStyleValue&>(const_cast<StyleValue const&>(*this).as_identifier()); } |     IdentifierStyleValue& as_identifier() { return const_cast<IdentifierStyleValue&>(const_cast<StyleValue const&>(*this).as_identifier()); } | ||||||
|     ImageStyleValue& as_image() { return const_cast<ImageStyleValue&>(const_cast<StyleValue const&>(*this).as_image()); } |     ImageStyleValue& as_image() { return const_cast<ImageStyleValue&>(const_cast<StyleValue const&>(*this).as_image()); } | ||||||
|     InheritStyleValue& as_inherit() { return const_cast<InheritStyleValue&>(const_cast<StyleValue const&>(*this).as_inherit()); } |     InheritStyleValue& as_inherit() { return const_cast<InheritStyleValue&>(const_cast<StyleValue const&>(*this).as_inherit()); } | ||||||
|  | @ -730,11 +735,11 @@ public: | ||||||
|         float value; |         float value; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     using PercentageBasis = Variant<Empty, Angle, Length>; |     using PercentageBasis = Variant<Empty, Angle, Frequency, Length>; | ||||||
| 
 | 
 | ||||||
|     class CalculationResult { |     class CalculationResult { | ||||||
|     public: |     public: | ||||||
|         CalculationResult(Variant<Number, Angle, Length, Percentage> value) |         CalculationResult(Variant<Number, Angle, Frequency, Length, Percentage> value) | ||||||
|             : m_value(move(value)) |             : m_value(move(value)) | ||||||
|         { |         { | ||||||
|         } |         } | ||||||
|  | @ -743,11 +748,11 @@ public: | ||||||
|         void multiply_by(CalculationResult const& other, Layout::Node const*); |         void multiply_by(CalculationResult const& other, Layout::Node const*); | ||||||
|         void divide_by(CalculationResult const& other, Layout::Node const*); |         void divide_by(CalculationResult const& other, Layout::Node const*); | ||||||
| 
 | 
 | ||||||
|         Variant<Number, Angle, Length, Percentage> const& value() const { return m_value; } |         Variant<Number, Angle, Frequency, Length, Percentage> const& value() const { return m_value; } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         void add_or_subtract_internal(SumOperation op, CalculationResult const& other, Layout::Node const*, PercentageBasis const& percentage_basis); |         void add_or_subtract_internal(SumOperation op, CalculationResult const& other, Layout::Node const*, PercentageBasis const& percentage_basis); | ||||||
|         Variant<Number, Angle, Length, Percentage> m_value; |         Variant<Number, Angle, Frequency, Length, Percentage> m_value; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     struct CalcSum; |     struct CalcSum; | ||||||
|  | @ -767,7 +772,7 @@ public: | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     struct CalcValue { |     struct CalcValue { | ||||||
|         Variant<Number, Angle, Length, Percentage, NonnullOwnPtr<CalcSum>> value; |         Variant<Number, Angle, Frequency, Length, Percentage, NonnullOwnPtr<CalcSum>> value; | ||||||
|         String to_string() const; |         String to_string() const; | ||||||
|         Optional<ResolvedType> resolved_type() const; |         Optional<ResolvedType> resolved_type() const; | ||||||
|         CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; |         CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; | ||||||
|  | @ -873,6 +878,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     Optional<Angle> resolve_angle() const; |     Optional<Angle> resolve_angle() const; | ||||||
|     Optional<AnglePercentage> resolve_angle_percentage(Angle const& percentage_basis) const; |     Optional<AnglePercentage> resolve_angle_percentage(Angle const& percentage_basis) const; | ||||||
|  |     Optional<Frequency> resolve_frequency() const; | ||||||
|  |     Optional<FrequencyPercentage> resolve_frequency_percentage(Frequency const& percentage_basis) const; | ||||||
|     Optional<Length> resolve_length(Layout::Node const& layout_node) const; |     Optional<Length> resolve_length(Layout::Node const& layout_node) const; | ||||||
|     Optional<LengthPercentage> resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const; |     Optional<LengthPercentage> resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const; | ||||||
|     Optional<Percentage> resolve_percentage() const; |     Optional<Percentage> resolve_percentage() const; | ||||||
|  | @ -1040,6 +1047,35 @@ private: | ||||||
|     // FIXME: Implement font-stretch and font-variant.
 |     // FIXME: Implement font-stretch and font-variant.
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class FrequencyStyleValue : public StyleValue { | ||||||
|  | public: | ||||||
|  |     static NonnullRefPtr<FrequencyStyleValue> create(Frequency frequency) | ||||||
|  |     { | ||||||
|  |         return adopt_ref(*new FrequencyStyleValue(move(frequency))); | ||||||
|  |     } | ||||||
|  |     virtual ~FrequencyStyleValue() override { } | ||||||
|  | 
 | ||||||
|  |     Frequency const& frequency() const { return m_frequency; } | ||||||
|  | 
 | ||||||
|  |     virtual String to_string() const override { return m_frequency.to_string(); } | ||||||
|  | 
 | ||||||
|  |     virtual bool equals(StyleValue const& other) const override | ||||||
|  |     { | ||||||
|  |         if (type() != other.type()) | ||||||
|  |             return false; | ||||||
|  |         return m_frequency == static_cast<FrequencyStyleValue const&>(other).m_frequency; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     explicit FrequencyStyleValue(Frequency frequency) | ||||||
|  |         : StyleValue(Type::Frequency) | ||||||
|  |         , m_frequency(move(frequency)) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Frequency m_frequency; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class IdentifierStyleValue final : public StyleValue { | class IdentifierStyleValue final : public StyleValue { | ||||||
| public: | public: | ||||||
|     static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id) |     static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id) | ||||||
|  |  | ||||||
|  | @ -43,6 +43,9 @@ class ElementInlineCSSStyleDeclaration; | ||||||
| class FlexFlowStyleValue; | class FlexFlowStyleValue; | ||||||
| class FlexStyleValue; | class FlexStyleValue; | ||||||
| class FontStyleValue; | class FontStyleValue; | ||||||
|  | class Frequency; | ||||||
|  | class FrequencyPercentage; | ||||||
|  | class FrequencyStyleValue; | ||||||
| class IdentifierStyleValue; | class IdentifierStyleValue; | ||||||
| class ImageStyleValue; | class ImageStyleValue; | ||||||
| class InheritStyleValue; | class InheritStyleValue; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Atkins
						Sam Atkins