Skip to content

Commit

Permalink
Fix display:none caching issue (#454)
Browse files Browse the repository at this point in the history
* Fix compilation with debug feature

* Clear cache when applying hidden layout to a node
  • Loading branch information
nicoburns authored Apr 19, 2023
1 parent 2b5366e commit d52ab8f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 28 deletions.
18 changes: 0 additions & 18 deletions src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ pub use self::grid::CssGridAlgorithm;
#[cfg(feature = "taffy_tree")]
pub(crate) mod taffy_tree;

#[cfg(any(feature = "debug", feature = "profile"))]
use crate::util::debug::NODE_LOGGER;

/// A common interface that all Taffy layout algorithms conform to
pub trait LayoutAlgorithm {
/// The name of the algorithm (mainly used for debug purposes)
Expand All @@ -53,21 +50,6 @@ pub trait LayoutAlgorithm {
) -> SizeAndBaselines;
}

#[cfg(feature = "debug")]
fn debug_log_node(
known_dimensions: Size<Option<f32>>,
parent_size: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
run_mode: RunMode,
sizing_mode: SizingMode,
) {
NODE_LOGGER.debug_log(run_mode);
NODE_LOGGER.labelled_debug_log("sizing_mode", sizing_mode);
NODE_LOGGER.labelled_debug_log("known_dimensions", known_dimensions);
NODE_LOGGER.labelled_debug_log("parent_size", parent_size);
NODE_LOGGER.labelled_debug_log("available_space", available_space);
}

/// The public interface to Taffy's hidden node algorithm implementation
pub struct HiddenAlgorithm;
impl LayoutAlgorithm for HiddenAlgorithm {
Expand Down
51 changes: 41 additions & 10 deletions src/compute/taffy_tree.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Computation specific for the default `Taffy` tree implementation

use crate::compute::{leaf, HiddenAlgorithm, LayoutAlgorithm};
use crate::compute::{leaf, LayoutAlgorithm};
use crate::geometry::{Point, Size};
use crate::style::{AvailableSpace, Display};
use crate::tree::{Layout, LayoutTree, NodeId, RunMode, SizeAndBaselines, SizingMode, Taffy, TaffyError};
Expand All @@ -12,6 +12,24 @@ use crate::compute::FlexboxAlgorithm;
#[cfg(feature = "grid")]
use crate::compute::CssGridAlgorithm;

#[cfg(any(feature = "debug", feature = "profile"))]
use crate::util::debug::NODE_LOGGER;

#[cfg(feature = "debug")]
fn debug_log_node(
known_dimensions: Size<Option<f32>>,
parent_size: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
run_mode: RunMode,
sizing_mode: SizingMode,
) {
NODE_LOGGER.debug_log(run_mode);
NODE_LOGGER.labelled_debug_log("sizing_mode", sizing_mode);
NODE_LOGGER.labelled_debug_log("known_dimensions", known_dimensions);
NODE_LOGGER.labelled_debug_log("parent_size", parent_size);
NODE_LOGGER.labelled_debug_log("available_space", available_space);
}

/// Updates the stored layout of the provided `node` and its children
pub(crate) fn compute_layout(
taffy: &mut Taffy,
Expand Down Expand Up @@ -125,15 +143,10 @@ fn compute_node_layout(

let display_mode = tree.nodes[node_key].style.display;
let computed_size_and_baselines = match (display_mode, has_children) {
(Display::None, _) => perform_computations::<HiddenAlgorithm>(
tree,
node,
known_dimensions,
parent_size,
available_space,
run_mode,
sizing_mode,
),
(Display::None, _) => {
perform_taffy_tree_hidden_layout(tree, node);
SizeAndBaselines { size: Size::ZERO, first_baselines: Point::NONE }
}
#[cfg(feature = "flexbox")]
(Display::Flex, true) => perform_computations::<FlexboxAlgorithm>(
tree,
Expand Down Expand Up @@ -186,6 +199,24 @@ fn compute_node_layout(
computed_size_and_baselines
}

/// Creates a layout for this node and its children, recursively.
/// Each hidden node has zero size and is placed at the origin
fn perform_taffy_tree_hidden_layout(tree: &mut Taffy, node: NodeId) {
/// Recursive function to apply hidden layout to all descendents
fn perform_hidden_layout_inner(tree: &mut Taffy, node: NodeId, order: u32) {
let node_key = node.into();
*tree.layout_mut(node) = Layout::with_order(order);
tree.nodes[node_key].cache.clear();
for order in 0..tree.children[node_key].len() {
perform_hidden_layout_inner(tree, tree.child(node, order), order as _);
}
}

for order in 0..tree.children[node.into()].len() {
perform_hidden_layout_inner(tree, tree.child(node, order), order as _);
}
}

/// Rounds the calculated [`Layout`] to exact pixel values
/// In order to ensure that no gaps in the layout are introduced we:
/// - Always round based on the absolute coordinates rather than parent-relative coordinates
Expand Down
35 changes: 35 additions & 0 deletions tests/relayout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,41 @@ fn toggle_root_display_none() {
assert_eq!(layout.size.height, 0.0);
}

#[test]
fn toggle_root_display_none_with_children() {
use taffy::prelude::*;

let mut taffy = taffy::Taffy::new();

let child = taffy
.new_leaf(Style { size: Size { width: points(800.0), height: points(100.0) }, ..Default::default() })
.unwrap();

let parent = taffy
.new_with_children(
Style { size: Size { width: points(800.0), height: points(100.0) }, ..Default::default() },
&[child],
)
.unwrap();

let root = taffy.new_with_children(Style::default(), &[parent]).unwrap();
taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);

taffy.set_style(root, Style { display: Display::None, ..Default::default() }).unwrap();
taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
assert_eq!(taffy.layout(child).unwrap().size.width, 0.0);
assert_eq!(taffy.layout(child).unwrap().size.height, 0.0);

taffy.set_style(root, Style::default()).unwrap();
taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
assert_eq!(taffy.layout(parent).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(parent).unwrap().size.height, 100.0);
assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
}

#[test]
fn toggle_flex_child_display_none() {
let hidden_style = Style {
Expand Down

0 comments on commit d52ab8f

Please sign in to comment.