mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 09:18:55 +00:00
LibWeb/CSS: Use generated FooUnit types instead of Foo::Type
I've also renamed the `m_type` and `type()` members to be `m_unit` and `unit()` instead, to match what they actually are.
This commit is contained in:
parent
bda4f8cbe8
commit
b3e32445d3
Notes:
github-actions[bot]
2025-09-11 16:08:15 +00:00
Author: https://github.com/AtkinsSJ
Commit: b3e32445d3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6071
29 changed files with 232 additions and 669 deletions
|
@ -12,20 +12,20 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
Angle::Angle(double value, Type type)
|
||||
: m_type(type)
|
||||
Angle::Angle(double value, AngleUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Angle Angle::make_degrees(double value)
|
||||
{
|
||||
return { value, Type::Deg };
|
||||
return { value, AngleUnit::Deg };
|
||||
}
|
||||
|
||||
Angle Angle::percentage_of(Percentage const& percentage) const
|
||||
{
|
||||
return Angle { percentage.as_fraction() * m_value, m_type };
|
||||
return Angle { percentage.as_fraction() * m_value, m_unit };
|
||||
}
|
||||
|
||||
String Angle::to_string(SerializationMode serialization_mode) const
|
||||
|
@ -48,14 +48,14 @@ String Angle::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
double Angle::to_degrees() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Deg:
|
||||
switch (m_unit) {
|
||||
case AngleUnit::Deg:
|
||||
return m_value;
|
||||
case Type::Grad:
|
||||
case AngleUnit::Grad:
|
||||
return m_value * (360.0 / 400.0);
|
||||
case Type::Rad:
|
||||
case AngleUnit::Rad:
|
||||
return AK::to_degrees(m_value);
|
||||
case Type::Turn:
|
||||
case AngleUnit::Turn:
|
||||
return m_value * 360.0;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -66,38 +66,6 @@ double Angle::to_radians() const
|
|||
return AK::to_radians(to_degrees());
|
||||
}
|
||||
|
||||
StringView Angle::unit_name() const
|
||||
{
|
||||
switch (m_type) {
|
||||
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_ascii_case("deg"sv)) {
|
||||
return Type::Deg;
|
||||
}
|
||||
if (name.equals_ignoring_ascii_case("grad"sv)) {
|
||||
return Type::Grad;
|
||||
}
|
||||
if (name.equals_ignoring_ascii_case("rad"sv)) {
|
||||
return Type::Rad;
|
||||
}
|
||||
if (name.equals_ignoring_ascii_case("turn"sv)) {
|
||||
return Type::Turn;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Angle Angle::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Angle const& reference_value)
|
||||
{
|
||||
CalculationResolutionContext context {
|
||||
|
|
|
@ -15,16 +15,7 @@ namespace Web::CSS {
|
|||
|
||||
class Angle {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
Deg,
|
||||
Grad,
|
||||
Rad,
|
||||
Turn,
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Angle(double value, Type type);
|
||||
Angle(double value, AngleUnit unit);
|
||||
static Angle make_degrees(double);
|
||||
Angle percentage_of(Percentage const&) const;
|
||||
|
||||
|
@ -33,13 +24,13 @@ public:
|
|||
double to_degrees() const;
|
||||
double to_radians() const;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
AngleUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
bool operator==(Angle const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
int operator<=>(Angle const& other) const
|
||||
|
@ -57,7 +48,7 @@ public:
|
|||
static Angle resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const&, Layout::Node const&, Angle const& reference_value);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
AngleUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -378,17 +378,17 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r
|
|||
return line_height.as_length().length().to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
|
||||
if (line_height.is_number())
|
||||
return Length(line_height.as_number().number(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
return Length(line_height.as_number().number(), LengthUnit::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
|
||||
if (line_height.is_percentage()) {
|
||||
// Percentages are relative to 1em. https://www.w3.org/TR/css-inline-3/#valdef-line-height-percentage
|
||||
auto const& percentage = line_height.as_percentage().percentage();
|
||||
return Length(percentage.as_fraction(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
return Length(percentage.as_fraction(), LengthUnit::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
}
|
||||
|
||||
if (line_height.is_calculated()) {
|
||||
CalculationResolutionContext context {
|
||||
.percentage_basis = Length(1, Length::Type::Em),
|
||||
.percentage_basis = Length(1, LengthUnit::Em),
|
||||
.length_resolution_context = Length::ResolutionContext { viewport_rect, font_metrics, root_font_metrics },
|
||||
};
|
||||
if (line_height.as_calculated().resolves_to_number()) {
|
||||
|
@ -397,7 +397,7 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r
|
|||
dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height.as_calculated().to_string(SerializationMode::Normal));
|
||||
return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing());
|
||||
}
|
||||
return Length(resolved.value(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
return Length(resolved.value(), LengthUnit::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
|
||||
}
|
||||
|
||||
auto resolved = line_height.as_calculated().resolve_length_deprecated(context);
|
||||
|
@ -565,7 +565,7 @@ Length ComputedProperties::border_spacing_horizontal(Layout::Node const& layout_
|
|||
if (style_value.is_length())
|
||||
return style_value.as_length().length();
|
||||
if (style_value.is_calculated())
|
||||
return style_value.as_calculated().resolve_length_deprecated({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(Length(0, Length::Type::Px));
|
||||
return style_value.as_calculated().resolve_length_deprecated({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(Length::make_px(0));
|
||||
return {};
|
||||
};
|
||||
|
||||
|
@ -587,7 +587,7 @@ Length ComputedProperties::border_spacing_vertical(Layout::Node const& layout_no
|
|||
if (style_value.is_length())
|
||||
return style_value.as_length().length();
|
||||
if (style_value.is_calculated())
|
||||
return style_value.as_calculated().resolve_length_deprecated({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(Length(0, Length::Type::Px));
|
||||
return style_value.as_calculated().resolve_length_deprecated({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(Length::make_px(0));
|
||||
return {};
|
||||
};
|
||||
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
Flex::Flex(double value, Type type)
|
||||
: m_type(type)
|
||||
Flex::Flex(double value, FlexUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Flex Flex::make_fr(double value)
|
||||
{
|
||||
return { value, Type::Fr };
|
||||
return { value, FlexUnit::Fr };
|
||||
}
|
||||
|
||||
Flex Flex::percentage_of(Percentage const& percentage) const
|
||||
{
|
||||
return Flex { percentage.as_fraction() * m_value, m_type };
|
||||
return Flex { percentage.as_fraction() * m_value, m_unit };
|
||||
}
|
||||
|
||||
String Flex::to_string(SerializationMode serialization_mode) const
|
||||
|
@ -44,28 +44,11 @@ String Flex::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
double Flex::to_fr() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Fr:
|
||||
switch (m_unit) {
|
||||
case FlexUnit::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 {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/CSS/SerializationMode.h>
|
||||
#include <LibWeb/CSS/Units.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
@ -16,26 +16,20 @@ namespace Web::CSS {
|
|||
// https://drafts.csswg.org/css-grid-2/#typedef-flex
|
||||
class Flex {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
Fr,
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Flex(double value, Type type);
|
||||
Flex(double value, FlexUnit unit);
|
||||
static Flex make_fr(double);
|
||||
Flex percentage_of(Percentage const&) const;
|
||||
|
||||
String to_string(SerializationMode = SerializationMode::Normal) const;
|
||||
double to_fr() const;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
FlexUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
bool operator==(Flex const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
int operator<=>(Flex const& other) const
|
||||
|
@ -51,7 +45,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
FlexUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -11,20 +11,20 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
Frequency::Frequency(double value, Type type)
|
||||
: m_type(type)
|
||||
Frequency::Frequency(double value, FrequencyUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Frequency Frequency::make_hertz(double value)
|
||||
{
|
||||
return { value, Type::Hz };
|
||||
return { value, FrequencyUnit::Hz };
|
||||
}
|
||||
|
||||
Frequency Frequency::percentage_of(Percentage const& percentage) const
|
||||
{
|
||||
return Frequency { percentage.as_fraction() * m_value, m_type };
|
||||
return Frequency { percentage.as_fraction() * m_value, m_unit };
|
||||
}
|
||||
|
||||
String Frequency::to_string(SerializationMode serialization_mode) const
|
||||
|
@ -47,36 +47,15 @@ String Frequency::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
double Frequency::to_hertz() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Hz:
|
||||
switch (m_unit) {
|
||||
case FrequencyUnit::Hz:
|
||||
return m_value;
|
||||
case Type::kHz:
|
||||
case FrequencyUnit::KHz:
|
||||
return m_value * 1000;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
StringView Frequency::unit_name() const
|
||||
{
|
||||
switch (m_type) {
|
||||
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_ascii_case("hz"sv)) {
|
||||
return Type::Hz;
|
||||
} else if (name.equals_ignoring_ascii_case("khz"sv)) {
|
||||
return Type::kHz;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Frequency Frequency::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Frequency const& reference_value)
|
||||
{
|
||||
CalculationResolutionContext context {
|
||||
|
|
|
@ -8,33 +8,27 @@
|
|||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/CSS/SerializationMode.h>
|
||||
#include <LibWeb/CSS/Units.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class Frequency {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
Hz,
|
||||
kHz
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Frequency(double value, Type type);
|
||||
Frequency(double value, FrequencyUnit unit);
|
||||
static Frequency make_hertz(double);
|
||||
Frequency percentage_of(Percentage const&) const;
|
||||
|
||||
String to_string(SerializationMode = SerializationMode::Normal) const;
|
||||
double to_hertz() const;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
FrequencyUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
bool operator==(Frequency const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
int operator<=>(Frequency const& other) const
|
||||
|
@ -52,7 +46,7 @@ public:
|
|||
static Frequency resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const&, Layout::Node const&, Frequency const& reference_value);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
FrequencyUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -1235,7 +1235,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
|
|||
auto const& from_length = from.as_length().length();
|
||||
auto const& to_length = to.as_length().length();
|
||||
auto interpolated_value = interpolate_raw(from_length.raw_value(), to_length.raw_value(), delta, calculation_context.accepted_type_ranges.get(ValueType::Length));
|
||||
return LengthStyleValue::create(Length(interpolated_value, from_length.type()));
|
||||
return LengthStyleValue::create(Length(interpolated_value, from_length.unit()));
|
||||
}
|
||||
case StyleValue::Type::Number: {
|
||||
auto interpolated_value = interpolate_raw(from.as_number().number(), to.as_number().number(), delta, calculation_context.accepted_type_ranges.get(ValueType::Number));
|
||||
|
@ -1287,7 +1287,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
|
|||
return LengthOrAuto::make_auto();
|
||||
// FIXME: Actually handle the units not matching.
|
||||
auto interpolated_value = interpolate_raw(from.length().raw_value(), to.length().raw_value(), delta, calculation_context.accepted_type_ranges.get(ValueType::Rect));
|
||||
return LengthOrAuto { Length { interpolated_value, from.length().type() } };
|
||||
return LengthOrAuto { Length { interpolated_value, from.length().unit() } };
|
||||
};
|
||||
|
||||
return RectStyleValue::create({
|
||||
|
|
|
@ -31,8 +31,8 @@ Length::FontMetrics::FontMetrics(CSSPixels font_size, Gfx::FontPixelMetrics cons
|
|||
{
|
||||
}
|
||||
|
||||
Length::Length(double value, Type type)
|
||||
: m_type(type)
|
||||
Length::Length(double value, LengthUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ Length::~Length() = default;
|
|||
|
||||
Length Length::make_px(double value)
|
||||
{
|
||||
return Length(value, Type::Px);
|
||||
return Length(value, LengthUnit::Px);
|
||||
}
|
||||
|
||||
Length Length::make_px(CSSPixels value)
|
||||
|
@ -50,37 +50,37 @@ Length Length::make_px(CSSPixels value)
|
|||
|
||||
Length Length::percentage_of(Percentage const& percentage) const
|
||||
{
|
||||
return Length { percentage.as_fraction() * raw_value(), m_type };
|
||||
return Length { percentage.as_fraction() * raw_value(), m_unit };
|
||||
}
|
||||
|
||||
CSSPixels Length::font_relative_length_to_px(Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Em:
|
||||
switch (m_unit) {
|
||||
case LengthUnit::Em:
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.font_size.to_double());
|
||||
case Type::Rem:
|
||||
case LengthUnit::Rem:
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Ex:
|
||||
case LengthUnit::Ex:
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.x_height.to_double());
|
||||
case Type::Rex:
|
||||
case LengthUnit::Rex:
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.x_height.to_double());
|
||||
case Type::Cap:
|
||||
case LengthUnit::Cap:
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.cap_height.to_double());
|
||||
case Type::Rcap:
|
||||
case LengthUnit::Rcap:
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.cap_height.to_double());
|
||||
case Type::Ch:
|
||||
case LengthUnit::Ch:
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.zero_advance.to_double());
|
||||
case Type::Rch:
|
||||
case LengthUnit::Rch:
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.zero_advance.to_double());
|
||||
case Type::Ic:
|
||||
case LengthUnit::Ic:
|
||||
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.font_size.to_double());
|
||||
case Type::Ric:
|
||||
case LengthUnit::Ric:
|
||||
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Lh:
|
||||
case LengthUnit::Lh:
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.line_height.to_double());
|
||||
case Type::Rlh:
|
||||
case LengthUnit::Rlh:
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.line_height.to_double());
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -89,38 +89,38 @@ CSSPixels Length::font_relative_length_to_px(Length::FontMetrics const& font_met
|
|||
|
||||
CSSPixels Length::viewport_relative_length_to_px(CSSPixelRect const& viewport_rect) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Vw:
|
||||
case Type::Svw:
|
||||
case Type::Lvw:
|
||||
case Type::Dvw:
|
||||
switch (m_unit) {
|
||||
case LengthUnit::Vw:
|
||||
case LengthUnit::Svw:
|
||||
case LengthUnit::Lvw:
|
||||
case LengthUnit::Dvw:
|
||||
return viewport_rect.width() * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
case Type::Vh:
|
||||
case Type::Svh:
|
||||
case Type::Lvh:
|
||||
case Type::Dvh:
|
||||
case LengthUnit::Vh:
|
||||
case LengthUnit::Svh:
|
||||
case LengthUnit::Lvh:
|
||||
case LengthUnit::Dvh:
|
||||
return viewport_rect.height() * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
case Type::Vi:
|
||||
case Type::Svi:
|
||||
case Type::Lvi:
|
||||
case Type::Dvi:
|
||||
case LengthUnit::Vi:
|
||||
case LengthUnit::Svi:
|
||||
case LengthUnit::Lvi:
|
||||
case LengthUnit::Dvi:
|
||||
// FIXME: Select the width or height based on which is the inline axis.
|
||||
return viewport_rect.width() * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
case Type::Vb:
|
||||
case Type::Svb:
|
||||
case Type::Lvb:
|
||||
case Type::Dvb:
|
||||
case LengthUnit::Vb:
|
||||
case LengthUnit::Svb:
|
||||
case LengthUnit::Lvb:
|
||||
case LengthUnit::Dvb:
|
||||
// FIXME: Select the width or height based on which is the block axis.
|
||||
return viewport_rect.height() * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
case Type::Vmin:
|
||||
case Type::Svmin:
|
||||
case Type::Lvmin:
|
||||
case Type::Dvmin:
|
||||
case LengthUnit::Vmin:
|
||||
case LengthUnit::Svmin:
|
||||
case LengthUnit::Lvmin:
|
||||
case LengthUnit::Dvmin:
|
||||
return min(viewport_rect.width(), viewport_rect.height()) * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
case Type::Vmax:
|
||||
case Type::Svmax:
|
||||
case Type::Lvmax:
|
||||
case Type::Dvmax:
|
||||
case LengthUnit::Vmax:
|
||||
case LengthUnit::Svmax:
|
||||
case LengthUnit::Lvmax:
|
||||
case LengthUnit::Dvmax:
|
||||
return max(viewport_rect.width(), viewport_rect.height()) * (CSSPixels::nearest_value_for(m_value) / 100);
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -215,7 +215,7 @@ String Length::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
// FIXME: Manually skip this for px so we avoid rounding errors in absolute_length_to_px.
|
||||
// Maybe provide alternative functions that don't produce CSSPixels?
|
||||
if (serialization_mode == SerializationMode::ResolvedValue && is_absolute() && m_type != Type::Px) {
|
||||
if (serialization_mode == SerializationMode::ResolvedValue && is_absolute() && m_unit != LengthUnit::Px) {
|
||||
StringBuilder builder;
|
||||
serialize_a_number(builder, absolute_length_to_px().to_double());
|
||||
builder.append("px"sv);
|
||||
|
@ -227,192 +227,6 @@ String Length::to_string(SerializationMode serialization_mode) const
|
|||
return builder.to_string_without_validation();
|
||||
}
|
||||
|
||||
StringView Length::unit_name() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Em:
|
||||
return "em"sv;
|
||||
case Type::Rem:
|
||||
return "rem"sv;
|
||||
case Type::Ex:
|
||||
return "ex"sv;
|
||||
case Type::Rex:
|
||||
return "rex"sv;
|
||||
case Type::Cap:
|
||||
return "cap"sv;
|
||||
case Type::Rcap:
|
||||
return "rcap"sv;
|
||||
case Type::Ch:
|
||||
return "ch"sv;
|
||||
case Type::Rch:
|
||||
return "rch"sv;
|
||||
case Type::Ic:
|
||||
return "ic"sv;
|
||||
case Type::Ric:
|
||||
return "ric"sv;
|
||||
case Type::Lh:
|
||||
return "lh"sv;
|
||||
case Type::Rlh:
|
||||
return "rlh"sv;
|
||||
case Type::Vw:
|
||||
return "vw"sv;
|
||||
case Type::Svw:
|
||||
return "svw"sv;
|
||||
case Type::Lvw:
|
||||
return "lvw"sv;
|
||||
case Type::Dvw:
|
||||
return "dvw"sv;
|
||||
case Type::Vh:
|
||||
return "vh"sv;
|
||||
case Type::Svh:
|
||||
return "svh"sv;
|
||||
case Type::Lvh:
|
||||
return "lvh"sv;
|
||||
case Type::Dvh:
|
||||
return "dvh"sv;
|
||||
case Type::Vi:
|
||||
return "vi"sv;
|
||||
case Type::Svi:
|
||||
return "svi"sv;
|
||||
case Type::Lvi:
|
||||
return "lvi"sv;
|
||||
case Type::Dvi:
|
||||
return "dvi"sv;
|
||||
case Type::Vb:
|
||||
return "vb"sv;
|
||||
case Type::Svb:
|
||||
return "svb"sv;
|
||||
case Type::Lvb:
|
||||
return "lvb"sv;
|
||||
case Type::Dvb:
|
||||
return "dvb"sv;
|
||||
case Type::Vmin:
|
||||
return "vmin"sv;
|
||||
case Type::Svmin:
|
||||
return "svmin"sv;
|
||||
case Type::Lvmin:
|
||||
return "lvmin"sv;
|
||||
case Type::Dvmin:
|
||||
return "dvmin"sv;
|
||||
case Type::Vmax:
|
||||
return "vmax"sv;
|
||||
case Type::Svmax:
|
||||
return "svmax"sv;
|
||||
case Type::Lvmax:
|
||||
return "lvmax"sv;
|
||||
case Type::Dvmax:
|
||||
return "dvmax"sv;
|
||||
case Type::Cm:
|
||||
return "cm"sv;
|
||||
case Type::Mm:
|
||||
return "mm"sv;
|
||||
case Type::Q:
|
||||
return "Q"sv;
|
||||
case Type::In:
|
||||
return "in"sv;
|
||||
case Type::Pt:
|
||||
return "pt"sv;
|
||||
case Type::Pc:
|
||||
return "pc"sv;
|
||||
case Type::Px:
|
||||
return "px"sv;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Optional<Length::Type> Length::unit_from_name(StringView name)
|
||||
{
|
||||
if (name.equals_ignoring_ascii_case("em"sv)) {
|
||||
return Length::Type::Em;
|
||||
} else if (name.equals_ignoring_ascii_case("rem"sv)) {
|
||||
return Length::Type::Rem;
|
||||
} else if (name.equals_ignoring_ascii_case("ex"sv)) {
|
||||
return Length::Type::Ex;
|
||||
} else if (name.equals_ignoring_ascii_case("rex"sv)) {
|
||||
return Length::Type::Rex;
|
||||
} else if (name.equals_ignoring_ascii_case("cap"sv)) {
|
||||
return Length::Type::Cap;
|
||||
} else if (name.equals_ignoring_ascii_case("rcap"sv)) {
|
||||
return Length::Type::Rcap;
|
||||
} else if (name.equals_ignoring_ascii_case("ch"sv)) {
|
||||
return Length::Type::Ch;
|
||||
} else if (name.equals_ignoring_ascii_case("rch"sv)) {
|
||||
return Length::Type::Rch;
|
||||
} else if (name.equals_ignoring_ascii_case("ic"sv)) {
|
||||
return Length::Type::Ic;
|
||||
} else if (name.equals_ignoring_ascii_case("ric"sv)) {
|
||||
return Length::Type::Ric;
|
||||
} else if (name.equals_ignoring_ascii_case("lh"sv)) {
|
||||
return Length::Type::Lh;
|
||||
} else if (name.equals_ignoring_ascii_case("rlh"sv)) {
|
||||
return Length::Type::Rlh;
|
||||
} else if (name.equals_ignoring_ascii_case("vw"sv)) {
|
||||
return Length::Type::Vw;
|
||||
} else if (name.equals_ignoring_ascii_case("svw"sv)) {
|
||||
return Length::Type::Svw;
|
||||
} else if (name.equals_ignoring_ascii_case("lvw"sv)) {
|
||||
return Length::Type::Lvw;
|
||||
} else if (name.equals_ignoring_ascii_case("dvw"sv)) {
|
||||
return Length::Type::Dvw;
|
||||
} else if (name.equals_ignoring_ascii_case("vh"sv)) {
|
||||
return Length::Type::Vh;
|
||||
} else if (name.equals_ignoring_ascii_case("svh"sv)) {
|
||||
return Length::Type::Svh;
|
||||
} else if (name.equals_ignoring_ascii_case("lvh"sv)) {
|
||||
return Length::Type::Lvh;
|
||||
} else if (name.equals_ignoring_ascii_case("dvh"sv)) {
|
||||
return Length::Type::Dvh;
|
||||
} else if (name.equals_ignoring_ascii_case("vi"sv)) {
|
||||
return Length::Type::Vi;
|
||||
} else if (name.equals_ignoring_ascii_case("svi"sv)) {
|
||||
return Length::Type::Svi;
|
||||
} else if (name.equals_ignoring_ascii_case("lvi"sv)) {
|
||||
return Length::Type::Lvi;
|
||||
} else if (name.equals_ignoring_ascii_case("dvi"sv)) {
|
||||
return Length::Type::Dvi;
|
||||
} else if (name.equals_ignoring_ascii_case("vb"sv)) {
|
||||
return Length::Type::Vb;
|
||||
} else if (name.equals_ignoring_ascii_case("svb"sv)) {
|
||||
return Length::Type::Svb;
|
||||
} else if (name.equals_ignoring_ascii_case("lvb"sv)) {
|
||||
return Length::Type::Lvb;
|
||||
} else if (name.equals_ignoring_ascii_case("dvb"sv)) {
|
||||
return Length::Type::Dvb;
|
||||
} else if (name.equals_ignoring_ascii_case("vmin"sv)) {
|
||||
return Length::Type::Vmin;
|
||||
} else if (name.equals_ignoring_ascii_case("svmin"sv)) {
|
||||
return Length::Type::Svmin;
|
||||
} else if (name.equals_ignoring_ascii_case("lvmin"sv)) {
|
||||
return Length::Type::Lvmin;
|
||||
} else if (name.equals_ignoring_ascii_case("dvmin"sv)) {
|
||||
return Length::Type::Dvmin;
|
||||
} else if (name.equals_ignoring_ascii_case("vmax"sv)) {
|
||||
return Length::Type::Vmax;
|
||||
} else if (name.equals_ignoring_ascii_case("svmax"sv)) {
|
||||
return Length::Type::Svmax;
|
||||
} else if (name.equals_ignoring_ascii_case("lvmax"sv)) {
|
||||
return Length::Type::Lvmax;
|
||||
} else if (name.equals_ignoring_ascii_case("dvmax"sv)) {
|
||||
return Length::Type::Dvmax;
|
||||
} else if (name.equals_ignoring_ascii_case("cm"sv)) {
|
||||
return Length::Type::Cm;
|
||||
} else if (name.equals_ignoring_ascii_case("mm"sv)) {
|
||||
return Length::Type::Mm;
|
||||
} else if (name.equals_ignoring_ascii_case("Q"sv)) {
|
||||
return Length::Type::Q;
|
||||
} else if (name.equals_ignoring_ascii_case("in"sv)) {
|
||||
return Length::Type::In;
|
||||
} else if (name.equals_ignoring_ascii_case("pt"sv)) {
|
||||
return Length::Type::Pt;
|
||||
} else if (name.equals_ignoring_ascii_case("pc"sv)) {
|
||||
return Length::Type::Pc;
|
||||
} else if (name.equals_ignoring_ascii_case("px"sv)) {
|
||||
return Length::Type::Px;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<Length> Length::absolutize(CSSPixelRect const& viewport_rect, FontMetrics const& font_metrics, FontMetrics const& root_font_metrics) const
|
||||
{
|
||||
if (is_px())
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibGfx/Forward.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibWeb/CSS/SerializationMode.h>
|
||||
#include <LibWeb/CSS/Units.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/PixelUnits.h>
|
||||
|
@ -19,57 +20,6 @@ namespace Web::CSS {
|
|||
|
||||
class WEB_API Length {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
// Font-relative
|
||||
Em,
|
||||
Rem,
|
||||
Ex,
|
||||
Rex,
|
||||
Cap,
|
||||
Rcap,
|
||||
Ch,
|
||||
Rch,
|
||||
Ic,
|
||||
Ric,
|
||||
Lh,
|
||||
Rlh,
|
||||
|
||||
// Viewport-relative
|
||||
Vw,
|
||||
Svw,
|
||||
Lvw,
|
||||
Dvw,
|
||||
Vh,
|
||||
Svh,
|
||||
Lvh,
|
||||
Dvh,
|
||||
Vi,
|
||||
Svi,
|
||||
Lvi,
|
||||
Dvi,
|
||||
Vb,
|
||||
Svb,
|
||||
Lvb,
|
||||
Dvb,
|
||||
Vmin,
|
||||
Svmin,
|
||||
Lvmin,
|
||||
Dvmin,
|
||||
Vmax,
|
||||
Svmax,
|
||||
Lvmax,
|
||||
Dvmax,
|
||||
|
||||
// Absolute
|
||||
Cm,
|
||||
Mm,
|
||||
Q,
|
||||
In,
|
||||
Pt,
|
||||
Pc,
|
||||
Px,
|
||||
};
|
||||
|
||||
struct FontMetrics {
|
||||
FontMetrics(CSSPixels font_size, Gfx::FontPixelMetrics const&);
|
||||
|
||||
|
@ -82,80 +32,23 @@ public:
|
|||
bool operator==(FontMetrics const&) const = default;
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Length(double value, Type type);
|
||||
Length(double value, LengthUnit unit);
|
||||
~Length();
|
||||
|
||||
static Length make_px(double value);
|
||||
static Length make_px(CSSPixels value);
|
||||
Length percentage_of(Percentage const&) const;
|
||||
|
||||
bool is_px() const { return m_type == Type::Px; }
|
||||
bool is_px() const { return m_unit == LengthUnit::Px; }
|
||||
|
||||
bool is_absolute() const
|
||||
{
|
||||
return m_type == Type::Cm
|
||||
|| m_type == Type::Mm
|
||||
|| m_type == Type::Q
|
||||
|| m_type == Type::In
|
||||
|| m_type == Type::Pt
|
||||
|| m_type == Type::Pc
|
||||
|| m_type == Type::Px;
|
||||
}
|
||||
bool is_absolute() const { return CSS::is_absolute(m_unit); }
|
||||
bool is_font_relative() const { return CSS::is_font_relative(m_unit); }
|
||||
bool is_viewport_relative() const { return CSS::is_viewport_relative(m_unit); }
|
||||
bool is_relative() const { return CSS::is_relative(m_unit); }
|
||||
|
||||
bool is_font_relative() const
|
||||
{
|
||||
return m_type == Type::Em
|
||||
|| m_type == Type::Rem
|
||||
|| m_type == Type::Ex
|
||||
|| m_type == Type::Rex
|
||||
|| m_type == Type::Cap
|
||||
|| m_type == Type::Rcap
|
||||
|| m_type == Type::Ch
|
||||
|| m_type == Type::Rch
|
||||
|| m_type == Type::Ic
|
||||
|| m_type == Type::Ric
|
||||
|| m_type == Type::Lh
|
||||
|| m_type == Type::Rlh;
|
||||
}
|
||||
|
||||
bool is_viewport_relative() const
|
||||
{
|
||||
return m_type == Type::Vw
|
||||
|| m_type == Type::Svw
|
||||
|| m_type == Type::Lvw
|
||||
|| m_type == Type::Dvw
|
||||
|| m_type == Type::Vh
|
||||
|| m_type == Type::Svh
|
||||
|| m_type == Type::Lvh
|
||||
|| m_type == Type::Dvh
|
||||
|| m_type == Type::Vi
|
||||
|| m_type == Type::Svi
|
||||
|| m_type == Type::Lvi
|
||||
|| m_type == Type::Dvi
|
||||
|| m_type == Type::Vb
|
||||
|| m_type == Type::Svb
|
||||
|| m_type == Type::Lvb
|
||||
|| m_type == Type::Dvb
|
||||
|| m_type == Type::Vmin
|
||||
|| m_type == Type::Svmin
|
||||
|| m_type == Type::Lvmin
|
||||
|| m_type == Type::Dvmin
|
||||
|| m_type == Type::Vmax
|
||||
|| m_type == Type::Svmax
|
||||
|| m_type == Type::Lvmax
|
||||
|| m_type == Type::Dvmax;
|
||||
}
|
||||
|
||||
bool is_relative() const
|
||||
{
|
||||
return is_font_relative() || is_viewport_relative();
|
||||
}
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
LengthUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
struct ResolutionContext {
|
||||
[[nodiscard]] static ResolutionContext for_element(DOM::AbstractElement const&);
|
||||
|
@ -200,20 +93,20 @@ public:
|
|||
constexpr double inch_pixels = 96.0;
|
||||
constexpr double centimeter_pixels = (inch_pixels / 2.54);
|
||||
|
||||
switch (m_type) {
|
||||
case Type::Cm:
|
||||
switch (m_unit) {
|
||||
case LengthUnit::Cm:
|
||||
return m_value * centimeter_pixels; // 1cm = 96px/2.54
|
||||
case Type::In:
|
||||
case LengthUnit::In:
|
||||
return m_value * inch_pixels; // 1in = 2.54 cm = 96px
|
||||
case Type::Px:
|
||||
case LengthUnit::Px:
|
||||
return m_value; // 1px = 1/96th of 1in
|
||||
case Type::Pt:
|
||||
case LengthUnit::Pt:
|
||||
return m_value * ((1.0 / 72.0) * inch_pixels); // 1pt = 1/72th of 1in
|
||||
case Type::Pc:
|
||||
case LengthUnit::Pc:
|
||||
return m_value * ((1.0 / 6.0) * inch_pixels); // 1pc = 1/6th of 1in
|
||||
case Type::Mm:
|
||||
case LengthUnit::Mm:
|
||||
return m_value * ((1.0 / 10.0) * centimeter_pixels); // 1mm = 1/10th of 1cm
|
||||
case Type::Q:
|
||||
case LengthUnit::Q:
|
||||
return m_value * ((1.0 / 40.0) * centimeter_pixels); // 1Q = 1/40th of 1cm
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -224,7 +117,7 @@ public:
|
|||
|
||||
bool operator==(Length const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
CSSPixels font_relative_length_to_px(FontMetrics const& font_metrics, FontMetrics const& root_font_metrics) const;
|
||||
|
@ -240,7 +133,7 @@ public:
|
|||
private:
|
||||
[[nodiscard]] CSSPixels to_px_slow_case(Layout::Node const&) const;
|
||||
|
||||
Type m_type;
|
||||
LengthUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -56,37 +56,37 @@ Optional<NumericType> NumericType::create_from_unit(StringView unit)
|
|||
}
|
||||
|
||||
// unit is a <length> unit
|
||||
if (Length::unit_from_name(unit).has_value()) {
|
||||
if (string_to_length_unit(unit).has_value()) {
|
||||
// Return «[ "length" → 1 ]»
|
||||
return NumericType { BaseType::Length, 1 };
|
||||
}
|
||||
|
||||
// unit is an <angle> unit
|
||||
if (Angle::unit_from_name(unit).has_value()) {
|
||||
if (string_to_angle_unit(unit).has_value()) {
|
||||
// Return «[ "angle" → 1 ]»
|
||||
return NumericType { BaseType::Angle, 1 };
|
||||
}
|
||||
|
||||
// unit is a <time> unit
|
||||
if (Time::unit_from_name(unit).has_value()) {
|
||||
if (string_to_time_unit(unit).has_value()) {
|
||||
// Return «[ "time" → 1 ]»
|
||||
return NumericType { BaseType::Time, 1 };
|
||||
}
|
||||
|
||||
// unit is a <frequency> unit
|
||||
if (Frequency::unit_from_name(unit).has_value()) {
|
||||
if (string_to_frequency_unit(unit).has_value()) {
|
||||
// Return «[ "frequency" → 1 ]»
|
||||
return NumericType { BaseType::Frequency, 1 };
|
||||
}
|
||||
|
||||
// unit is a <resolution> unit
|
||||
if (Resolution::unit_from_name(unit).has_value()) {
|
||||
if (string_to_resolution_unit(unit).has_value()) {
|
||||
// Return «[ "resolution" → 1 ]»
|
||||
return NumericType { BaseType::Resolution, 1 };
|
||||
}
|
||||
|
||||
// unit is a <flex> unit
|
||||
if (Flex::unit_from_name(unit).has_value()) {
|
||||
if (string_to_flex_unit(unit).has_value()) {
|
||||
// Return «[ "flex" → 1 ]»
|
||||
return NumericType { BaseType::Flex, 1 };
|
||||
}
|
||||
|
|
|
@ -131,12 +131,12 @@ static Vector<ComponentValue> replace_an_attr_function(DOM::AbstractElement& ele
|
|||
first_argument_tokens.discard_a_token(); // raw-string
|
||||
syntax = RawString {};
|
||||
} else if (syntax_ident == "%"sv
|
||||
|| Angle::unit_from_name(syntax_ident).has_value()
|
||||
|| Flex::unit_from_name(syntax_ident).has_value()
|
||||
|| Frequency::unit_from_name(syntax_ident).has_value()
|
||||
|| Length::unit_from_name(syntax_ident).has_value()
|
||||
|| Resolution::unit_from_name(syntax_ident).has_value()
|
||||
|| Time::unit_from_name(syntax_ident).has_value()) {
|
||||
|| string_to_angle_unit(syntax_ident).has_value()
|
||||
|| string_to_flex_unit(syntax_ident).has_value()
|
||||
|| string_to_frequency_unit(syntax_ident).has_value()
|
||||
|| string_to_length_unit(syntax_ident).has_value()
|
||||
|| string_to_resolution_unit(syntax_ident).has_value()
|
||||
|| string_to_time_unit(syntax_ident).has_value()) {
|
||||
syntax = TypeSyntaxNode::create("number"_fly_string).release_nonnull<SyntaxNode>();
|
||||
unit_name = first_argument_tokens.consume_a_token().token().ident();
|
||||
} else {
|
||||
|
|
|
@ -292,7 +292,7 @@ RefPtr<LinearGradientStyleValue const> Parser::parse_linear_gradient_function(To
|
|||
tokens.discard_a_token(); // <angle>
|
||||
auto angle_value = first_param.token().dimension_value();
|
||||
auto unit_string = first_param.token().dimension_unit();
|
||||
auto angle_type = Angle::unit_from_name(unit_string);
|
||||
auto angle_type = string_to_angle_unit(unit_string);
|
||||
|
||||
if (!angle_type.has_value())
|
||||
return nullptr;
|
||||
|
@ -395,7 +395,7 @@ RefPtr<ConicGradientStyleValue const> Parser::parse_conic_gradient_function(Toke
|
|||
if (!tokens.has_next_token())
|
||||
return nullptr;
|
||||
|
||||
Angle from_angle(0, Angle::Type::Deg);
|
||||
auto from_angle = Angle::make_degrees(0);
|
||||
RefPtr<PositionStyleValue const> at_position;
|
||||
Optional<InterpolationMethod> maybe_interpolation_method;
|
||||
|
||||
|
@ -426,7 +426,7 @@ RefPtr<ConicGradientStyleValue const> Parser::parse_conic_gradient_function(Toke
|
|||
if (angle_token.is(Token::Type::Dimension)) {
|
||||
auto angle = angle_token.token().dimension_value();
|
||||
auto angle_unit = angle_token.token().dimension_unit();
|
||||
auto angle_type = Angle::unit_from_name(angle_unit);
|
||||
auto angle_type = string_to_angle_unit(angle_unit);
|
||||
if (!angle_type.has_value())
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -1729,7 +1729,7 @@ LengthOrCalculated Parser::parse_as_sizes_attribute(DOM::Element const& element,
|
|||
// AD-HOC: If element has no sizes attribute, this algorithm always logs a parse error and then returns 100vw.
|
||||
// The attribute is optional, so avoid spamming the debug log with false positives by just returning early.
|
||||
if (!element.has_attribute(HTML::AttributeNames::sizes))
|
||||
return Length(100, Length::Type::Vw);
|
||||
return Length(100, LengthUnit::Vw);
|
||||
|
||||
// 1. Let unparsed sizes list be the result of parsing a comma-separated list of component values
|
||||
// from the value of element's sizes attribute (or the empty string, if the attribute is absent).
|
||||
|
@ -1828,7 +1828,7 @@ LengthOrCalculated Parser::parse_as_sizes_attribute(DOM::Element const& element,
|
|||
}
|
||||
|
||||
// 4. Return 100vw.
|
||||
return Length(100, Length::Type::Vw);
|
||||
return Length(100, LengthUnit::Vw);
|
||||
}
|
||||
|
||||
bool Parser::has_ignored_vendor_prefix(StringView string)
|
||||
|
|
|
@ -158,22 +158,22 @@ Optional<Dimension> Parser::parse_dimension(ComponentValue const& component_valu
|
|||
auto numeric_value = component_value.token().dimension_value();
|
||||
auto unit_string = component_value.token().dimension_unit();
|
||||
|
||||
if (auto length_type = Length::unit_from_name(unit_string); length_type.has_value())
|
||||
if (auto length_type = string_to_length_unit(unit_string); length_type.has_value())
|
||||
return Length { numeric_value, length_type.release_value() };
|
||||
|
||||
if (auto angle_type = Angle::unit_from_name(unit_string); angle_type.has_value())
|
||||
if (auto angle_type = string_to_angle_unit(unit_string); angle_type.has_value())
|
||||
return Angle { numeric_value, angle_type.release_value() };
|
||||
|
||||
if (auto flex_type = Flex::unit_from_name(unit_string); flex_type.has_value())
|
||||
if (auto flex_type = string_to_flex_unit(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 = string_to_frequency_unit(unit_string); frequency_type.has_value())
|
||||
return Frequency { numeric_value, frequency_type.release_value() };
|
||||
|
||||
if (auto resolution_type = Resolution::unit_from_name(unit_string); resolution_type.has_value())
|
||||
if (auto resolution_type = string_to_resolution_unit(unit_string); resolution_type.has_value())
|
||||
return Resolution { numeric_value, resolution_type.release_value() };
|
||||
|
||||
if (auto time_type = Time::unit_from_name(unit_string); time_type.has_value())
|
||||
if (auto time_type = string_to_time_unit(unit_string); time_type.has_value())
|
||||
return Time { numeric_value, time_type.release_value() };
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1027,7 @@ RefPtr<StyleValue const> Parser::parse_angle_value(TokenStream<ComponentValue>&
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto angle_type = Angle::unit_from_name(dimension_token.dimension_unit()); angle_type.has_value()) {
|
||||
if (auto angle_type = string_to_angle_unit(dimension_token.dimension_unit()); angle_type.has_value()) {
|
||||
transaction.commit();
|
||||
return AngleStyleValue::create(Angle { (dimension_token.dimension_value()), angle_type.release_value() });
|
||||
}
|
||||
|
@ -1058,7 +1058,7 @@ RefPtr<StyleValue const> Parser::parse_angle_percentage_value(TokenStream<Compon
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto angle_type = Angle::unit_from_name(dimension_token.dimension_unit()); angle_type.has_value()) {
|
||||
if (auto angle_type = string_to_angle_unit(dimension_token.dimension_unit()); angle_type.has_value()) {
|
||||
transaction.commit();
|
||||
return AngleStyleValue::create(Angle { (dimension_token.dimension_value()), angle_type.release_value() });
|
||||
}
|
||||
|
@ -1092,7 +1092,7 @@ RefPtr<StyleValue const> Parser::parse_flex_value(TokenStream<ComponentValue>& t
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto flex_type = Flex::unit_from_name(dimension_token.dimension_unit()); flex_type.has_value()) {
|
||||
if (auto flex_type = string_to_flex_unit(dimension_token.dimension_unit()); flex_type.has_value()) {
|
||||
transaction.commit();
|
||||
return FlexStyleValue::create(Flex { (dimension_token.dimension_value()), flex_type.release_value() });
|
||||
}
|
||||
|
@ -1114,7 +1114,7 @@ RefPtr<StyleValue const> Parser::parse_frequency_value(TokenStream<ComponentValu
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto frequency_type = Frequency::unit_from_name(dimension_token.dimension_unit()); frequency_type.has_value()) {
|
||||
if (auto frequency_type = string_to_frequency_unit(dimension_token.dimension_unit()); frequency_type.has_value()) {
|
||||
transaction.commit();
|
||||
return FrequencyStyleValue::create(Frequency { (dimension_token.dimension_value()), frequency_type.release_value() });
|
||||
}
|
||||
|
@ -1136,7 +1136,7 @@ RefPtr<StyleValue const> Parser::parse_frequency_percentage_value(TokenStream<Co
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto frequency_type = Frequency::unit_from_name(dimension_token.dimension_unit()); frequency_type.has_value()) {
|
||||
if (auto frequency_type = string_to_frequency_unit(dimension_token.dimension_unit()); frequency_type.has_value()) {
|
||||
transaction.commit();
|
||||
return FrequencyStyleValue::create(Frequency { (dimension_token.dimension_value()), frequency_type.release_value() });
|
||||
}
|
||||
|
@ -1161,7 +1161,7 @@ RefPtr<StyleValue const> Parser::parse_length_value(TokenStream<ComponentValue>&
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto length_type = Length::unit_from_name(dimension_token.dimension_unit()); length_type.has_value()) {
|
||||
if (auto length_type = string_to_length_unit(dimension_token.dimension_unit()); length_type.has_value()) {
|
||||
transaction.commit();
|
||||
return LengthStyleValue::create(Length { (dimension_token.dimension_value()), length_type.release_value() });
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ RefPtr<StyleValue const> Parser::parse_length_percentage_value(TokenStream<Compo
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto length_type = Length::unit_from_name(dimension_token.dimension_unit()); length_type.has_value()) {
|
||||
if (auto length_type = string_to_length_unit(dimension_token.dimension_unit()); length_type.has_value()) {
|
||||
transaction.commit();
|
||||
return LengthStyleValue::create(Length { (dimension_token.dimension_value()), length_type.release_value() });
|
||||
}
|
||||
|
@ -1263,7 +1263,7 @@ RefPtr<StyleValue const> Parser::parse_resolution_value(TokenStream<ComponentVal
|
|||
// https://drafts.csswg.org/css-values-4/#resolution
|
||||
if (dimension_token.dimension_value() < 0)
|
||||
return nullptr;
|
||||
if (auto resolution_type = Resolution::unit_from_name(dimension_token.dimension_unit()); resolution_type.has_value()) {
|
||||
if (auto resolution_type = string_to_resolution_unit(dimension_token.dimension_unit()); resolution_type.has_value()) {
|
||||
transaction.commit();
|
||||
return ResolutionStyleValue::create(Resolution { (dimension_token.dimension_value()), resolution_type.release_value() });
|
||||
}
|
||||
|
@ -1285,7 +1285,7 @@ RefPtr<StyleValue const> Parser::parse_time_value(TokenStream<ComponentValue>& t
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto time_type = Time::unit_from_name(dimension_token.dimension_unit()); time_type.has_value()) {
|
||||
if (auto time_type = string_to_time_unit(dimension_token.dimension_unit()); time_type.has_value()) {
|
||||
transaction.commit();
|
||||
return TimeStyleValue::create(Time { (dimension_token.dimension_value()), time_type.release_value() });
|
||||
}
|
||||
|
@ -1307,7 +1307,7 @@ RefPtr<StyleValue const> Parser::parse_time_percentage_value(TokenStream<Compone
|
|||
if (tokens.next_token().is(Token::Type::Dimension)) {
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& dimension_token = tokens.consume_a_token().token();
|
||||
if (auto time_type = Time::unit_from_name(dimension_token.dimension_unit()); time_type.has_value()) {
|
||||
if (auto time_type = string_to_time_unit(dimension_token.dimension_unit()); time_type.has_value()) {
|
||||
transaction.commit();
|
||||
return TimeStyleValue::create(Time { (dimension_token.dimension_value()), time_type.release_value() });
|
||||
}
|
||||
|
@ -4228,13 +4228,13 @@ RefPtr<CalculationNode const> Parser::convert_to_calculation_node(CalcParsing::N
|
|||
auto numeric_value = component_value->token().dimension_value();
|
||||
auto unit_string = component_value->token().dimension_unit();
|
||||
|
||||
if (auto length_type = Length::unit_from_name(unit_string); length_type.has_value())
|
||||
if (auto length_type = string_to_length_unit(unit_string); length_type.has_value())
|
||||
return NumericCalculationNode::create(Length { numeric_value, length_type.release_value() }, context);
|
||||
|
||||
if (auto angle_type = Angle::unit_from_name(unit_string); angle_type.has_value())
|
||||
if (auto angle_type = string_to_angle_unit(unit_string); angle_type.has_value())
|
||||
return NumericCalculationNode::create(Angle { numeric_value, angle_type.release_value() }, context);
|
||||
|
||||
if (auto flex_type = Flex::unit_from_name(unit_string); flex_type.has_value()) {
|
||||
if (auto flex_type = string_to_flex_unit(unit_string); flex_type.has_value()) {
|
||||
// https://www.w3.org/TR/css3-grid-layout/#fr-unit
|
||||
// NOTE: <flex> values are not <length>s (nor are they compatible with <length>s, like some <percentage> values),
|
||||
// so they cannot be represented in or combined with other unit types in calc() expressions.
|
||||
|
@ -4247,13 +4247,13 @@ RefPtr<CalculationNode const> Parser::convert_to_calculation_node(CalcParsing::N
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto frequency_type = Frequency::unit_from_name(unit_string); frequency_type.has_value())
|
||||
if (auto frequency_type = string_to_frequency_unit(unit_string); frequency_type.has_value())
|
||||
return NumericCalculationNode::create(Frequency { numeric_value, frequency_type.release_value() }, context);
|
||||
|
||||
if (auto resolution_type = Resolution::unit_from_name(unit_string); resolution_type.has_value())
|
||||
if (auto resolution_type = string_to_resolution_unit(unit_string); resolution_type.has_value())
|
||||
return NumericCalculationNode::create(Resolution { numeric_value, resolution_type.release_value() }, context);
|
||||
|
||||
if (auto time_type = Time::unit_from_name(unit_string); time_type.has_value())
|
||||
if (auto time_type = string_to_time_unit(unit_string); time_type.has_value())
|
||||
return NumericCalculationNode::create(Time { numeric_value, time_type.release_value() }, context);
|
||||
|
||||
ErrorReporter::the().report(InvalidValueError {
|
||||
|
|
|
@ -10,15 +10,15 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
Resolution::Resolution(double value, Type type)
|
||||
: m_type(type)
|
||||
Resolution::Resolution(double value, ResolutionUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Resolution Resolution::make_dots_per_pixel(double value)
|
||||
{
|
||||
return { value, Type::Dppx };
|
||||
return { value, ResolutionUnit::Dppx };
|
||||
}
|
||||
|
||||
String Resolution::to_string(SerializationMode serialization_mode) const
|
||||
|
@ -42,44 +42,16 @@ String Resolution::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
double Resolution::to_dots_per_pixel() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Dpi:
|
||||
switch (m_unit) {
|
||||
case ResolutionUnit::Dpi:
|
||||
return m_value / 96; // 1in = 2.54cm = 96px
|
||||
case Type::Dpcm:
|
||||
case ResolutionUnit::Dpcm:
|
||||
return m_value / (96.0 / 2.54); // 1cm = 96px/2.54
|
||||
case Type::Dppx:
|
||||
case Type::X:
|
||||
case ResolutionUnit::Dppx:
|
||||
case ResolutionUnit::X:
|
||||
return m_value;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
StringView Resolution::unit_name() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Dpi:
|
||||
return "dpi"sv;
|
||||
case Type::Dpcm:
|
||||
return "dpcm"sv;
|
||||
case Type::Dppx:
|
||||
return "dppx"sv;
|
||||
case Type::X:
|
||||
return "x"sv;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Optional<Resolution::Type> Resolution::unit_from_name(StringView name)
|
||||
{
|
||||
if (name.equals_ignoring_ascii_case("dpi"sv))
|
||||
return Type::Dpi;
|
||||
if (name.equals_ignoring_ascii_case("dpcm"sv))
|
||||
return Type::Dpcm;
|
||||
if (name.equals_ignoring_ascii_case("dppx"sv))
|
||||
return Type::Dppx;
|
||||
if (name.equals_ignoring_ascii_case("x"sv))
|
||||
return Type::X;
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,33 +8,25 @@
|
|||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/CSS/SerializationMode.h>
|
||||
#include <LibWeb/CSS/Units.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class Resolution {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
Dpi,
|
||||
Dpcm,
|
||||
Dppx,
|
||||
X,
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Resolution(double value, Type type);
|
||||
Resolution(double value, ResolutionUnit unit);
|
||||
static Resolution make_dots_per_pixel(double);
|
||||
|
||||
String to_string(SerializationMode = SerializationMode::Normal) const;
|
||||
double to_dots_per_pixel() const;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
ResolutionUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
bool operator==(Resolution const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
int operator<=>(Resolution const& other) const
|
||||
|
@ -50,7 +42,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
ResolutionUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -1132,7 +1132,7 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti
|
|||
}
|
||||
}
|
||||
|
||||
CSS::Time delay { 0, CSS::Time::Type::S };
|
||||
auto delay = Time::make_seconds(0);
|
||||
if (auto delay_value = cascaded_properties.property(PropertyID::AnimationDelay); delay_value) {
|
||||
if (delay_value->is_time()) {
|
||||
delay = delay_value->as_time().time();
|
||||
|
|
|
@ -178,25 +178,25 @@ static CalculationNode::NumericValue clamp_and_censor_numeric_value(NumericCalcu
|
|||
return Number { value.type(), clamp_and_censor(context.resolve_numbers_as_integers ? value.integer_value() : value.value(), accepted_range->min, accepted_range->max) };
|
||||
},
|
||||
[&](Angle const& value) -> CalculationNode::NumericValue {
|
||||
return Angle { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Angle { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
},
|
||||
[&](Flex const& value) -> CalculationNode::NumericValue {
|
||||
return Flex { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Flex { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
},
|
||||
[&](Frequency const& value) -> CalculationNode::NumericValue {
|
||||
return Frequency { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Frequency { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
},
|
||||
[&](Length const& value) -> CalculationNode::NumericValue {
|
||||
return Length { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Length { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
},
|
||||
[&](Percentage const& value) -> CalculationNode::NumericValue {
|
||||
return Percentage { clamp_and_censor(value.value(), accepted_range->min, accepted_range->max) };
|
||||
},
|
||||
[&](Resolution const& value) -> CalculationNode::NumericValue {
|
||||
return Resolution { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Resolution { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
},
|
||||
[&](Time const& value) -> CalculationNode::NumericValue {
|
||||
return Time { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.type() };
|
||||
return Time { clamp_and_censor(value.raw_value(), accepted_range->min, accepted_range->max), value.unit() };
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -689,14 +689,14 @@ bool NumericCalculationNode::contains_percentage() const
|
|||
bool NumericCalculationNode::is_in_canonical_unit() const
|
||||
{
|
||||
return m_value.visit(
|
||||
[](Angle const& angle) { return angle.type() == Angle::Type::Deg; },
|
||||
[](Flex const& flex) { return flex.type() == Flex::Type::Fr; },
|
||||
[](Frequency const& frequency) { return frequency.type() == Frequency::Type::Hz; },
|
||||
[](Length const& length) { return length.type() == Length::Type::Px; },
|
||||
[](Angle const& angle) { return angle.unit() == AngleUnit::Deg; },
|
||||
[](Flex const& flex) { return flex.unit() == FlexUnit::Fr; },
|
||||
[](Frequency const& frequency) { return frequency.unit() == FrequencyUnit::Hz; },
|
||||
[](Length const& length) { return length.unit() == LengthUnit::Px; },
|
||||
[](Number const&) { return true; },
|
||||
[](Percentage const&) { return true; },
|
||||
[](Resolution const& resolution) { return resolution.type() == Resolution::Type::Dppx; },
|
||||
[](Time const& time) { return time.type() == Time::Type::S; });
|
||||
[](Resolution const& resolution) { return resolution.unit() == ResolutionUnit::Dppx; },
|
||||
[](Time const& time) { return time.unit() == TimeUnit::S; });
|
||||
}
|
||||
|
||||
static Optional<CalculatedStyleValue::CalculationResult> try_get_value_with_canonical_unit(CalculationNode const& child, CalculationContext const& context, CalculationResolutionContext const& resolution_context)
|
||||
|
@ -807,7 +807,7 @@ NonnullRefPtr<NumericCalculationNode const> NumericCalculationNode::negated(Calc
|
|||
return create(Number(number.type(), -number.value()), context);
|
||||
},
|
||||
[&]<typename T>(T const& value) {
|
||||
return create(T(-value.raw_value(), value.type()), context);
|
||||
return create(T(-value.raw_value(), value.unit()), context);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3157,7 +3157,7 @@ static Optional<NumericChildAndIndex> find_numeric_child_with_same_unit(Vector<N
|
|||
return target.value().has<Number>();
|
||||
},
|
||||
[&]<typename T>(T const& value) {
|
||||
if (auto const* other = target.value().get_pointer<T>(); other && other->type() == value.type()) {
|
||||
if (auto const* other = target.value().get_pointer<T>(); other && other->unit() == value.unit()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -3213,19 +3213,19 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
[](Empty const&) -> RefPtr<NumericCalculationNode const> { return nullptr; },
|
||||
[&](Angle const& angle) -> RefPtr<NumericCalculationNode const> {
|
||||
VERIFY(context.percentages_resolve_as == ValueType::Angle);
|
||||
if (angle.type() == Angle::Type::Deg)
|
||||
if (angle.unit() == AngleUnit::Deg)
|
||||
return NumericCalculationNode::create(angle.percentage_of(*percentage), context);
|
||||
return NumericCalculationNode::create(Angle::make_degrees(angle.to_degrees()).percentage_of(*percentage), context);
|
||||
},
|
||||
[&](Frequency const& frequency) -> RefPtr<NumericCalculationNode const> {
|
||||
VERIFY(context.percentages_resolve_as == ValueType::Frequency);
|
||||
if (frequency.type() == Frequency::Type::Hz)
|
||||
if (frequency.unit() == FrequencyUnit::Hz)
|
||||
return NumericCalculationNode::create(frequency.percentage_of(*percentage), context);
|
||||
return NumericCalculationNode::create(Frequency::make_hertz(frequency.to_hertz()).percentage_of(*percentage), context);
|
||||
},
|
||||
[&](Length const& length) -> RefPtr<NumericCalculationNode const> {
|
||||
VERIFY(context.percentages_resolve_as == ValueType::Length);
|
||||
if (length.type() == Length::Type::Px)
|
||||
if (length.unit() == LengthUnit::Px)
|
||||
return NumericCalculationNode::create(length.percentage_of(*percentage), context);
|
||||
if (length.is_absolute())
|
||||
return NumericCalculationNode::create(Length::make_px(length.absolute_length_to_px()).percentage_of(*percentage), context);
|
||||
|
@ -3235,7 +3235,7 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
},
|
||||
[&](Time const& time) -> RefPtr<NumericCalculationNode const> {
|
||||
VERIFY(context.percentages_resolve_as == ValueType::Time);
|
||||
if (time.type() == Time::Type::S)
|
||||
if (time.unit() == TimeUnit::S)
|
||||
return NumericCalculationNode::create(time.percentage_of(*percentage), context);
|
||||
return NumericCalculationNode::create(Time::make_seconds(time.to_seconds()).percentage_of(*percentage), context);
|
||||
});
|
||||
|
@ -3250,22 +3250,22 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
// NOTE: We use nullptr here to signify "use the original".
|
||||
RefPtr<CalculationNode const> resolved = root_numeric.value().visit(
|
||||
[&](Angle const& angle) -> RefPtr<CalculationNode const> {
|
||||
if (angle.type() == Angle::Type::Deg)
|
||||
if (angle.unit() == AngleUnit::Deg)
|
||||
return nullptr;
|
||||
return NumericCalculationNode::create(Angle::make_degrees(angle.to_degrees()), context);
|
||||
},
|
||||
[&](Flex const& flex) -> RefPtr<CalculationNode const> {
|
||||
if (flex.type() == Flex::Type::Fr)
|
||||
if (flex.unit() == FlexUnit::Fr)
|
||||
return nullptr;
|
||||
return NumericCalculationNode::create(Flex::make_fr(flex.to_fr()), context);
|
||||
},
|
||||
[&](Frequency const& frequency) -> RefPtr<CalculationNode const> {
|
||||
if (frequency.type() == Frequency::Type::Hz)
|
||||
if (frequency.unit() == FrequencyUnit::Hz)
|
||||
return nullptr;
|
||||
return NumericCalculationNode::create(Frequency::make_hertz(frequency.to_hertz()), context);
|
||||
},
|
||||
[&](Length const& length) -> RefPtr<CalculationNode const> {
|
||||
if (length.type() == Length::Type::Px)
|
||||
if (length.unit() == LengthUnit::Px)
|
||||
return nullptr;
|
||||
if (length.is_absolute())
|
||||
return NumericCalculationNode::create(Length::make_px(length.absolute_length_to_px()), context);
|
||||
|
@ -3280,12 +3280,12 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
return nullptr;
|
||||
},
|
||||
[&](Resolution const& resolution) -> RefPtr<CalculationNode const> {
|
||||
if (resolution.type() == Resolution::Type::Dppx)
|
||||
if (resolution.unit() == ResolutionUnit::Dppx)
|
||||
return nullptr;
|
||||
return NumericCalculationNode::create(Resolution::make_dots_per_pixel(resolution.to_dots_per_pixel()), context);
|
||||
},
|
||||
[&](Time const& time) -> RefPtr<CalculationNode const> {
|
||||
if (time.type() == Time::Type::S)
|
||||
if (time.unit() == TimeUnit::S)
|
||||
return nullptr;
|
||||
return NumericCalculationNode::create(Time::make_seconds(time.to_seconds()), context);
|
||||
});
|
||||
|
@ -3461,7 +3461,7 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
return NumericCalculationNode::create(Number(Number::Type::Number, number.value() + child_numeric.value().get<Number>().value()), context);
|
||||
},
|
||||
[&]<typename T>(T const& value) {
|
||||
return NumericCalculationNode::create(T(value.raw_value() + child_numeric.value().get<T>().raw_value(), value.type()), context);
|
||||
return NumericCalculationNode::create(T(value.raw_value() + child_numeric.value().get<T>().raw_value(), value.unit()), context);
|
||||
});
|
||||
summed_children[existing_child_and_index->index] = move(new_value);
|
||||
} else {
|
||||
|
@ -3543,7 +3543,17 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
|
|||
all_numeric = false;
|
||||
break;
|
||||
}
|
||||
multiplied_children.append(as<NumericCalculationNode>(*sum_child).value().visit([&](Percentage const& percentage) { return NumericCalculationNode::create(Percentage(percentage.value() * multiplier->value()), context); }, [&](Number const& number) { return NumericCalculationNode::create(Number(Number::Type::Number, number.value() * multiplier->value()), context); }, [&]<typename T>(T const& value) { return NumericCalculationNode::create(T(value.raw_value() * multiplier->value(), value.type()), context); }));
|
||||
auto& child_value = as<NumericCalculationNode>(*sum_child).value();
|
||||
multiplied_children.append(child_value.visit(
|
||||
[&](Percentage const& percentage) {
|
||||
return NumericCalculationNode::create(Percentage(percentage.value() * multiplier->value()), context);
|
||||
},
|
||||
[&](Number const& number) {
|
||||
return NumericCalculationNode::create(Number(Number::Type::Number, number.value() * multiplier->value()), context);
|
||||
},
|
||||
[&]<typename T>(T const& value) {
|
||||
return NumericCalculationNode::create(T(value.raw_value() * multiplier->value(), value.unit()), context);
|
||||
}));
|
||||
}
|
||||
|
||||
if (all_numeric)
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
Time::Time(double value, Type type)
|
||||
: m_type(type)
|
||||
Time::Time(double value, TimeUnit unit)
|
||||
: m_unit(unit)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
Time Time::make_seconds(double value)
|
||||
{
|
||||
return { value, Type::S };
|
||||
return { value, TimeUnit::S };
|
||||
}
|
||||
|
||||
Time Time::percentage_of(Percentage const& percentage) const
|
||||
{
|
||||
return Time { percentage.as_fraction() * m_value, m_type };
|
||||
return Time { percentage.as_fraction() * m_value, m_unit };
|
||||
}
|
||||
|
||||
String Time::to_string(SerializationMode serialization_mode) const
|
||||
|
@ -47,10 +47,10 @@ String Time::to_string(SerializationMode serialization_mode) const
|
|||
|
||||
double Time::to_seconds() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::S:
|
||||
switch (m_unit) {
|
||||
case TimeUnit::S:
|
||||
return m_value;
|
||||
case Type::Ms:
|
||||
case TimeUnit::Ms:
|
||||
return m_value / 1000.0;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -58,36 +58,15 @@ double Time::to_seconds() const
|
|||
|
||||
double Time::to_milliseconds() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::S:
|
||||
switch (m_unit) {
|
||||
case TimeUnit::S:
|
||||
return m_value * 1000.0;
|
||||
case Type::Ms:
|
||||
case TimeUnit::Ms:
|
||||
return m_value;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
StringView Time::unit_name() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::S:
|
||||
return "s"sv;
|
||||
case Type::Ms:
|
||||
return "ms"sv;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Optional<Time::Type> Time::unit_from_name(StringView name)
|
||||
{
|
||||
if (name.equals_ignoring_ascii_case("s"sv)) {
|
||||
return Type::S;
|
||||
} else if (name.equals_ignoring_ascii_case("ms"sv)) {
|
||||
return Type::Ms;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Time Time::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Time const& reference_value)
|
||||
{
|
||||
CalculationResolutionContext context {
|
||||
|
|
|
@ -8,20 +8,14 @@
|
|||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/CSS/SerializationMode.h>
|
||||
#include <LibWeb/CSS/Units.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class Time {
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
S,
|
||||
Ms,
|
||||
};
|
||||
|
||||
static Optional<Type> unit_from_name(StringView);
|
||||
|
||||
Time(double value, Type type);
|
||||
Time(double value, TimeUnit unit);
|
||||
static Time make_seconds(double);
|
||||
Time percentage_of(Percentage const&) const;
|
||||
|
||||
|
@ -29,13 +23,13 @@ public:
|
|||
double to_milliseconds() const;
|
||||
double to_seconds() const;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
double raw_value() const { return m_value; }
|
||||
StringView unit_name() const;
|
||||
TimeUnit unit() const { return m_unit; }
|
||||
StringView unit_name() const { return CSS::to_string(m_unit); }
|
||||
|
||||
bool operator==(Time const& other) const
|
||||
{
|
||||
return m_type == other.m_type && m_value == other.m_value;
|
||||
return m_unit == other.m_unit && m_value == other.m_value;
|
||||
}
|
||||
|
||||
int operator<=>(Time const& other) const
|
||||
|
@ -53,7 +47,7 @@ public:
|
|||
static Time resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const&, Layout::Node const&, Time const& reference_value);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
TimeUnit m_unit;
|
||||
double m_value { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ void HTMLInputElement::adjust_computed_style(CSS::ComputedProperties& style)
|
|||
|
||||
if (type_state() != TypeAttributeState::FileUpload) {
|
||||
if (style.property(CSS::PropertyID::Width).has_auto())
|
||||
style.set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length(size(), CSS::Length::Type::Ch)));
|
||||
style.set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length(size(), CSS::LengthUnit::Ch)));
|
||||
}
|
||||
|
||||
// NOTE: Other browsers apply a minimum height of a single line's line-height to single-line input elements.
|
||||
|
|
|
@ -53,9 +53,9 @@ void HTMLTextAreaElement::adjust_computed_style(CSS::ComputedProperties& style)
|
|||
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::InlineBlock)));
|
||||
|
||||
if (style.property(CSS::PropertyID::Width).has_auto())
|
||||
style.set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length(cols(), CSS::Length::Type::Ch)));
|
||||
style.set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length(cols(), CSS::LengthUnit::Ch)));
|
||||
if (style.property(CSS::PropertyID::Height).has_auto())
|
||||
style.set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length(rows(), CSS::Length::Type::Lh)));
|
||||
style.set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length(rows(), CSS::LengthUnit::Lh)));
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::initialize(JS::Realm& realm)
|
||||
|
|
|
@ -407,7 +407,7 @@ Optional<CSS::MediaFeatureValue> Window::query_media_feature(CSS::MediaFeatureID
|
|||
// FIXME: Make this a preference
|
||||
return CSS::MediaFeatureValue(CSS::Keyword::NoPreference);
|
||||
case CSS::MediaFeatureID::Resolution:
|
||||
return CSS::MediaFeatureValue(CSS::Resolution(device_pixel_ratio(), CSS::Resolution::Type::Dppx));
|
||||
return CSS::MediaFeatureValue(CSS::Resolution::make_dots_per_pixel(device_pixel_ratio()));
|
||||
case CSS::MediaFeatureID::Scan:
|
||||
// FIXME: Detect this from the display, if we can. Most displays aren't scanning and should return None.
|
||||
return CSS::MediaFeatureValue(CSS::Keyword::None);
|
||||
|
|
|
@ -342,7 +342,7 @@ Optional<Vector<CSS::LengthPercentage>> IntersectionObserver::parse_a_margin(JS:
|
|||
for (auto const& token : tokens) {
|
||||
// If token is an absolute length dimension token, replace it with a an equivalent pixel length.
|
||||
if (token.is(CSS::Parser::Token::Type::Dimension)) {
|
||||
auto length = CSS::Length(token.token().dimension_value(), CSS::Length::unit_from_name(token.token().dimension_unit()).value());
|
||||
auto length = CSS::Length(token.token().dimension_value(), CSS::string_to_length_unit(token.token().dimension_unit()).value());
|
||||
if (length.is_absolute()) {
|
||||
length.absolute_length_to_px();
|
||||
tokens_length_percentage.append(length);
|
||||
|
|
|
@ -126,7 +126,7 @@ LinearGradientData resolve_linear_gradient_data(Layout::NodeWithStyle const& nod
|
|||
|
||||
ConicGradientData resolve_conic_gradient_data(Layout::NodeWithStyle const& node, CSS::ConicGradientStyleValue const& conic_gradient)
|
||||
{
|
||||
CSS::Angle one_turn(360.0f, CSS::Angle::Type::Deg);
|
||||
CSS::Angle one_turn(360.0f, CSS::AngleUnit::Deg);
|
||||
auto resolved_color_stops = resolve_color_stop_positions(
|
||||
node, conic_gradient.color_stop_list(), [&](auto const& angle_percentage) {
|
||||
return angle_percentage.resolved(node, one_turn).to_degrees() / one_turn.to_degrees();
|
||||
|
|
|
@ -1589,7 +1589,7 @@ void PaintableWithLines::resolve_paint_properties()
|
|||
return max(glyph_height.scaled(0.1), 1);
|
||||
},
|
||||
[&](CSS::LengthPercentage const& length_percentage) {
|
||||
auto resolved_length = length_percentage.resolved(text_node, CSS::Length(1, CSS::Length::Type::Em).to_px(text_node)).to_px(*fragment.m_layout_node);
|
||||
auto resolved_length = length_percentage.resolved(text_node, CSS::Length(1, CSS::LengthUnit::Em).to_px(text_node)).to_px(*fragment.m_layout_node);
|
||||
return max(resolved_length, 1);
|
||||
});
|
||||
}();
|
||||
|
|
|
@ -29,22 +29,22 @@ GC::Ref<SVGLength> SVGLength::from_length_percentage(JS::Realm& realm, CSS::Leng
|
|||
if (length_percentage.is_length())
|
||||
return create(
|
||||
realm, [&] {
|
||||
switch (length_percentage.length().type()) {
|
||||
case CSS::Length::Type::Em:
|
||||
switch (length_percentage.length().unit()) {
|
||||
case CSS::LengthUnit::Em:
|
||||
return SVG_LENGTHTYPE_EMS;
|
||||
case CSS::Length::Type::Ex:
|
||||
case CSS::LengthUnit::Ex:
|
||||
return SVG_LENGTHTYPE_EXS;
|
||||
case CSS::Length::Type::Px:
|
||||
case CSS::LengthUnit::Px:
|
||||
return SVG_LENGTHTYPE_PX;
|
||||
case CSS::Length::Type::Cm:
|
||||
case CSS::LengthUnit::Cm:
|
||||
return SVG_LENGTHTYPE_CM;
|
||||
case CSS::Length::Type::Mm:
|
||||
case CSS::LengthUnit::Mm:
|
||||
return SVG_LENGTHTYPE_MM;
|
||||
case CSS::Length::Type::In:
|
||||
case CSS::LengthUnit::In:
|
||||
return SVG_LENGTHTYPE_IN;
|
||||
case CSS::Length::Type::Pt:
|
||||
case CSS::LengthUnit::Pt:
|
||||
return SVG_LENGTHTYPE_PT;
|
||||
case CSS::Length::Type::Pc:
|
||||
case CSS::LengthUnit::Pc:
|
||||
return SVG_LENGTHTYPE_PC;
|
||||
default:
|
||||
return SVG_LENGTHTYPE_UNKNOWN;
|
||||
|
|
|
@ -300,7 +300,7 @@ ErrorOr<void> ViewTransition::capture_the_old_state()
|
|||
// 6. Set capture’s old transform to a <transform-function> that would map element’s border box from the
|
||||
// snapshot containing block origin to its current visual position.
|
||||
// FIXME: Actually compute the right transform here.
|
||||
capture->old_transform = CSS::Transformation(CSS::TransformFunction::Translate, Vector<CSS::TransformValue>({ CSS::TransformValue(CSS::Length(0, CSS::Length::Type::Px)), CSS::TransformValue(CSS::Length(0, CSS::Length::Type::Px)) }));
|
||||
capture->old_transform = CSS::Transformation(CSS::TransformFunction::Translate, Vector<CSS::TransformValue>({ CSS::TransformValue(CSS::Length(0, CSS::LengthUnit::Px)), CSS::TransformValue(CSS::Length(0, CSS::LengthUnit::Px)) }));
|
||||
|
||||
// 7. Set capture’s old writing-mode to the computed value of writing-mode on element.
|
||||
capture->old_writing_mode = element.layout_node()->computed_values().writing_mode();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue