blitz_dom_api/
geometry.rs1use blitz_dom::{BaseDocument, NodeId};
6
7use crate::Result;
8
9#[derive(Debug, Clone, Copy, PartialEq, Default)]
14pub struct Rect {
15 pub x: f64,
17 pub y: f64,
19 pub width: f64,
21 pub height: f64,
23}
24
25impl Rect {
26 pub const ZERO: Self = Self {
28 x: 0.0,
29 y: 0.0,
30 width: 0.0,
31 height: 0.0,
32 };
33
34 pub fn left(&self) -> f64 {
36 self.x
37 }
38
39 pub fn top(&self) -> f64 {
41 self.y
42 }
43
44 pub fn right(&self) -> f64 {
46 self.x + self.width
47 }
48
49 pub fn bottom(&self) -> f64 {
51 self.y + self.height
52 }
53}
54
55pub fn bounding_client_rect(doc: &BaseDocument, node: NodeId) -> Result<Rect> {
73 Ok(match doc.get_client_bounding_rect(node) {
74 Some(rect) => Rect {
75 x: rect.x,
76 y: rect.y,
77 width: rect.width,
78 height: rect.height,
79 },
80 None => Rect::ZERO,
81 })
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::document;
88 use crate::element;
89 use crate::node;
90 use crate::test_support::viewport_skeleton;
91
92 #[test]
93 fn bounding_client_rect_reports_the_laid_out_box() {
94 let (mut doc, _html, _head, body) = viewport_skeleton(400, 300);
95 let id = document::create_element(&mut doc, "div").unwrap();
96 element::set_attribute(&mut doc, id, "style", "width: 120px; height: 40px").unwrap();
97 node::append_child(&mut doc, body, id).unwrap();
98 doc.resolve(0.0);
99
100 let rect = bounding_client_rect(&doc, id).unwrap();
101 assert_eq!(rect.width, 120.0);
102 assert_eq!(rect.height, 40.0);
103 assert_eq!(rect.right(), rect.x + 120.0);
104 assert_eq!(rect.bottom(), rect.y + 40.0);
105 }
106
107 #[test]
111 fn the_read_does_not_flush_layout() {
112 let (mut doc, _html, _head, body) = viewport_skeleton(400, 300);
113 let id = document::create_element(&mut doc, "div").unwrap();
114 element::set_attribute(&mut doc, id, "style", "width: 120px; height: 40px").unwrap();
115 node::append_child(&mut doc, body, id).unwrap();
116 doc.resolve(0.0);
117
118 element::set_attribute(&mut doc, id, "style", "width: 200px; height: 40px").unwrap();
119 assert_eq!(bounding_client_rect(&doc, id).unwrap().width, 120.0);
120 doc.resolve(0.0);
121 assert_eq!(bounding_client_rect(&doc, id).unwrap().width, 200.0);
122 }
123
124 #[test]
125 fn a_detached_node_reports_zeros() {
126 let (mut doc, _html, _head, _body) = viewport_skeleton(400, 300);
127 let id = document::create_element(&mut doc, "div").unwrap();
128 doc.resolve(0.0);
129 assert_eq!(bounding_client_rect(&doc, id).unwrap(), Rect::ZERO);
130 }
131}