tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 1061HTML 997Markdown 12TOML 83120 Definiciones

Release/0.2.2 (#281)

* Fix clippy lints

* Vertical border and padding percentage values are multiplied by available_space.width (#273)

* fixed vertical padding + border calculation

* changes:
    added fix to release notes,
    added new tests in "border_and_padding.rs"

* fixed percentage border and padding heights being scaled by available_space.width

* fmt, add fix to release notes

* added test

(cherry picked from commit 996e70d13e6b0bbf59b07a3bea80ddce7de9cfdd)

* Revert "Resolve vertical percentage padding/border against node height"

All percentage padding/border values resolve against the node's inline size
(width in horizontal writing modes) as per the CSS spec.

See: https://developer.mozilla.org/en-US/docs/Web/CSS/padding#values

* Bump version to 0.2.2

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>

df9799325a1a368cc36b5dd85d6ad830fd1c0b85 · por Nico Burns · (hace 3 años) · padre 5ce388d24 · ver el árbol en este commit

Delta semántico · 11

benches/big_tree.rs

examples/flexbox-gap.rs

  • cambió por dentro fn main

scripts/gentest/src/main.rs

src/compute/leaf.rs

src/error.rs

  • cambió por dentro fn fmt

8 archivos · +133 −25

diff --git a/Cargo.toml b/Cargo.toml
index 1ab507664..03794535f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "taffy"
-version = "0.2.1"
+version = "0.2.2"
 authors = [
     "Alice Cecile <alice.i.cecile@gmail.com>",
     "Johnathan Kelley <jkelleyrtp@gmail.com>",
diff --git a/RELEASES.md b/RELEASES.md
index 9f5b9b5a8..d61a64f47 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,11 @@
 # Release Notes
 
+## 0.2.2
+
+### Fixes
+
+- Border or padding on the horizontal axis could, in some cases, increase the height of nodes.
+
 ## 0.2.1
 
 ### Fixes
diff --git a/benches/big_tree.rs b/benches/big_tree.rs
index 12154205a..5118593d4 100644
--- a/benches/big_tree.rs
+++ b/benches/big_tree.rs
@@ -73,14 +73,13 @@ fn build_yoga_deep_hierarchy(taffy: &mut Taffy, node_count: u32, branching_facto
         flex_grow: 1.0,
         ..Default::default()
     };
-    let mut build_leaf_node = |taffy: &mut Taffy| taffy.new_leaf(style.clone()).unwrap();
+    let mut build_leaf_node = |taffy: &mut Taffy| taffy.new_leaf(style).unwrap();
     let mut build_flex_node =
-        |taffy: &mut Taffy, children: Vec<Node>| taffy.new_with_children(style.clone(), &children).unwrap();
+        |taffy: &mut Taffy, children: Vec<Node>| taffy.new_with_children(style, &children).unwrap();
 
     let tree = build_deep_tree(taffy, node_count, branching_factor, &mut build_leaf_node, &mut build_flex_node);
-    let root = taffy.new_with_children(Style::DEFAULT, &tree).unwrap();
 
-    root
+    taffy.new_with_children(Style::DEFAULT, &tree).unwrap()
 }
 
 fn taffy_benchmarks(c: &mut Criterion) {
diff --git a/examples/flexbox-gap.rs b/examples/flexbox-gap.rs
index 6992df90d..d791b73a3 100644
--- a/examples/flexbox-gap.rs
+++ b/examples/flexbox-gap.rs
@@ -8,9 +8,9 @@ fn main() -> Result<(), taffy::error::TaffyError> {
 
     let child_style =
         Style { size: Size { width: Dimension::Points(20.0), height: Dimension::Points(20.0) }, ..Default::default() };
-    let child0 = taffy.new_leaf(child_style.clone())?;
-    let child1 = taffy.new_leaf(child_style.clone())?;
-    let child2 = taffy.new_leaf(child_style.clone())?;
+    let child0 = taffy.new_leaf(child_style)?;
+    let child1 = taffy.new_leaf(child_style)?;
+    let child2 = taffy.new_leaf(child_style)?;
 
     let root = taffy.new_with_children(
         Style { gap: Size { width: Dimension::Points(10.0), height: Dimension::Undefined }, ..Default::default() },
diff --git a/scripts/gentest/src/main.rs b/scripts/gentest/src/main.rs
index cb793a11b..bfdca4a2d 100644
--- a/scripts/gentest/src/main.rs
+++ b/scripts/gentest/src/main.rs
@@ -192,7 +192,7 @@ fn generate_assertions(ident: &str, node: &json::JsonValue) -> TokenStream {
         let mut c = Vec::new();
         if let json::JsonValue::Array(ref value) = node["children"] {
             for (idx, child) in value.iter().enumerate() {
-                c.push(generate_assertions(&format!("{}{}", ident, idx), child));
+                c.push(generate_assertions(&format!("{ident}{idx}"), child));
             }
         };
         c.into_iter().fold(quote!(), |a, b| quote!(#a #b))
@@ -430,15 +430,12 @@ fn generate_node(ident: &str, node: &json::JsonValue) -> TokenStream {
     let (children_body, children) = match node["children"] {
         json::JsonValue::Array(ref value) => {
             if !value.is_empty() {
-                let body = value
-                    .iter()
-                    .enumerate()
-                    .map(|(i, child)| generate_node(&format!("{}{}", ident, i), child))
-                    .collect();
+                let body =
+                    value.iter().enumerate().map(|(i, child)| generate_node(&format!("{ident}{i}"), child)).collect();
                 let idents = value
                     .iter()
                     .enumerate()
-                    .map(|(i, _)| Ident::new(&format!("{}{}", ident, i), Span::call_site()))
+                    .map(|(i, _)| Ident::new(&format!("{ident}{i}"), Span::call_site()))
                     .collect::<Vec<_>>();
                 (body, quote!(&[#(#idents),*]))
             } else {
diff --git a/src/compute/leaf.rs b/src/compute/leaf.rs
index 6dd1865dd..275b62383 100644
--- a/src/compute/leaf.rs
+++ b/src/compute/leaf.rs
@@ -66,6 +66,8 @@ pub(crate) fn compute(
         return node_size.unwrap_or(measured_size).maybe_clamp(node_min_size, node_max_size);
     }
 
+    // Note: both horizontal and vertical percentage padding/borders are resolved against the container's inline size (i.e. width).
+    // This is not a bug, but is how CSS is specified (see: https://developer.mozilla.org/en-US/docs/Web/CSS/padding#values)
     let padding = style.padding.resolve_or_default(available_space.width.into_option());
     let border = style.border.resolve_or_default(available_space.width.into_option());
 
@@ -77,8 +79,8 @@ pub(crate) fn compute(
             .maybe_clamp(node_min_size.width, node_max_size.width),
         height: node_size
             .height
-            // .unwrap_or(0.0) + padding.horizontal_axis_sum() + border.horizontal_axis_sum(), // content-box
-            .unwrap_or(0.0 + padding.horizontal_axis_sum() + border.horizontal_axis_sum()) // border-box
+            // .unwrap_or(0.0) + padding.vertical_axis_sum() + border.vertical_axis_sum(), // content-box
+            .unwrap_or(0.0 + padding.vertical_axis_sum() + border.vertical_axis_sum()) // border-box
             .maybe_clamp(node_min_size.height, node_max_size.height),
     }
 }
diff --git a/src/error.rs b/src/error.rs
index 88cef3bea..57764743b 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -31,16 +31,14 @@ pub enum TaffyError {
 impl Display for TaffyError {
     fn fmt(&self, f: &mut Formatter) -> Result {
         match self {
-            TaffyError::ChildIndexOutOfBounds { parent, child_index, child_count } => write!(
-                f,
-                "Index (is {}) should be < child_count ({}) for parent node {:?}",
-                child_index, child_count, parent
-            ),
+            TaffyError::ChildIndexOutOfBounds { parent, child_index, child_count } => {
+                write!(f, "Index (is {child_index}) should be < child_count ({child_count}) for parent node {parent:?}")
+            }
             TaffyError::InvalidParentNode(parent) => {
-                write!(f, "Parent Node {:?} is not in the Taffy instance", parent)
+                write!(f, "Parent Node {parent:?} is not in the Taffy instance")
             }
-            TaffyError::InvalidChildNode(child) => write!(f, "Child Node {:?} is not in the Taffy instance", child),
-            TaffyError::InvalidInputNode(node) => write!(f, "Supplied Node {:?} is not in the Taffy instance", node),
+            TaffyError::InvalidChildNode(child) => write!(f, "Child Node {child:?} is not in the Taffy instance"),
+            TaffyError::InvalidInputNode(node) => write!(f, "Supplied Node {node:?} is not in the Taffy instance"),
         }
     }
 }
diff --git a/tests/border_and_padding.rs b/tests/border_and_padding.rs
new file mode 100644
index 000000000..2c727921e
--- /dev/null
+++ b/tests/border_and_padding.rs
@@ -0,0 +1,106 @@
+use taffy::prelude::*;
+
+fn arr_to_rect<T: Copy>(items: [T; 4]) -> Rect<T> {
+    Rect { left: items[0], right: items[1], top: items[2], bottom: items[3] }
+}
+
+#[test]
+fn border_on_a_single_axis_doesnt_increase_size() {
+    for i in 0..4 {
+        let mut taffy = Taffy::new();
+        let node = taffy
+            .new_leaf(Style {
+                border: {
+                    let mut lengths = [Dimension::Points(0.); 4];
+                    lengths[i] = Dimension::Points(10.);
+                    arr_to_rect(lengths)
+                },
+                ..Default::default()
+            })
+            .unwrap();
+
+        taffy
+            .compute_layout(
+                node,
+                Size { height: AvailableSpace::Definite(100.0), width: AvailableSpace::Definite(100.0) },
+            )
+            .ok();
+
+        let layout = taffy.layout(node).unwrap();
+        assert_eq!(layout.size.width * layout.size.height, 0.);
+    }
+}
+
+#[test]
+fn padding_on_a_single_axis_doesnt_increase_size() {
+    for i in 0..4 {
+        let mut taffy = Taffy::new();
+        let node = taffy
+            .new_leaf(Style {
+                border: {
+                    let mut lengths = [Dimension::Points(0.); 4];
+                    lengths[i] = Dimension::Points(10.);
+                    arr_to_rect(lengths)
+                },
+                ..Default::default()
+            })
+            .unwrap();
+
+        taffy
+            .compute_layout(
+                node,
+                Size { height: AvailableSpace::Definite(100.0), width: AvailableSpace::Definite(100.0) },
+            )
+            .ok();
+
+        let layout = taffy.layout(node).unwrap();
+        assert_eq!(layout.size.width * layout.size.height, 0.);
+    }
+}
+
+#[test]
+fn border_and_padding_on_a_single_axis_doesnt_increase_size() {
+    for i in 0..4 {
+        let mut taffy = Taffy::new();
+        let rect = {
+            let mut lengths = [Dimension::Points(0.); 4];
+            lengths[i] = Dimension::Points(10.);
+            arr_to_rect(lengths)
+        };
+        let node = taffy.new_leaf(Style { border: rect, padding: rect, ..Default::default() }).unwrap();
+
+        taffy
+            .compute_layout(
+                node,
+                Size { height: AvailableSpace::Definite(100.0), width: AvailableSpace::Definite(100.0) },
+            )
+            .ok();
+        let layout = taffy.layout(node).unwrap();
+        assert_eq!(layout.size.width * layout.size.height, 0.);
+    }
+}
+
+#[test]
+fn vertical_border_and_padding_percentage_values_use_available_space_correctly() {
+    let mut taffy = Taffy::new();
+
+    let node = taffy
+        .new_leaf(Style {
+            padding: Rect {
+                left: Dimension::Percent(1.0),
+                top: Dimension::Percent(1.0),
+                right: Dimension::Points(0.),
+                bottom: Dimension::Points(0.),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+
+    taffy
+        .compute_layout(node, Size { width: AvailableSpace::Definite(200.0), height: AvailableSpace::Definite(100.0) })
+        .ok();
+
+    let layout = taffy.layout(node).unwrap();
+    assert_eq!(layout.size.width, 200.0);
+    assert_eq!(layout.size.height, 200.0);
+}