mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 16:58:58 +00:00
LibWeb/CSS: Use Size in GridSize
Reduces a bunch of duplicate logic here for holding different sizing functions, and also removes a user of `auto` Length.
This commit is contained in:
parent
ad5f7c56c1
commit
ae40c7ed95
Notes:
github-actions[bot]
2025-09-04 12:34:21 +00:00
Author: https://github.com/AtkinsSJ
Commit: ae40c7ed95
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6043
5 changed files with 92 additions and 102 deletions
|
@ -11,41 +11,26 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
GridSize::GridSize(Type type, LengthPercentage length_percentage)
|
||||
: m_value(move(length_percentage))
|
||||
{
|
||||
VERIFY(type == Type::FitContent);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
GridSize::GridSize(LengthPercentage length_percentage)
|
||||
: m_type(Type::LengthPercentage)
|
||||
, m_value(move(length_percentage))
|
||||
GridSize::GridSize(Size size)
|
||||
: m_value(move(size))
|
||||
{
|
||||
}
|
||||
|
||||
GridSize::GridSize(Flex flex_factor)
|
||||
: m_type(Type::FlexibleLength)
|
||||
, m_value(move(flex_factor))
|
||||
: m_value(move(flex_factor))
|
||||
{
|
||||
}
|
||||
|
||||
GridSize::GridSize(Type type)
|
||||
: m_value { Empty() }
|
||||
{
|
||||
VERIFY(type == Type::MinContent || type == Type::MaxContent);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
GridSize::~GridSize() = default;
|
||||
|
||||
bool GridSize::is_auto(Layout::AvailableSize const& available_size) const
|
||||
{
|
||||
if (m_type == Type::LengthPercentage) {
|
||||
auto& length_percentage = m_value.get<LengthPercentage>();
|
||||
if (length_percentage.contains_percentage())
|
||||
if (auto const* size = m_value.get_pointer<Size>()) {
|
||||
if (size->is_auto())
|
||||
return true;
|
||||
if (size->contains_percentage())
|
||||
return !available_size.is_definite();
|
||||
return length_percentage.is_auto();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -53,59 +38,83 @@ bool GridSize::is_auto(Layout::AvailableSize const& available_size) const
|
|||
|
||||
bool GridSize::is_fixed(Layout::AvailableSize const& available_size) const
|
||||
{
|
||||
if (m_type == Type::LengthPercentage) {
|
||||
auto& length_percentage = m_value.get<LengthPercentage>();
|
||||
if (length_percentage.contains_percentage())
|
||||
if (auto const* size = m_value.get_pointer<Size>()) {
|
||||
if (!size->is_length_percentage())
|
||||
return false;
|
||||
if (size->contains_percentage())
|
||||
return available_size.is_definite();
|
||||
return !length_percentage.is_auto();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GridSize::is_flexible_length() const
|
||||
{
|
||||
return m_value.has<Flex>();
|
||||
}
|
||||
|
||||
bool GridSize::is_fit_content() const
|
||||
{
|
||||
if (auto const* size = m_value.get_pointer<Size>())
|
||||
return size->is_fit_content();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GridSize::is_max_content() const
|
||||
{
|
||||
if (auto const* size = m_value.get_pointer<Size>())
|
||||
return size->is_max_content();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GridSize::is_min_content() const
|
||||
{
|
||||
if (auto const* size = m_value.get_pointer<Size>())
|
||||
return size->is_min_content();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GridSize::is_intrinsic(Layout::AvailableSize const& available_size) const
|
||||
{
|
||||
return is_auto(available_size) || is_max_content() || is_min_content() || is_fit_content();
|
||||
return m_value.visit(
|
||||
[&available_size](Size const& size) {
|
||||
return size.is_auto()
|
||||
|| size.is_max_content()
|
||||
|| size.is_min_content()
|
||||
|| size.is_fit_content()
|
||||
|| (size.contains_percentage() && !available_size.is_definite());
|
||||
},
|
||||
[](Flex const&) {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool GridSize::is_definite() const
|
||||
{
|
||||
return m_value.visit(
|
||||
[](Size const& size) {
|
||||
return (size.is_length() && !size.length().is_auto()) || size.is_percentage() || size.is_calculated();
|
||||
},
|
||||
[](Flex const&) { return false; });
|
||||
}
|
||||
|
||||
GridSize GridSize::make_auto()
|
||||
{
|
||||
return GridSize(CSS::Length::make_auto());
|
||||
}
|
||||
|
||||
Size GridSize::css_size() const
|
||||
{
|
||||
VERIFY(m_type == Type::LengthPercentage || m_type == Type::FitContent);
|
||||
auto& length_percentage = m_value.get<LengthPercentage>();
|
||||
if (length_percentage.is_auto())
|
||||
return CSS::Size::make_auto();
|
||||
if (length_percentage.is_length())
|
||||
return CSS::Size::make_length(length_percentage.length());
|
||||
if (length_percentage.is_calculated())
|
||||
return CSS::Size::make_calculated(length_percentage.calculated());
|
||||
return CSS::Size::make_percentage(length_percentage.percentage());
|
||||
return GridSize(Size::make_auto());
|
||||
}
|
||||
|
||||
String GridSize::to_string(SerializationMode mode) const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::LengthPercentage:
|
||||
return m_value.get<LengthPercentage>().to_string(mode);
|
||||
case Type::FitContent:
|
||||
return MUST(String::formatted("fit-content({})", m_value.get<LengthPercentage>().to_string(mode)));
|
||||
case Type::FlexibleLength:
|
||||
return m_value.get<Flex>().to_string();
|
||||
case Type::MaxContent:
|
||||
return "max-content"_string;
|
||||
case Type::MinContent:
|
||||
return "min-content"_string;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
return m_value.visit([mode](auto const& it) { return it.to_string(mode); });
|
||||
}
|
||||
|
||||
GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size)
|
||||
: m_min_grid_size(min_grid_size)
|
||||
, m_max_grid_size(max_grid_size)
|
||||
: m_min_grid_size(move(min_grid_size))
|
||||
, m_max_grid_size(move(max_grid_size))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -10,57 +10,40 @@
|
|||
#include <AK/FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/CSS/PercentageOr.h>
|
||||
#include <LibWeb/CSS/Size.h>
|
||||
#include <LibWeb/Layout/AvailableSpace.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class GridSize {
|
||||
public:
|
||||
enum class Type {
|
||||
LengthPercentage,
|
||||
FlexibleLength,
|
||||
FitContent,
|
||||
MaxContent,
|
||||
MinContent,
|
||||
};
|
||||
|
||||
GridSize(Type, LengthPercentage);
|
||||
GridSize(LengthPercentage);
|
||||
GridSize(Size);
|
||||
GridSize(Flex);
|
||||
GridSize(Type);
|
||||
~GridSize();
|
||||
|
||||
static GridSize make_auto();
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
||||
bool is_auto(Layout::AvailableSize const&) const;
|
||||
bool is_fixed(Layout::AvailableSize const&) const;
|
||||
bool is_flexible_length() const { return m_type == Type::FlexibleLength; }
|
||||
bool is_fit_content() const { return m_type == Type::FitContent; }
|
||||
bool is_max_content() const { return m_type == Type::MaxContent; }
|
||||
bool is_min_content() const { return m_type == Type::MinContent; }
|
||||
bool is_flexible_length() const;
|
||||
bool is_fit_content() const;
|
||||
bool is_max_content() const;
|
||||
bool is_min_content() const;
|
||||
|
||||
LengthPercentage const& length_percentage() const { return m_value.get<LengthPercentage>(); }
|
||||
Size css_size() const { return m_value.get<Size>(); }
|
||||
double flex_factor() const { return m_value.get<Flex>().to_fr(); }
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#layout-algorithm
|
||||
// An intrinsic sizing function (min-content, max-content, auto, fit-content()).
|
||||
bool is_intrinsic(Layout::AvailableSize const&) const;
|
||||
|
||||
bool is_definite() const
|
||||
{
|
||||
return type() == Type::LengthPercentage && !length_percentage().is_auto();
|
||||
}
|
||||
|
||||
Size css_size() const;
|
||||
bool is_definite() const;
|
||||
|
||||
String to_string(SerializationMode) const;
|
||||
bool operator==(GridSize const& other) const = default;
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
Variant<Empty, LengthPercentage, Flex> m_value;
|
||||
Variant<Size, Flex> m_value;
|
||||
};
|
||||
|
||||
class GridMinMax {
|
||||
|
|
|
@ -298,7 +298,7 @@ private:
|
|||
|
||||
Optional<GridSize> parse_grid_track_breadth(TokenStream<ComponentValue>&);
|
||||
Optional<GridSize> parse_grid_inflexible_breadth(TokenStream<ComponentValue>&);
|
||||
Optional<GridSize> parse_grid_fixed_breadth(TokenStream<ComponentValue>&);
|
||||
Optional<LengthPercentage> parse_grid_fixed_breadth(TokenStream<ComponentValue>&);
|
||||
|
||||
Optional<GridLineNames> parse_grid_line_names(TokenStream<ComponentValue>&);
|
||||
|
||||
|
|
|
@ -3582,7 +3582,7 @@ Optional<GridSize> Parser::parse_grid_inflexible_breadth(TokenStream<ComponentVa
|
|||
// <inflexible-breadth> = <length-percentage [0,∞]> | min-content | max-content | auto
|
||||
|
||||
if (auto fixed_breadth = parse_grid_fixed_breadth(tokens); fixed_breadth.has_value())
|
||||
return fixed_breadth;
|
||||
return GridSize { Size::make_length_percentage(fixed_breadth.value()) };
|
||||
|
||||
auto transaction = tokens.begin_transaction();
|
||||
if (!tokens.has_next_token())
|
||||
|
@ -3591,11 +3591,11 @@ Optional<GridSize> Parser::parse_grid_inflexible_breadth(TokenStream<ComponentVa
|
|||
auto const& token = tokens.consume_a_token();
|
||||
if (token.is_ident("max-content"sv)) {
|
||||
transaction.commit();
|
||||
return GridSize(GridSize::Type::MaxContent);
|
||||
return GridSize(Size::make_max_content());
|
||||
}
|
||||
if (token.is_ident("min-content"sv)) {
|
||||
transaction.commit();
|
||||
return GridSize(GridSize::Type::MinContent);
|
||||
return GridSize(Size::make_min_content());
|
||||
}
|
||||
if (token.is_ident("auto"sv)) {
|
||||
transaction.commit();
|
||||
|
@ -3606,7 +3606,7 @@ Optional<GridSize> Parser::parse_grid_inflexible_breadth(TokenStream<ComponentVa
|
|||
}
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#typedef-fixed-breadth
|
||||
Optional<GridSize> Parser::parse_grid_fixed_breadth(TokenStream<ComponentValue>& tokens)
|
||||
Optional<LengthPercentage> Parser::parse_grid_fixed_breadth(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// <fixed-breadth> = <length-percentage [0,∞]>
|
||||
|
||||
|
@ -3619,7 +3619,7 @@ Optional<GridSize> Parser::parse_grid_fixed_breadth(TokenStream<ComponentValue>&
|
|||
if (length_percentage->is_percentage() && length_percentage->percentage().value() < 0)
|
||||
return {};
|
||||
transaction.commit();
|
||||
return GridSize(length_percentage.release_value());
|
||||
return length_percentage.release_value();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#typedef-line-names
|
||||
|
@ -3871,7 +3871,7 @@ Optional<ExplicitGridTrack> Parser::parse_grid_track_size(TokenStream<ComponentV
|
|||
if (function_tokens.has_next_token())
|
||||
return {};
|
||||
transaction.commit();
|
||||
return ExplicitGridTrack(GridSize(GridSize::Type::FitContent, maybe_length_percentage->length_percentage()));
|
||||
return ExplicitGridTrack(GridSize(Size::make_fit_content(maybe_length_percentage.release_value())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3895,14 +3895,14 @@ Optional<ExplicitGridTrack> Parser::parse_grid_fixed_size(TokenStream<ComponentV
|
|||
auto const& function_token = token.function();
|
||||
if (function_token.name.equals_ignoring_ascii_case("minmax"sv)) {
|
||||
{
|
||||
GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens); };
|
||||
GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens).map([](auto& it) { return GridSize(Size::make_length_percentage(it)); }); };
|
||||
GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_track_breadth(tokens); };
|
||||
if (auto result = parse_grid_minmax(tokens, parse_min, parse_max); result.has_value())
|
||||
return result;
|
||||
}
|
||||
{
|
||||
GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_inflexible_breadth(tokens); };
|
||||
GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens); };
|
||||
GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens).map([](auto& it) { return GridSize(Size::make_length_percentage(it)); }); };
|
||||
if (auto result = parse_grid_minmax(tokens, parse_min, parse_max); result.has_value())
|
||||
return result;
|
||||
}
|
||||
|
@ -3912,7 +3912,7 @@ Optional<ExplicitGridTrack> Parser::parse_grid_fixed_size(TokenStream<ComponentV
|
|||
}
|
||||
|
||||
if (auto fixed_breadth = parse_grid_fixed_breadth(tokens); fixed_breadth.has_value()) {
|
||||
return ExplicitGridTrack(fixed_breadth.value());
|
||||
return ExplicitGridTrack(GridSize { Size::make_length_percentage(fixed_breadth.release_value()) });
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -189,8 +189,8 @@ GridFormattingContext::GridTrack GridFormattingContext::GridTrack::create_auto()
|
|||
GridFormattingContext::GridTrack GridFormattingContext::GridTrack::create_gap(CSSPixels size)
|
||||
{
|
||||
return GridTrack {
|
||||
.min_track_sizing_function = CSS::GridSize(CSS::Length::make_px(size)),
|
||||
.max_track_sizing_function = CSS::GridSize(CSS::Length::make_px(size)),
|
||||
.min_track_sizing_function = CSS::GridSize(CSS::Size::make_px(size)),
|
||||
.max_track_sizing_function = CSS::GridSize(CSS::Size::make_px(size)),
|
||||
.base_size = size,
|
||||
.is_gap = true,
|
||||
};
|
||||
|
@ -207,9 +207,7 @@ GridFormattingContext::~GridFormattingContext() = default;
|
|||
CSSPixels GridFormattingContext::resolve_definite_track_size(CSS::GridSize const& grid_size, AvailableSpace const& available_space) const
|
||||
{
|
||||
VERIFY(grid_size.is_definite());
|
||||
if (grid_size.type() == CSS::GridSize::Type::LengthPercentage)
|
||||
return grid_size.css_size().to_px(grid_container(), available_space.width.to_px_or_zero());
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
int GridFormattingContext::count_of_repeated_auto_fill_or_fit_tracks(GridDimension dimension, CSS::ExplicitGridTrack const& repeated_track)
|
||||
|
@ -1856,8 +1854,8 @@ void GridFormattingContext::collapse_auto_fit_tracks_if_needed(GridDimension dim
|
|||
continue;
|
||||
|
||||
// NOTE: A collapsed track is treated as having a fixed track sizing function of 0px
|
||||
tracks[track_index].min_track_sizing_function = CSS::GridSize(CSS::Length::make_px(0));
|
||||
tracks[track_index].max_track_sizing_function = CSS::GridSize(CSS::Length::make_px(0));
|
||||
tracks[track_index].min_track_sizing_function = CSS::GridSize(CSS::Size::make_px(0));
|
||||
tracks[track_index].max_track_sizing_function = CSS::GridSize(CSS::Size::make_px(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2114,7 +2112,7 @@ void GridFormattingContext::run(AvailableSpace const& available_space)
|
|||
|
||||
if (i < tracks.size()) {
|
||||
auto const& track = tracks[i];
|
||||
result.append(CSS::ExplicitGridTrack { CSS::GridSize { CSS::LengthPercentage(CSS::Length::make_px(track.base_size)) } });
|
||||
result.append(CSS::ExplicitGridTrack { CSS::GridSize { CSS::Size::make_px(track.base_size) } });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -2646,7 +2644,7 @@ CSSPixels GridFormattingContext::content_based_minimum_size(GridItem const& item
|
|||
spans_only_tracks_with_limited_max_track_sizing_function = false;
|
||||
break;
|
||||
}
|
||||
sum_of_max_sizing_functions += track.max_track_sizing_function.length_percentage().to_px(item.box, m_available_space->width.to_px_or_zero());
|
||||
sum_of_max_sizing_functions += track.max_track_sizing_function.css_size().to_px(item.box, m_available_space->width.to_px_or_zero());
|
||||
}
|
||||
if (spans_only_tracks_with_limited_max_track_sizing_function) {
|
||||
result = min(result, sum_of_max_sizing_functions);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue