Skip to main content

script/dom/performance/
performancecontainertiming.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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/// <https://wicg.github.io/container-timing/#sec-performance-container-timing>
25#[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    /// The descendant whose paint produced this entry.
37    last_painted_element: Option<Dom<Element>>,
38    /// The element carrying the `containertiming` attribute.
39    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-identifier>
99    fn Identifier(&self) -> DOMString {
100        self.identifier.clone().root()
101    }
102
103    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-intersectionrect>
104    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-size>
117    fn Size(&self) -> u64 {
118        self.size.round() as u64
119    }
120
121    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-firstrendertime>
122    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-painttime>
129    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-lastpaintedelement>
136    fn GetLastPaintedElement(&self) -> Option<DomRoot<Element>> {
137        self.last_painted_element.as_deref().map(DomRoot::from_ref)
138    }
139
140    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-rootelement>
141    fn GetRootElement(&self) -> Option<DomRoot<Element>> {
142        self.root_element.as_deref().map(DomRoot::from_ref)
143    }
144}