summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorTobias Christiansen <tobyase@serenityos.org>2021-10-04 13:46:10 +0200
committerAndreas Kling <kling@serenityos.org>2021-10-04 13:59:28 +0200
commit873e95cb6ae7959a9f6512e36d3fbd41a5395fcb (patch)
treeb95f28a31909daa580b857ebc510b6e9b7d1e579 /Userland/Libraries/LibWeb
parent9af85881f588141334d39c4102e43b930418506f (diff)
downloadserenity-873e95cb6ae7959a9f6512e36d3fbd41a5395fcb.zip
LibWeb: Flexbox: Care more about cross-axis margins
Auto margins are still not supported at all, but this is a good start into supporting margins on flex items. The way cross-before (top for row, left for column) is handled is very naive.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp36
1 files changed, 30 insertions, 6 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
index 6d4b8ff826..2b5f033102 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
@@ -26,11 +26,19 @@ FlexFormattingContext::~FlexFormattingContext()
{
}
+struct DirectionAgnosticMargins {
+ float main_before { 0 };
+ float main_after { 0 };
+ float cross_before { 0 };
+ float cross_after { 0 };
+};
+
struct FlexItem {
Box& box;
float flex_base_size { 0 };
float hypothetical_main_size { 0 };
float hypothetical_cross_size { 0 };
+ float hypothetical_cross_size_with_margins() { return hypothetical_cross_size + margins.cross_before + margins.cross_after; }
float target_main_size { 0 };
bool frozen { false };
Optional<float> flex_factor {};
@@ -40,6 +48,7 @@ struct FlexItem {
float cross_size { 0 };
float main_offset { 0 };
float cross_offset { 0 };
+ DirectionAgnosticMargins margins {};
bool is_min_violation { false };
bool is_max_violation { false };
};
@@ -274,6 +283,20 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
else
box.box_model().margin.bottom = margin;
};
+ auto populate_specified_margins = [&is_row](FlexItem& item) {
+ auto width_of_containing_block = item.box.width_of_logical_containing_block();
+ if (is_row) {
+ item.margins.main_before = item.box.computed_values().margin().left.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.main_after = item.box.computed_values().margin().right.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.cross_before = item.box.computed_values().margin().top.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.cross_after = item.box.computed_values().margin().bottom.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ } else {
+ item.margins.main_before = item.box.computed_values().margin().left.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.main_after = item.box.computed_values().margin().right.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.cross_before = item.box.computed_values().margin().top.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ item.margins.cross_after = item.box.computed_values().margin().bottom.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
+ }
+ };
// 1. Generate anonymous flex items
// More like, sift through the already generated items.
@@ -307,7 +330,9 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
return IterationDecision::Continue;
child_box.set_flex_item(true);
- flex_items.append({ child_box });
+ FlexItem flex_item = { child_box };
+ populate_specified_margins(flex_item);
+ flex_items.append(move(flex_item));
return IterationDecision::Continue;
});
@@ -660,8 +685,8 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
// 8.2
float largest_hypothetical_cross_size = 0;
for (auto& flex_item : flex_line.items) {
- if (largest_hypothetical_cross_size < flex_item->hypothetical_cross_size)
- largest_hypothetical_cross_size = flex_item->hypothetical_cross_size;
+ if (largest_hypothetical_cross_size < flex_item->hypothetical_cross_size_with_margins())
+ largest_hypothetical_cross_size = flex_item->hypothetical_cross_size_with_margins();
}
// 8.3
@@ -684,7 +709,6 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
for (auto& flex_line : flex_lines) {
for (auto& flex_item : flex_line.items) {
if (is_cross_auto(flex_item->box) && box.computed_values().align_items() == CSS::AlignItems::Stretch) {
- // FIXME: Take margins into account
flex_item->cross_size = flex_line.cross_size;
} else {
flex_item->cross_size = flex_item->hypothetical_cross_size;
@@ -758,7 +782,7 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
// 14. Align all flex items along the cross-axis
// FIXME: Get the alignment via "align-self" of the item (which accesses "align-items" of the parent if unset)
- // FIXME: Take margins into account
+ // FIXME: Take better care of margins
float line_cross_offset = 0;
for (auto& flex_line : flex_lines) {
for (auto* flex_item : flex_line.items) {
@@ -768,7 +792,7 @@ void FlexFormattingContext::run(Box& box, LayoutMode)
// Fallthrough
case CSS::AlignItems::FlexStart:
case CSS::AlignItems::Stretch:
- flex_item->cross_offset = line_cross_offset;
+ flex_item->cross_offset = line_cross_offset + flex_item->margins.cross_before;
break;
case CSS::AlignItems::FlexEnd:
flex_item->cross_offset = line_cross_offset + flex_line.cross_size - flex_item->cross_size;