Implement legacy text alignment (#698)
* Add TextAlign style
* Add legacy text-align support to the test generator
* Implement legacy text alignment
* Fix docs
42f75c6023434c27c9d6e69e2f3f3b5818ddd8e3 · por Nico Burns · (hace 2 años) · padre 5e4dcf1e1 · ver el árbol en este commit
Delta semántico · 23
scripts/gentest/src/main.rs
scripts/gentest/test_helper.js
tests/generated/block/block_item_text_align_center.rs
tests/generated/block/block_item_text_align_left.rs
tests/generated/block/block_item_text_align_right.rs
tests/generated/block/mod.rs
diff --git a/scripts/gentest/src/main.rs b/scripts/gentest/src/main.rs
index 9b519e5be..6a5d0ff16 100644
--- a/scripts/gentest/src/main.rs
+++ b/scripts/gentest/src/main.rs
@@ -444,6 +444,16 @@ fn generate_node(ident: &str, node: &Value) -> TokenStream {
(quote!(), quote!())
};
+ let text_align = match style["textAlign"] {
+ Value::String(ref value) => match value.as_ref() {
+ "-webkit-left" => quote!(text_align: taffy::style::TextAlign::LegacyLeft,),
+ "-webkit-right" => quote!(text_align: taffy::style::TextAlign::LegacyRight,),
+ "-webkit-center" => quote!(text_align: taffy::style::TextAlign::LegacyCenter,),
+ _ => quote!(),
+ },
+ _ => quote!(),
+ };
+
let align_items = match style["alignItems"] {
Value::String(ref value) => match value.as_ref() {
"start" => quote!(align_items: Some(taffy::style::AlignItems::Start),),
@@ -618,6 +628,7 @@ fn generate_node(ident: &str, node: &Value) -> TokenStream {
#box_sizing
#direction
#position
+ #text_align
#flex_direction
#flex_wrap
#overflow
diff --git a/scripts/gentest/test_helper.js b/scripts/gentest/test_helper.js
index f776dc65b..09a53e897 100644
--- a/scripts/gentest/test_helper.js
+++ b/scripts/gentest/test_helper.js
@@ -209,10 +209,12 @@ function describeElement(e) {
position: parseEnum(e.style.position),
direction: parseEnum(e.style.direction),
- flexDirection: parseEnum(e.style.flexDirection),
writingMode: parseEnum(e.style.writingMode),
+ textAlign: parseEnum(e.style.textAlign),
+
+ flexDirection: parseEnum(e.style.flexDirection),
flexWrap: parseEnum(e.style.flexWrap),
overflowX: parseEnum(e.style.overflowX),
overflowY: parseEnum(e.style.overflowY),
diff --git a/src/compute/block.rs b/src/compute/block.rs
index 512e885fa..02f5d14a7 100644
--- a/src/compute/block.rs
+++ b/src/compute/block.rs
@@ -9,7 +9,7 @@ use crate::util::sys::f32_max;
use crate::util::sys::Vec;
use crate::util::MaybeMath;
use crate::util::{MaybeResolve, ResolveOrZero};
-use crate::{BoxGenerationMode, BoxSizing, LayoutBlockContainer};
+use crate::{BlockContainerStyle, BoxGenerationMode, BoxSizing, LayoutBlockContainer, TextAlign};
#[cfg(feature = "content_size")]
use super::common::content_size::compute_content_size_contribution;
@@ -190,6 +190,8 @@ fn compute_inner(tree: &mut impl LayoutBlockContainer, node_id: NodeId, inputs:
|| matches!(size.height, Some(h) if h > 0.0)
|| matches!(min_size.height, Some(h) if h > 0.0);
+ let text_align = style.text_align();
+
drop(style);
// 1. Generate items
@@ -219,6 +221,7 @@ fn compute_inner(tree: &mut impl LayoutBlockContainer, node_id: NodeId, inputs:
container_outer_width,
content_box_inset,
resolved_content_box_inset,
+ text_align,
own_margins_collapse_with_children,
);
let container_outer_height = known_dimensions
@@ -383,6 +386,7 @@ fn perform_final_layout_on_in_flow_children(
container_outer_width: f32,
content_box_inset: Rect<f32>,
resolved_content_box_inset: Rect<f32>,
+ text_align: TextAlign,
own_margins_collapse_with_children: Line<bool>,
) -> (Size<f32>, f32, CollapsibleMarginSet, CollapsibleMarginSet) {
// Resolve container_inner_width for sizing child nodes using initial content_box_inset
@@ -469,11 +473,26 @@ fn perform_final_layout_on_in_flow_children(
x: resolved_content_box_inset.left,
y: committed_y_offset + active_collapsible_margin_set.resolve(),
};
- let location = Point {
+ let mut location = Point {
x: resolved_content_box_inset.left + inset_offset.x + resolved_margin.left,
y: committed_y_offset + inset_offset.y + y_margin_offset,
};
+ // Apply alignment
+ let item_outer_width = item_layout.size.width + resolved_margin.horizontal_axis_sum();
+ if item_outer_width < container_inner_width {
+ match text_align {
+ TextAlign::Auto => {
+ // Do nothing
+ }
+ TextAlign::LegacyLeft => {
+ // Do nothing. Left aligned by default.
+ }
+ TextAlign::LegacyRight => location.x += container_inner_width - item_outer_width,
+ TextAlign::LegacyCenter => location.x += (container_inner_width - item_outer_width) / 2.0,
+ }
+ }
+
let scrollbar_size = Size {
width: if item.overflow.y == Overflow::Scroll { item.scrollbar_width } else { 0.0 },
height: if item.overflow.x == Overflow::Scroll { item.scrollbar_width } else { 0.0 },
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 8a44ed36d..91e89775f 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -153,7 +153,7 @@ struct AlgoConstants {
inner_container_size: Size<f32>,
}
-/// Computes the layout of [`LayoutPartialTree`] according to the flexbox algorithm
+/// Computes the layout of a box according to the flexbox algorithm
pub fn compute_flexbox_layout(
tree: &mut impl LayoutFlexboxContainer,
node: NodeId,
diff --git a/src/style/block.rs b/src/style/block.rs
new file mode 100644
index 000000000..04b758336
--- /dev/null
+++ b/src/style/block.rs
@@ -0,0 +1,26 @@
+//! Style types for Block layout
+use crate::{CoreStyle, Style};
+
+/// The set of styles required for a CSS Grid item (child of a CSS Grid container)
+pub trait BlockContainerStyle: CoreStyle {
+ /// Defines which row in the grid the item should start and end at
+ #[inline(always)]
+ fn text_align(&self) -> TextAlign {
+ Style::DEFAULT.text_align
+ }
+}
+
+/// Used by block layout to implement the legacy behaviour of `<center>` and `<div align="left | right | center">`
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+pub enum TextAlign {
+ /// No special legacy text align behaviour.
+ #[default]
+ Auto,
+ /// Corresponds to `-webkit-left` or `-moz-left` in browsers
+ LegacyLeft,
+ /// Corresponds to `-webkit-right` or `-moz-right` in browsers
+ LegacyRight,
+ /// Corresponds to `-webkit-center` or `-moz-center` in browsers
+ LegacyCenter,
+}
diff --git a/src/style/mod.rs b/src/style/mod.rs
index d32924879..67d8e047a 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -2,17 +2,20 @@
mod alignment;
mod dimension;
+#[cfg(feature = "block_layout")]
+mod block;
#[cfg(feature = "flexbox")]
mod flex;
+#[cfg(feature = "grid")]
+mod grid;
pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf};
pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
+#[cfg(feature = "block_layout")]
+pub use self::block::{BlockContainerStyle, TextAlign};
#[cfg(feature = "flexbox")]
pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
-
-#[cfg(feature = "grid")]
-mod grid;
#[cfg(feature = "grid")]
pub(crate) use self::grid::{GenericGridPlacement, OriginZeroGridPlacement};
#[cfg(feature = "grid")]
@@ -20,6 +23,7 @@ pub use self::grid::{
GridAutoFlow, GridContainerStyle, GridItemStyle, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction,
MinTrackSizingFunction, NonRepeatedTrackSizingFunction, TrackSizingFunction,
};
+
use crate::geometry::{Point, Rect, Size};
#[cfg(feature = "grid")]
@@ -394,13 +398,20 @@ pub struct Style {
#[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
pub gap: Size<LengthPercentage>,
- // Flexbox properties
+ // Block container properties
+ /// How items elements should aligned in the inline axis
+ #[cfg(feature = "block_layout")]
+ pub text_align: TextAlign,
+
+ // Flexbox container properties
/// Which direction does the main axis flow in?
#[cfg(feature = "flexbox")]
pub flex_direction: FlexDirection,
/// Should elements wrap, or stay in a single line?
#[cfg(feature = "flexbox")]
pub flex_wrap: FlexWrap,
+
+ // Flexbox item properties
/// Sets the initial main axis size of the item
#[cfg(feature = "flexbox")]
pub flex_basis: Dimension,
@@ -472,6 +483,9 @@ impl Style {
align_content: None,
#[cfg(any(feature = "flexbox", feature = "grid"))]
justify_content: None,
+ // Block
+ #[cfg(feature = "block_layout")]
+ text_align: TextAlign::Auto,
// Flexbox
#[cfg(feature = "flexbox")]
flex_direction: FlexDirection::Row,
@@ -629,6 +643,22 @@ impl<T: CoreStyle> CoreStyle for &'_ T {
}
}
+#[cfg(feature = "block_layout")]
+impl BlockContainerStyle for &Style {
+ #[inline(always)]
+ fn text_align(&self) -> TextAlign {
+ self.text_align
+ }
+}
+
+#[cfg(feature = "block_layout")]
+impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
+ #[inline(always)]
+ fn text_align(&self) -> TextAlign {
+ (*self).text_align()
+ }
+}
+
#[cfg(feature = "flexbox")]
impl FlexboxContainerStyle for &Style {
#[inline(always)]
@@ -890,6 +920,8 @@ mod tests {
padding: Rect::zero(),
border: Rect::zero(),
gap: Size::zero(),
+ #[cfg(feature = "block_layout")]
+ text_align: Default::default(),
#[cfg(feature = "flexbox")]
flex_grow: 0.0,
#[cfg(feature = "flexbox")]
diff --git a/src/tree/traits.rs b/src/tree/traits.rs
index a549232ea..e9382ae95 100644
--- a/src/tree/traits.rs
+++ b/src/tree/traits.rs
@@ -133,6 +133,8 @@ use crate::style::{AvailableSpace, CoreStyle};
use crate::style::{FlexboxContainerStyle, FlexboxItemStyle};
#[cfg(feature = "grid")]
use crate::style::{GridContainerStyle, GridItemStyle};
+#[cfg(feature = "block_layout")]
+use crate::BlockContainerStyle;
use core::ops::{Deref, DerefMut};
/// This trait is Taffy's abstraction for downward tree traversal.
@@ -251,7 +253,7 @@ pub trait LayoutGridContainer: LayoutPartialTree {
/// Extends [`LayoutPartialTree`] with getters for the styles required for CSS Block layout
pub trait LayoutBlockContainer: LayoutPartialTree {
/// The style type representing the CSS Block container's styles
- type BlockContainerStyle<'a>: CoreStyle
+ type BlockContainerStyle<'a>: BlockContainerStyle
where
Self: 'a;
/// The style type representing each CSS Block item's styles
diff --git a/test_fixtures/block/block_item_text_align_center.html b/test_fixtures/block/block_item_text_align_center.html
new file mode 100644
index 000000000..4fb5dcdb3
--- /dev/null
+++ b/test_fixtures/block/block_item_text_align_center.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="display: block; width: 200px; height: 200px; text-align: -webkit-center;">
+ <div style="max-width: 100px; height: 50px;"></div>
+ <div style="max-width: 300px; height: 50px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/block/block_item_text_align_left.html b/test_fixtures/block/block_item_text_align_left.html
new file mode 100644
index 000000000..c91efe9ae
--- /dev/null
+++ b/test_fixtures/block/block_item_text_align_left.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="display: block; width: 200px; height: 200px; text-align: -webkit-left;">
+ <div style="max-width: 100px; height: 50px;"></div>
+ <div style="max-width: 300px; height: 50px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/block/block_item_text_align_right.html b/test_fixtures/block/block_item_text_align_right.html
new file mode 100644
index 000000000..80a27eec4
--- /dev/null
+++ b/test_fixtures/block/block_item_text_align_right.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="display: block; width: 200px; height: 200px; text-align: -webkit-right;">
+ <div style="max-width: 100px; height: 50px;"></div>
+ <div style="max-width: 300px; height: 50px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/generated/block/block_item_text_align_center.rs b/tests/generated/block/block_item_text_align_center.rs
new file mode 100644
index 000000000..b64c3c2c8
--- /dev/null
+++ b/tests/generated/block/block_item_text_align_center.rs
@@ -0,0 +1,226 @@
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_center__border_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ text_align: taffy::style::TextAlign::LegacyCenter,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node0, 50f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_center__content_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ text_align: taffy::style::TextAlign::LegacyCenter,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node0, 50f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
diff --git a/tests/generated/block/block_item_text_align_left.rs b/tests/generated/block/block_item_text_align_left.rs
new file mode 100644
index 000000000..82513df84
--- /dev/null
+++ b/tests/generated/block/block_item_text_align_left.rs
@@ -0,0 +1,226 @@
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_left__border_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ text_align: taffy::style::TextAlign::LegacyLeft,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_left__content_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ text_align: taffy::style::TextAlign::LegacyLeft,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
diff --git a/tests/generated/block/block_item_text_align_right.rs b/tests/generated/block/block_item_text_align_right.rs
new file mode 100644
index 000000000..0c4f6d8d4
--- /dev/null
+++ b/tests/generated/block/block_item_text_align_right.rs
@@ -0,0 +1,226 @@
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_right__border_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ text_align: taffy::style::TextAlign::LegacyRight,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node0, 100f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn block_item_text_align_right__content_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(100f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Length(50f32) },
+ max_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(300f32), height: auto() },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Block,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ text_align: taffy::style::TextAlign::LegacyRight,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(200f32),
+ height: taffy::style::Dimension::Length(200f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node, 200f32, size.width);
+ assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node, 200f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0, 100f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0, 50f32, size.height);
+ assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node0, 100f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node0,
+ 0f32,
+ layout.scroll_height()
+ );
+ #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
+ let layout @ Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1, 200f32, size.width);
+ assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1, 50f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1, 0f32, location.x);
+ assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node1, 50f32, location.y);
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_width(),
+ 0f32,
+ "scroll_width of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_width()
+ );
+ #[cfg(feature = "content_size")]
+ assert_eq!(
+ layout.scroll_height(),
+ 0f32,
+ "scroll_height of node {:?}. Expected {}. Actual {}",
+ node1,
+ 0f32,
+ layout.scroll_height()
+ );
+}
diff --git a/tests/generated/block/mod.rs b/tests/generated/block/mod.rs
index dacd4f83d..621d0358a 100644
--- a/tests/generated/block/mod.rs
+++ b/tests/generated/block/mod.rs
@@ -81,6 +81,9 @@ mod block_inset_percentage;
mod block_intrinsic_width;
mod block_item_max_width;
mod block_item_min_width_overrides_max_width;
+mod block_item_text_align_center;
+mod block_item_text_align_left;
+mod block_item_text_align_right;
mod block_margin_auto_bottom;
mod block_margin_auto_bottom_and_top;
mod block_margin_auto_left;