at (8,8) content-size 36.84375x17.46875 [BFC] children: inline
+ line 0 width: 36.84375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 5, rect: [8,8 36.84375x17.46875]
+ "hello"
+ TextNode <#text>
diff --git a/Tests/LibWeb/Layout/input/grid/unresolvable-percentage-track.html b/Tests/LibWeb/Layout/input/grid/unresolvable-percentage-track.html
new file mode 100644
index 0000000000..d09cd4eaea
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/grid/unresolvable-percentage-track.html
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp
index 7e7356c16b..939d476b95 100644
--- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp
+++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp
@@ -36,6 +36,33 @@ GridSize::GridSize()
GridSize::~GridSize() = default;
+bool GridSize::is_auto(Layout::AvailableSize const& available_size) const
+{
+ if (m_type == Type::LengthPercentage) {
+ if (m_length_percentage.is_percentage())
+ return !available_size.is_definite();
+ return m_length_percentage.is_auto();
+ }
+
+ return false;
+}
+
+bool GridSize::is_fixed(Layout::AvailableSize const& available_size) const
+{
+ if (m_type == Type::LengthPercentage) {
+ if (m_length_percentage.is_percentage())
+ return available_size.is_definite();
+ return !m_length_percentage.is_auto();
+ }
+
+ return false;
+}
+
+bool GridSize::is_intrinsic(Layout::AvailableSize const& available_size) const
+{
+ return is_auto(available_size) || is_max_content() || is_min_content();
+}
+
GridSize GridSize::make_auto()
{
return GridSize(CSS::Length::make_auto());
diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h
index 19af23c36b..87206ec053 100644
--- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h
+++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h
@@ -8,6 +8,7 @@
#include
#include
+#include
namespace Web::CSS {
@@ -30,8 +31,8 @@ public:
Type type() const { return m_type; }
- bool is_auto() const { return m_type == Type::LengthPercentage && m_length_percentage.is_auto(); }
- bool is_length_percentage() const { return m_type == Type::LengthPercentage; }
+ 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_max_content() const { return m_type == Type::MaxContent; }
bool is_min_content() const { return m_type == Type::MinContent; }
@@ -42,10 +43,7 @@ public:
// https://www.w3.org/TR/css-grid-2/#layout-algorithm
// An intrinsic sizing function (min-content, max-content, auto, fit-content()).
// FIXME: Add missing properties once implemented.
- bool is_intrinsic_track_sizing() const
- {
- return is_auto() || is_max_content() || is_min_content();
- }
+ bool is_intrinsic(Layout::AvailableSize const&) const;
bool is_definite() const
{
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
index 609509a4e6..3bb0ad0b91 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
@@ -630,59 +630,23 @@ void GridFormattingContext::initialize_track_sizes(AvailableSpace const& availab
auto& tracks_and_gaps = dimension == GridDimension::Column ? m_grid_columns_and_gaps : m_grid_rows_and_gaps;
auto& available_size = dimension == GridDimension::Column ? available_space.width : available_space.height;
- // For each track, if the track’s min track sizing function is:
for (auto& track : tracks_and_gaps) {
if (track.is_gap)
continue;
- switch (track.min_track_sizing_function.type()) {
- // - A fixed sizing function
- // Resolve to an absolute length and use that size as the track’s initial base size.
- case CSS::GridSize::Type::LengthPercentage: {
- if (!track.min_track_sizing_function.is_auto()) {
- track.base_size = track.min_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
- }
-
- break;
- }
- // - An intrinsic sizing function
- // Use an initial base size of zero.
- case CSS::GridSize::Type::FlexibleLength:
- case CSS::GridSize::Type::MaxContent:
- case CSS::GridSize::Type::MinContent: {
+ if (track.min_track_sizing_function.is_fixed(available_size)) {
+ track.base_size = track.min_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
+ } else if (track.min_track_sizing_function.is_intrinsic(available_size)) {
track.base_size = 0;
- break;
- }
- default:
- VERIFY_NOT_REACHED();
}
- // For each track, if the track’s max track sizing function is:
- switch (track.max_track_sizing_function.type()) {
- // - A fixed sizing function
- // Resolve to an absolute length and use that size as the track’s initial growth limit.
- case CSS::GridSize::Type::LengthPercentage: {
- if (!track.max_track_sizing_function.is_auto()) {
- track.growth_limit = track.max_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
- } else {
- track.growth_limit = INFINITY;
- }
- break;
- }
- // - A flexible sizing function
- // Use an initial growth limit of infinity.
- case CSS::GridSize::Type::FlexibleLength: {
+ if (track.max_track_sizing_function.is_fixed(available_size)) {
+ track.growth_limit = track.max_track_sizing_function.css_size().to_px(grid_container(), available_size.to_px());
+ } else if (track.max_track_sizing_function.is_flexible_length()) {
track.growth_limit = INFINITY;
- break;
- }
- // - An intrinsic sizing function
- // Use an initial growth limit of infinity.
- case CSS::GridSize::Type::MaxContent:
- case CSS::GridSize::Type::MinContent: {
+ } else if (track.max_track_sizing_function.is_intrinsic(available_size)) {
track.growth_limit = INFINITY;
- break;
- }
- default:
+ } else {
VERIFY_NOT_REACHED();
}
@@ -891,7 +855,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
// function by distributing extra space as needed to accommodate these items’ minimum contributions.
Vector intrinsic_minimum_spanned_tracks;
for (auto& track : spanned_tracks) {
- if (track.min_track_sizing_function.is_intrinsic_track_sizing())
+ if (track.min_track_sizing_function.is_intrinsic(available_size))
intrinsic_minimum_spanned_tracks.append(track);
}
auto item_size_contribution = [&] {
@@ -929,7 +893,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
if (available_size.is_max_content()) {
Vector max_content_minimum_tracks;
for (auto& track : spanned_tracks) {
- if (track.min_track_sizing_function.is_auto() || track.min_track_sizing_function.is_max_content()) {
+ if (track.min_track_sizing_function.is_auto(available_size) || track.min_track_sizing_function.is_max_content()) {
max_content_minimum_tracks.append(track);
}
}
@@ -951,7 +915,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
// 5. For intrinsic maximums: Next increase the growth limit of tracks with an intrinsic max track sizing
Vector intrinsic_maximum_tracks;
for (auto& track : spanned_tracks) {
- if (track.max_track_sizing_function.is_intrinsic_track_sizing()) {
+ if (track.max_track_sizing_function.is_intrinsic(available_size)) {
intrinsic_maximum_tracks.append(track);
}
}
@@ -974,7 +938,7 @@ void GridFormattingContext::increase_sizes_to_accommodate_spanning_items_crossin
// content contributions.
Vector max_content_maximum_tracks;
for (auto& track : spanned_tracks) {
- if (track.max_track_sizing_function.is_max_content() || track.max_track_sizing_function.is_auto()) {
+ if (track.max_track_sizing_function.is_max_content() || track.max_track_sizing_function.is_auto(available_size)) {
max_content_maximum_tracks.append(track);
}
}
@@ -1183,19 +1147,19 @@ void GridFormattingContext::stretch_auto_tracks(AvailableSpace const& available_
// step instead.
CSSPixels used_space = 0;
for (auto& track : tracks_and_gaps) {
- if (!track.max_track_sizing_function.is_auto())
+ if (!track.max_track_sizing_function.is_auto(available_size))
used_space += track.base_size;
}
CSSPixels remaining_space = available_size.is_definite() ? available_size.to_px() - used_space : 0;
auto count_of_auto_max_sizing_tracks = 0;
for (auto& track : tracks_and_gaps) {
- if (track.max_track_sizing_function.is_auto())
+ if (track.max_track_sizing_function.is_auto(available_size))
count_of_auto_max_sizing_tracks++;
}
for (auto& track : tracks_and_gaps) {
- if (track.max_track_sizing_function.is_auto())
+ if (track.max_track_sizing_function.is_auto(available_size))
track.base_size = max(track.base_size, remaining_space / count_of_auto_max_sizing_tracks);
}
}
@@ -1424,6 +1388,8 @@ void GridFormattingContext::resolve_grid_item_heights()
void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const& available_space)
{
+ m_available_space = available_space;
+
place_grid_items(available_space);
initialize_grid_tracks_for_columns_and_rows(available_space);
@@ -1812,7 +1778,8 @@ CSSPixels GridFormattingContext::automatic_minimum_size(GridItem const& item, Gr
auto item_track_index = item.raw_position(dimension);
// FIXME: Check all tracks spanned by an item
- auto item_spans_auto_tracks = tracks[item_track_index].min_track_sizing_function.is_auto();
+ AvailableSize const& available_size = dimension == GridDimension::Column ? m_available_space->width : m_available_space->height;
+ auto item_spans_auto_tracks = tracks[item_track_index].min_track_sizing_function.is_auto(available_size);
if (item_spans_auto_tracks && !item.box().is_scroll_container()) {
return item.add_border_box_sizes(content_based_minimum_size(item, dimension), dimension, m_state);
}
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
index e9f50326e4..e8d351705a 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
@@ -201,6 +201,8 @@ private:
Vector m_grid_items;
Vector> m_boxes_to_place;
+ Optional m_available_space;
+
void determine_grid_container_height();
void determine_intrinsic_size_of_grid_container(AvailableSpace const& available_space);