⎇ d52ab8f8305292875fbbe1b672c12daf63dca3be
src/compute/mod.rs
Ñawpa willay
Pi imata llamkarqan
ch'uya
Fix `display:none` caching issue (#454)
1//! The layout algorithms themselves
2
3pub(crate) mod common;
4pub(crate) mod leaf;
5
6pub use leaf::compute;
7
8#[cfg(feature = "flexbox")]
9pub(crate) mod flexbox;
10
11#[cfg(feature = "grid")]
12pub(crate) mod grid;
13
14use crate::geometry::{Point, Size};
15use crate::style::AvailableSpace;
16use crate::tree::{Layout, LayoutTree, NodeId, SizeAndBaselines, SizingMode};
17
18#[cfg(feature = "flexbox")]
19pub use self::flexbox::FlexboxAlgorithm;
20
21#[cfg(feature = "grid")]
22pub use self::grid::CssGridAlgorithm;
23
24#[cfg(feature = "taffy_tree")]
25pub(crate) mod taffy_tree;
26
27/// A common interface that all Taffy layout algorithms conform to
28pub trait LayoutAlgorithm {
29 /// The name of the algorithm (mainly used for debug purposes)
30 const NAME: &'static str;
31
32 /// Compute the size of the node given the specified constraints
33 fn measure_size(
34 tree: &mut impl LayoutTree,
35 node: NodeId,
36 known_dimensions: Size<Option<f32>>,
37 parent_size: Size<Option<f32>>,
38 available_space: Size<AvailableSpace>,
39 sizing_mode: SizingMode,
40 ) -> Size<f32>;
41
42 /// Perform a full layout on the node given the specified constraints
43 fn perform_layout(
44 tree: &mut impl LayoutTree,
45 node: NodeId,
46 known_dimensions: Size<Option<f32>>,
47 parent_size: Size<Option<f32>>,
48 available_space: Size<AvailableSpace>,
49 sizing_mode: SizingMode,
50 ) -> SizeAndBaselines;
51}
52
53/// The public interface to Taffy's hidden node algorithm implementation
54pub struct HiddenAlgorithm;
55impl LayoutAlgorithm for HiddenAlgorithm {
56 const NAME: &'static str = "NONE";
57
58 fn perform_layout(
59 tree: &mut impl LayoutTree,
60 node: NodeId,
61 _known_dimensions: Size<Option<f32>>,
62 _parent_size: Size<Option<f32>>,
63 _available_space: Size<AvailableSpace>,
64 _sizing_mode: SizingMode,
65 ) -> SizeAndBaselines {
66 perform_hidden_layout(tree, node);
67 SizeAndBaselines { size: Size::ZERO, first_baselines: Point::NONE }
68 }
69
70 fn measure_size(
71 _tree: &mut impl LayoutTree,
72 _node: NodeId,
73 _known_dimensions: Size<Option<f32>>,
74 _parent_size: Size<Option<f32>>,
75 _available_space: Size<AvailableSpace>,
76 _sizing_mode: SizingMode,
77 ) -> Size<f32> {
78 Size::ZERO
79 }
80}
81
82/// Creates a layout for this node and its children, recursively.
83/// Each hidden node has zero size and is placed at the origin
84fn perform_hidden_layout(tree: &mut impl LayoutTree, node: NodeId) {
85 /// Recursive function to apply hidden layout to all descendents
86 fn perform_hidden_layout_inner(tree: &mut impl LayoutTree, node: NodeId, order: u32) {
87 *tree.layout_mut(node) = Layout::with_order(order);
88 for order in 0..tree.child_count(node) {
89 perform_hidden_layout_inner(tree, tree.child(node, order), order as _);
90 }
91 }
92
93 for order in 0..tree.child_count(node) {
94 perform_hidden_layout_inner(tree, tree.child(node, order), order as _);
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::perform_hidden_layout;
101 use crate::geometry::{Point, Size};
102 use crate::style::{Display, Style};
103 use crate::Taffy;
104
105 #[test]
106 fn hidden_layout_should_hide_recursively() {
107 let mut taffy = Taffy::new();
108
109 let style: Style = Style { display: Display::Flex, size: Size::from_points(50.0, 50.0), ..Default::default() };
110
111 let grandchild_00 = taffy.new_leaf(style.clone()).unwrap();
112 let grandchild_01 = taffy.new_leaf(style.clone()).unwrap();
113 let child_00 = taffy.new_with_children(style.clone(), &[grandchild_00, grandchild_01]).unwrap();
114
115 let grandchild_02 = taffy.new_leaf(style.clone()).unwrap();
116 let child_01 = taffy.new_with_children(style.clone(), &[grandchild_02]).unwrap();
117
118 let root = taffy
119 .new_with_children(
120 Style { display: Display::None, size: Size::from_points(50.0, 50.0), ..Default::default() },
121 &[child_00, child_01],
122 )
123 .unwrap();
124
125 perform_hidden_layout(&mut taffy, root.into());
126
127 // Whatever size and display-mode the nodes had previously,
128 // all layouts should resolve to ZERO due to the root's DISPLAY::NONE
129 for (node, _) in taffy.nodes.iter().filter(|(node, _)| *node != root.into()) {
130 if let Ok(layout) = taffy.layout(node.into()) {
131 assert_eq!(layout.size, Size::zero());
132 assert_eq!(layout.location, Point::zero());
133 }
134 }
135 }
136}