Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ default = [
"grid",
"block_layout",
"float_layout",
"table_layout",
"calc",
"content_size",
"detailed_layout_info",
Expand All @@ -53,6 +54,8 @@ default = [
block_layout = []
## Enables the Float layout algorithm. This is a sub-feature of block layout.
float_layout = []
## Enables the CSS Table layout algorithm. See [`compute_table_layout`](crate::compute_table_layout).
table_layout = ["alloc", "block_layout"]
## Enables the Flexbox layout algorithm. See [`compute_flexbox_layout`](crate::compute_flexbox_layout).
flexbox = []
## Enables support for `flex-wrap: balance` and `flex-line-count` from [CSS Flexbox Level 2](https://drafts.csswg.org/css-flexbox-2/)
Expand Down
3 changes: 3 additions & 0 deletions benches/src/yoga_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ fn apply_taffy_style(node: &mut yg::Node, style: &tf::Style) {
tf::Display::Grid => panic!("Yoga does not support CSS Grid layout"),
tf::Display::Block => panic!("Yoga does not support CSS Block layout"),
tf::Display::FlowRoot => panic!("Yoga does not support CSS Block layout"),
tf::Display::Table | tf::Display::TableRowGroup | tf::Display::TableRow | tf::Display::TableCell => {
panic!("Yoga does not support CSS Table layout")
}
});

// box_sizing
Expand Down
8 changes: 8 additions & 0 deletions scripts/gentest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ async fn main() {
if name.starts_with("balance") {
writeln!(&mut mod_file, r#"#[cfg(feature = "flexbox_balance")]"#).unwrap();
}
if name.starts_with("table") {
writeln!(&mut mod_file, r#"#[cfg(feature = "table_layout")]"#).unwrap();
}
writeln!(
&mut mod_file,
"#[test]
Expand Down Expand Up @@ -664,6 +667,11 @@ fn generate_node(w: &mut XmlWriter, node: &Value) {
}

maybe_write(w, "text-align", get_str_attr(&style["textAlign"], None));
maybe_write(w, "table-layout", get_str_attr(&style["tableLayout"], None));
maybe_write(w, "border-spacing-x", get_dim_attr(&style["borderSpacing"]["x"], None));
maybe_write(w, "border-spacing-y", get_dim_attr(&style["borderSpacing"]["y"], None));
maybe_write(w, "colspan", get_num_attr(&style["colspan"], None));
maybe_write(w, "rowspan", get_num_attr(&style["rowspan"], None));
maybe_write(w, "align-items", get_str_attr(&style["alignItems"], None));
maybe_write(w, "align-self", get_str_attr(&style["alignSelf"], None));
maybe_write(w, "justify-items", get_str_attr(&style["justifyItems"], None));
Expand Down
22 changes: 21 additions & 1 deletion scripts/gentest/test_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ function parseGridPosition(input) {
return undefined;
}

function parseBorderSpacing(input) {
if (!input) return undefined;
const parts = input.trim().split(/\s+/).map(part => parseDimension(part));
const x = parts[0];
const y = parts[1] ?? parts[0];
if (!x && !y) return undefined;
return { x, y };
}

function describeElement(e) {

// Get precise, unrounded dimensions for the current element and it's parent
Expand All @@ -211,9 +220,14 @@ function describeElement(e) {

const computedStyle = getComputedStyle(e);

// Real table elements (<table>, <tr>, <td>, ...) get their display from the UA
// stylesheet rather than an inline style, so fall back to the computed value for them
const isTableElement = ['TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TR', 'TD', 'TH'].includes(e.tagName);
const displayValue = e.style.display || (isTableElement ? computedStyle.display : '');

return {
style: {
display: parseEnum(e.style.display),
display: parseEnum(displayValue),
boxSizing: parseEnum(computedStyle.boxSizing),

position: parseEnum(e.style.position),
Expand All @@ -226,6 +240,12 @@ function describeElement(e) {

textAlign: parseEnum(e.style.textAlign),

tableLayout: parseEnum(e.style.tableLayout),
// border-spacing is inherited, so only record it on the table itself
borderSpacing: displayValue === 'table' ? parseBorderSpacing(computedStyle.borderSpacing) : undefined,
colspan: e.colSpan > 1 ? e.colSpan : undefined,
rowspan: e.rowSpan > 1 ? e.rowSpan : undefined,

flexDirection: parseEnum(e.style.flexDirection),
flexWrap: parseEnum(e.style.flexWrap),
flexLineCount: parseNumber(e.style.flexLineCount),
Expand Down
15 changes: 12 additions & 3 deletions src/compute/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,13 @@ fn compute_inner(
#[allow(unused_mut)] mut block_ctx: &mut BlockContext<'_>,
) -> LayoutOutput {
let LayoutInput {
known_dimensions, parent_size, available_space, run_mode, vertical_margins_are_collapsible, ..
known_dimensions,
parent_size,
available_space,
run_mode,
vertical_margins_are_collapsible,
content_offset_y,
..
} = inputs;

let style = tree.get_block_container_style(node_id);
Expand Down Expand Up @@ -599,6 +605,7 @@ fn compute_inner(
own_margins_collapse_with_children,
#[cfg(feature = "content_size")]
is_scroll_container,
content_offset_y,
block_ctx,
);

Expand Down Expand Up @@ -947,6 +954,7 @@ fn perform_final_layout_on_in_flow_children(
direction: Direction,
own_margins_collapse_with_children: Line<bool>,
#[cfg(feature = "content_size")] is_scroll_container: bool,
content_offset_y: f32,
block_ctx: &mut BlockContext<'_>,
) -> (Rect<f32>, f32, CollapsibleMarginSet, CollapsibleMarginSet, Option<f32>) {
// Resolve container_inner_width for sizing child nodes using initial content_box_inset
Expand Down Expand Up @@ -981,8 +989,8 @@ fn perform_final_layout_on_in_flow_children(

#[cfg_attr(not(feature = "content_size"), allow(unused_mut))]
let mut inflow_overflow_rect = Rect::ZERO;
let mut committed_y_offset = resolved_content_box_inset.top;
let mut y_offset_for_absolute = resolved_content_box_inset.top;
let mut committed_y_offset = resolved_content_box_inset.top + content_offset_y;
let mut y_offset_for_absolute = resolved_content_box_inset.top + content_offset_y;
let mut first_child_top_margin_set = CollapsibleMarginSet::ZERO;
let mut active_collapsible_margin_set = CollapsibleMarginSet::ZERO;
let mut is_collapsing_with_first_margin_set = true;
Expand Down Expand Up @@ -1257,6 +1265,7 @@ fn perform_final_layout_on_in_flow_children(
parent_size,
available_space: available_space.map_width(|_| AvailableSpace::Definite(stretch_width)),
vertical_margins_are_collapsible: if item.is_in_same_bfc { Line::TRUE } else { Line::FALSE },
content_offset_y: 0.0,
};

#[cfg(feature = "float_layout")]
Expand Down
3 changes: 3 additions & 0 deletions src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,7 @@ fn determine_hypothetical_cross_size(
height: if constants.is_row { child_available_cross } else { child_known_main },
},
vertical_margins_are_collapsible: Line::FALSE,
content_offset_y: 0.0,
},
)
.size
Expand Down Expand Up @@ -1864,6 +1865,7 @@ fn calculate_children_base_lines(
},
},
vertical_margins_are_collapsible: Line::FALSE,
content_offset_y: 0.0,
},
);

Expand Down Expand Up @@ -2358,6 +2360,7 @@ fn calculate_flex_item(
parent_size: node_inner_size,
available_space: container_size.map(|s| s.into()),
vertical_margins_are_collapsible: Line::FALSE,
content_offset_y: 0.0,
},
);
let LayoutOutput {
Expand Down
7 changes: 7 additions & 0 deletions src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! | [`compute_flexbox_layout`] | Layout a Flexbox container and it's direct children |
//! | [`compute_grid_layout`] | Layout a CSS Grid container and it's direct children |
//! | [`compute_block_layout`] | Layout a Block container and it's direct children |
//! | [`compute_table_layout`] | Layout a Table container and it's direct children |
//! | [`compute_leaf_layout`] | Applies common properties like padding/border/aspect-ratio to a node before deferring to a passed closure to determine it's size. Can be applied to nodes like text or image nodes. |
//! | [`compute_root_layout`] | Layout the root node of a tree (regardless of it's layout mode). This function is typically called once to begin a layout run. | |
//! | [`compute_hidden_layout`] | Mark a node as hidden during layout (like `Display::None`) |
Expand Down Expand Up @@ -36,6 +37,9 @@ pub(crate) mod flexbox;
#[cfg(feature = "grid")]
pub(crate) mod grid;

#[cfg(feature = "table_layout")]
pub(crate) mod table;

pub use leaf::compute_leaf_layout;

#[cfg(feature = "block_layout")]
Expand All @@ -47,6 +51,9 @@ pub use self::flexbox::compute_flexbox_layout;
#[cfg(feature = "grid")]
pub use self::grid::compute_grid_layout;

#[cfg(feature = "table_layout")]
pub use self::table::compute_table_layout;

#[cfg(feature = "float_layout")]
pub use self::float::{BfcSlot, ContentSlot, FloatContext, FloatIntrinsicWidthCalculator};

Expand Down
Loading