gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 89Markdown 11TOML 91930 Definiciones

Add is_table for block items (#701)

950a0eb1322f15e5d1083f4793b55d52061718de · por Nico Burns · (hace 2 años) · padre 416558f35 · ver el árbol en este commit

Delta semántico · 11

src/compute/block.rs

src/style/block.rs

src/style/mod.rs

src/tree/traits.rs

4 archivos · +54 −17

diff --git a/src/compute/block.rs b/src/compute/block.rs
index 02f5d14a7..eeb2aa009 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::{BlockContainerStyle, BoxGenerationMode, BoxSizing, LayoutBlockContainer, TextAlign};
+use crate::{BlockContainerStyle, BlockItemStyle, BoxGenerationMode, BoxSizing, LayoutBlockContainer, TextAlign};
 
 #[cfg(feature = "content_size")]
 use super::common::content_size::compute_content_size_contribution;
@@ -23,6 +23,9 @@ struct BlockItem {
     /// and controls the order in which the nodes are placed
     order: u32,
 
+    /// Items that are tables don't have stretch sizing applied to them
+    is_table: bool,
+
     /// The base size of this item
     size: Size<Option<f32>>,
     /// The minimum allowable size of this item
@@ -310,6 +313,7 @@ fn generate_item_list(
             BlockItem {
                 node_id: child_node_id,
                 order: order as u32,
+                is_table: child_style.is_table(),
                 size: child_style
                     .size()
                     .maybe_resolve(node_inner_size)
@@ -408,18 +412,21 @@ fn perform_final_layout_on_in_flow_children(
             let item_margin = item.margin.map(|margin| margin.resolve_to_option(container_outer_width));
             let item_non_auto_margin = item_margin.map(|m| m.unwrap_or(0.0));
             let item_non_auto_x_margin_sum = item_non_auto_margin.horizontal_axis_sum();
-            let known_dimensions = item
-                .size
-                .map_width(|width| {
-                    // TODO: Allow stretch-sizing to be conditional, as there are exceptions.
-                    // e.g. Table children of blocks do not stretch fit
-                    Some(
-                        width
-                            .unwrap_or(container_inner_width - item_non_auto_x_margin_sum)
-                            .maybe_clamp(item.min_size.width, item.max_size.width),
-                    )
-                })
-                .maybe_clamp(item.min_size, item.max_size);
+            let known_dimensions = if item.is_table {
+                Size::NONE
+            } else {
+                item.size
+                    .map_width(|width| {
+                        // TODO: Allow stretch-sizing to be conditional, as there are exceptions.
+                        // e.g. Table children of blocks do not stretch fit
+                        Some(
+                            width
+                                .unwrap_or(container_inner_width - item_non_auto_x_margin_sum)
+                                .maybe_clamp(item.min_size.width, item.max_size.width),
+                        )
+                    })
+                    .maybe_clamp(item.min_size, item.max_size)
+            };
 
             let item_layout = tree.perform_child_layout(
                 item.node_id,
diff --git a/src/style/block.rs b/src/style/block.rs
index 04b758336..7cea35eda 100644
--- a/src/style/block.rs
+++ b/src/style/block.rs
@@ -1,7 +1,7 @@
 //! 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)
+/// The set of styles required for a Block layout container
 pub trait BlockContainerStyle: CoreStyle {
     /// Defines which row in the grid the item should start and end at
     #[inline(always)]
@@ -10,6 +10,15 @@ pub trait BlockContainerStyle: CoreStyle {
     }
 }
 
+/// The set of styles required for a Block layout item (child of a Block container)
+pub trait BlockItemStyle: CoreStyle {
+    /// Whether the item is a table. Table children are handled specially in block layout.
+    #[inline(always)]
+    fn is_table(&self) -> bool {
+        false
+    }
+}
+
 /// 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))]
diff --git a/src/style/mod.rs b/src/style/mod.rs
index 71a6f608e..9c35d202b 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -13,7 +13,7 @@ pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, J
 pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
 
 #[cfg(feature = "block_layout")]
-pub use self::block::{BlockContainerStyle, TextAlign};
+pub use self::block::{BlockContainerStyle, BlockItemStyle, TextAlign};
 #[cfg(feature = "flexbox")]
 pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
 #[cfg(feature = "grid")]
@@ -330,6 +330,9 @@ impl Overflow {
 pub struct Style {
     /// What layout strategy should be used?
     pub display: Display,
+    /// Whether a child is display:table or not. This affects children of block layouts.
+    /// This should really be part of `Display`, but it is currently seperate because table layout isn't implemented
+    pub item_is_table: bool,
     /// Should size styles apply to the content box or the border box of the node
     pub box_sizing: BoxSizing,
 
@@ -456,6 +459,7 @@ impl Style {
     /// The [`Default`] layout, in a form that can be used in const functions
     pub const DEFAULT: Style = Style {
         display: Display::DEFAULT,
+        item_is_table: false,
         box_sizing: BoxSizing::BorderBox,
         overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
         scrollbar_width: 0.0,
@@ -659,6 +663,22 @@ impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
     }
 }
 
+#[cfg(feature = "block_layout")]
+impl BlockItemStyle for Style {
+    #[inline(always)]
+    fn is_table(&self) -> bool {
+        self.item_is_table
+    }
+}
+
+#[cfg(feature = "block_layout")]
+impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
+    #[inline(always)]
+    fn is_table(&self) -> bool {
+        (*self).is_table()
+    }
+}
+
 #[cfg(feature = "flexbox")]
 impl FlexboxContainerStyle for Style {
     #[inline(always)]
@@ -895,6 +915,7 @@ mod tests {
 
         let old_defaults = Style {
             display: Default::default(),
+            item_is_table: false,
             box_sizing: Default::default(),
             overflow: Default::default(),
             scrollbar_width: 0.0,
diff --git a/src/tree/traits.rs b/src/tree/traits.rs
index e9382ae95..7c5a9ab35 100644
--- a/src/tree/traits.rs
+++ b/src/tree/traits.rs
@@ -134,7 +134,7 @@ use crate::style::{FlexboxContainerStyle, FlexboxItemStyle};
 #[cfg(feature = "grid")]
 use crate::style::{GridContainerStyle, GridItemStyle};
 #[cfg(feature = "block_layout")]
-use crate::BlockContainerStyle;
+use crate::{BlockContainerStyle, BlockItemStyle};
 use core::ops::{Deref, DerefMut};
 
 /// This trait is Taffy's abstraction for downward tree traversal.
@@ -257,7 +257,7 @@ pub trait LayoutBlockContainer: LayoutPartialTree {
     where
         Self: 'a;
     /// The style type representing each CSS Block item's styles
-    type BlockItemStyle<'a>: CoreStyle
+    type BlockItemStyle<'a>: BlockItemStyle
     where
         Self: 'a;