Skip to main content

script/dom/performance/
performancenavigationtiming.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 net_traits::{ResourceFetchTiming, ResourceTimingType};
8use script_bindings::reflector::reflect_dom_object_with_cx;
9
10use super::performanceresourcetiming::{InitiatorType, PerformanceResourceTiming};
11use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
12use crate::dom::bindings::codegen::Bindings::PerformanceNavigationTimingBinding::{
13    NavigationTimingType, PerformanceNavigationTimingMethods,
14};
15use crate::dom::bindings::inheritance::Castable;
16use crate::dom::bindings::root::{Dom, DomRoot};
17use crate::dom::document::Document;
18use crate::dom::globalscope::GlobalScope;
19
20#[dom_struct]
21/// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming>
22/// Only the current document resource is included in the performance timeline;
23/// there is only one PerformanceNavigationTiming object in the performance timeline.
24pub(crate) struct PerformanceNavigationTiming {
25    /// <https://w3c.github.io/navigation-timing/#PerformanceResourceTiming>
26    performanceresourcetiming: PerformanceResourceTiming,
27    document: Dom<Document>,
28    nav_type: NavigationTimingType,
29}
30
31impl PerformanceNavigationTiming {
32    fn new_inherited(document: &Document) -> PerformanceNavigationTiming {
33        PerformanceNavigationTiming {
34            performanceresourcetiming: PerformanceResourceTiming::new_inherited(
35                document.url(),
36                InitiatorType::Navigation,
37                document
38                    .resource_fetch_timing()
39                    .as_ref()
40                    .unwrap_or(&ResourceFetchTiming::new(ResourceTimingType::None)),
41            ),
42            document: Dom::from_ref(document),
43            nav_type: NavigationTimingType::Navigate,
44        }
45    }
46
47    pub(crate) fn new(
48        cx: &mut JSContext,
49        global: &GlobalScope,
50        document: &Document,
51    ) -> DomRoot<PerformanceNavigationTiming> {
52        reflect_dom_object_with_cx(
53            Box::new(PerformanceNavigationTiming::new_inherited(document)),
54            global,
55            cx,
56        )
57    }
58}
59
60// https://w3c.github.io/navigation-timing/
61impl PerformanceNavigationTimingMethods<crate::DomTypeHolder> for PerformanceNavigationTiming {
62    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-unloadeventstart>
63    fn UnloadEventStart(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
64        self.upcast::<PerformanceResourceTiming>()
65            .to_dom_high_res_time_stamp(
66                cx,
67                self.document.navigation_timing().unload_event_start.get(),
68            )
69    }
70
71    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-unloadeventend>
72    fn UnloadEventEnd(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
73        self.upcast::<PerformanceResourceTiming>()
74            .to_dom_high_res_time_stamp(
75                cx,
76                self.document.navigation_timing().unload_event_end.get(),
77            )
78    }
79
80    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-dominteractive>
81    fn DomInteractive(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
82        self.upcast::<PerformanceResourceTiming>()
83            .to_dom_high_res_time_stamp(cx, self.document.navigation_timing().dom_interactive.get())
84    }
85
86    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-domcontentloadedeventstart>
87    fn DomContentLoadedEventStart(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
88        self.upcast::<PerformanceResourceTiming>()
89            .to_dom_high_res_time_stamp(
90                cx,
91                self.document
92                    .navigation_timing()
93                    .dom_content_loaded_event_start
94                    .get(),
95            )
96    }
97
98    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-domcontentloadedeventend>
99    fn DomContentLoadedEventEnd(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
100        self.upcast::<PerformanceResourceTiming>()
101            .to_dom_high_res_time_stamp(
102                cx,
103                self.document
104                    .navigation_timing()
105                    .dom_content_loaded_event_end
106                    .get(),
107            )
108    }
109
110    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-domcomplete>
111    fn DomComplete(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
112        self.upcast::<PerformanceResourceTiming>()
113            .to_dom_high_res_time_stamp(cx, self.document.navigation_timing().dom_complete.get())
114    }
115
116    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-loadeventstart>
117    fn LoadEventStart(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
118        self.upcast::<PerformanceResourceTiming>()
119            .to_dom_high_res_time_stamp(
120                cx,
121                self.document.navigation_timing().load_event_start.get(),
122            )
123    }
124
125    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-loadeventend>
126    fn LoadEventEnd(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
127        self.upcast::<PerformanceResourceTiming>()
128            .to_dom_high_res_time_stamp(cx, self.document.navigation_timing().load_event_end.get())
129    }
130
131    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-type>
132    fn Type(&self) -> NavigationTimingType {
133        self.nav_type
134    }
135
136    /// <https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-redirectcount>
137    fn RedirectCount(&self) -> u16 {
138        self.document.get_redirect_count()
139    }
140
141    // check-tidy: no specs after this line
142    // Servo-only timing for when top-level content (not iframes) is complete
143    fn TopLevelDomComplete(&self, cx: &mut JSContext) -> DOMHighResTimeStamp {
144        self.upcast::<PerformanceResourceTiming>()
145            .to_dom_high_res_time_stamp(
146                cx,
147                self.document
148                    .navigation_timing()
149                    .top_level_dom_complete
150                    .get(),
151            )
152    }
153}