diff --git a/src/algo.rs b/src/algo.rs
index 0cc1729c7..12c087ea6 100644
--- a/src/algo.rs
+++ b/src/algo.rs
@@ -34,6 +34,7 @@ struct FlexItem<'a> {
hypothetical_inner_main_size: f32,
hypothetical_outer_main_size: f32,
target_main_size: f32,
+ outer_target_main_size: f32,
violation: f32,
frozen: bool,
@@ -209,6 +210,7 @@ fn compute_internal(
hypothetical_inner_main_size: 0.0,
hypothetical_outer_main_size: 0.0,
target_main_size: 0.0,
+ outer_target_main_size: 0.0,
violation: 0.0,
frozen: false,
@@ -428,6 +430,9 @@ fn compute_internal(
for child in line.items.iter_mut() {
child.target_main_size = child.hypothetical_inner_main_size;
+ child.outer_target_main_size = child.target_main_size
+ + child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0)
+ + child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
if (child.node.flex_grow == 0.0 && child.node.flex_shrink == 0.0)
|| (growing && child.flex_basis > child.hypothetical_inner_main_size)
@@ -553,6 +558,9 @@ fn compute_internal(
child.violation = clamped - child.target_main_size;
total_violation += child.violation;
child.target_main_size = clamped;
+ child.outer_target_main_size = child.target_main_size
+ + child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0)
+ + child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
}
// e. Freeze over-flexed items. The total violation is the sum of the adjustments
@@ -589,13 +597,15 @@ fn compute_internal(
let mut longest_line = f32::MIN;
for line in &flex_lines {
- let length: f32 = line.items.iter().map(|item| item.target_main_size).sum();
+ let length: f32 = line.items.iter().map(|item| item.outer_target_main_size).sum();
longest_line = if length > longest_line { length } else { longest_line };
}
(longest_line + padding_main + border_main)
};
+ let inner_container_main_size = container_main_size - padding_main - border_main;
+
// 9.4. Cross Size Determination
// 7. Determine the hypothetical cross size of each item by performing layout with the
@@ -725,15 +735,15 @@ fn compute_internal(
}
if is_stretch {
- // TODO use result somehow
- compute_internal(
+ let size = compute_internal(
child.node,
if node.flex_direction.is_row() { child.target_main_size } else { child.target_cross_size },
if node.flex_direction.is_row() { child.target_cross_size } else { child.target_main_size },
if node.flex_direction.is_row() { container_main_size } else { available_cross },
if node.flex_direction.is_row() { available_cross } else { container_main_size },
percent_calc_base_child,
- );
+ ).size;
+ child.target_cross_size = size.cross(node.flex_direction);
}
}
}
@@ -747,8 +757,16 @@ fn compute_internal(
// 2. Align the items along the main-axis per justify-content.
for line in &mut flex_lines {
- let used_space: f32 = line.items.iter().map(|child| child.target_main_size).sum();
- let free_space = available_main - used_space;
+ let used_space: f32 = line.items.iter().map(|child| child.outer_target_main_size).sum();
+ let free_space = inner_container_main_size - used_space;
+
+ // TODO does not make a ton of sense to have this here but we want to have this somewhere.
+ for child in &mut line.items {
+ child.main_margin_start =
+ child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+ child.main_margin_end =
+ child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+ }
if free_space > 0.0 {
let mut num_auto_margins = 0;
@@ -778,11 +796,6 @@ fn compute_internal(
let mut is_first = true;
for child in &mut line.items {
- child.main_margin_start =
- child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
- child.main_margin_end =
- child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-
child.offset_main = match node.justify_content {
style::JustifyContent::FlexStart => 0.0,
style::JustifyContent::Center => if is_first {
@@ -826,6 +839,12 @@ fn compute_internal(
for line in &mut flex_lines {
for child in &mut line.items {
+ // TODO probably move this somewhere else, as with main margin resolution. Only auto margins should be resolved here.
+ child.cross_margin_start =
+ child.node.cross_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+ child.cross_margin_end =
+ child.node.cross_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+
if child.target_cross_size < line.cross_size {
let free_space = line.cross_size - child.target_cross_size;
@@ -839,11 +858,6 @@ fn compute_internal(
} else if child.node.cross_margin_end(node.flex_direction) == style::Dimension::Auto {
child.cross_margin_end = free_space;
} else {
- child.cross_margin_start =
- child.node.cross_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
- child.cross_margin_end =
- child.node.cross_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-
// 14. Align all flex items along the cross-axis per align-self, if neither of the item’s
// cross-axis margins are auto.
@@ -881,10 +895,11 @@ fn compute_internal(
let total_cross_size: f32 = flex_lines.iter().map(|line| line.cross_size).sum();
let container_cross_size =
if node_cross.is_finite() { node_cross } else { (total_cross_size + padding_cross + border_cross) };
+ let inner_container_cross_size = container_cross_size - padding_cross - border_cross;
// 16. Align all flex lines per align-content.
- let free_space = container_cross_size - total_cross_size;
+ let free_space = inner_container_cross_size - total_cross_size;
let num_lines = flex_lines.len();
let mut is_first = true;
diff --git a/test_fixtures/justify_content_column_min_height_and_margin_bottom.html b/test_fixtures/justify_content_column_min_height_and_margin_bottom.html
new file mode 100644
index 000000000..4eda0a929
--- /dev/null
+++ b/test_fixtures/justify_content_column_min_height_and_margin_bottom.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <script src="../scripts/gentest/test_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+ <title>
+ Test description
+ </title>
+<head/>
+<body>
+
+<div id="test-root" style="min-height: 50px; justify-content: center; flex-direction: column;">
+ <div style="height: 20px; width: 20px; margin-bottom: 10px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/justify_content_column_min_height_and_margin.html b/test_fixtures/justify_content_column_min_height_and_margin_top.html
similarity index 100%
rename from test_fixtures/justify_content_column_min_height_and_margin.html
rename to test_fixtures/justify_content_column_min_height_and_margin_top.html
diff --git a/test_fixtures/justify_content_colunn_max_height_and_margin.html b/test_fixtures/justify_content_colunn_max_height_and_margin.html
index 8d1a2d4ea..b1fb9ceb4 100644
--- a/test_fixtures/justify_content_colunn_max_height_and_margin.html
+++ b/test_fixtures/justify_content_colunn_max_height_and_margin.html
@@ -9,8 +9,8 @@
<head/>
<body>
-<div id="test-root" style="height: 100px; max-height: 80px; margin-top: 100px; justify-content: center; flex-direction: column;">
- <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="height: 100px; max-height: 80px; justify-content: center; flex-direction: column;">
+ <div style="height: 20px; width: 20px; margin-top: 100px;"></div>
</div>
</body>
diff --git a/test_fixtures/justify_content_overflow_min_max.html b/test_fixtures/justify_content_overflow_min_max.html
index 41f78c570..3300d7082 100644
--- a/test_fixtures/justify_content_overflow_min_max.html
+++ b/test_fixtures/justify_content_overflow_min_max.html
@@ -10,9 +10,9 @@
<body>
<div id="test-root" style="min-height: 100px; max-height: 110px; justify-content: center; flex-direction: column;">
- <div style="width: 50px; height: 50px;"></div>
- <div style="width: 50px; height: 50px;"></div>
- <div style="width: 50px; height: 50px;"></div>
+ <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
+ <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
+ <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
</div>
</body>
diff --git a/test_fixtures/justify_content_row_max_width_and_margin.html b/test_fixtures/justify_content_row_max_width_and_margin.html
index db162a7e1..2dff79893 100644
--- a/test_fixtures/justify_content_row_max_width_and_margin.html
+++ b/test_fixtures/justify_content_row_max_width_and_margin.html
@@ -9,8 +9,8 @@
<head/>
<body>
-<div id="test-root" style="width: 100px; max-width: 80px; margin-left: 100px; justify-content: center; flex-direction: row;">
- <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="width: 100px; max-width: 80px; justify-content: center; flex-direction: row;">
+ <div style="height: 20px; width: 20px; margin-left: 100px;"></div>
</div>
</body>
diff --git a/test_fixtures/justify_content_row_min_width_and_margin.html b/test_fixtures/justify_content_row_min_width_and_margin.html
index 902b528ed..aba377f96 100644
--- a/test_fixtures/justify_content_row_min_width_and_margin.html
+++ b/test_fixtures/justify_content_row_min_width_and_margin.html
@@ -9,8 +9,8 @@
<head/>
<body>
-<div id="test-root" style="min-width: 50px; margin-left: 100px; justify-content: center; flex-direction: row;">
- <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="min-width: 50px; justify-content: center; flex-direction: row;">
+ <div style="height: 20px; width: 20px; margin-left: 10px;"></div>
</div>
</body>
diff --git a/tests/generated.rs b/tests/generated.rs
index c6180df4c..60c87641d 100644
--- a/tests/generated.rs
+++ b/tests/generated.rs
@@ -887,6 +887,32 @@ mod generated {
assert_eq!(layout.children[1].y, 0.0000);
}
+ #[test]
+ fn justify_content_column_min_height_and_margin_top() {
+ let layout = stretch::compute(&stretch::style::Node {
+ flex_direction: stretch::style::FlexDirection::Column,
+ justify_content: stretch::style::JustifyContent::Center,
+ min_height: stretch::style::Dimension::Points(50.0000),
+ children: vec![stretch::style::Node {
+ width: stretch::style::Dimension::Points(20.0000),
+ height: stretch::style::Dimension::Points(20.0000),
+ margin: stretch::style::Edges { top: stretch::style::Dimension::Points(10.0000), ..Default::default() },
+ ..Default::default()
+ }],
+ ..Default::default()
+ });
+
+ assert_eq!(layout.width, 20.0000);
+ assert_eq!(layout.height, 50.0000);
+ assert_eq!(layout.x, 0.0000);
+ assert_eq!(layout.y, 0.0000);
+
+ assert_eq!(layout.children[0].width, 20.0000);
+ assert_eq!(layout.children[0].height, 20.0000);
+ assert_eq!(layout.children[0].x, 0.0000);
+ assert_eq!(layout.children[0].y, 20.0000);
+ }
+
#[test]
fn justify_content_overflow_min_max() {
let layout = stretch::compute(&stretch::style::Node {
@@ -896,16 +922,19 @@ mod generated {
max_height: stretch::style::Dimension::Points(110.0000),
children: vec![
stretch::style::Node {
+ flex_shrink: 0.0000,
width: stretch::style::Dimension::Points(50.0000),
height: stretch::style::Dimension::Points(50.0000),
..Default::default()
},
stretch::style::Node {
+ flex_shrink: 0.0000,
width: stretch::style::Dimension::Points(50.0000),
height: stretch::style::Dimension::Points(50.0000),
..Default::default()
},
stretch::style::Node {
+ flex_shrink: 0.0000,
width: stretch::style::Dimension::Points(50.0000),
height: stretch::style::Dimension::Points(50.0000),
..Default::default()
@@ -920,19 +949,19 @@ mod generated {
assert_eq!(layout.y, 0.0000);
assert_eq!(layout.children[0].width, 50.0000);
- assert_eq!(layout.children[0].height, 37.0000);
+ assert_eq!(layout.children[0].height, 50.0000);
assert_eq!(layout.children[0].x, 0.0000);
- assert_eq!(layout.children[0].y, 0.0000);
+ assert_eq!(layout.children[0].y, -20.0000);
assert_eq!(layout.children[1].width, 50.0000);
- assert_eq!(layout.children[1].height, 36.0000);
+ assert_eq!(layout.children[1].height, 50.0000);
assert_eq!(layout.children[1].x, 0.0000);
- assert_eq!(layout.children[1].y, 37.0000);
+ assert_eq!(layout.children[1].y, 30.0000);
assert_eq!(layout.children[2].width, 50.0000);
- assert_eq!(layout.children[2].height, 37.0000);
+ assert_eq!(layout.children[2].height, 50.0000);
assert_eq!(layout.children[2].x, 0.0000);
- assert_eq!(layout.children[2].y, 73.0000);
+ assert_eq!(layout.children[2].y, 80.0000);
}
#[test]
@@ -1917,10 +1946,13 @@ mod generated {
let layout = stretch::compute(&stretch::style::Node {
justify_content: stretch::style::JustifyContent::Center,
min_width: stretch::style::Dimension::Points(50.0000),
- margin: stretch::style::Edges { start: stretch::style::Dimension::Points(100.0000), ..Default::default() },
children: vec![stretch::style::Node {
width: stretch::style::Dimension::Points(20.0000),
height: stretch::style::Dimension::Points(20.0000),
+ margin: stretch::style::Edges {
+ start: stretch::style::Dimension::Points(10.0000),
+ ..Default::default()
+ },
..Default::default()
}],
..Default::default()
@@ -1928,12 +1960,12 @@ mod generated {
assert_eq!(layout.width, 50.0000);
assert_eq!(layout.height, 20.0000);
- assert_eq!(layout.x, 100.0000);
+ assert_eq!(layout.x, 0.0000);
assert_eq!(layout.y, 0.0000);
assert_eq!(layout.children[0].width, 20.0000);
assert_eq!(layout.children[0].height, 20.0000);
- assert_eq!(layout.children[0].x, 15.0000);
+ assert_eq!(layout.children[0].x, 20.0000);
assert_eq!(layout.children[0].y, 0.0000);
}
@@ -5736,10 +5768,13 @@ mod generated {
justify_content: stretch::style::JustifyContent::Center,
width: stretch::style::Dimension::Points(100.0000),
max_width: stretch::style::Dimension::Points(80.0000),
- margin: stretch::style::Edges { start: stretch::style::Dimension::Points(100.0000), ..Default::default() },
children: vec![stretch::style::Node {
width: stretch::style::Dimension::Points(20.0000),
height: stretch::style::Dimension::Points(20.0000),
+ margin: stretch::style::Edges {
+ start: stretch::style::Dimension::Points(100.0000),
+ ..Default::default()
+ },
..Default::default()
}],
..Default::default()
@@ -5747,12 +5782,12 @@ mod generated {
assert_eq!(layout.width, 80.0000);
assert_eq!(layout.height, 20.0000);
- assert_eq!(layout.x, 100.0000);
+ assert_eq!(layout.x, 0.0000);
assert_eq!(layout.y, 0.0000);
- assert_eq!(layout.children[0].width, 20.0000);
+ assert_eq!(layout.children[0].width, 0.0000);
assert_eq!(layout.children[0].height, 20.0000);
- assert_eq!(layout.children[0].x, 30.0000);
+ assert_eq!(layout.children[0].x, 90.0000);
assert_eq!(layout.children[0].y, 0.0000);
}
@@ -6275,10 +6310,13 @@ mod generated {
justify_content: stretch::style::JustifyContent::Center,
height: stretch::style::Dimension::Points(100.0000),
max_height: stretch::style::Dimension::Points(80.0000),
- margin: stretch::style::Edges { top: stretch::style::Dimension::Points(100.0000), ..Default::default() },
children: vec![stretch::style::Node {
width: stretch::style::Dimension::Points(20.0000),
height: stretch::style::Dimension::Points(20.0000),
+ margin: stretch::style::Edges {
+ top: stretch::style::Dimension::Points(100.0000),
+ ..Default::default()
+ },
..Default::default()
}],
..Default::default()
@@ -6287,12 +6325,12 @@ mod generated {
assert_eq!(layout.width, 20.0000);
assert_eq!(layout.height, 80.0000);
assert_eq!(layout.x, 0.0000);
- assert_eq!(layout.y, 100.0000);
+ assert_eq!(layout.y, 0.0000);
assert_eq!(layout.children[0].width, 20.0000);
- assert_eq!(layout.children[0].height, 20.0000);
+ assert_eq!(layout.children[0].height, 0.0000);
assert_eq!(layout.children[0].x, 0.0000);
- assert_eq!(layout.children[0].y, 30.0000);
+ assert_eq!(layout.children[0].y, 90.0000);
}
#[test]
@@ -8419,32 +8457,6 @@ mod generated {
assert_eq!(layout.children[1].y, 75.0000);
}
- #[test]
- fn justify_content_column_min_height_and_margin() {
- let layout = stretch::compute(&stretch::style::Node {
- flex_direction: stretch::style::FlexDirection::Column,
- justify_content: stretch::style::JustifyContent::Center,
- min_height: stretch::style::Dimension::Points(50.0000),
- children: vec![stretch::style::Node {
- width: stretch::style::Dimension::Points(20.0000),
- height: stretch::style::Dimension::Points(20.0000),
- margin: stretch::style::Edges { top: stretch::style::Dimension::Points(10.0000), ..Default::default() },
- ..Default::default()
- }],
- ..Default::default()
- });
-
- assert_eq!(layout.width, 20.0000);
- assert_eq!(layout.height, 50.0000);
- assert_eq!(layout.x, 0.0000);
- assert_eq!(layout.y, 0.0000);
-
- assert_eq!(layout.children[0].width, 20.0000);
- assert_eq!(layout.children[0].height, 20.0000);
- assert_eq!(layout.children[0].x, 0.0000);
- assert_eq!(layout.children[0].y, 20.0000);
- }
-
#[test]
fn align_flex_start_with_shrinking_children() {
let layout = stretch::compute(&stretch::style::Node {
@@ -8488,4 +8500,33 @@ mod generated {
assert_eq!(layout.children[0].children[0].children[0].y, 0.0000);
}
+ #[test]
+ fn justify_content_column_min_height_and_margin_bottom() {
+ let layout = stretch::compute(&stretch::style::Node {
+ flex_direction: stretch::style::FlexDirection::Column,
+ justify_content: stretch::style::JustifyContent::Center,
+ min_height: stretch::style::Dimension::Points(50.0000),
+ children: vec![stretch::style::Node {
+ width: stretch::style::Dimension::Points(20.0000),
+ height: stretch::style::Dimension::Points(20.0000),
+ margin: stretch::style::Edges {
+ bottom: stretch::style::Dimension::Points(10.0000),
+ ..Default::default()
+ },
+ ..Default::default()
+ }],
+ ..Default::default()
+ });
+
+ assert_eq!(layout.width, 20.0000);
+ assert_eq!(layout.height, 50.0000);
+ assert_eq!(layout.x, 0.0000);
+ assert_eq!(layout.y, 0.0000);
+
+ assert_eq!(layout.children[0].width, 20.0000);
+ assert_eq!(layout.children[0].height, 20.0000);
+ assert_eq!(layout.children[0].x, 0.0000);
+ assert_eq!(layout.children[0].y, 10.0000);
+ }
+
}