mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb/CSS: Absolutize grid-related StyleValues
This commit is contained in:
parent
597fe8288c
commit
7de17dce9d
Notes:
github-actions[bot]
2025-11-19 23:47:02 +00:00
Author: https://github.com/AtkinsSJ
Commit: 7de17dce9d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6857
Reviewed-by: https://github.com/tcl3 ✅
12 changed files with 161 additions and 26 deletions
|
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2022, Martin Falisse <mfalisse@outlook.com>
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "GridTrackPlacement.h"
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
|
|
@ -38,4 +40,34 @@ String GridTrackPlacement::to_string(SerializationMode mode) const
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
GridTrackPlacement GridTrackPlacement::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
auto absolutize_integer_or_calculated = [&context](IntegerOrCalculated const& integer_or_calculated) {
|
||||
if (!integer_or_calculated.is_calculated())
|
||||
return integer_or_calculated;
|
||||
auto absolutized = integer_or_calculated.calculated()->absolutized(context);
|
||||
if (absolutized->is_calculated())
|
||||
return IntegerOrCalculated { absolutized->as_calculated() };
|
||||
VERIFY(absolutized->is_integer());
|
||||
return IntegerOrCalculated { absolutized->as_integer().integer() };
|
||||
};
|
||||
|
||||
return m_value.visit(
|
||||
[this](Auto const&) {
|
||||
return *this;
|
||||
},
|
||||
[&](AreaOrLine const& area_or_line) -> GridTrackPlacement {
|
||||
return AreaOrLine {
|
||||
.line_number = area_or_line.line_number.map(absolutize_integer_or_calculated),
|
||||
.name = area_or_line.name,
|
||||
};
|
||||
},
|
||||
[&](Span const& span) -> GridTrackPlacement {
|
||||
return Span {
|
||||
.value = absolutize_integer_or_calculated(span.value),
|
||||
.name = span.name,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2022, Martin Falisse <mfalisse@outlook.com>
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -55,6 +56,8 @@ public:
|
|||
|
||||
String to_string(SerializationMode mode) const;
|
||||
|
||||
GridTrackPlacement absolutized(ComputationContext const&) const;
|
||||
|
||||
bool operator==(GridTrackPlacement const& other) const = default;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Martin Falisse <mfalisse@outlook.com>
|
||||
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -110,6 +111,41 @@ String GridSize::to_string(SerializationMode mode) const
|
|||
return m_value.visit([mode](auto const& it) { return it.to_string(mode); });
|
||||
}
|
||||
|
||||
GridSize GridSize::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
auto absolutize_length_percentage = [&context](LengthPercentage const& length_percentage) -> Optional<LengthPercentage> {
|
||||
if (length_percentage.is_length()) {
|
||||
auto length = length_percentage.length().absolutize(context.length_resolution_context.viewport_rect, context.length_resolution_context.font_metrics, context.length_resolution_context.root_font_metrics);
|
||||
if (length.has_value())
|
||||
return length.release_value();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (length_percentage.is_calculated())
|
||||
return LengthPercentage::from_style_value(length_percentage.calculated()->absolutized(context));
|
||||
|
||||
return {};
|
||||
};
|
||||
return m_value.visit(
|
||||
[&](Size const& size) -> GridSize {
|
||||
if (size.is_length_percentage()) {
|
||||
if (auto result = absolutize_length_percentage(size.length_percentage()); result.has_value())
|
||||
return Size::make_length_percentage(result.release_value());
|
||||
}
|
||||
|
||||
if (size.is_fit_content() && size.fit_content_available_space().has_value()) {
|
||||
if (auto result = absolutize_length_percentage(size.fit_content_available_space().value()); result.has_value()) {
|
||||
return Size::make_fit_content(result.release_value());
|
||||
}
|
||||
}
|
||||
|
||||
return GridSize { size };
|
||||
},
|
||||
[](Flex const& flex) {
|
||||
return GridSize { flex };
|
||||
});
|
||||
}
|
||||
|
||||
GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size)
|
||||
: m_min_grid_size(move(min_grid_size))
|
||||
, m_max_grid_size(move(max_grid_size))
|
||||
|
|
@ -127,6 +163,14 @@ String GridMinMax::to_string(SerializationMode mode) const
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
GridMinMax GridMinMax::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
return GridMinMax {
|
||||
m_min_grid_size.absolutized(context),
|
||||
m_max_grid_size.absolutized(context),
|
||||
};
|
||||
}
|
||||
|
||||
GridRepeat::GridRepeat(GridRepeatType grid_repeat_type, GridTrackSizeList&& grid_track_size_list, size_t repeat_count)
|
||||
: m_type(grid_repeat_type)
|
||||
, m_grid_track_size_list(move(grid_track_size_list))
|
||||
|
|
@ -162,6 +206,15 @@ String GridRepeat::to_string(SerializationMode mode) const
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
GridRepeat GridRepeat::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
return GridRepeat {
|
||||
m_type,
|
||||
m_grid_track_size_list.absolutized(context),
|
||||
m_repeat_count,
|
||||
};
|
||||
}
|
||||
|
||||
ExplicitGridTrack::ExplicitGridTrack(Variant<GridRepeat, GridMinMax, GridSize>&& value)
|
||||
: m_value(move(value))
|
||||
{
|
||||
|
|
@ -174,6 +227,13 @@ String ExplicitGridTrack::to_string(SerializationMode mode) const
|
|||
});
|
||||
}
|
||||
|
||||
ExplicitGridTrack ExplicitGridTrack::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
return m_value.visit([&](auto const& it) {
|
||||
return ExplicitGridTrack { it.absolutized(context) };
|
||||
});
|
||||
}
|
||||
|
||||
String GridLineNames::to_string() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
|
@ -239,4 +299,19 @@ void GridTrackSizeList::append(ExplicitGridTrack&& explicit_track)
|
|||
m_list.append(move(explicit_track));
|
||||
}
|
||||
|
||||
GridTrackSizeList GridTrackSizeList::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
GridTrackSizeList result;
|
||||
for (auto const& item : m_list) {
|
||||
item.visit(
|
||||
[&result, &context](ExplicitGridTrack const& track) {
|
||||
result.append(track.absolutized(context));
|
||||
},
|
||||
[&result](GridLineNames names) {
|
||||
result.append(move(names));
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Martin Falisse <mfalisse@outlook.com>
|
||||
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -40,6 +41,7 @@ public:
|
|||
bool is_definite() const;
|
||||
|
||||
String to_string(SerializationMode) const;
|
||||
GridSize absolutized(ComputationContext const&) const;
|
||||
bool operator==(GridSize const& other) const = default;
|
||||
|
||||
private:
|
||||
|
|
@ -54,6 +56,7 @@ public:
|
|||
GridSize const& max_grid_size() const& { return m_max_grid_size; }
|
||||
|
||||
String to_string(SerializationMode) const;
|
||||
GridMinMax absolutized(ComputationContext const&) const;
|
||||
bool operator==(GridMinMax const& other) const = default;
|
||||
|
||||
private:
|
||||
|
|
@ -97,6 +100,8 @@ public:
|
|||
void append(GridLineNames&&);
|
||||
void append(ExplicitGridTrack&&);
|
||||
|
||||
GridTrackSizeList absolutized(ComputationContext const&) const;
|
||||
|
||||
private:
|
||||
Vector<Variant<ExplicitGridTrack, GridLineNames>> m_list;
|
||||
};
|
||||
|
|
@ -129,6 +134,7 @@ public:
|
|||
GridRepeatType type() const& { return m_type; }
|
||||
|
||||
String to_string(SerializationMode) const;
|
||||
GridRepeat absolutized(ComputationContext const&) const;
|
||||
bool operator==(GridRepeat const& other) const = default;
|
||||
|
||||
private:
|
||||
|
|
@ -151,6 +157,7 @@ public:
|
|||
GridSize const& grid_size() const { return m_value.get<GridSize>(); }
|
||||
|
||||
String to_string(SerializationMode) const;
|
||||
ExplicitGridTrack absolutized(ComputationContext const&) const;
|
||||
bool operator==(ExplicitGridTrack const& other) const = default;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
|
@ -21,4 +21,12 @@ String GridTrackPlacementStyleValue::to_string(SerializationMode mode) const
|
|||
return m_grid_track_placement.to_string(mode);
|
||||
}
|
||||
|
||||
ValueComparingNonnullRefPtr<StyleValue const> GridTrackPlacementStyleValue::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
auto absolutized_placement = m_grid_track_placement.absolutized(context);
|
||||
if (absolutized_placement == m_grid_track_placement)
|
||||
return *this;
|
||||
return create(move(absolutized_placement));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
|
@ -22,6 +22,8 @@ public:
|
|||
GridTrackPlacement const& grid_track_placement() const { return m_grid_track_placement; }
|
||||
virtual String to_string(SerializationMode) const override;
|
||||
|
||||
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
|
||||
|
||||
bool properties_equal(GridTrackPlacementStyleValue const& other) const { return m_grid_track_placement == other.m_grid_track_placement; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
|
@ -31,4 +31,12 @@ ValueComparingNonnullRefPtr<GridTrackSizeListStyleValue const> GridTrackSizeList
|
|||
return adopt_ref(*new (nothrow) GridTrackSizeListStyleValue(CSS::GridTrackSizeList()));
|
||||
}
|
||||
|
||||
ValueComparingNonnullRefPtr<StyleValue const> GridTrackSizeListStyleValue::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
auto absolutized = m_grid_track_size_list.absolutized(context);
|
||||
if (absolutized == m_grid_track_size_list)
|
||||
return *this;
|
||||
return create(move(absolutized));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
|
@ -26,6 +26,8 @@ public:
|
|||
|
||||
virtual String to_string(SerializationMode) const override;
|
||||
|
||||
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
|
||||
|
||||
bool properties_equal(GridTrackSizeListStyleValue const& other) const { return m_grid_track_size_list == other.m_grid_track_size_list; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ Harness status: OK
|
|||
|
||||
Found 25 tests
|
||||
|
||||
18 Pass
|
||||
7 Fail
|
||||
22 Pass
|
||||
3 Fail
|
||||
Pass Property grid-auto-columns value '1px'
|
||||
Fail Property grid-auto-columns value 'calc(10px + 0.5em)'
|
||||
Pass Property grid-auto-columns value 'calc(10px + 0.5em)'
|
||||
Fail Property grid-auto-columns value 'calc(10px - 0.5em)'
|
||||
Pass Property grid-auto-columns value '4%'
|
||||
Pass Property grid-auto-columns value '5fr'
|
||||
|
|
@ -13,13 +13,13 @@ Pass Property grid-auto-columns value 'min-content'
|
|||
Pass Property grid-auto-columns value 'max-content'
|
||||
Pass Property grid-auto-columns value 'auto'
|
||||
Pass Property grid-auto-columns value 'minmax(1px, 5fr)'
|
||||
Fail Property grid-auto-columns value 'minmax(calc(10px + 0.5em), max-content)'
|
||||
Pass Property grid-auto-columns value 'minmax(calc(10px + 0.5em), max-content)'
|
||||
Fail Property grid-auto-columns value 'minmax(calc(10px - 0.5em), max-content)'
|
||||
Pass Property grid-auto-columns value 'minmax(4%, auto)'
|
||||
Fail Property grid-auto-columns value 'minmax(min-content, calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-columns value 'minmax(min-content, calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-columns value 'minmax(auto, 4%)'
|
||||
Pass Property grid-auto-columns value 'fit-content(1px)'
|
||||
Fail Property grid-auto-columns value 'fit-content(calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-columns value 'fit-content(calc(10px + 0.5em))'
|
||||
Fail Property grid-auto-columns value 'fit-content(calc(10px - 0.5em))'
|
||||
Pass Property grid-auto-columns value 'fit-content(4%)'
|
||||
Pass Property grid-auto-columns value '0px'
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ Harness status: OK
|
|||
|
||||
Found 25 tests
|
||||
|
||||
18 Pass
|
||||
7 Fail
|
||||
22 Pass
|
||||
3 Fail
|
||||
Pass Property grid-auto-rows value '1px'
|
||||
Fail Property grid-auto-rows value 'calc(10px + 0.5em)'
|
||||
Pass Property grid-auto-rows value 'calc(10px + 0.5em)'
|
||||
Fail Property grid-auto-rows value 'calc(10px - 0.5em)'
|
||||
Pass Property grid-auto-rows value '4%'
|
||||
Pass Property grid-auto-rows value '5fr'
|
||||
|
|
@ -13,13 +13,13 @@ Pass Property grid-auto-rows value 'min-content'
|
|||
Pass Property grid-auto-rows value 'max-content'
|
||||
Pass Property grid-auto-rows value 'auto'
|
||||
Pass Property grid-auto-rows value 'minmax(1px, 5fr)'
|
||||
Fail Property grid-auto-rows value 'minmax(calc(10px + 0.5em), max-content)'
|
||||
Pass Property grid-auto-rows value 'minmax(calc(10px + 0.5em), max-content)'
|
||||
Fail Property grid-auto-rows value 'minmax(calc(10px - 0.5em), max-content)'
|
||||
Pass Property grid-auto-rows value 'minmax(4%, auto)'
|
||||
Fail Property grid-auto-rows value 'minmax(min-content, calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-rows value 'minmax(min-content, calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-rows value 'minmax(auto, 4%)'
|
||||
Pass Property grid-auto-rows value 'fit-content(1px)'
|
||||
Fail Property grid-auto-rows value 'fit-content(calc(10px + 0.5em))'
|
||||
Pass Property grid-auto-rows value 'fit-content(calc(10px + 0.5em))'
|
||||
Fail Property grid-auto-rows value 'fit-content(calc(10px - 0.5em))'
|
||||
Pass Property grid-auto-rows value 'fit-content(4%)'
|
||||
Pass Property grid-auto-rows value '0px'
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 32 tests
|
||||
|
||||
29 Pass
|
||||
3 Fail
|
||||
32 Pass
|
||||
Pass Property grid-template-columns value 'none'
|
||||
Pass Property grid-template-columns value '1px'
|
||||
Pass Property grid-template-columns value '1px [a]'
|
||||
|
|
@ -28,9 +27,9 @@ Pass Property grid-template-columns value '[a] 1px repeat(auto-fit, 2px [b] 3px)
|
|||
Pass Property grid-template-rows value '100% [a] repeat(1, [b] 200% [c]) [d] 300%'
|
||||
Pass Property grid-template-rows value '100% [a] repeat(auto-fill, [b] 200% [c]) [d] 300%'
|
||||
Pass Property grid-template-rows value '100% [a] repeat(auto-fit, [b] 200% [c]) [d] 300%'
|
||||
Fail Property grid-template-columns value '[a] 1em repeat(1, 2em [b] 3em) 4em [d]'
|
||||
Fail Property grid-template-columns value '[a] 1em repeat(auto-fill, 2em [b] 3em) 4em [d]'
|
||||
Fail Property grid-template-columns value '[a] 1em repeat(auto-fit, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-columns value '[a] 1em repeat(1, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-columns value '[a] 1em repeat(auto-fill, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-columns value '[a] 1em repeat(auto-fit, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-columns value 'repeat(1, 2px [a] 3px) [b] repeat(auto-fill, [c] 200% [d]) [e] 300%'
|
||||
Pass Property grid-template-columns value '[a] repeat(auto-fill, [b] 200% [c]) repeat(1, 2px [d] 3px) [e] 300%'
|
||||
Pass Property grid-template-columns value 'repeat(1, [a] 2px [b] 3px) [b] repeat(auto-fill, [c] 200% [d]) [e] 300%'
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 24 tests
|
||||
|
||||
21 Pass
|
||||
3 Fail
|
||||
24 Pass
|
||||
Pass Property grid-template-rows value 'none'
|
||||
Pass Property grid-template-rows value '1px'
|
||||
Pass Property grid-template-rows value '1px [a]'
|
||||
|
|
@ -25,6 +24,6 @@ Pass Property grid-template-rows value '[a] 1px repeat(auto-fit, 2px [b] 3px) 4p
|
|||
Pass Property grid-template-rows value '100% [a] repeat(1, [b] 200% [c]) [d] 300%'
|
||||
Pass Property grid-template-rows value '100% [a] repeat(auto-fill, [b] 200% [c]) [d] 300%'
|
||||
Pass Property grid-template-rows value '100% [a] repeat(auto-fit, [b] 200% [c]) [d] 300%'
|
||||
Fail Property grid-template-rows value '[a] 1em repeat(1, 2em [b] 3em) 4em [d]'
|
||||
Fail Property grid-template-rows value '[a] 1em repeat(auto-fill, 2em [b] 3em) 4em [d]'
|
||||
Fail Property grid-template-rows value '[a] 1em repeat(auto-fit, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-rows value '[a] 1em repeat(1, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-rows value '[a] 1em repeat(auto-fill, 2em [b] 3em) 4em [d]'
|
||||
Pass Property grid-template-rows value '[a] 1em repeat(auto-fit, 2em [b] 3em) 4em [d]'
|
||||
Loading…
Add table
Add a link
Reference in a new issue