use blitz_dom::{BaseDocument, NodeId};
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Rect {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
}
impl Rect {
pub const ZERO: Self = Self {
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
};
pub fn left(&self) -> f64 {
self.x
}
pub fn top(&self) -> f64 {
self.y
}
pub fn right(&self) -> f64 {
self.x + self.width
}
pub fn bottom(&self) -> f64 {
self.y + self.height
}
}
pub fn bounding_client_rect(doc: &BaseDocument, node: NodeId) -> Result<Rect> {
Ok(match doc.get_client_bounding_rect(node) {
Some(rect) => Rect {
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
},
None => Rect::ZERO,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::document;
use crate::element;
use crate::node;
use crate::test_support::viewport_skeleton;
#[test]
fn bounding_client_rect_reports_the_laid_out_box() {
let (mut doc, _html, _head, body) = viewport_skeleton(400, 300);
let id = document::create_element(&mut doc, "div").unwrap();
element::set_attribute(&mut doc, id, "style", "width: 120px; height: 40px").unwrap();
node::append_child(&mut doc, body, id).unwrap();
doc.resolve(0.0);
let rect = bounding_client_rect(&doc, id).unwrap();
assert_eq!(rect.width, 120.0);
assert_eq!(rect.height, 40.0);
assert_eq!(rect.right(), rect.x + 120.0);
assert_eq!(rect.bottom(), rect.y + 40.0);
}
#[test]
fn the_read_does_not_flush_layout() {
let (mut doc, _html, _head, body) = viewport_skeleton(400, 300);
let id = document::create_element(&mut doc, "div").unwrap();
element::set_attribute(&mut doc, id, "style", "width: 120px; height: 40px").unwrap();
node::append_child(&mut doc, body, id).unwrap();
doc.resolve(0.0);
element::set_attribute(&mut doc, id, "style", "width: 200px; height: 40px").unwrap();
assert_eq!(bounding_client_rect(&doc, id).unwrap().width, 120.0);
doc.resolve(0.0);
assert_eq!(bounding_client_rect(&doc, id).unwrap().width, 200.0);
}
#[test]
fn a_detached_node_reports_zeros() {
let (mut doc, _html, _head, _body) = viewport_skeleton(400, 300);
let id = document::create_element(&mut doc, "div").unwrap();
doc.resolve(0.0);
assert_eq!(bounding_client_rect(&doc, id).unwrap(), Rect::ZERO);
}
}