mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:27:45 +00:00
LibWeb: Use LengthPercentage in CSS::GridSize
Using LengthPercentage instead of Length and Percentage separately is going to allow GridSize to store calc() values. It also allows to simplify some parts of layout code.
This commit is contained in:
parent
6a21bbb5b2
commit
7fee05e18c
3 changed files with 53 additions and 75 deletions
|
@ -6,38 +6,31 @@
|
||||||
|
|
||||||
#include "GridTrackSize.h"
|
#include "GridTrackSize.h"
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibWeb/CSS/Size.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
GridSize::GridSize(Length length)
|
GridSize::GridSize(LengthPercentage length_percentage)
|
||||||
: m_type(Type::Length)
|
: m_type(Type::LengthPercentage)
|
||||||
, m_length(length)
|
, m_length_percentage(length_percentage) {};
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GridSize::GridSize(Percentage percentage)
|
|
||||||
: m_type(Type::Percentage)
|
|
||||||
, m_length { Length::make_px(0) }
|
|
||||||
, m_percentage(percentage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GridSize::GridSize(float flexible_length)
|
GridSize::GridSize(float flexible_length)
|
||||||
: m_type(Type::FlexibleLength)
|
: m_type(Type::FlexibleLength)
|
||||||
, m_length { Length::make_px(0) }
|
, m_length_percentage { Length::make_px(0) }
|
||||||
, m_flexible_length(flexible_length)
|
, m_flexible_length(flexible_length)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GridSize::GridSize(Type type)
|
GridSize::GridSize(Type type)
|
||||||
: m_length { Length::make_auto() }
|
: m_length_percentage { Length::make_auto() }
|
||||||
{
|
{
|
||||||
VERIFY(type == Type::MinContent || type == Type::MaxContent);
|
VERIFY(type == Type::MinContent || type == Type::MaxContent);
|
||||||
m_type = type;
|
m_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
GridSize::GridSize()
|
GridSize::GridSize()
|
||||||
: m_length { Length::make_auto() }
|
: m_type(Type::LengthPercentage)
|
||||||
|
, m_length_percentage { Length::make_auto() }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,13 +41,21 @@ GridSize GridSize::make_auto()
|
||||||
return GridSize(CSS::Length::make_auto());
|
return GridSize(CSS::Length::make_auto());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size GridSize::css_size() const
|
||||||
|
{
|
||||||
|
VERIFY(m_type == Type::LengthPercentage);
|
||||||
|
if (m_length_percentage.is_auto())
|
||||||
|
return CSS::Size::make_auto();
|
||||||
|
if (m_length_percentage.is_length())
|
||||||
|
return CSS::Size::make_length(m_length_percentage.length());
|
||||||
|
return CSS::Size::make_percentage(m_length_percentage.percentage());
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<String> GridSize::to_string() const
|
ErrorOr<String> GridSize::to_string() const
|
||||||
{
|
{
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::Length:
|
case Type::LengthPercentage:
|
||||||
return m_length.to_string();
|
return m_length_percentage.to_string();
|
||||||
case Type::Percentage:
|
|
||||||
return m_percentage.to_string();
|
|
||||||
case Type::FlexibleLength:
|
case Type::FlexibleLength:
|
||||||
return String::formatted("{}fr", m_flexible_length);
|
return String::formatted("{}fr", m_flexible_length);
|
||||||
case Type::MaxContent:
|
case Type::MaxContent:
|
||||||
|
@ -65,11 +66,6 @@ ErrorOr<String> GridSize::to_string() const
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Length GridSize::length() const
|
|
||||||
{
|
|
||||||
return m_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size)
|
GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size)
|
||||||
: m_min_grid_size(min_grid_size)
|
: m_min_grid_size(min_grid_size)
|
||||||
, m_max_grid_size(max_grid_size)
|
, m_max_grid_size(max_grid_size)
|
||||||
|
|
|
@ -7,23 +7,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/PercentageOr.h>
|
||||||
#include <LibWeb/CSS/Percentage.h>
|
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
class GridSize {
|
class GridSize {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Length,
|
LengthPercentage,
|
||||||
Percentage,
|
|
||||||
FlexibleLength,
|
FlexibleLength,
|
||||||
MaxContent,
|
MaxContent,
|
||||||
MinContent,
|
MinContent,
|
||||||
};
|
};
|
||||||
|
|
||||||
GridSize(Length);
|
GridSize(LengthPercentage);
|
||||||
GridSize(Percentage);
|
|
||||||
GridSize(float);
|
GridSize(float);
|
||||||
GridSize(Type);
|
GridSize(Type);
|
||||||
GridSize();
|
GridSize();
|
||||||
|
@ -33,14 +30,13 @@ public:
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
bool is_length() const { return m_type == Type::Length; }
|
bool is_auto() const { return m_type == Type::LengthPercentage && m_length_percentage.is_auto(); }
|
||||||
bool is_percentage() const { return m_type == Type::Percentage; }
|
bool is_length_percentage() const { return m_type == Type::LengthPercentage; }
|
||||||
bool is_flexible_length() const { return m_type == Type::FlexibleLength; }
|
bool is_flexible_length() const { return m_type == Type::FlexibleLength; }
|
||||||
bool is_max_content() const { return m_type == Type::MaxContent; }
|
bool is_max_content() const { return m_type == Type::MaxContent; }
|
||||||
bool is_min_content() const { return m_type == Type::MinContent; }
|
bool is_min_content() const { return m_type == Type::MinContent; }
|
||||||
|
|
||||||
Length length() const;
|
LengthPercentage length_percentage() const { return m_length_percentage; };
|
||||||
Percentage percentage() const { return m_percentage; }
|
|
||||||
float flexible_length() const { return m_flexible_length; }
|
float flexible_length() const { return m_flexible_length; }
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-grid-2/#layout-algorithm
|
// https://www.w3.org/TR/css-grid-2/#layout-algorithm
|
||||||
|
@ -48,29 +44,27 @@ public:
|
||||||
// FIXME: Add missing properties once implemented.
|
// FIXME: Add missing properties once implemented.
|
||||||
bool is_intrinsic_track_sizing() const
|
bool is_intrinsic_track_sizing() const
|
||||||
{
|
{
|
||||||
return (m_type == Type::Length && m_length.is_auto()) || m_type == Type::MaxContent || m_type == Type::MinContent;
|
return is_auto() || is_max_content() || is_min_content();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_definite() const
|
bool is_definite() const
|
||||||
{
|
{
|
||||||
return (m_type == Type::Length && !m_length.is_auto()) || is_percentage();
|
return type() == Type::LengthPercentage && !m_length_percentage.is_auto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size css_size() const;
|
||||||
|
|
||||||
ErrorOr<String> to_string() const;
|
ErrorOr<String> to_string() const;
|
||||||
bool operator==(GridSize const& other) const
|
bool operator==(GridSize const& other) const
|
||||||
{
|
{
|
||||||
return m_type == other.type()
|
return m_type == other.type()
|
||||||
&& m_length == other.length()
|
&& m_length_percentage == other.length_percentage()
|
||||||
&& m_percentage == other.percentage()
|
|
||||||
&& m_flexible_length == other.flexible_length();
|
&& m_flexible_length == other.flexible_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
// Length includes a RefPtr<CalculatedStyleValue> member, but we can't include the header StyleValue.h as it includes
|
LengthPercentage m_length_percentage;
|
||||||
// this file already. To break the cyclic dependency, we must initialize m_length in the constructor.
|
|
||||||
Length m_length;
|
|
||||||
Percentage m_percentage { Percentage(0) };
|
|
||||||
float m_flexible_length { 0 };
|
float m_flexible_length { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,12 @@ CSSPixels GridFormattingContext::resolve_definite_track_size(CSS::GridSize const
|
||||||
{
|
{
|
||||||
VERIFY(grid_size.is_definite());
|
VERIFY(grid_size.is_definite());
|
||||||
switch (grid_size.type()) {
|
switch (grid_size.type()) {
|
||||||
case CSS::GridSize::Type::Length:
|
case CSS::GridSize::Type::LengthPercentage: {
|
||||||
if (grid_size.length().is_auto())
|
if (!grid_size.length_percentage().is_auto()) {
|
||||||
break;
|
return grid_size.css_size().to_px(grid_container(), available_space.width.to_px());
|
||||||
return grid_size.length().to_px(grid_container());
|
}
|
||||||
case CSS::GridSize::Type::Percentage:
|
|
||||||
if (available_space.width.is_definite())
|
|
||||||
return grid_size.percentage().as_fraction() * available_space.width.to_px().value();
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -621,14 +619,11 @@ void GridFormattingContext::initialize_track_sizes(AvailableSize const& availabl
|
||||||
switch (track.min_track_sizing_function.type()) {
|
switch (track.min_track_sizing_function.type()) {
|
||||||
// - A fixed sizing function
|
// - A fixed sizing function
|
||||||
// Resolve to an absolute length and use that size as the track’s initial base size.
|
// Resolve to an absolute length and use that size as the track’s initial base size.
|
||||||
case CSS::GridSize::Type::Length: {
|
case CSS::GridSize::Type::LengthPercentage: {
|
||||||
if (!track.min_track_sizing_function.length().is_auto())
|
if (!track.min_track_sizing_function.is_auto()) {
|
||||||
track.base_size = track.min_track_sizing_function.length().to_px(grid_container());
|
track.base_size = track.min_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
case CSS::GridSize::Type::Percentage: {
|
|
||||||
if (available_size.is_definite())
|
|
||||||
track.base_size = track.min_track_sizing_function.percentage().as_fraction() * available_size.to_px().value();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// - An intrinsic sizing function
|
// - An intrinsic sizing function
|
||||||
|
@ -647,18 +642,12 @@ void GridFormattingContext::initialize_track_sizes(AvailableSize const& availabl
|
||||||
switch (track.max_track_sizing_function.type()) {
|
switch (track.max_track_sizing_function.type()) {
|
||||||
// - A fixed sizing function
|
// - A fixed sizing function
|
||||||
// Resolve to an absolute length and use that size as the track’s initial growth limit.
|
// Resolve to an absolute length and use that size as the track’s initial growth limit.
|
||||||
case CSS::GridSize::Type::Length: {
|
case CSS::GridSize::Type::LengthPercentage: {
|
||||||
if (!track.max_track_sizing_function.length().is_auto())
|
if (!track.max_track_sizing_function.is_auto()) {
|
||||||
track.growth_limit = track.max_track_sizing_function.length().to_px(grid_container());
|
track.growth_limit = track.max_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
|
||||||
else
|
} else {
|
||||||
// - An intrinsic sizing function
|
|
||||||
// Use an initial growth limit of infinity.
|
|
||||||
track.growth_limit = INFINITY;
|
track.growth_limit = INFINITY;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
case CSS::GridSize::Type::Percentage: {
|
|
||||||
if (available_size.is_definite())
|
|
||||||
track.growth_limit = track.max_track_sizing_function.percentage().as_fraction() * available_size.to_px().value();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// - A flexible sizing function
|
// - A flexible sizing function
|
||||||
|
@ -766,9 +755,8 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
}
|
}
|
||||||
track.base_size = base_size;
|
track.base_size = base_size;
|
||||||
} break;
|
} break;
|
||||||
case CSS::GridSize::Type::Length:
|
case CSS::GridSize::Type::LengthPercentage: {
|
||||||
case CSS::GridSize::Type::Percentage: {
|
if (track.min_track_sizing_function.is_auto() && available_size.is_intrinsic_sizing_constraint()) {
|
||||||
if (track.min_track_sizing_function.length().is_auto() && available_size.is_intrinsic_sizing_constraint()) {
|
|
||||||
// If the track has an auto min track sizing function and the grid container is being sized under a
|
// If the track has an auto min track sizing function and the grid container is being sized under a
|
||||||
// min-/max-content constraint, set the track’s base size to the maximum of its items’ limited
|
// min-/max-content constraint, set the track’s base size to the maximum of its items’ limited
|
||||||
// min-/max-content contributions (respectively), floored at zero. The limited min-/max-content
|
// min-/max-content contributions (respectively), floored at zero. The limited min-/max-content
|
||||||
|
@ -823,7 +811,7 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
|
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.growth_limit = growth_limit;
|
track.growth_limit = growth_limit;
|
||||||
} else if (max_track_sizing_function.is_max_content() || (max_track_sizing_function.is_length() && max_track_sizing_function.length().is_auto())) {
|
} else if (max_track_sizing_function.is_max_content() || max_track_sizing_function.is_auto()) {
|
||||||
// If the track has a max-content max track sizing function, set its growth limit to the maximum of
|
// If the track has a max-content max track sizing function, set its growth limit to the maximum of
|
||||||
// the items’ max-content contributions. For fit-content() maximums, furthermore clamp this growth
|
// the items’ max-content contributions. For fit-content() maximums, furthermore clamp this growth
|
||||||
// limit by the fit-content() argument.
|
// limit by the fit-content() argument.
|
||||||
|
@ -1142,19 +1130,19 @@ void GridFormattingContext::stretch_auto_tracks(AvailableSize const& available_s
|
||||||
// step instead.
|
// step instead.
|
||||||
CSSPixels used_space = 0;
|
CSSPixels used_space = 0;
|
||||||
for (auto& track : tracks) {
|
for (auto& track : tracks) {
|
||||||
if (!(track.max_track_sizing_function.is_length() && track.max_track_sizing_function.length().is_auto()))
|
if (!track.max_track_sizing_function.is_auto())
|
||||||
used_space += track.base_size;
|
used_space += track.base_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSSPixels remaining_space = available_size.is_definite() ? available_size.to_px() - used_space : 0;
|
CSSPixels remaining_space = available_size.is_definite() ? available_size.to_px() - used_space : 0;
|
||||||
auto count_of_auto_max_sizing_tracks = 0;
|
auto count_of_auto_max_sizing_tracks = 0;
|
||||||
for (auto& track : tracks) {
|
for (auto& track : tracks) {
|
||||||
if (track.max_track_sizing_function.is_length() && track.max_track_sizing_function.length().is_auto())
|
if (track.max_track_sizing_function.is_auto())
|
||||||
count_of_auto_max_sizing_tracks++;
|
count_of_auto_max_sizing_tracks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& track : tracks) {
|
for (auto& track : tracks) {
|
||||||
if (track.max_track_sizing_function.is_length() && track.max_track_sizing_function.length().is_auto())
|
if (track.max_track_sizing_function.is_auto())
|
||||||
track.base_size = max(track.base_size, remaining_space / count_of_auto_max_sizing_tracks);
|
track.base_size = max(track.base_size, remaining_space / count_of_auto_max_sizing_tracks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue