script/dom/performance/
performancecontainertiming.rs1use dom_struct::dom_struct;
6use euclid::Box2D;
7use js::context::JSContext;
8use script_bindings::reflector::reflect_dom_object;
9use servo_base::cross_process_instant::CrossProcessInstant;
10use time::Duration;
11use webrender_api::units::LayoutPixel;
12
13use super::performanceentry::{EntryType, PerformanceEntry};
14use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
15use crate::dom::bindings::codegen::Bindings::PerformanceContainerTimingBinding::PerformanceContainerTimingMethods;
16use crate::dom::bindings::reflector::DomGlobal;
17use crate::dom::bindings::root::{Dom, DomRoot};
18use crate::dom::bindings::str::DOMString;
19use crate::dom::domrectreadonly::DOMRectReadOnly;
20use crate::dom::element::Element;
21use crate::dom::globalscope::GlobalScope;
22
23#[dom_struct]
25pub(crate) struct PerformanceContainerTiming {
26 entry: PerformanceEntry,
27 identifier: DOMString,
28 #[no_trace]
29 intersection_rect: Box2D<f32, LayoutPixel>,
30 size: f32,
31 #[no_trace]
32 first_render_time: CrossProcessInstant,
33 #[no_trace]
34 paint_time: CrossProcessInstant,
35 last_painted_element: Option<Dom<Element>>,
37 root_element: Option<Dom<Element>>,
39}
40
41impl PerformanceContainerTiming {
42 fn new_inherited(
43 identifier: DOMString,
44 intersection_rect: Box2D<f32, LayoutPixel>,
45 size: f32,
46 first_render_time: CrossProcessInstant,
47 paint_time: CrossProcessInstant,
48 last_painted_element: Option<&Element>,
49 root_element: Option<&Element>,
50 ) -> PerformanceContainerTiming {
51 PerformanceContainerTiming {
52 entry: PerformanceEntry::new_inherited(
53 DOMString::new(),
54 EntryType::ContainerTiming,
55 Some(paint_time),
56 Duration::ZERO,
57 ),
58 identifier,
59 intersection_rect,
60 size,
61 first_render_time,
62 paint_time,
63 last_painted_element: last_painted_element.map(Dom::from_ref),
64 root_element: root_element.map(Dom::from_ref),
65 }
66 }
67
68 #[expect(clippy::too_many_arguments)]
69 pub(crate) fn new(
70 cx: &mut JSContext,
71 global: &GlobalScope,
72 identifier: DOMString,
73 intersection_rect: Box2D<f32, LayoutPixel>,
74 size: f32,
75 first_render_time: CrossProcessInstant,
76 paint_time: CrossProcessInstant,
77 last_painted_element: Option<&Element>,
78 root_element: Option<&Element>,
79 ) -> DomRoot<PerformanceContainerTiming> {
80 reflect_dom_object(
81 cx,
82 Box::new(PerformanceContainerTiming::new_inherited(
83 identifier,
84 intersection_rect,
85 size,
86 first_render_time,
87 paint_time,
88 last_painted_element,
89 root_element,
90 )),
91 global,
92 )
93 }
94}
95
96impl PerformanceContainerTimingMethods<crate::DomTypeHolder> for PerformanceContainerTiming {
97 fn Identifier(&self) -> DOMString {
99 self.identifier.clone()
100 }
101
102 fn IntersectionRect(&self, cx: &mut JSContext) -> DomRoot<DOMRectReadOnly> {
104 DOMRectReadOnly::new(
105 cx,
106 &self.global(),
107 None,
108 self.intersection_rect.min.x as f64,
109 self.intersection_rect.min.y as f64,
110 self.intersection_rect.width() as f64,
111 self.intersection_rect.height() as f64,
112 )
113 }
114
115 fn Size(&self) -> u64 {
117 self.size.round() as u64
118 }
119
120 fn FirstRenderTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
122 self.global()
123 .performance(cx)
124 .to_dom_high_res_time_stamp(self.first_render_time)
125 }
126
127 fn PaintTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
129 self.global()
130 .performance(cx)
131 .to_dom_high_res_time_stamp(self.paint_time)
132 }
133
134 fn GetLastPaintedElement(&self) -> Option<DomRoot<Element>> {
136 self.last_painted_element.as_deref().map(DomRoot::from_ref)
137 }
138
139 fn GetRootElement(&self) -> Option<DomRoot<Element>> {
141 self.root_element.as_deref().map(DomRoot::from_ref)
142 }
143}