Support `Overflow::Hidden` (#424)
* Impl Default for Point. Use derive for Rect and Size Default impls
* Add overflow style property
* Add scrollbar width property
* Add/fix support for overflow property to gentest script
* Enable do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent test
* Add tests for automatic minimum size of flex items with different overflow values
* Implement setting automatic minimum size of flex items to 0 for nodes with non-visible overflow
* Flexbox: only compute/store main axis resolved minimum size
* Derive Serialize/Deserialize for Point<T> when serde feature is enabled
* Add tests for automatic minimum size of grid items with different overflow values
* Add get and set methods to Point
* Implement resolving automatic minimum size to zero for grid items with non-visible overflow
* Optimise style resolution when sizing grid items
* Ensure that scrollbars take up space when generating tests
* Add support for scrollbar_width property to gentest script
* Add tests for overflow:hidden
These tests were generated by temporarily setting overflow:hidden on
every node across the entire generated test suite and then manually
creating copies of the tests with overflow:hidden for those testse
that failed.
* Use 0 when distributing intrinsic minimums of scroll containers to auto tracks, even when sizing under a min- or max-content constraint
* Apply fit-content limit to min-content contributions when item is a scroll container
* Always use indefinite main axis available space when determining flex base size
* Remove WIP overflow:scroll and overflow:auto support
* Add extra feature flags for flexbox-specific code
* Replace <head/> with </head> in test fixtures
* Add note about allow(dead_code)
b9fce82ccc823839f673144ed08f2e0e53f52b76 · ruwaq Nico Burns · 2023-04-10T19:21:13Z (3 wata ñawpaq) · tayta 325413cd1 · kay commitpi sach'ata qhaway
Semántico sayk'uy · 91
scripts/gentest/src/main.rs
scripts/gentest/test_helper.js
src/compute/grid/track_sizing.rs
src/compute/grid/types/grid_item.rs
tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs
tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs
tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs
tests/generated/grid_fit_content_points_min_content_hidden.rs
tests/generated/grid_overflow_inline_axis_hidden.rs
tests/generated/grid_overflow_inline_axis_visible.rs
tests/generated/grid_percent_items_nested_moderate.rs
tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs
tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs
tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs
tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs
tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs
tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs
tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs
tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs
tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs
tests/generated/measure_child_with_flex_shrink_hidden.rs
tests/generated/overflow_main_axis_shrink_hidden.rs
tests/generated/overflow_main_axis_shrink_visible.rs
tests/generated/percentage_moderate_complexity.rs
49 qillqakuna · +1994 −126
diff --git a/scripts/gentest/src/main.rs b/scripts/gentest/src/main.rs
index fee14f8ae..02bd0258b 100644
--- a/scripts/gentest/src/main.rs
+++ b/scripts/gentest/src/main.rs
@@ -51,6 +51,8 @@ async fn main() {
info!("spawning webdriver client and collecting test descriptions");
let client = ClientBuilder::native().capabilities(caps.clone()).connect(webdriver_url).await.unwrap();
+ asserts_non_zero_width_scrollbars(client.clone()).await;
+
let mut test_descs = vec![];
for (name, fixture_path) in fixtures {
test_descs.push(test_root_element(client.clone(), name, fixture_path).await);
@@ -103,6 +105,27 @@ async fn main() {
Command::new("cargo").arg("fmt").current_dir(repo_root).status().unwrap();
}
+async fn asserts_non_zero_width_scrollbars(client: Client) {
+ // Load minimal test page defined in the string
+ const TEST_PAGE: &str = r#"data:text/html;charset=utf-8,<html><body><div style="overflow:scroll" /></body></html>"#;
+ client.goto(TEST_PAGE).await.unwrap();
+
+ // Determine the width of the scrollbar
+ let scrollbar_width = client
+ .execute("return document.body.firstChild.clientWidth - document.body.firstChild.offsetWidth;", vec![])
+ .await
+ .unwrap();
+ let Value::Number(scrollbar_width) = scrollbar_width else { panic!("Error retrieving scrollbar_width") };
+ let scrollbar_width = scrollbar_width.as_f64().unwrap();
+
+ if scrollbar_width == 0.0 {
+ panic!(concat!(
+ "\n\n Error: Scrollbar width of zero detected. This test generation script must be run with scrollbars set to take up space.\n",
+ " On macOS this can be done by setting Show Scrollbars to 'always' in the Appearance section of the System Settings app.\n\n"
+ ))
+ }
+}
+
async fn test_root_element(client: Client, name: String, fixture_path: impl AsRef<Path>) -> (String, Value) {
let fixture_path = fixture_path.as_ref();
@@ -352,13 +375,30 @@ fn generate_node(ident: &str, node: &Value) -> TokenStream {
_ => quote!(),
};
- let overflow = match style["overflow"] {
- Value::String(ref value) => match value.as_ref() {
- "hidden" => quote!(overflow: taffy::style::Overflow::Hidden,),
- "scroll" => quote!(overflow: taffy::style::Overflow::Scroll,),
- _ => quote!(),
- },
- _ => quote!(),
+ fn quote_overflow(overflow: &Value) -> Option<TokenStream> {
+ match overflow {
+ Value::String(ref value) => match value.as_ref() {
+ "hidden" => Some(quote!(taffy::style::Overflow::Hidden)),
+ "scroll" => Some(quote!(taffy::style::Overflow::Scroll)),
+ "auto" => Some(quote!(taffy::style::Overflow::Auto)),
+ _ => None,
+ },
+ _ => None,
+ }
+ }
+ let overflow_x = quote_overflow(&style["overflowX"]);
+ let overflow_y = quote_overflow(&style["overflowY"]);
+ let (overflow, _scrollbar_width) = if overflow_x.is_some() || overflow_y.is_some() {
+ let overflow_x = overflow_x.unwrap_or(quote!(taffy::style::Overflow::Visible));
+ let overflow_y = overflow_y.unwrap_or(quote!(taffy::style::Overflow::Visible));
+ let overflow = quote!(overflow: taffy::geometry::Point { x: #overflow_x, y: #overflow_y },);
+ let scrollbar_width = quote_number_prop("scrollbar_width", style, |value: f32| {
+ let value = value as u8;
+ quote!(#value)
+ });
+ (overflow, scrollbar_width)
+ } else {
+ (quote!(), quote!())
};
let align_items = match style["alignItems"] {
diff --git a/scripts/gentest/test_helper.js b/scripts/gentest/test_helper.js
index b05eb7e7d..1b233a1e3 100644
--- a/scripts/gentest/test_helper.js
+++ b/scripts/gentest/test_helper.js
@@ -1,4 +1,13 @@
+function getScrollBarWidth() {
+ let el = document.createElement("div");
+ el.style.cssText = "overflow:scroll; visibility:hidden; position:absolute;";
+ document.body.appendChild(el);
+ let width = el.offsetWidth - el.clientWidth;
+ el.remove();
+ return width;
+}
+
class TrackSizingParser {
static INITIAL_CHAR_REGEX = /[a-z-A-Z0-9]/;
static TOKEN_CHAR_REGEX = /[-\.a-z-A-Z0-9%]/;
@@ -188,7 +197,9 @@ function describeElement(e) {
writingMode: parseEnum(e.style.writingMode),
flexWrap: parseEnum(e.style.flexWrap),
- overflow: parseEnum(e.style.overflow),
+ overflowX: parseEnum(e.style.overflowX),
+ overflowY: parseEnum(e.style.overflowY),
+ scrollbarWidth: getScrollBarWidth(),
alignItems: parseEnum(e.style.alignItems),
alignSelf: parseEnum(e.style.alignSelf),
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index eef31a4ba..49ce7b350 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -11,7 +11,7 @@ use crate::prelude::{TaffyMaxContent, TaffyMinContent};
use crate::resolve::{MaybeResolve, ResolveOrZero};
use crate::style::{
AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, FlexWrap, JustifyContent,
- LengthPercentageAuto, Position,
+ LengthPercentageAuto, Overflow, Position,
};
use crate::style::{FlexDirection, Style};
use crate::sys::Vec;
@@ -63,6 +63,8 @@ struct FlexItem {
/// The cross-alignment of this item
align_self: AlignSelf,
+ /// The overflow style of the item
+ overflow: Point<Overflow>,
/// The flex shrink style of the item
flex_shrink: f32,
/// The flex grow style of the item
@@ -70,7 +72,7 @@ struct FlexItem {
/// The minimum size of the item. This differs from min_size above because it also
/// takes into account content based automatic minimum sizes
- resolved_minimum_size: Size<f32>,
+ resolved_minimum_main_size: f32,
/// The final offset of this item
inset: Rect<Option<f32>>,
@@ -250,7 +252,7 @@ fn compute_preliminary(
NODE_LOGGER.labelled_log("item.inner_flex_basis", item.inner_flex_basis);
NODE_LOGGER.labelled_debug_log("item.hypothetical_outer_size", item.hypothetical_outer_size);
NODE_LOGGER.labelled_debug_log("item.hypothetical_inner_size", item.hypothetical_inner_size);
- NODE_LOGGER.labelled_debug_log("item.resolved_minimum_size", item.resolved_minimum_size);
+ NODE_LOGGER.labelled_debug_log("item.resolved_minimum_main_size", item.resolved_minimum_main_size);
}
// 4. Determine the main size of the flex container
@@ -488,6 +490,7 @@ fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: Node, constants:
padding: child_style.padding.resolve_or_zero(constants.node_inner_size.width),
border: child_style.border.resolve_or_zero(constants.node_inner_size.width),
align_self: child_style.align_self.unwrap_or(constants.align_items),
+ overflow: child_style.overflow,
flex_grow: child_style.flex_grow,
flex_shrink: child_style.flex_shrink,
flex_basis: 0.0,
@@ -495,7 +498,7 @@ fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: Node, constants:
violation: 0.0,
frozen: false,
- resolved_minimum_size: Size::zero(),
+ resolved_minimum_main_size: 0.0,
hypothetical_inner_size: Size::zero(),
hypothetical_outer_size: Size::zero(),
target_size: Size::zero(),
@@ -593,7 +596,10 @@ fn determine_flex_base_size(
let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
let child_min_cross = child.min_size.cross(dir).maybe_add(cross_axis_margin_sum);
let child_max_cross = child.max_size.cross(dir).maybe_add(cross_axis_margin_sum);
- let cross_axis_available_space = cross_axis_parent_size.maybe_clamp(child_min_cross, child_max_cross).into();
+ let cross_axis_available_space: AvailableSpace = available_space
+ .cross(dir)
+ .map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
+ .maybe_clamp(child_min_cross, child_max_cross);
child.flex_basis = 'flex_basis: {
// A. If the item has a definite used flex basis, that’s the flex base size.
@@ -637,7 +643,17 @@ fn determine_flex_base_size(
// flex item’s cross size. The flex base size is the item’s resulting main size.
let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
- let child_available_space = available_space.with_cross(dir, cross_axis_available_space);
+ let child_available_space = Size::MAX_CONTENT
+ .with_main(
+ dir,
+ // Map AvailableSpace::Definite to AvailableSpace::MaxContent
+ if available_space.main(dir) == AvailableSpace::MinContent {
+ AvailableSpace::MinContent
+ } else {
+ AvailableSpace::MaxContent
+ },
+ )
+ .with_cross(dir, cross_axis_available_space);
let child_known_dimensions = {
let mut ckd = child.size;
@@ -697,24 +713,28 @@ fn determine_flex_base_size(
// be set to their usual values in the cross axis so that wrapping content can wrap correctly.
//
// See https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution
- let min_content_size = {
- let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
- let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
+ let style_min_main_size =
+ child.min_size.or(child.overflow.map(Overflow::maybe_into_automatic_min_size).into()).main(dir);
- tree.measure_child_size(
- child.node,
- Size::NONE,
- child_parent_size,
- child_available_space,
- SizingMode::ContentSize,
- )
- };
+ child.resolved_minimum_main_size = style_min_main_size.unwrap_or({
+ let min_content_size = {
+ let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
+ let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
- // 4.5. Automatic Minimum Size of Flex Items
- // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
- let clamped_min_content_size = min_content_size.maybe_min(child.size).maybe_min(child.max_size);
- child.resolved_minimum_size =
- child.min_size.unwrap_or(clamped_min_content_size).maybe_max(padding_border_axes_sums);
+ tree.measure_child_size(
+ child.node,
+ Size::NONE,
+ child_parent_size,
+ child_available_space,
+ SizingMode::ContentSize,
+ )
+ };
+
+ // 4.5. Automatic Minimum Size of Flex Items
+ // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
+ let clamped_min_content_size = min_content_size.maybe_min(child.size).maybe_min(child.max_size);
+ clamped_min_content_size.maybe_max(padding_border_axes_sums).main(dir)
+ });
}
}
@@ -875,12 +895,11 @@ fn determine_container_main_size(
let flex_basis_min = clamping_basis.filter(|_| item.flex_shrink == 0.0);
let flex_basis_max = clamping_basis.filter(|_| item.flex_grow == 0.0);
- let resolved_min = item.resolved_minimum_size.main(constants.dir);
let min_main_size = style_min
.maybe_max(flex_basis_min)
.or(flex_basis_min)
- .unwrap_or(resolved_min)
- .max(resolved_min);
+ .unwrap_or(item.resolved_minimum_main_size)
+ .max(item.resolved_minimum_main_size);
let max_main_size =
style_max.maybe_min(flex_basis_max).or(flex_basis_max).unwrap_or(f32::INFINITY);
@@ -1151,7 +1170,7 @@ fn resolve_flexible_lengths(line: &mut FlexLine, constants: &AlgoConstants, orig
// If the item’s target main size was made larger by this, it’s a min violation.
let total_violation = unfrozen.iter_mut().fold(0.0, |acc, child| -> f32 {
- let resolved_min_main: Option<f32> = child.resolved_minimum_size.main(constants.dir).into();
+ let resolved_min_main: Option<f32> = child.resolved_minimum_main_size.into();
let max_main = child.max_size.main(constants.dir);
let clamped = child.target_size.main(constants.dir).maybe_clamp(resolved_min_main, max_main).max(0.0);
child.violation = clamped - child.target_size.main(constants.dir);
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index cfd415487..4d1137cb3 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -562,13 +562,23 @@ fn resolve_intrinsic_track_sizes(
}
MinTrackSizingFunction::Auto => {
let space = match axis_available_grid_space {
- AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+ // QUIRK: The spec says that:
+ //
+ // If the grid container is being sized under a min- or max-content constraint, use the items’ limited
+ // min-content contributions in place of their minimum contributions here.
+ //
+ // However, in practice browsers only seem to apply this rule if the item is not a scroll container
+ // (note that overflow:hidden counts as a scroll container), giving the automatic minimum size of scroll
+ // containers (zero) precedence over the min-content contributions.
+ AvailableSpace::MinContent | AvailableSpace::MaxContent
+ if !item.overflow.get(axis).is_scroll_container() =>
+ {
let axis_minimum_size = item_sizer.minimum_contribution(item, axis_tracks);
let axis_min_content_size = item_sizer.min_content_contribution(item);
let limit = track.max_track_sizing_function.definite_limit(axis_inner_node_size);
axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
}
- AvailableSpace::Definite(_) => item_sizer.minimum_contribution(item, axis_tracks),
+ _ => item_sizer.minimum_contribution(item, axis_tracks),
};
f32_max(track.base_size, space)
}
@@ -582,12 +592,19 @@ fn resolve_intrinsic_track_sizes(
// Handle growth limits
if let MaxTrackSizingFunction::FitContent(_) = track.max_track_sizing_function {
+ // If item is not a scroll container, then increase the growth limit to at least the
+ // size of the min-content contribution
+ if !item.overflow.get(axis).is_scroll_container() {
+ let min_content_contribution = item_sizer.min_content_contribution(item);
+ track.growth_limit_planned_increase =
+ f32_max(track.growth_limit_planned_increase, min_content_contribution);
+ }
+
+ // Always increase the growth limit to at least the size of the *fit-content limited*
+ // max-cotent contribution
let fit_content_limit = track.fit_content_limit(axis_inner_node_size);
- let min_content_contribution = item_sizer.min_content_contribution(item);
let max_content_contribution =
f32_min(item_sizer.max_content_contribution(item), fit_content_limit);
- track.growth_limit_planned_increase =
- f32_max(track.growth_limit_planned_increase, min_content_contribution);
track.growth_limit_planned_increase =
f32_max(track.growth_limit_planned_increase, max_content_contribution);
} else if track.max_track_sizing_function.is_max_content_alike()
@@ -629,28 +646,49 @@ fn resolve_intrinsic_track_sizes(
move |track: &GridTrack| track.min_track_sizing_function.definite_value(axis_inner_node_size).is_none();
for item in batch.iter_mut().filter(|item| item.crosses_intrinsic_track(axis)) {
// ...by distributing extra space as needed to accommodate these items’ minimum contributions.
- // If the grid container is being sized under a min- or max-content constraint, use the items’ limited min-content contributions
- // in place of their minimum contributions here.
+ //
+ // QUIRK: The spec says that:
+ //
+ // If the grid container is being sized under a min- or max-content constraint, use the items’ limited min-content contributions
+ // in place of their minimum contributions here.
+ //
+ // However, in practice browsers only seem to apply this rule if the item is not a scroll container (note that overflow:hidden counts as
+ // a scroll container), giving the automatic minimum size of scroll containers (zero) precedence over the min-content contributions.
let space = match axis_available_grid_space {
- AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+ AvailableSpace::MinContent | AvailableSpace::MaxContent
+ if !item.overflow.get(axis).is_scroll_container() =>
+ {
let axis_minimum_size = item_sizer.minimum_contribution(item, axis_tracks);
let axis_min_content_size = item_sizer.min_content_contribution(item);
let limit = item.spanned_track_limit(axis, axis_tracks, axis_inner_node_size);
axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
}
- AvailableSpace::Definite(_) => item_sizer.minimum_contribution(item, axis_tracks),
+ _ => item_sizer.minimum_contribution(item, axis_tracks),
};
let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
if space > 0.0 {
- distribute_item_space_to_base_size(
- is_flex,
- use_flex_factor_for_distribution,
- space,
- tracks,
- has_intrinsic_min_track_sizing_function,
- |_| f32::INFINITY,
- IntrinsicContributionType::Minimum,
- );
+ if item.overflow.get(axis).is_scroll_container() {
+ let fit_content_limit = move |track: &GridTrack| track.fit_content_limit(axis_inner_node_size);
+ distribute_item_space_to_base_size(
+ is_flex,
+ use_flex_factor_for_distribution,
+ space,
+ tracks,
+ has_intrinsic_min_track_sizing_function,
+ fit_content_limit,
+ IntrinsicContributionType::Minimum,
+ );
+ } else {
+ distribute_item_space_to_base_size(
+ is_flex,
+ use_flex_factor_for_distribution,
+ space,
+ tracks,
+ has_intrinsic_min_track_sizing_function,
+ |_| f32::INFINITY,
+ IntrinsicContributionType::Minimum,
+ );
+ }
}
}
flush_planned_base_size_increases(axis_tracks);
@@ -666,15 +704,28 @@ fn resolve_intrinsic_track_sizes(
let space = item_sizer.min_content_contribution(item);
let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
if space > 0.0 {
- distribute_item_space_to_base_size(
- is_flex,
- use_flex_factor_for_distribution,
- space,
- tracks,
- has_min_or_max_content_min_track_sizing_function,
- |_| f32::INFINITY,
- IntrinsicContributionType::Minimum,
- );
+ if item.overflow.get(axis).is_scroll_container() {
+ let fit_content_limit = move |track: &GridTrack| track.fit_content_limit(axis_inner_node_size);
+ distribute_item_space_to_base_size(
+ is_flex,
+ use_flex_factor_for_distribution,
+ space,
+ tracks,
+ has_min_or_max_content_min_track_sizing_function,
+ fit_content_limit,
+ IntrinsicContributionType::Minimum,
+ );
+ } else {
+ distribute_item_space_to_base_size(
+ is_flex,
+ use_flex_factor_for_distribution,
+ space,
+ tracks,
+ has_min_or_max_content_min_track_sizing_function,
+ |_| f32::INFINITY,
+ IntrinsicContributionType::Minimum,
+ );
+ }
}
}
flush_planned_base_size_increases(axis_tracks);
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index cd9fb8234..f6be292c7 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -2,14 +2,15 @@
use super::GridTrack;
use crate::axis::AbstractAxis;
use crate::compute::grid::OriginZeroLine;
-use crate::geometry::{Line, Rect, Size};
+use crate::geometry::{Line, Point, Rect, Size};
use crate::layout::SizingMode;
use crate::math::MaybeMath;
use crate::node::Node;
use crate::prelude::LayoutTree;
use crate::resolve::{MaybeResolve, ResolveOrZero};
use crate::style::{
- AlignItems, AlignSelf, AvailableSpace, LengthPercentageAuto, MaxTrackSizingFunction, MinTrackSizingFunction, Style,
+ AlignItems, AlignSelf, AvailableSpace, Dimension, LengthPercentageAuto, MaxTrackSizingFunction,
+ MinTrackSizingFunction, Overflow, Style,
};
use core::ops::Range;
@@ -32,6 +33,16 @@ pub(in super::super) struct GridItem {
/// (in origin-zero coordinates)
pub column: Line<OriginZeroLine>,
+ /// The item's overflow style
+ pub overflow: Point<Overflow>,
+ /// The item's size style
+ pub size: Size<Dimension>,
+ /// The item's min_size style
+ pub min_size: Size<Dimension>,
+ /// The item's max_size style
+ pub max_size: Size<Dimension>,
+ /// The item's aspect_ratio style
+ pub aspect_ratio: Option<f32>,
/// The item's margin style
pub margin: Rect<LengthPercentageAuto>,
/// The item's align_self property, or the parent's align_items property is not set
@@ -87,6 +98,11 @@ impl GridItem {
source_order,
row: row_span,
column: col_span,
+ overflow: style.overflow,
+ size: style.size,
+ min_size: style.min_size,
+ max_size: style.max_size,
+ aspect_ratio: style.aspect_ratio,
margin: style.margin,
align_self: style.align_self.unwrap_or(parent_align_items),
justify_self: style.justify_self.unwrap_or(parent_justify_items),
@@ -206,17 +222,15 @@ impl GridItem {
/// allow percentage sizes further down the tree to resolve properly in some cases
fn known_dimensions(
&self,
- tree: &mut impl LayoutTree,
inner_node_size: Size<Option<f32>>,
grid_area_size: Size<Option<f32>>,
) -> Size<Option<f32>> {
let margins = self.margins_axis_sums_with_baseline_shims(inner_node_size.width);
- let style = tree.style(self.node);
- let aspect_ratio = style.aspect_ratio;
- let inherent_size = style.size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
- let min_size = style.min_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
- let max_size = style.max_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+ let aspect_ratio = self.aspect_ratio;
+ let inherent_size = self.size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+ let min_size = self.min_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+ let max_size = self.max_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
let grid_area_minus_item_margins_size = grid_area_size.maybe_sub(margins);
@@ -227,8 +241,8 @@ impl GridItem {
// - Alignment style is "stretch"
// - The node is not absolutely positioned
// - The node does not have auto margins in this axis.
- if style.margin.left != LengthPercentageAuto::Auto
- && style.margin.right != LengthPercentageAuto::Auto
+ if self.margin.left != LengthPercentageAuto::Auto
+ && self.margin.right != LengthPercentageAuto::Auto
&& self.justify_self == AlignSelf::Stretch
{
return grid_area_minus_item_margins_size.width;
@@ -245,8 +259,8 @@ impl GridItem {
// - Alignment style is "stretch"
// - The node is not absolutely positioned
// - The node does not have auto margins in this axis.
- if style.margin.top != LengthPercentageAuto::Auto
- && style.margin.bottom != LengthPercentageAuto::Auto
+ if self.margin.top != LengthPercentageAuto::Auto
+ && self.margin.bottom != LengthPercentageAuto::Auto
&& self.align_self == AlignSelf::Stretch
{
return grid_area_minus_item_margins_size.height;
@@ -326,7 +340,7 @@ impl GridItem {
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
- let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
+ let known_dimensions = self.known_dimensions(inner_node_size, available_space);
tree.measure_child_size(
self.node,
known_dimensions,
@@ -364,7 +378,7 @@ impl GridItem {
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
- let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
+ let known_dimensions = self.known_dimensions(inner_node_size, available_space);
tree.measure_child_size(
self.node,
known_dimensions,
@@ -409,15 +423,15 @@ impl GridItem {
known_dimensions: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
- let style = tree.style(self.node);
- let size = style
+ let size = self
.size
.maybe_resolve(inner_node_size)
- .maybe_apply_aspect_ratio(style.aspect_ratio)
+ .maybe_apply_aspect_ratio(self.aspect_ratio)
.get(axis)
.or_else(|| {
- style.min_size.maybe_resolve(inner_node_size).maybe_apply_aspect_ratio(style.aspect_ratio).get(axis)
+ self.min_size.maybe_resolve(inner_node_size).maybe_apply_aspect_ratio(self.aspect_ratio).get(axis)
})
+ .or_else(|| self.overflow.get(axis).maybe_into_automatic_min_size())
.unwrap_or_else(|| {
// Automatic minimum size. See https://www.w3.org/TR/css-grid-1/#min-size-auto
diff --git a/src/geometry.rs b/src/geometry.rs
index 65dce8e3e..e0ebad338 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -11,7 +11,7 @@ use crate::style::FlexDirection;
use crate::axis::AbstractAxis;
/// An axis-aligned UI rectangle
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Rect<T> {
/// This can represent either the x-coordinate of the starting edge,
@@ -34,17 +34,6 @@ pub struct Rect<T> {
pub bottom: T,
}
-impl<T: Default> Default for Rect<T> {
- fn default() -> Self {
- Rect {
- left: Default::default(),
- right: Default::default(),
- top: Default::default(),
- bottom: Default::default(),
- }
- }
-}
-
impl<U, T: Add<U>> Add<Rect<U>> for Rect<T> {
type Output = Rect<T::Output>;
@@ -248,7 +237,7 @@ impl<T: Add + Copy> Line<T> {
}
/// The width and height of a [`Rect`]
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Size<T> {
/// The x extent of the rectangle
@@ -257,12 +246,6 @@ pub struct Size<T> {
pub height: T,
}
-impl<T: Default> Default for Size<T> {
- fn default() -> Self {
- Size { width: Default::default(), height: Default::default() }
- }
-}
-
// Generic Add impl for Size<T> + Size<U> where T + U has an Add impl
impl<U, T: Add<U>> Add<Size<U>> for Size<T> {
type Output = Size<<T as Add<U>>::Output>;
@@ -272,6 +255,9 @@ impl<U, T: Add<U>> Add<Size<U>> for Size<T> {
}
}
+// Note: we allow dead_code here as we want to provide a complete API of helpers that is symetrical in all axes,
+// but sometimes we only currently have a use for the helper in a single axis
+#[allow(dead_code)]
impl<T> Size<T> {
/// Applies the function `f` to both the width and height
///
@@ -335,7 +321,6 @@ impl<T> Size<T> {
/// Creates a new value of type Self with the main axis set to value provided
///
/// Whether this is the width or height depends on the `direction` provided
- #[allow(dead_code)]
#[cfg(feature = "flexbox")]
pub(crate) fn with_main(self, direction: FlexDirection, value: T) -> Self {
let mut new = self;
@@ -361,6 +346,34 @@ impl<T> Size<T> {
new
}
+ /// Creates a new value of type Self with the main axis modified by the callback provided
+ ///
+ /// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
+ pub(crate) fn map_main(self, direction: FlexDirection, mapper: impl FnOnce(T) -> T) -> Self {
+ let mut new = self;
+ if direction.is_row() {
+ new.width = mapper(new.width);
+ } else {
+ new.height = mapper(new.height);
+ }
+ new
+ }
+
+ /// Creates a new value of type Self with the cross axis modified by the callback provided
+ ///
+ /// Whether this is the width or height depends on the `direction` provided
+ #[cfg(feature = "flexbox")]
+ pub(crate) fn map_cross(self, direction: FlexDirection, mapper: impl FnOnce(T) -> T) -> Self {
+ let mut new = self;
+ if direction.is_row() {
+ new.height = mapper(new.height);
+ } else {
+ new.width = mapper(new.width);
+ }
+ new
+ }
+
/// Gets the extent of the main layout axis
///
/// Whether this is the width or height depends on the `direction` provided
@@ -478,7 +491,8 @@ impl Size<Dimension> {
/// A 2-dimensional coordinate.
///
/// When used in association with a [`Rect`], represents the bottom-left corner.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Point<T> {
/// The x-coordinate
pub x: T,
@@ -496,6 +510,44 @@ impl Point<Option<f32>> {
pub const NONE: Self = Self { x: None, y: None };
}
+impl<T> Point<T> {
+ /// Applies the function `f` to both the x and y
+ ///
+ /// This is used to transform a `Point<T>` into a `Point<R>`.
+ pub fn map<R, F>(self, f: F) -> Point<R>
+ where
+ F: Fn(T) -> R,
+ {
+ Point { x: f(self.x), y: f(self.y) }
+ }
+
+ /// Gets the extent of the specified layout axis
+ /// Whether this is the width or height depends on the `GridAxis` provided
+ #[cfg(feature = "grid")]
+ pub fn get(self, axis: AbstractAxis) -> T {
+ match axis {
+ AbstractAxis::Inline => self.x,
+ AbstractAxis::Block => self.y,
+ }
+ }
+
+ /// Sets the extent of the specified layout axis
+ /// Whether this is the width or height depends on the `GridAxis` provided
+ #[cfg(feature = "grid")]
+ pub fn set(&mut self, axis: AbstractAxis, value: T) {
+ match axis {
+ AbstractAxis::Inline => self.x = value,
+ AbstractAxis::Block => self.y = value,
+ }
+ }
+}
+
+impl<T> From<Point<T>> for Size<T> {
+ fn from(value: Point<T>) -> Self {
+ Size { width: value.x, height: value.y }
+ }
+}
+
/// Generic struct which holds a "min" value and a "max" value
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
diff --git a/src/style/mod.rs b/src/style/mod.rs
index a784bd6e8..d7e169053 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -20,7 +20,7 @@ pub use self::grid::{
GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
NonRepeatedTrackSizingFunction, TrackSizingFunction,
};
-use crate::geometry::{Rect, Size};
+use crate::geometry::{Point, Rect, Size};
#[cfg(feature = "grid")]
use crate::geometry::Line;
@@ -94,6 +94,46 @@ impl Default for Position {
}
}
+/// How children overflowing their container should affect layout
+///
+/// In CSS the primary effect of this property is to control whether contents of a parent container that overflow that container should
+/// be displayed anyway, be clipped, or trigger the container to become a scroll container. However it also has secondary effects on layout,
+/// the main ones being:
+///
+/// - The automatic minimum size Flexbox/CSS Grid items with non-`Visible` overflow is `0` rather than being content based
+///
+/// In Taffy, we only implement the layout related secondary effects as we are not concerned with drawing/painting.
+///
+/// <https://developer.mozilla.org/en-US/docs/Web/CSS/overflow>
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+pub enum Overflow {
+ /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of it's content.
+ #[default]
+ Visible,
+ /// The automatic minimum size of this node as a flexbox/grid item should be `0`.
+ Hidden,
+}
+
+impl Overflow {
+ /// Returns true for overflow modes that contain their contents (`Overflow::Hidden`, `Overflow::Scroll`, `Overflow::Auto`)
+ /// or else false for overflow modes that allow their contains to spill (`Overflow::Visible`).
+ #[inline(always)]
+ pub(crate) fn is_scroll_container(self) -> bool {
+ self != Overflow::Visible
+ }
+
+ /// Returns `Some(0.0)` if the overflow mode would cause the automatic minimum size of a Flexbox or CSS Grid item
+ /// to be `0`. Else returns None.
+ #[inline(always)]
+ pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
+ match self.is_scroll_container() {
+ true => Some(0.0),
+ false => None,
+ }
+ }
+}
+
/// The flexbox layout information for a single [`Node`](crate::node::Node).
///
/// The most important idea in flexbox is the notion of a "main" and "cross" axis, which are always perpendicular to each other.
@@ -115,6 +155,10 @@ pub struct Style {
/// What layout strategy should be used?
pub display: Display,
+ // Overflow properties
+ /// How children overflowing their container should affect layout
+ pub overflow: Point<Overflow>,
+
// Position properties
/// What should the `position` value of this struct use as a base offset?
pub position: Position,
@@ -225,6 +269,7 @@ impl Style {
/// The [`Default`] layout, in a form that can be used in const functions
pub const DEFAULT: Style = Style {
display: Display::DEFAULT,
+ overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
position: Position::Relative,
inset: Rect::auto(),
margin: Rect::zero(),
@@ -296,6 +341,7 @@ mod tests {
let old_defaults = Style {
display: Default::default(),
+ overflow: Default::default(),
position: Default::default(),
#[cfg(feature = "flexbox")]
flex_direction: Default::default(),
@@ -375,6 +421,7 @@ mod tests {
// Display and Position
assert_type_size::<Display>(1);
assert_type_size::<Position>(1);
+ assert_type_size::<Overflow>(1);
// Dimensions and aggregations of Dimensions
assert_type_size::<f32>(4);
diff --git a/test_fixtures/xdo_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html b/test_fixtures/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
similarity index 100%
rename from test_fixtures/xdo_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
rename to test_fixtures/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.html b/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.html
new file mode 100644
index 000000000..95d61db9b
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.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="display: grid; grid-template-columns: fit-content(50%);grid-template-rows: 40px">
+ <div style="overflow: hidden;">HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.html b/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.html
new file mode 100644
index 000000000..a02c71614
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.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="display: grid; grid-template-columns: fit-content(50%);grid-template-rows: 40px">
+ <div style="overflow: hidden;">HHHH​HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_points_min_content_hidden.html b/test_fixtures/grid_fit_content_points_min_content_hidden.html
new file mode 100644
index 000000000..84f675243
--- /dev/null
+++ b/test_fixtures/grid_fit_content_points_min_content_hidden.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="display: grid; grid-template-columns: fit-content(30px);grid-template-rows: 40px">
+ <div style="overflow: hidden;">HHHH​HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_overflow_inline_axis_hidden.html b/test_fixtures/grid_overflow_inline_axis_hidden.html
new file mode 100644
index 000000000..d71fb04fa
--- /dev/null
+++ b/test_fixtures/grid_overflow_inline_axis_hidden.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="display:grid;width:50px; height: 50px;">
+ <div style="overflow: hidden;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_overflow_inline_axis_visible.html b/test_fixtures/grid_overflow_inline_axis_visible.html
new file mode 100644
index 000000000..e62f76208
--- /dev/null
+++ b/test_fixtures/grid_overflow_inline_axis_visible.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="display:grid;width:50px; height: 50px;">
+ <div style="overflow: visible;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html b/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html
new file mode 100644
index 000000000..3ca067899
--- /dev/null
+++ b/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html
@@ -0,0 +1,34 @@
+<!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="
+ display: grid;
+ grid-template-rows: 40px 40px;
+ grid-template-columns: min-content max-content fit-content(20px) auto 10px 20% minmax(2px, auto) minmax(2px, 4px) minmax(2px, min-content) minmax(2px, max-content) minmax(min-content, max-content) minmax(min-content, auto) minmax(max-content, auto);
+">
+ <div style="grid-column: 1 / span 13;overflow: hidden;">HHHHHHHHHHHHHHHH​HHHHHHHHHHHHHHHH</div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_max_content_auto_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_auto_indefinite_hidden.html
new file mode 100644
index 000000000..e303b382f
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_auto_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:max-content auto;grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;>HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html
new file mode 100644
index 000000000..2e74e60e5
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:max-content fit-content(10px);grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html
new file mode 100644
index 000000000..8db65781c
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:max-content fit-content(80px);grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2;overflow: hidden">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html
new file mode 100644
index 000000000..bf33749a9
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:min-content auto;grid-template-rows: 40px">
+ <div></div>
+ <div></div>
+ <div style="grid-column: 1 / span 2;overflow: hidden;">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html
new file mode 100644
index 000000000..4971d2d64
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:min-content fit-content(10px);grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html
new file mode 100644
index 000000000..d17b1dc1d
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:min-content fit-content(30px);grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html
new file mode 100644
index 000000000..aba6ee46f
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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="display: grid; grid-template-columns:min-content fit-content(80px);grid-template-rows: 40px">
+ <div style="grid-row: 1; grid-column: 1"></div>
+ <div style="grid-row: 1; grid-column: 2"></div>
+ <div style="grid-row: 1; grid-column: 1 / span 2;overflow: hidden;">HHHH​HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html b/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html
new file mode 100644
index 000000000..495f58259
--- /dev/null
+++ b/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html
@@ -0,0 +1,23 @@
+<!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="display: grid; grid-template-columns:min-content max-content fit-content(20px) auto 10px 20%;grid-template-rows: 40px 40px">
+ <div style="grid-column: 1 / span 6;overflow: hidden">HHHHHHHH​HHHHHHHH</div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/measure_child_with_flex_shrink_hidden.html b/test_fixtures/measure_child_with_flex_shrink_hidden.html
new file mode 100644
index 000000000..07797f5c3
--- /dev/null
+++ b/test_fixtures/measure_child_with_flex_shrink_hidden.html
@@ -0,0 +1,18 @@
+<!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="width:100px; height: auto">
+ <div style="width: 50px;height: 50px"></div>
+ <div style="overflow: hidden;">HHHHHHHHHH​HHHHHHHHHH​HHHHHHHHHH​HHHHHHHHHH​HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/overflow_main_axis_shrink_hidden.html b/test_fixtures/overflow_main_axis_shrink_hidden.html
new file mode 100644
index 000000000..68c34189b
--- /dev/null
+++ b/test_fixtures/overflow_main_axis_shrink_hidden.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="width:50px; height: 50px;">
+ <div style="flex-shrink: 1;overflow: hidden;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/overflow_main_axis_shrink_visible.html b/test_fixtures/overflow_main_axis_shrink_visible.html
new file mode 100644
index 000000000..f47f1bb43
--- /dev/null
+++ b/test_fixtures/overflow_main_axis_shrink_visible.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="width:50px; height: 50px;">
+ <div style="flex-shrink: 1;overflow: visible;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html b/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html
new file mode 100644
index 000000000..5b47628bb
--- /dev/null
+++ b/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html
@@ -0,0 +1,19 @@
+<!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="flex-direction: row;">
+ <div style="flex-direction: column;flex-basis: 0px;overflow: hidden;">
+ <div style="width: 100px; height: 50px;"></div>
+ </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/caching.rs b/tests/caching.rs
index 581ce43e9..a1a3c2fb6 100644
--- a/tests/caching.rs
+++ b/tests/caching.rs
@@ -30,7 +30,7 @@ mod caching {
taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
- assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+ assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 3);
}
#[test]
@@ -62,6 +62,6 @@ mod caching {
}
taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
- assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+ assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 3);
}
}
diff --git a/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs b/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs
new file mode 100644
index 000000000..c747ba6ed
--- /dev/null
+++ b/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs
@@ -0,0 +1,67 @@
+#[test]
+fn do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node00 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(100f32),
+ height: taffy::style::Dimension::Points(100f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node0 = taffy
+ .new_with_children(
+ taffy::style::Style {
+ position: taffy::style::Position::Absolute,
+ flex_direction: taffy::style::FlexDirection::Column,
+ inset: taffy::geometry::Rect {
+ left: taffy::style::LengthPercentageAuto::Points(0f32),
+ right: auto(),
+ top: taffy::style::LengthPercentageAuto::Points(0f32),
+ bottom: auto(),
+ },
+ ..Default::default()
+ },
+ &[node00],
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+ assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node00).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 100f32, size.width);
+ assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 100f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs b/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs
new file mode 100644
index 000000000..04fe10b89
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_percent_indefinite_max_content_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![fit_content(percent(0.5f32))],
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 10f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs b/tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs
new file mode 100644
index 000000000..bac384717
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_percent_indefinite_min_content_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![fit_content(percent(0.5f32))],
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_fit_content_points_min_content_hidden.rs b/tests/generated/grid_fit_content_points_min_content_hidden.rs
new file mode 100644
index 000000000..f1569f365
--- /dev/null
+++ b/tests/generated/grid_fit_content_points_min_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_points_min_content_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![fit_content(points(30f32))],
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 30f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_overflow_inline_axis_hidden.rs b/tests/generated/grid_overflow_inline_axis_hidden.rs
new file mode 100644
index 000000000..64c40045b
--- /dev/null
+++ b/tests/generated/grid_overflow_inline_axis_hidden.rs
@@ -0,0 +1,55 @@
+#[test]
+fn grid_overflow_inline_axis_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_overflow_inline_axis_visible.rs b/tests/generated/grid_overflow_inline_axis_visible.rs
new file mode 100644
index 000000000..8e6255fd7
--- /dev/null
+++ b/tests/generated/grid_overflow_inline_axis_visible.rs
@@ -0,0 +1,49 @@
+#[test]
+fn grid_overflow_inline_axis_visible() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style { ..Default::default() },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_percent_items_nested_moderate.rs b/tests/generated/grid_percent_items_nested_moderate.rs
index 80e3a8214..da361ae74 100644
--- a/tests/generated/grid_percent_items_nested_moderate.rs
+++ b/tests/generated/grid_percent_items_nested_moderate.rs
@@ -89,10 +89,10 @@ fn grid_percent_items_nested_moderate() {
assert!(location.y - 8f32 < 0.1, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y);
let Layout { size, location, .. } = taffy.layout(node00).unwrap();
assert!(
- size.width - 38.40625f32 < 0.1,
+ size.width - 38.414063f32 < 0.1,
"width of node {:?}. Expected {}. Actual {}",
node00.data(),
- 38.40625f32,
+ 38.414063f32,
size.width
);
assert!(size.height - 6f32 < 0.1, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height);
diff --git a/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs b/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs
new file mode 100644
index 000000000..d8bd307e3
--- /dev/null
+++ b/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs
@@ -0,0 +1,146 @@
+#[test]
+fn grid_span_13_most_non_flex_with_minmax_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(13u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHHHHHHHH\u{200b}HHHHHHHHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node9 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node10 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node11 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node12 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node13 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![
+ min_content(),
+ max_content(),
+ fit_content(points(20f32)),
+ auto(),
+ points(10f32),
+ percent(0.2f32),
+ minmax(points(2f32), auto()),
+ minmax(points(2f32), points(4f32)),
+ minmax(points(2f32), min_content()),
+ minmax(points(2f32), max_content()),
+ minmax(min_content(), max_content()),
+ minmax(min_content(), auto()),
+ minmax(max_content(), auto()),
+ ],
+ ..Default::default()
+ },
+ &[node0, node1, node2, node3, node4, node5, node6, node7, node8, node9, node10, node11, node12, node13],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 322f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 322f32, size.width);
+ assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 322f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 322f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 16f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 16f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 95f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 95f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 16f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 16f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+ assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 111f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node4).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+ assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 111f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node5).unwrap();
+ assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 10f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+ assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 111f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node6).unwrap();
+ assert_eq!(size.width, 64f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 64f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+ assert_eq!(location.x, 121f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 121f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node7).unwrap();
+ assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node7.data(), 2f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+ assert_eq!(location.x, 185f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 185f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+ assert_eq!(size.width, 4f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 4f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.height);
+ assert_eq!(location.x, 187f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 187f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node9).unwrap();
+ assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node9.data(), 2f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node9.data(), 40f32, size.height);
+ assert_eq!(location.x, 191f32, "x of node {:?}. Expected {}. Actual {}", node9.data(), 191f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node9.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+ assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 2f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 40f32, size.height);
+ assert_eq!(location.x, 193f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 193f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node11).unwrap();
+ assert_eq!(size.width, 16f32, "width of node {:?}. Expected {}. Actual {}", node11.data(), 16f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node11.data(), 40f32, size.height);
+ assert_eq!(location.x, 195f32, "x of node {:?}. Expected {}. Actual {}", node11.data(), 195f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node11.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node12).unwrap();
+ assert_eq!(size.width, 15f32, "width of node {:?}. Expected {}. Actual {}", node12.data(), 15f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node12.data(), 40f32, size.height);
+ assert_eq!(location.x, 211f32, "x of node {:?}. Expected {}. Actual {}", node12.data(), 211f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node12.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node13).unwrap();
+ assert_eq!(size.width, 96f32, "width of node {:?}. Expected {}. Actual {}", node13.data(), 96f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node13.data(), 40f32, size.height);
+ assert_eq!(location.x, 226f32, "x of node {:?}. Expected {}. Actual {}", node13.data(), 226f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node13.data(), 40f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs
new file mode 100644
index 000000000..963d4e55d
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs
@@ -0,0 +1,51 @@
+#[test]
+fn grid_span_2_max_content_auto_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![max_content(), auto()],
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs
new file mode 100644
index 000000000..27dc3e801
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_max_content_fit_content_10px_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![max_content(), fit_content(points(10f32))],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 80f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs
new file mode 100644
index 000000000..8daf9a8a8
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_max_content_fit_content_80px_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![max_content(), fit_content(points(80f32))],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 80f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs
new file mode 100644
index 000000000..92b1a421a
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs
@@ -0,0 +1,66 @@
+#[test]
+fn grid_span_2_min_content_auto_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![min_content(), auto()],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, size.width);
+ assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 10f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs
new file mode 100644
index 000000000..8ebbf29fc
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_10px_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![min_content(), fit_content(points(10f32))],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 10f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs
new file mode 100644
index 000000000..418447df7
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_30px_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![min_content(), fit_content(points(30f32))],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 70f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 70f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 30f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 70f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 70f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs
new file mode 100644
index 000000000..4f5d0c7c8
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_80px_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHH\u{200b}HHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32)],
+ grid_template_columns: vec![min_content(), fit_content(points(80f32))],
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs b/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs
new file mode 100644
index 000000000..3ef4b3a54
--- /dev/null
+++ b/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs
@@ -0,0 +1,97 @@
+#[test]
+fn grid_span_6_all_non_flex_indefinite_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(6u16) },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHH\u{200b}HHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![
+ min_content(),
+ max_content(),
+ fit_content(points(20f32)),
+ auto(),
+ points(10f32),
+ percent(0.2f32),
+ ],
+ ..Default::default()
+ },
+ &[node0, node1, node2, node3, node4, node5, node6],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 160f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 160f32, size.width);
+ assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 80f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 160f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 160f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 19f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 19f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 99f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 99f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 19f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 19f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+ assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 118f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node4).unwrap();
+ assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 0f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+ assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 118f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node5).unwrap();
+ assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 10f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+ assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 118f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node6).unwrap();
+ assert_eq!(size.width, 32f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 32f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+ assert_eq!(location.x, 128f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 128f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, location.y);
+}
diff --git a/tests/generated/measure_child_with_flex_shrink_hidden.rs b/tests/generated/measure_child_with_flex_shrink_hidden.rs
new file mode 100644
index 000000000..7a5d9c049
--- /dev/null
+++ b/tests/generated/measure_child_with_flex_shrink_hidden.rs
@@ -0,0 +1,68 @@
+#[test]
+fn measure_child_with_flex_shrink_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(100f32),
+ height: taffy::style::Dimension::Auto,
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 9f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 9f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 91f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 91f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.height);
+ assert_eq!(location.x, 9f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 9f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+}
diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs
index 4be363806..748958cd5 100644
--- a/tests/generated/mod.rs
+++ b/tests/generated/mod.rs
@@ -222,6 +222,7 @@ mod display_none_with_child;
mod display_none_with_margin;
mod display_none_with_position;
mod display_none_with_position_absolute;
+mod do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent;
mod flex_basis_and_main_dimen_set_when_flexing;
mod flex_basis_flex_grow_column;
mod flex_basis_flex_grow_row;
@@ -482,14 +483,20 @@ mod grid_fit_content_percent_indefinite_argument;
#[cfg(feature = "grid")]
mod grid_fit_content_percent_indefinite_max_content;
#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_max_content_hidden;
+#[cfg(feature = "grid")]
mod grid_fit_content_percent_indefinite_min_content;
#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_min_content_hidden;
+#[cfg(feature = "grid")]
mod grid_fit_content_points_argument;
#[cfg(feature = "grid")]
mod grid_fit_content_points_max_content;
#[cfg(feature = "grid")]
mod grid_fit_content_points_min_content;
#[cfg(feature = "grid")]
+mod grid_fit_content_points_min_content_hidden;
+#[cfg(feature = "grid")]
mod grid_fr_fixed_size_no_content_proportions;
#[cfg(feature = "grid")]
mod grid_fr_fixed_size_no_content_proportions_sub_1_sum;
@@ -650,6 +657,10 @@ mod grid_minmax_min_content_percent_indefinite;
#[cfg(feature = "grid")]
mod grid_out_of_order_items;
#[cfg(feature = "grid")]
+mod grid_overflow_inline_axis_hidden;
+#[cfg(feature = "grid")]
+mod grid_overflow_inline_axis_visible;
+#[cfg(feature = "grid")]
mod grid_overflow_rows;
#[cfg(feature = "grid")]
mod grid_padding_border_overrides_container_max_size;
@@ -702,28 +713,46 @@ mod grid_size_child_fixed_tracks;
#[cfg(feature = "grid")]
mod grid_span_13_most_non_flex_with_minmax_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_13_most_non_flex_with_minmax_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_max_content_auto_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_max_content_auto_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_max_content_fit_content_10px_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_max_content_fit_content_10px_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_max_content_fit_content_80px_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_max_content_fit_content_80px_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_max_content_max_content_indefinite;
#[cfg(feature = "grid")]
mod grid_span_2_min_content_auto_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_min_content_auto_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_min_content_fit_content_10px_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_10px_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_min_content_fit_content_30px_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_30px_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_min_content_fit_content_80px_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_80px_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_2_min_content_max_content_indefinite;
#[cfg(feature = "grid")]
mod grid_span_2_min_content_min_content_indefinite;
#[cfg(feature = "grid")]
mod grid_span_6_all_non_flex_indefinite;
#[cfg(feature = "grid")]
+mod grid_span_6_all_non_flex_indefinite_hidden;
+#[cfg(feature = "grid")]
mod grid_span_8_all_track_types_indefinite;
#[cfg(feature = "grid")]
mod gridflex_column_integration;
@@ -812,6 +841,7 @@ mod measure_child_constraint;
mod measure_child_constraint_padding_parent;
mod measure_child_with_flex_grow;
mod measure_child_with_flex_shrink;
+mod measure_child_with_flex_shrink_hidden;
mod measure_child_with_min_size_greater_than_available_space;
mod measure_flex_basis_overrides_measure;
mod measure_height_overrides_measure;
@@ -839,6 +869,8 @@ mod nested_overflowing_child_in_constraint_parent;
mod only_shrinkable_item_with_flex_basis_zero;
mod overflow_cross_axis;
mod overflow_main_axis;
+mod overflow_main_axis_shrink_hidden;
+mod overflow_main_axis_shrink_visible;
mod padding_align_end_child;
mod padding_border_overrides_max_size;
mod padding_border_overrides_min_size;
diff --git a/tests/generated/overflow_main_axis_shrink_hidden.rs b/tests/generated/overflow_main_axis_shrink_hidden.rs
new file mode 100644
index 000000000..bed451012
--- /dev/null
+++ b/tests/generated/overflow_main_axis_shrink_hidden.rs
@@ -0,0 +1,55 @@
+#[test]
+fn overflow_main_axis_shrink_hidden() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style {
+ overflow: taffy::geometry::Point {
+ x: taffy::style::Overflow::Hidden,
+ y: taffy::style::Overflow::Hidden,
+ },
+ flex_shrink: 1f32,
+ ..Default::default()
+ },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/overflow_main_axis_shrink_visible.rs b/tests/generated/overflow_main_axis_shrink_visible.rs
new file mode 100644
index 000000000..171502e3d
--- /dev/null
+++ b/tests/generated/overflow_main_axis_shrink_visible.rs
@@ -0,0 +1,48 @@
+#[test]
+fn overflow_main_axis_shrink_visible() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf_with_measure(
+ taffy::style::Style { flex_shrink: 1f32, ..Default::default() },
+ taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+ const TEXT: &str = "HHHHHHHHHH";
+ super::measure_standard_text(
+ known_dimensions,
+ available_space,
+ TEXT,
+ super::WritingMode::Horizontal,
+ None,
+ )
+ }),
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(50f32),
+ height: taffy::style::Dimension::Points(50f32),
+ },
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/percentage_moderate_complexity.rs b/tests/generated/percentage_moderate_complexity.rs
index 7201b3956..0e93704d5 100644
--- a/tests/generated/percentage_moderate_complexity.rs
+++ b/tests/generated/percentage_moderate_complexity.rs
@@ -91,10 +91,10 @@ fn percentage_moderate_complexity() {
assert!(location.y - 8f32 < 0.1, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y);
let Layout { size, location, .. } = taffy.layout(node00).unwrap();
assert!(
- size.width - 38.40625f32 < 0.1,
+ size.width - 38.414063f32 < 0.1,
"width of node {:?}. Expected {}. Actual {}",
node00.data(),
- 38.40625f32,
+ 38.414063f32,
size.width
);
assert!(size.height - 6f32 < 0.1, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height);