script/dom/performance/
largestcontentfulpaint.rs1use 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 #[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 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 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 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 fn Size(&self) -> u32 {
110 self.size as u32
111 }
112
113 fn Url(&self) -> DOMString {
115 self.url.clone()
116 }
117
118 fn Id(&self) -> DOMString {
120 self.GetElement()
121 .map(|element| element.Id())
122 .unwrap_or_default()
123 }
124
125 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 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 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}