Skip to content
Draft
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/compute/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@ impl BlockContext<'_> {
pos
}

/// Snapshot the current float placement state. The snapshot can be passed to
/// [`restore_float_snapshot`](Self::restore_float_snapshot) to undo the placement of any
/// floats placed after the snapshot was taken (e.g. to speculatively place floats).
pub fn float_snapshot(&self) -> FloatContext {
self.bfc.float_context.clone()
}

/// Restore a float placement state snapshot taken with
/// [`float_snapshot`](Self::float_snapshot)
pub fn restore_float_snapshot(&mut self, snapshot: FloatContext) {
self.bfc.float_context = snapshot;
}

/// Search a space suitable for laying out non-floated content into
pub fn find_content_slot(&self, min_y: f32, height: f32, clear: Clear, after: Option<usize>) -> ContentSlot {
let mut slot = self.bfc.float_context.find_content_slot(
Expand Down
62 changes: 31 additions & 31 deletions tests/hand_written/floats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,37 @@ fn float_beside_existing_float_moves_down_instead_of_overflowing() {
assert_eq!(taffy.layout(left2).unwrap().location, Point { x: 0.0, y: 100.0 });
}

/// Regression test for <https://wpt.live/css/CSS2/floats/floats-zero-height-wrap-002.xht>
///
/// A zero-height float takes up no space, but still affects the placement of content
/// whose vertical extent crosses its position.
#[test]
fn zero_height_float_affects_crossing_content() {
let mut taffy = new_test_tree();

let f1 = taffy.new_leaf(float_block(10.0, 30.0, Float::Left)).unwrap();
let zero =
taffy.new_leaf(Style { clear: taffy::style::Clear::Left, ..float_block(100.0, 0.0, Float::Left) }).unwrap();
// A BFC box whose vertical extent would cross the zero-height float: it doesn't fit
// beside the float's 100px inset, so it must be placed below it
let bfc = taffy
.new_leaf(Style {
display: Display::Block,
overflow: Point { x: Overflow::Hidden, y: Overflow::Hidden },
size: Size { width: length(450.0), height: length(40.0) },
..Default::default()
})
.unwrap();

let root = taffy.new_with_children(root_style(500.0), &[f1, zero, bfc]).unwrap();

taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();

assert_eq!(taffy.layout(f1).unwrap().location, Point { x: 0.0, y: 0.0 });
assert_eq!(taffy.layout(zero).unwrap().location, Point { x: 0.0, y: 30.0 });
assert_eq!(taffy.layout(bfc).unwrap().location, Point { x: 0.0, y: 30.0 });
}

/// Regression test for <https://wpt.live/css/CSS2/floats/floats-wrap-top-below-bfc-001l.xht>
///
/// A box establishing a new block formatting context must not overlap floats over its full
Expand Down Expand Up @@ -190,34 +221,3 @@ fn bfc_avoids_floats_over_full_height() {
// The BFC box starts below the float (y = 30 + 30 = 60), not beside the spacer
assert_eq!(taffy.layout(bfc).unwrap().location, Point { x: 0.0, y: 60.0 });
}

/// Regression test for <https://wpt.live/css/CSS2/floats/floats-zero-height-wrap-002.xht>
///
/// A zero-height float takes up no space, but still affects the placement of content
/// whose vertical extent crosses its position.
#[test]
fn zero_height_float_affects_crossing_content() {
let mut taffy = new_test_tree();

let f1 = taffy.new_leaf(float_block(10.0, 30.0, Float::Left)).unwrap();
let zero =
taffy.new_leaf(Style { clear: taffy::style::Clear::Left, ..float_block(100.0, 0.0, Float::Left) }).unwrap();
// A BFC box whose vertical extent would cross the zero-height float: it doesn't fit
// beside the float's 100px inset, so it must be placed below it
let bfc = taffy
.new_leaf(Style {
display: Display::Block,
overflow: Point { x: Overflow::Hidden, y: Overflow::Hidden },
size: Size { width: length(450.0), height: length(40.0) },
..Default::default()
})
.unwrap();

let root = taffy.new_with_children(root_style(500.0), &[f1, zero, bfc]).unwrap();

taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();

assert_eq!(taffy.layout(f1).unwrap().location, Point { x: 0.0, y: 0.0 });
assert_eq!(taffy.layout(zero).unwrap().location, Point { x: 0.0, y: 30.0 });
assert_eq!(taffy.layout(bfc).unwrap().location, Point { x: 0.0, y: 30.0 });
}