Skip to content

Commit

Permalink
Add is_table for block items (#701)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns authored Aug 1, 2024
1 parent 416558f commit 950a0eb
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 17 deletions.
33 changes: 20 additions & 13 deletions src/compute/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
11 changes: 10 additions & 1 deletion src/style/block.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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))]
Expand Down
23 changes: 22 additions & 1 deletion src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/tree/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 950a0eb

Please sign in to comment.