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 script_bindings::reflector::reflect_dom_object_with_cx;
8use servo_base::cross_process_instant::CrossProcessInstant;
9use servo_url::ServoUrl;
10use time::Duration;
11
12use super::performanceentry::{EntryType, PerformanceEntry};
13use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
14use crate::dom::bindings::codegen::Bindings::LargestContentfulPaintBinding::LargestContentfulPaintMethods;
15use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
16use crate::dom::bindings::inheritance::Castable;
17use crate::dom::bindings::reflector::DomGlobal;
18use crate::dom::bindings::root::{Dom, DomRoot};
19use crate::dom::bindings::str::DOMString;
20use crate::dom::element::Element;
21use crate::dom::globalscope::GlobalScope;
22use crate::dom::node::Node;
23
24#[dom_struct]
25pub(crate) struct LargestContentfulPaint {
26    entry: PerformanceEntry,
27    #[no_trace]
28    load_time: CrossProcessInstant,
29    #[no_trace]
30    render_time: CrossProcessInstant,
31    size: usize,
32    url: DOMString,
33    element: Option<Dom<Element>>,
34}
35
36impl LargestContentfulPaint {
37    pub(crate) fn new_inherited(
38        render_time: CrossProcessInstant,
39        size: usize,
40        url: Option<ServoUrl>,
41        element: Option<&Element>,
42    ) -> LargestContentfulPaint {
43        LargestContentfulPaint {
44            entry: PerformanceEntry::new_inherited(
45                DOMString::from(""),
46                EntryType::LargestContentfulPaint,
47                Some(render_time),
48                Duration::ZERO,
49            ),
50            load_time: CrossProcessInstant::epoch(),
51            render_time,
52            size,
53            url: url.map(|u| DOMString::from(u.as_str())).unwrap_or_default(),
54            element: Some(Dom::from_ref(
55                element.expect("Element for LCP entry should be non-null"),
56            )),
57        }
58    }
59
60    pub(crate) fn new(
61        cx: &mut JSContext,
62        global: &GlobalScope,
63        render_time: CrossProcessInstant,
64        size: usize,
65        url: Option<ServoUrl>,
66        element: Option<&Element>,
67    ) -> DomRoot<LargestContentfulPaint> {
68        reflect_dom_object_with_cx(
69            Box::new(LargestContentfulPaint::new_inherited(
70                render_time,
71                size,
72                url,
73                element,
74            )),
75            global,
76            cx,
77        )
78    }
79}
80
81impl LargestContentfulPaintMethods<crate::DomTypeHolder> for LargestContentfulPaint {
82    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-loadtime>
83    fn LoadTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
84        self.global()
85            .performance(cx)
86            .to_dom_high_res_time_stamp(self.load_time)
87    }
88
89    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-rendertime>
90    fn RenderTime(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
91        self.global()
92            .performance(cx)
93            .to_dom_high_res_time_stamp(self.render_time)
94    }
95
96    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-size>
97    fn Size(&self) -> u32 {
98        self.size as u32
99    }
100
101    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-url>
102    fn Url(&self) -> DOMString {
103        self.url.clone()
104    }
105
106    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-id>
107    fn Id(&self) -> DOMString {
108        self.GetElement()
109            .map(|element| element.Id())
110            .unwrap_or_default()
111    }
112
113    /// <https://www.w3.org/TR/largest-contentful-paint/#dom-largestcontentfulpaint-element>
114    fn GetElement(&self) -> Option<DomRoot<Element>> {
115        self.element
116            .as_ref()
117            .filter(|element| {
118                element
119                    .upcast::<Node>()
120                    .is_connected_with_browsing_context()
121            })
122            .map(|element| element.as_rooted())
123    }
124}