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::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/// <https://wicg.github.io/container-timing/#sec-performance-container-timing>
24#[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    /// The descendant whose paint produced this entry.
36    last_painted_element: Option<Dom<Element>>,
37    /// The element carrying the `containertiming` attribute.
38    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-identifier>
98    fn Identifier(&self) -> DOMString {
99        self.identifier.clone()
100    }
101
102    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-intersectionrect>
103    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-size>
116    fn Size(&self) -> u64 {
117        self.size.round() as u64
118    }
119
120    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-firstrendertime>
121    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-painttime>
128    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    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-lastpaintedelement>
135    fn GetLastPaintedElement(&self) -> Option<DomRoot<Element>> {
136        self.last_painted_element.as_deref().map(DomRoot::from_ref)
137    }
138
139    /// <https://wicg.github.io/container-timing/#dom-performancecontainertiming-rootelement>
140    fn GetRootElement(&self) -> Option<DomRoot<Element>> {
141        self.root_element.as_deref().map(DomRoot::from_ref)
142    }
143}