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