script/dom/performance/
performancetiming.rs1use std::cell::Cell;
6use std::rc::Rc;
7
8use dom_struct::dom_struct;
9use js::context::JSContext;
10use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
11use script_bindings::root::DomRoot;
12use servo_base::cross_process_instant::CrossProcessInstant;
13
14use crate::dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods;
15use crate::dom::document::document::NavigationTiming;
16use crate::dom::globalscope::GlobalScope;
17
18#[dom_struct]
19pub(crate) struct PerformanceTiming {
20 reflector_: Reflector,
21 #[no_trace]
22 #[conditional_malloc_size_of]
23 navigation_timing: Rc<NavigationTiming>,
24 redirect_start: Cell<u64>,
26 redirect_end: Cell<u64>,
28 fetch_start: Cell<u64>,
30 domain_lookup_start: Cell<u64>,
32 domain_lookup_end: Cell<u64>,
34 connect_start: Cell<u64>,
36 connect_end: Cell<u64>,
38 secure_connection_start: Cell<u64>,
40 request_start: Cell<u64>,
42 response_start: Cell<u64>,
44 response_end: Cell<u64>,
46}
47
48impl PerformanceTiming {
49 pub(crate) fn new_inherited(navigation_timing: Rc<NavigationTiming>) -> PerformanceTiming {
50 PerformanceTiming {
51 reflector_: Reflector::new(),
52 navigation_timing,
53 redirect_start: Default::default(),
54 redirect_end: Default::default(),
55 fetch_start: Default::default(),
56 domain_lookup_start: Default::default(),
57 domain_lookup_end: Default::default(),
58 connect_start: Default::default(),
59 connect_end: Default::default(),
60 secure_connection_start: Default::default(),
61 request_start: Default::default(),
62 response_start: Default::default(),
63 response_end: Default::default(),
64 }
65 }
66
67 pub(crate) fn new(
68 cx: &mut JSContext,
69 global: &GlobalScope,
70 navigation_timing: Rc<NavigationTiming>,
71 ) -> DomRoot<PerformanceTiming> {
72 reflect_dom_object_with_cx(
73 Box::new(PerformanceTiming::new_inherited(navigation_timing)),
74 global,
75 cx,
76 )
77 }
78
79 fn instant_to_millis(instant: &Cell<Option<CrossProcessInstant>>) -> u64 {
80 let instant = instant.get().unwrap_or(CrossProcessInstant::epoch());
83 let epoch = CrossProcessInstant::epoch();
84 (instant - epoch).whole_milliseconds() as u64
85 }
86}
87
88impl PerformanceTimingMethods<crate::DomTypeHolder> for PerformanceTiming {
89 fn NavigationStart(&self) -> u64 {
91 Self::instant_to_millis(&self.navigation_timing.navigation_start)
92 }
93
94 fn UnloadEventStart(&self) -> u64 {
96 Self::instant_to_millis(&self.navigation_timing.unload_event_start)
97 }
98
99 fn UnloadEventEnd(&self) -> u64 {
101 Self::instant_to_millis(&self.navigation_timing.unload_event_end)
102 }
103
104 fn RedirectStart(&self) -> u64 {
106 self.redirect_start.get()
107 }
108
109 fn RedirectEnd(&self) -> u64 {
111 self.redirect_end.get()
112 }
113
114 fn FetchStart(&self) -> u64 {
116 self.fetch_start.get()
117 }
118
119 fn DomainLookupStart(&self) -> u64 {
121 self.domain_lookup_start.get()
122 }
123
124 fn DomainLookupEnd(&self) -> u64 {
126 self.domain_lookup_end.get()
127 }
128
129 fn ConnectStart(&self) -> u64 {
131 self.connect_start.get()
132 }
133
134 fn ConnectEnd(&self) -> u64 {
136 self.connect_end.get()
137 }
138
139 fn SecureConnectionStart(&self) -> u64 {
141 self.secure_connection_start.get()
142 }
143
144 fn RequestStart(&self) -> u64 {
146 self.request_start.get()
147 }
148
149 fn ResponseStart(&self) -> u64 {
151 self.response_start.get()
152 }
153
154 fn ResponseEnd(&self) -> u64 {
156 self.response_end.get()
157 }
158
159 fn DomLoading(&self) -> u64 {
161 Self::instant_to_millis(&self.navigation_timing.dom_loading)
162 }
163
164 fn DomInteractive(&self) -> u64 {
166 Self::instant_to_millis(&self.navigation_timing.dom_interactive)
167 }
168
169 fn DomContentLoadedEventStart(&self) -> u64 {
171 Self::instant_to_millis(&self.navigation_timing.dom_content_loaded_event_start)
172 }
173
174 fn DomContentLoadedEventEnd(&self) -> u64 {
176 Self::instant_to_millis(&self.navigation_timing.dom_content_loaded_event_end)
177 }
178
179 fn DomComplete(&self) -> u64 {
181 Self::instant_to_millis(&self.navigation_timing.dom_complete)
182 }
183
184 fn LoadEventStart(&self) -> u64 {
186 Self::instant_to_millis(&self.navigation_timing.load_event_start)
187 }
188
189 fn LoadEventEnd(&self) -> u64 {
191 Self::instant_to_millis(&self.navigation_timing.load_event_end)
192 }
193}