Skip to main content

blitz_dom/
debug.rs

1use blitz_traits::node_id::NodeId;
2use parley::layout::PositionedLayoutItem;
3
4use crate::BaseDocument;
5
6impl BaseDocument {
7    pub fn print_taffy_tree(&self) {
8        taffy::print_tree(self, taffy::NodeId::from(0usize));
9    }
10
11    pub fn debug_log_node(&self, node_id: NodeId) {
12        let node = &self.nodes[node_id];
13
14        #[cfg(feature = "tracing")]
15        {
16            tracing::info!("Layout: {:?}", node.final_layout());
17            tracing::info!("Style: {:?}", node.style());
18        }
19
20        println!("\nNode {} {}", node.id, node.node_debug_str());
21
22        println!("Attrs:");
23
24        for attr in node.attrs().into_iter().flatten() {
25            println!("    {}: {}", attr.name.local, attr.value);
26        }
27
28        if node.flags.is_inline_root() {
29            let inline_layout = &node
30                .data
31                .downcast_element()
32                .unwrap()
33                .inline_layout_data
34                .as_ref()
35                .unwrap();
36
37            println!(
38                "Size: {}x{}",
39                inline_layout.layout.width(),
40                inline_layout.layout.height()
41            );
42            println!("Text content: {:?}", inline_layout.text);
43            println!("Inline Boxes:");
44            for ibox in inline_layout.layout.inline_boxes() {
45                print!("(id: {}) ", ibox.id);
46            }
47            println!();
48            println!("Lines:");
49            for (i, line) in inline_layout.layout.lines().enumerate() {
50                let metrics = line.metrics();
51                let x = metrics.inline_min_coord;
52                let y = metrics.block_min_coord;
53                let w = metrics.inline_max_coord - metrics.inline_min_coord;
54                let h = metrics.block_max_coord - metrics.block_min_coord;
55                println!("Line {i}: x:{x} y:{y} width:{w} height:{h}");
56                for item in line.items() {
57                    print!("  ");
58                    match item {
59                        PositionedLayoutItem::GlyphRun(run) => {
60                            print!(
61                                "RUN (x: {}, w: {}) ",
62                                run.offset().round(),
63                                run.run().advance()
64                            )
65                        }
66                        PositionedLayoutItem::InlineBox(ibox) => print!(
67                            "BOX {:?} (id: {} x: {} y: {} w: {}, h: {})",
68                            ibox.kind,
69                            ibox.id,
70                            ibox.x.round(),
71                            ibox.y.round(),
72                            ibox.width.round(),
73                            ibox.height.round()
74                        ),
75                    }
76                    println!();
77                }
78            }
79        }
80
81        let layout = node.final_layout();
82        println!("Layout:");
83        println!(
84            "  x: {x} y: {y} w: {width} h: {height} overflow: l:{ol} r:{or} t:{ot} b:{ob}",
85            x = layout.location.x,
86            y = layout.location.y,
87            width = layout.size.width,
88            height = layout.size.height,
89            ol = layout.scrollable_overflow_rect.left,
90            or = layout.scrollable_overflow_rect.right,
91            ot = layout.scrollable_overflow_rect.top,
92            ob = layout.scrollable_overflow_rect.bottom,
93        );
94        println!(
95            "  border: l:{l} r:{r} t:{t} b:{b}",
96            l = layout.border.left,
97            r = layout.border.right,
98            t = layout.border.top,
99            b = layout.border.bottom,
100        );
101        println!(
102            "  padding: l:{l} r:{r} t:{t} b:{b}",
103            l = layout.padding.left,
104            r = layout.padding.right,
105            t = layout.padding.top,
106            b = layout.padding.bottom,
107        );
108        println!(
109            "  margin: l:{l} r:{r} t:{t} b:{b}",
110            l = layout.margin.left,
111            r = layout.margin.right,
112            t = layout.margin.top,
113            b = layout.margin.bottom,
114        );
115        println!("Parent: {:?}", node.parent);
116
117        let children: Vec<_> = node
118            .children
119            .iter()
120            .map(|id| &self.nodes[*id])
121            .map(|node| (node.id, node.order(), node.node_debug_str()))
122            .collect();
123        println!("Children: {children:?}");
124
125        println!("Layout Parent: {:?}", node.layout_parent.get());
126
127        let layout_children: Option<Vec<_>> = node.layout_children.borrow().as_ref().map(|lc| {
128            lc.iter()
129                .map(|id| &self.nodes[*id])
130                .map(|node| (node.id, node.order(), node.node_debug_str()))
131                .collect()
132        });
133        if let Some(layout_children) = layout_children {
134            println!("Layout Children: {layout_children:?}");
135        }
136
137        let paint_children: Option<Vec<_>> = node.paint_children.borrow().as_ref().map(|lc| {
138            lc.iter()
139                .map(|id| &self.nodes[*id])
140                .map(|node| (node.id, node.order(), node.node_debug_str()))
141                .collect()
142        });
143        if let Some(paint_children) = paint_children {
144            println!("Paint Children: {paint_children:?}");
145        }
146        // taffy::print_tree(&self.dom, node_id.into());
147    }
148}