Skip to main content

script/dom/performance/
largestcontentfulpaint.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 js::context::JSContext;
7use layout_api::LCPCandidate;
8use paint_api::display_list::PaintTimingInfo;
9use script_bindings::reflector::reflect_dom_object;
10use servo_base::cross_process_instant::CrossProcessInstant;
11use time::Duration;
12
13use super::performanceentry::{EntryType, PerformanceEntry};
14use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
15use crate::dom::bindings::codegen::Bindings::LargestContentfulPaintBinding::LargestContentfulPaintMethods;
16use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
17use crate::dom::bindings::inheritance::Castable;
18use crate::dom::bindings::reflector::DomGlobal;
19use crate::dom::bindings::root::{Dom, DomRoot};
20use crate::dom::bindings::str::DOMString;
21use crate::dom::element::Element;
22use crate::dom::globalscope::GlobalScope;
23use crate::dom::node::Node;
24
25#[dom_struct]
26pub(crate) struct LargestContentfulPaint {
27    entry: PerformanceEntry,
28    #[no_trace]
29    load_time: Option<CrossProcessInstant>,
30    #[no_trace]
31    render_time: CrossProcessInstant,
32    size: usize,
33    url: DOMString,
34    element: Option<Dom<Element>>,
35    /// <https://www.w3.org/TR/paint-timing/#paint-timing-info>
36    #[no_trace]
37    paint_timing_info: PaintTimingInfo,
38}
39
40impl LargestContentfulPaint {
41    pub(crate) fn new_inherited(
42        candidate: &LCPCandidate,
43        element: Option<&Element>,
44        load_time: Option<CrossProcessInstant>,
45        paint_timing_info: PaintTimingInfo,
46    ) -> LargestContentfulPaint {
47        // From: <https://www.w3.org/TR/largest-contentful-paint/#sec-largest-contentful-paint-interface>
48        //
49        // The renderTime attribute must return the default paint timestamp
50        // given this’s paint timing info.
51        let render_time = paint_timing_info.default_paint_timestamp();
52        LargestContentfulPaint {
53            entry: PerformanceEntry::new_inherited(
54                DOMString::new(),
55                EntryType::LargestContentfulPaint,
56                Some(render_time),
57                Duration::ZERO,
58            ),
59            load_time,
60            render_time,
61            size: candidate.area,
62            url: candidate
63                .url
64                .as_ref()
65                .map(|url| DOMString::from(url.as_str()))
66                .unwrap_or_default(),
67            element: element.map(Dom::from_ref),
68            paint_timing_info,
69        }
70    }
71
72    pub(crate) fn new(
73        cx: &mut JSContext,
74        global: &GlobalScope,
75        candidate: &LCPCandidate,
76        element: Option<&Element>,
77        load_time: Option<CrossProcessInstant>,
78        paint_timing_info: PaintTimingInfo,
79    ) -> DomRoot<LargestContentfulPaint> {
80        reflect_dom_object(
81            cx,
82            Box::new(LargestContentfulPaint::new_inherited(
83                candidate,
84                element,
85                load_time,
86                paint_timing_info,
87            )),
88            global,
89        )
90    }
91}
92
93impl LargestContentfulPaintMethods<crate::DomTypeHolder> for LargestContentfulPaint {
94    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-loadtime>
95    fn LoadTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
96        self.global()
97            .performance(cx)
98            .maybe_to_dom_high_res_time_stamp(self.load_time)
99    }
100
101    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-rendertime>
102    fn RenderTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
103        self.global()
104            .performance(cx)
105            .to_dom_high_res_time_stamp(self.render_time)
106    }
107
108    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-size>
109    fn Size(&self) -> u32 {
110        self.size as u32
111    }
112
113    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-url>
114    fn Url(&self) -> DOMString {
115        self.url.clone()
116    }
117
118    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-id>
119    fn Id(&self) -> DOMString {
120        self.GetElement()
121            .map(|element| element.Id())
122            .unwrap_or_default()
123    }
124
125    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-element>
126    fn GetElement(&self) -> Option<DomRoot<Element>> {
127        self.element
128            .as_ref()
129            .filter(|element| {
130                element
131                    .upcast::<Node>()
132                    .is_connected_with_browsing_context()
133            })
134            .map(|element| element.as_rooted())
135    }
136
137    /// <https://www.w3.org/TR/paint-timing/#dom-painttimingmixin-painttime>
138    fn PaintTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
139        self.global()
140            .performance(cx)
141            .to_dom_high_res_time_stamp(self.paint_timing_info.paint_time())
142    }
143
144    /// <https://www.w3.org/TR/paint-timing/#dom-painttimingmixin-presentationtime>
145    fn GetPresentationTime(&self, cx: &mut JSContext) -> Option<DOMHighResTimeStamp> {
146        Some(
147            self.global()
148                .performance(cx)
149                .maybe_to_dom_high_res_time_stamp(self.paint_timing_info.presentation_time()),
150        )
151    }
152}