Skip to main content

script/dom/performance/
performancetiming.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 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    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-redirectstart>
25    redirect_start: Cell<u64>,
26    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-redirectend>
27    redirect_end: Cell<u64>,
28    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-fetchstart>
29    fetch_start: Cell<u64>,
30    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-domainlookupstart>
31    domain_lookup_start: Cell<u64>,
32    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-domainlookupend>
33    domain_lookup_end: Cell<u64>,
34    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-connectstart>
35    connect_start: Cell<u64>,
36    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-connectend>
37    connect_end: Cell<u64>,
38    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-secureconnectstart>
39    secure_connection_start: Cell<u64>,
40    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-requeststart>
41    request_start: Cell<u64>,
42    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-responsestart>
43    response_start: Cell<u64>,
44    /// <https://www.w3.org/TR/navigation-timing/#dom-performancetiming-responseend>
45    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        // From <https://www.w3.org/TR/navigation-timing/#terminology>:
81        // Throughout this work, time is measured in milliseconds since midnight of January 1, 1970 (UTC).
82        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    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-navigationstart>
90    fn NavigationStart(&self) -> u64 {
91        Self::instant_to_millis(&self.navigation_timing.navigation_start)
92    }
93
94    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-unloadeventstart
95    fn UnloadEventStart(&self) -> u64 {
96        Self::instant_to_millis(&self.navigation_timing.unload_event_start)
97    }
98
99    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-unloadeventend>
100    fn UnloadEventEnd(&self) -> u64 {
101        Self::instant_to_millis(&self.navigation_timing.unload_event_end)
102    }
103
104    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-redirectstart>
105    fn RedirectStart(&self) -> u64 {
106        self.redirect_start.get()
107    }
108
109    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-redirectend>
110    fn RedirectEnd(&self) -> u64 {
111        self.redirect_end.get()
112    }
113
114    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-fetchstart>
115    fn FetchStart(&self) -> u64 {
116        self.fetch_start.get()
117    }
118
119    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domainlookupstart>
120    fn DomainLookupStart(&self) -> u64 {
121        self.domain_lookup_start.get()
122    }
123
124    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domainlookupend>
125    fn DomainLookupEnd(&self) -> u64 {
126        self.domain_lookup_end.get()
127    }
128
129    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-connectstart>
130    fn ConnectStart(&self) -> u64 {
131        self.connect_start.get()
132    }
133
134    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-connectend>
135    fn ConnectEnd(&self) -> u64 {
136        self.connect_end.get()
137    }
138
139    /// <https://w3c.github.io/navigation-timing#dom-performancetiming-secureconnectionstart>
140    fn SecureConnectionStart(&self) -> u64 {
141        self.secure_connection_start.get()
142    }
143
144    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-requeststart>
145    fn RequestStart(&self) -> u64 {
146        self.request_start.get()
147    }
148
149    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-responsestart>
150    fn ResponseStart(&self) -> u64 {
151        self.response_start.get()
152    }
153
154    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-responseend>
155    fn ResponseEnd(&self) -> u64 {
156        self.response_end.get()
157    }
158
159    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domloading>
160    fn DomLoading(&self) -> u64 {
161        Self::instant_to_millis(&self.navigation_timing.dom_loading)
162    }
163
164    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-dominteractive>
165    fn DomInteractive(&self) -> u64 {
166        Self::instant_to_millis(&self.navigation_timing.dom_interactive)
167    }
168
169    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domcontentloadedeventstart>
170    fn DomContentLoadedEventStart(&self) -> u64 {
171        Self::instant_to_millis(&self.navigation_timing.dom_content_loaded_event_start)
172    }
173
174    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domcontentloadedeventend>
175    fn DomContentLoadedEventEnd(&self) -> u64 {
176        Self::instant_to_millis(&self.navigation_timing.dom_content_loaded_event_end)
177    }
178
179    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-domcomplete>
180    fn DomComplete(&self) -> u64 {
181        Self::instant_to_millis(&self.navigation_timing.dom_complete)
182    }
183
184    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-loadeventstart>
185    fn LoadEventStart(&self) -> u64 {
186        Self::instant_to_millis(&self.navigation_timing.load_event_start)
187    }
188
189    /// <https://w3c.github.io/navigation-timing/#dom-performancetiming-loadeventend>
190    fn LoadEventEnd(&self) -> u64 {
191        Self::instant_to_millis(&self.navigation_timing.load_event_end)
192    }
193}