mirror of
https://github.com/RGBCube/serenity
synced 2025-07-19 06:57:34 +00:00
LibWeb: Add CSS::Percentage, PercentageOr and LengthPercentage types
Length and Percentage are different types, and sometimes only one or the other is allowed in a given CSS property. This is a first step towards separating them.
This commit is contained in:
parent
71ab8fb757
commit
01b57fa8b7
5 changed files with 158 additions and 2 deletions
|
@ -311,8 +311,9 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
|
||||||
return true;
|
return true;
|
||||||
)~~~");
|
)~~~");
|
||||||
} else if (type_name == "percentage") {
|
} else if (type_name == "percentage") {
|
||||||
|
// FIXME: Detecting lengths here is temporary until Length/Percentage are fully separated.
|
||||||
property_generator.append(R"~~~(
|
property_generator.append(R"~~~(
|
||||||
if ((style_value.has_length() && style_value.to_length().is_percentage()) || style_value.is_calculated())
|
if (style_value.is_percentage() || style_value.is_calculated() || (style_value.has_length() && !style_value.to_length().is_percentage()))
|
||||||
return true;
|
return true;
|
||||||
)~~~");
|
)~~~");
|
||||||
} else if (type_name == "number" || type_name == "integer") {
|
} else if (type_name == "number" || type_name == "integer") {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <LibGfx/Font.h>
|
#include <LibGfx/Font.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
|
#include <LibWeb/CSS/Percentage.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/HTML/BrowsingContext.h>
|
#include <LibWeb/HTML/BrowsingContext.h>
|
||||||
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
||||||
|
@ -32,11 +33,22 @@ Length Length::make_auto()
|
||||||
{
|
{
|
||||||
return Length(0, Type::Auto);
|
return Length(0, Type::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
Length Length::make_px(float value)
|
Length Length::make_px(float value)
|
||||||
{
|
{
|
||||||
return Length(value, Type::Px);
|
return Length(value, Type::Px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Length Length::percentage_of(Percentage const& percentage) const
|
||||||
|
{
|
||||||
|
if (is_undefined_or_auto()) {
|
||||||
|
dbgln("Attempting to get percentage of an undefined or auto length, this seems wrong? But for now we just return the original length.");
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Length { percentage.as_fraction() * raw_value(), m_type };
|
||||||
|
}
|
||||||
|
|
||||||
Length Length::resolved(const Length& fallback_for_undefined, const Layout::Node& layout_node, float reference_for_percent) const
|
Length Length::resolved(const Length& fallback_for_undefined, const Layout::Node& layout_node, float reference_for_percent) const
|
||||||
{
|
{
|
||||||
if (is_undefined())
|
if (is_undefined())
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
|
|
||||||
static Length make_auto();
|
static Length make_auto();
|
||||||
static Length make_px(float value);
|
static Length make_px(float value);
|
||||||
|
Length percentage_of(Percentage const&) const;
|
||||||
|
|
||||||
Length resolved(const Length& fallback_for_undefined, const Layout::Node& layout_node, float reference_for_percent) const;
|
Length resolved(const Length& fallback_for_undefined, const Layout::Node& layout_node, float reference_for_percent) const;
|
||||||
Length resolved_or_auto(const Layout::Node& layout_node, float reference_for_percent) const;
|
Length resolved_or_auto(const Layout::Node& layout_node, float reference_for_percent) const;
|
||||||
|
|
141
Userland/Libraries/LibWeb/CSS/Percentage.h
Normal file
141
Userland/Libraries/LibWeb/CSS/Percentage.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/Variant.h>
|
||||||
|
#include <LibWeb/CSS/Length.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
class Percentage {
|
||||||
|
public:
|
||||||
|
explicit Percentage(int value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Percentage(float value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float value() const { return m_value; }
|
||||||
|
float as_fraction() const { return m_value * 0.01f; }
|
||||||
|
|
||||||
|
String to_string() const
|
||||||
|
{
|
||||||
|
return String::formatted("{}%", m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(Percentage const& other) const { return m_value == other.m_value; }
|
||||||
|
bool operator!=(Percentage const& other) const { return !(*this == other); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class PercentageOr {
|
||||||
|
public:
|
||||||
|
PercentageOr(T t)
|
||||||
|
: m_value(move(t))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PercentageOr(Percentage percentage)
|
||||||
|
: m_value(move(percentage))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PercentageOr<T>& operator=(T t)
|
||||||
|
{
|
||||||
|
m_value = move(t);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PercentageOr<T>& operator=(Percentage percentage)
|
||||||
|
{
|
||||||
|
m_value = move(percentage);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_percentage() const { return m_value.template has<Percentage>(); }
|
||||||
|
|
||||||
|
Percentage const& percentage() const
|
||||||
|
{
|
||||||
|
VERIFY(is_percentage());
|
||||||
|
return m_value.template get<Percentage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
T resolved(T const& reference_value) const
|
||||||
|
{
|
||||||
|
if (is_percentage())
|
||||||
|
return reference_value.percentage_of(m_value.template get<Percentage>());
|
||||||
|
|
||||||
|
return m_value.template get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
String to_string() const
|
||||||
|
{
|
||||||
|
if (is_percentage())
|
||||||
|
return m_value.template get<Percentage>().to_string();
|
||||||
|
|
||||||
|
return m_value.template get<T>().to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(PercentageOr<T> const& other) const
|
||||||
|
{
|
||||||
|
if (is_percentage() != other.is_percentage())
|
||||||
|
return false;
|
||||||
|
if (is_percentage())
|
||||||
|
return (m_value.template get<Percentage>() == other.m_value.template get<Percentage>());
|
||||||
|
return (m_value.template get<T>() == other.m_value.template get<T>());
|
||||||
|
}
|
||||||
|
bool operator!=(PercentageOr<T> const& other) const { return !(*this == other); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool is_non_percentage_value() const { return m_value.template has<T>(); }
|
||||||
|
T const& non_percentage_value() const { return m_value.template get<T>(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Variant<T, Percentage> m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(PercentageOr<T> const& percentage_or, T const& t)
|
||||||
|
{
|
||||||
|
return percentage_or == PercentageOr<T> { t };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(T const& t, PercentageOr<T> const& percentage_or)
|
||||||
|
{
|
||||||
|
return t == percentage_or;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(PercentageOr<T> const& percentage_or, Percentage const& percentage)
|
||||||
|
{
|
||||||
|
return percentage_or == PercentageOr<T> { percentage };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(Percentage const& percentage, PercentageOr<T> const& percentage_or)
|
||||||
|
{
|
||||||
|
return percentage == percentage_or;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LengthPercentage : public PercentageOr<Length> {
|
||||||
|
public:
|
||||||
|
using PercentageOr<Length>::PercentageOr;
|
||||||
|
|
||||||
|
bool is_length() const { return is_non_percentage_value(); }
|
||||||
|
Length const& length() const { return non_percentage_value(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -26,7 +26,6 @@ class BorderRadiusStyleValue;
|
||||||
class BorderStyleValue;
|
class BorderStyleValue;
|
||||||
class BoxShadowStyleValue;
|
class BoxShadowStyleValue;
|
||||||
class CalculatedStyleValue;
|
class CalculatedStyleValue;
|
||||||
class CalculatedStyleValue;
|
|
||||||
class ColorStyleValue;
|
class ColorStyleValue;
|
||||||
class CSSImportRule;
|
class CSSImportRule;
|
||||||
class CSSMediaRule;
|
class CSSMediaRule;
|
||||||
|
@ -46,6 +45,7 @@ class ImageStyleValue;
|
||||||
class InheritStyleValue;
|
class InheritStyleValue;
|
||||||
class InitialStyleValue;
|
class InitialStyleValue;
|
||||||
class Length;
|
class Length;
|
||||||
|
class LengthPercentage;
|
||||||
class LengthStyleValue;
|
class LengthStyleValue;
|
||||||
class ListStyleStyleValue;
|
class ListStyleStyleValue;
|
||||||
class MediaList;
|
class MediaList;
|
||||||
|
@ -54,6 +54,7 @@ class MediaQueryList;
|
||||||
class MediaQueryListEvent;
|
class MediaQueryListEvent;
|
||||||
class NumericStyleValue;
|
class NumericStyleValue;
|
||||||
class OverflowStyleValue;
|
class OverflowStyleValue;
|
||||||
|
class Percentage;
|
||||||
class PositionStyleValue;
|
class PositionStyleValue;
|
||||||
class PropertyOwningCSSStyleDeclaration;
|
class PropertyOwningCSSStyleDeclaration;
|
||||||
class Screen;
|
class Screen;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue