mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 13:37:43 +00:00
LibWeb: Implement CSS Angle class
This corresponds to `<angle>` in the grammar.
This commit is contained in:
parent
a07fed4e53
commit
355d1936f2
9 changed files with 293 additions and 31 deletions
|
@ -15,6 +15,7 @@ set(SOURCES
|
||||||
Bindings/Wrappable.cpp
|
Bindings/Wrappable.cpp
|
||||||
Crypto/Crypto.cpp
|
Crypto/Crypto.cpp
|
||||||
Crypto/SubtleCrypto.cpp
|
Crypto/SubtleCrypto.cpp
|
||||||
|
CSS/Angle.cpp
|
||||||
CSS/CSSConditionRule.cpp
|
CSS/CSSConditionRule.cpp
|
||||||
CSS/CSSGroupingRule.cpp
|
CSS/CSSGroupingRule.cpp
|
||||||
CSS/CSSImportRule.cpp
|
CSS/CSSImportRule.cpp
|
||||||
|
|
99
Userland/Libraries/LibWeb/CSS/Angle.cpp
Normal file
99
Userland/Libraries/LibWeb/CSS/Angle.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Angle.h"
|
||||||
|
#include <AK/Math.h>
|
||||||
|
#include <LibWeb/CSS/StyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
Angle::Angle(int value, Type type)
|
||||||
|
: m_type(type)
|
||||||
|
, m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle::Angle(float value, Type type)
|
||||||
|
: m_type(type)
|
||||||
|
, m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle Angle::make_calculated(NonnullRefPtr<CalculatedStyleValue> calculated_style_value)
|
||||||
|
{
|
||||||
|
Angle angle { 0, Type::Calculated };
|
||||||
|
angle.m_calculated_style = move(calculated_style_value);
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle Angle::make_degrees(float value)
|
||||||
|
{
|
||||||
|
return { value, Type::Deg };
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle Angle::percentage_of(Percentage const& percentage) const
|
||||||
|
{
|
||||||
|
VERIFY(!is_calculated());
|
||||||
|
|
||||||
|
return Angle { percentage.as_fraction() * m_value, m_type };
|
||||||
|
}
|
||||||
|
|
||||||
|
String Angle::to_string() const
|
||||||
|
{
|
||||||
|
if (is_calculated())
|
||||||
|
return m_calculated_style->to_string();
|
||||||
|
return String::formatted("{}{}", m_value, unit_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
float Angle::to_degrees() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::Calculated:
|
||||||
|
return m_calculated_style->resolve_angle()->to_degrees();
|
||||||
|
case Type::Deg:
|
||||||
|
return m_value;
|
||||||
|
case Type::Grad:
|
||||||
|
return m_value * (360.0f / 400.0f);
|
||||||
|
case Type::Rad:
|
||||||
|
return m_value * (360.0f / 2 * AK::Pi<float>);
|
||||||
|
case Type::Turn:
|
||||||
|
return m_value * 360.0f;
|
||||||
|
}
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView Angle::unit_name() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::Calculated:
|
||||||
|
return "calculated"sv;
|
||||||
|
case Type::Deg:
|
||||||
|
return "deg"sv;
|
||||||
|
case Type::Grad:
|
||||||
|
return "grad"sv;
|
||||||
|
case Type::Rad:
|
||||||
|
return "rad"sv;
|
||||||
|
case Type::Turn:
|
||||||
|
return "turn"sv;
|
||||||
|
}
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Angle::Type> Angle::unit_from_name(StringView name)
|
||||||
|
{
|
||||||
|
if (name.equals_ignoring_case("deg"sv)) {
|
||||||
|
return Type::Deg;
|
||||||
|
} else if (name.equals_ignoring_case("grad"sv)) {
|
||||||
|
return Type::Grad;
|
||||||
|
} else if (name.equals_ignoring_case("rad"sv)) {
|
||||||
|
return Type::Rad;
|
||||||
|
} else if (name.equals_ignoring_case("turn"sv)) {
|
||||||
|
return Type::Turn;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
Userland/Libraries/LibWeb/CSS/Angle.h
Normal file
57
Userland/Libraries/LibWeb/CSS/Angle.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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 Angle {
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
Calculated,
|
||||||
|
Deg,
|
||||||
|
Grad,
|
||||||
|
Rad,
|
||||||
|
Turn,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Optional<Type> unit_from_name(StringView);
|
||||||
|
|
||||||
|
Angle(int value, Type type);
|
||||||
|
Angle(float value, Type type);
|
||||||
|
static Angle make_calculated(NonnullRefPtr<CalculatedStyleValue>);
|
||||||
|
static Angle make_degrees(float);
|
||||||
|
Angle percentage_of(Percentage const&) const;
|
||||||
|
|
||||||
|
bool is_calculated() const { return m_type == Type::Calculated; }
|
||||||
|
|
||||||
|
String to_string() const;
|
||||||
|
float to_degrees() const;
|
||||||
|
|
||||||
|
bool operator==(Angle 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!=(Angle const& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringView unit_name() const;
|
||||||
|
|
||||||
|
Type m_type;
|
||||||
|
float m_value { 0 };
|
||||||
|
RefPtr<CalculatedStyleValue> m_calculated_style;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -4298,6 +4298,8 @@ Optional<CalculatedStyleValue::CalcValue> Parser::parse_calc_value(TokenStream<S
|
||||||
return {};
|
return {};
|
||||||
auto& dimension = maybe_dimension.value();
|
auto& dimension = maybe_dimension.value();
|
||||||
|
|
||||||
|
if (dimension.is_angle())
|
||||||
|
return CalculatedStyleValue::CalcValue { dimension.angle() };
|
||||||
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())
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
Angle AnglePercentage::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const& layout_node, Angle const& reference_value) const
|
||||||
|
{
|
||||||
|
return calculated->resolve_angle_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);
|
||||||
|
|
|
@ -8,6 +8,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/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
@ -80,7 +81,7 @@ public:
|
||||||
return m_value.template get<Percentage>();
|
return m_value.template get<Percentage>();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual T resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&, [[maybe_unused]] T const& reference_value) const
|
virtual T resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, [[maybe_unused]] Layout::Node const&, [[maybe_unused]] T const& reference_value) const
|
||||||
{
|
{
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -151,6 +152,14 @@ bool operator==(Percentage const& percentage, PercentageOr<T> const& percentage_
|
||||||
return percentage == percentage_or;
|
return percentage == percentage_or;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AnglePercentage : public PercentageOr<Angle> {
|
||||||
|
public:
|
||||||
|
using PercentageOr<Angle>::PercentageOr;
|
||||||
|
|
||||||
|
bool is_angle() const { return is_t(); }
|
||||||
|
Angle const& angle() const { return get_t(); }
|
||||||
|
virtual Angle resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&, Angle 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;
|
||||||
|
@ -171,6 +180,13 @@ struct AK::Formatter<Web::CSS::Percentage> : Formatter<StringView> {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
struct AK::Formatter<Web::CSS::AnglePercentage> : Formatter<StringView> {
|
||||||
|
ErrorOr<void> format(FormatBuilder& builder, Web::CSS::AnglePercentage const& angle_percentage)
|
||||||
|
{
|
||||||
|
return Formatter<StringView>::format(builder, angle_percentage.to_string());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,12 @@ StyleValue::~StyleValue()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AngleStyleValue const& StyleValue::as_angle() const
|
||||||
|
{
|
||||||
|
VERIFY(is_angle());
|
||||||
|
return static_cast<AngleStyleValue const&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
BackgroundStyleValue const& StyleValue::as_background() const
|
BackgroundStyleValue const& StyleValue::as_background() const
|
||||||
{
|
{
|
||||||
VERIFY(is_background());
|
VERIFY(is_background());
|
||||||
|
@ -309,6 +315,24 @@ void CalculatedStyleValue::CalculationResult::add_or_subtract_internal(SumOperat
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[&](Angle const& angle) {
|
||||||
|
auto this_degrees = angle.to_degrees();
|
||||||
|
if (other.m_value.has<Angle>()) {
|
||||||
|
auto other_degrees = other.m_value.get<Angle>().to_degrees();
|
||||||
|
if (op == SumOperation::Add)
|
||||||
|
m_value = Angle::make_degrees(this_degrees + other_degrees);
|
||||||
|
else
|
||||||
|
m_value = Angle::make_degrees(this_degrees - other_degrees);
|
||||||
|
} else {
|
||||||
|
VERIFY(percentage_basis.has<Angle>());
|
||||||
|
|
||||||
|
auto other_degrees = percentage_basis.get<Angle>().percentage_of(other.m_value.get<Percentage>()).to_degrees();
|
||||||
|
if (op == SumOperation::Add)
|
||||||
|
m_value = Angle::make_degrees(this_degrees + other_degrees);
|
||||||
|
else
|
||||||
|
m_value = Angle::make_degrees(this_degrees - other_degrees);
|
||||||
|
}
|
||||||
|
},
|
||||||
[&](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>()) {
|
||||||
|
@ -369,6 +393,9 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
|
||||||
*this = new_value;
|
*this = new_value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[&](Angle const& angle) {
|
||||||
|
m_value = Angle::make_degrees(angle.to_degrees() * 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);
|
||||||
|
@ -393,6 +420,9 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const&
|
||||||
.value = number.value / denominator
|
.value = number.value / denominator
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
[&](Angle const& angle) {
|
||||||
|
m_value = Angle::make_degrees(angle.to_degrees() / 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);
|
||||||
|
@ -418,9 +448,8 @@ String CalculatedStyleValue::CalcValue::to_string() const
|
||||||
{
|
{
|
||||||
return value.visit(
|
return value.visit(
|
||||||
[](Number const& number) { return String::number(number.value); },
|
[](Number const& number) { return String::number(number.value); },
|
||||||
[](Length const& length) { return length.to_string(); },
|
[](NonnullOwnPtr<CalcSum> const& sum) { return String::formatted("({})", sum->to_string()); },
|
||||||
[](Percentage const& percentage) { return percentage.to_string(); },
|
[](auto const& v) { return v.to_string(); });
|
||||||
[](NonnullOwnPtr<CalcSum> const& sum) { return String::formatted("({})", sum->to_string()); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String CalculatedStyleValue::CalcSum::to_string() const
|
String CalculatedStyleValue::CalcSum::to_string() const
|
||||||
|
@ -482,20 +511,38 @@ String CalculatedStyleValue::CalcNumberSumPartWithOperator::to_string() const
|
||||||
return String::formatted(" {} {}", op == SumOperation::Add ? "+"sv : "-"sv, value->to_string());
|
return String::formatted(" {} {}", op == SumOperation::Add ? "+"sv : "-"sv, value->to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<Angle> CalculatedStyleValue::resolve_angle() const
|
||||||
|
{
|
||||||
|
auto result = m_expression->resolve(nullptr, {});
|
||||||
|
|
||||||
|
if (result.value().has<Angle>())
|
||||||
|
return result.value().get<Angle>();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<AnglePercentage> CalculatedStyleValue::resolve_angle_percentage(Angle const& percentage_basis) const
|
||||||
|
{
|
||||||
|
auto result = m_expression->resolve(nullptr, percentage_basis);
|
||||||
|
|
||||||
|
return result.value().visit(
|
||||||
|
[&](Angle const& angle) -> Optional<AnglePercentage> {
|
||||||
|
return angle;
|
||||||
|
},
|
||||||
|
[&](Percentage const& percentage) -> Optional<AnglePercentage> {
|
||||||
|
return percentage;
|
||||||
|
},
|
||||||
|
[&](auto const&) -> Optional<AnglePercentage> {
|
||||||
|
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, {});
|
||||||
|
|
||||||
return result.value().visit(
|
if (result.value().has<Length>())
|
||||||
[&](Number) -> Optional<Length> {
|
return result.value().get<Length>();
|
||||||
return {};
|
return {};
|
||||||
},
|
|
||||||
[&](Length const& length) -> Optional<Length> {
|
|
||||||
return length;
|
|
||||||
},
|
|
||||||
[&](Percentage const&) -> Optional<Length> {
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<LengthPercentage> CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, Length const& percentage_basis) const
|
Optional<LengthPercentage> CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, Length const& percentage_basis) const
|
||||||
|
@ -503,14 +550,14 @@ Optional<LengthPercentage> CalculatedStyleValue::resolve_length_percentage(Layou
|
||||||
auto result = m_expression->resolve(&layout_node, percentage_basis);
|
auto result = m_expression->resolve(&layout_node, percentage_basis);
|
||||||
|
|
||||||
return result.value().visit(
|
return result.value().visit(
|
||||||
[&](Number) -> Optional<LengthPercentage> {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
[&](Length const& length) -> Optional<LengthPercentage> {
|
[&](Length const& length) -> Optional<LengthPercentage> {
|
||||||
return length;
|
return length;
|
||||||
},
|
},
|
||||||
[&](Percentage const& percentage) -> Optional<LengthPercentage> {
|
[&](Percentage const& percentage) -> Optional<LengthPercentage> {
|
||||||
return percentage;
|
return percentage;
|
||||||
|
},
|
||||||
|
[&](auto const&) -> Optional<LengthPercentage> {
|
||||||
|
return {};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +744,7 @@ Optional<CalculatedStyleValue::ResolvedType> CalculatedStyleValue::CalcValue::re
|
||||||
[](Number const& number) -> Optional<CalculatedStyleValue::ResolvedType> {
|
[](Number const& number) -> Optional<CalculatedStyleValue::ResolvedType> {
|
||||||
return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number };
|
return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number };
|
||||||
},
|
},
|
||||||
|
[](Angle const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Angle }; },
|
||||||
[](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(); });
|
||||||
|
@ -725,17 +773,11 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberValue::r
|
||||||
CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcValue::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const
|
CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcValue::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const
|
||||||
{
|
{
|
||||||
return value.visit(
|
return value.visit(
|
||||||
[&](Number const& number) -> CalculatedStyleValue::CalculationResult {
|
|
||||||
return CalculatedStyleValue::CalculationResult { number };
|
|
||||||
},
|
|
||||||
[&](Length const& length) -> CalculatedStyleValue::CalculationResult {
|
|
||||||
return CalculatedStyleValue::CalculationResult { length };
|
|
||||||
},
|
|
||||||
[&](Percentage const& percentage) -> CalculatedStyleValue::CalculationResult {
|
|
||||||
return CalculatedStyleValue::CalculationResult { percentage };
|
|
||||||
},
|
|
||||||
[&](NonnullOwnPtr<CalcSum> const& sum) -> CalculatedStyleValue::CalculationResult {
|
[&](NonnullOwnPtr<CalcSum> const& sum) -> CalculatedStyleValue::CalculationResult {
|
||||||
return sum->resolve(layout_node, percentage_basis);
|
return sum->resolve(layout_node, percentage_basis);
|
||||||
|
},
|
||||||
|
[&](auto const& v) -> CalculatedStyleValue::CalculationResult {
|
||||||
|
return CalculatedStyleValue::CalculationResult { v };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
#include <LibGfx/Bitmap.h>
|
#include <LibGfx/Bitmap.h>
|
||||||
#include <LibGfx/Color.h>
|
#include <LibGfx/Color.h>
|
||||||
|
#include <LibWeb/CSS/Angle.h>
|
||||||
#include <LibWeb/CSS/Display.h>
|
#include <LibWeb/CSS/Display.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
#include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
|
#include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
|
||||||
|
@ -283,6 +284,7 @@ public:
|
||||||
virtual ~StyleValue();
|
virtual ~StyleValue();
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
Angle,
|
||||||
Background,
|
Background,
|
||||||
BackgroundRepeat,
|
BackgroundRepeat,
|
||||||
BackgroundSize,
|
BackgroundSize,
|
||||||
|
@ -316,6 +318,7 @@ public:
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
|
bool is_angle() const { return type() == Type::Angle; }
|
||||||
bool is_background() const { return type() == Type::Background; }
|
bool is_background() const { return type() == Type::Background; }
|
||||||
bool is_background_repeat() const { return type() == Type::BackgroundRepeat; }
|
bool is_background_repeat() const { return type() == Type::BackgroundRepeat; }
|
||||||
bool is_background_size() const { return type() == Type::BackgroundSize; }
|
bool is_background_size() const { return type() == Type::BackgroundSize; }
|
||||||
|
@ -346,6 +349,7 @@ public:
|
||||||
|
|
||||||
bool is_builtin() const { return is_inherit() || is_initial() || is_unset(); }
|
bool is_builtin() const { return is_inherit() || is_initial() || is_unset(); }
|
||||||
|
|
||||||
|
AngleStyleValue const& as_angle() const;
|
||||||
BackgroundStyleValue const& as_background() const;
|
BackgroundStyleValue const& as_background() const;
|
||||||
BackgroundRepeatStyleValue const& as_background_repeat() const;
|
BackgroundRepeatStyleValue const& as_background_repeat() const;
|
||||||
BackgroundSizeStyleValue const& as_background_size() const;
|
BackgroundSizeStyleValue const& as_background_size() const;
|
||||||
|
@ -374,6 +378,7 @@ public:
|
||||||
UnsetStyleValue const& as_unset() const;
|
UnsetStyleValue const& as_unset() const;
|
||||||
StyleValueList const& as_value_list() const;
|
StyleValueList const& as_value_list() const;
|
||||||
|
|
||||||
|
AngleStyleValue& as_angle() { return const_cast<AngleStyleValue&>(const_cast<StyleValue const&>(*this).as_angle()); }
|
||||||
BackgroundStyleValue& as_background() { return const_cast<BackgroundStyleValue&>(const_cast<StyleValue const&>(*this).as_background()); }
|
BackgroundStyleValue& as_background() { return const_cast<BackgroundStyleValue&>(const_cast<StyleValue const&>(*this).as_background()); }
|
||||||
BackgroundRepeatStyleValue& as_background_repeat() { return const_cast<BackgroundRepeatStyleValue&>(const_cast<StyleValue const&>(*this).as_background_repeat()); }
|
BackgroundRepeatStyleValue& as_background_repeat() { return const_cast<BackgroundRepeatStyleValue&>(const_cast<StyleValue const&>(*this).as_background_repeat()); }
|
||||||
BackgroundSizeStyleValue& as_background_size() { return const_cast<BackgroundSizeStyleValue&>(const_cast<StyleValue const&>(*this).as_background_size()); }
|
BackgroundSizeStyleValue& as_background_size() { return const_cast<BackgroundSizeStyleValue&>(const_cast<StyleValue const&>(*this).as_background_size()); }
|
||||||
|
@ -435,6 +440,35 @@ private:
|
||||||
Type m_type { Type::Invalid };
|
Type m_type { Type::Invalid };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AngleStyleValue : public StyleValue {
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<AngleStyleValue> create(Angle angle)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new AngleStyleValue(move(angle)));
|
||||||
|
}
|
||||||
|
virtual ~AngleStyleValue() override { }
|
||||||
|
|
||||||
|
Angle const& angle() const { return m_angle; }
|
||||||
|
|
||||||
|
virtual String to_string() const override { return m_angle.to_string(); }
|
||||||
|
|
||||||
|
virtual bool equals(StyleValue const& other) const override
|
||||||
|
{
|
||||||
|
if (type() != other.type())
|
||||||
|
return false;
|
||||||
|
return m_angle == static_cast<AngleStyleValue const&>(other).m_angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit AngleStyleValue(Angle angle)
|
||||||
|
: StyleValue(Type::Angle)
|
||||||
|
, m_angle(move(angle))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle m_angle;
|
||||||
|
};
|
||||||
|
|
||||||
class BackgroundStyleValue final : public StyleValue {
|
class BackgroundStyleValue final : public StyleValue {
|
||||||
public:
|
public:
|
||||||
static NonnullRefPtr<BackgroundStyleValue> create(
|
static NonnullRefPtr<BackgroundStyleValue> create(
|
||||||
|
@ -696,11 +730,11 @@ public:
|
||||||
float value;
|
float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
using PercentageBasis = Variant<Empty, Length>;
|
using PercentageBasis = Variant<Empty, Angle, Length>;
|
||||||
|
|
||||||
class CalculationResult {
|
class CalculationResult {
|
||||||
public:
|
public:
|
||||||
CalculationResult(Variant<Number, Length, Percentage> value)
|
CalculationResult(Variant<Number, Angle, Length, Percentage> value)
|
||||||
: m_value(move(value))
|
: m_value(move(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -709,11 +743,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, Length, Percentage> const& value() const { return m_value; }
|
Variant<Number, Angle, 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, Length, Percentage> m_value;
|
Variant<Number, Angle, Length, Percentage> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CalcSum;
|
struct CalcSum;
|
||||||
|
@ -733,7 +767,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CalcValue {
|
struct CalcValue {
|
||||||
Variant<Number, Length, Percentage, NonnullOwnPtr<CalcSum>> value;
|
Variant<Number, Angle, 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;
|
||||||
|
@ -836,6 +870,9 @@ public:
|
||||||
String to_string() const override;
|
String to_string() const override;
|
||||||
ResolvedType resolved_type() const { return m_resolved_type; }
|
ResolvedType resolved_type() const { return m_resolved_type; }
|
||||||
NonnullOwnPtr<CalcSum> const& expression() const { return m_expression; }
|
NonnullOwnPtr<CalcSum> const& expression() const { return m_expression; }
|
||||||
|
|
||||||
|
Optional<Angle> resolve_angle() const;
|
||||||
|
Optional<AnglePercentage> resolve_angle_percentage(Angle 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;
|
||||||
|
|
|
@ -19,6 +19,9 @@ class SubtleCrypto;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
class Angle;
|
||||||
|
class AnglePercentage;
|
||||||
|
class AngleStyleValue;
|
||||||
class BackgroundRepeatStyleValue;
|
class BackgroundRepeatStyleValue;
|
||||||
class BackgroundSizeStyleValue;
|
class BackgroundSizeStyleValue;
|
||||||
class BackgroundStyleValue;
|
class BackgroundStyleValue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue