Skip to main content

script/dom/
navigationpreloadmanager.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::rc::Rc;
6
7use dom_struct::dom_struct;
8use js::jsval::UndefinedValue;
9use script_bindings::reflector::{Reflector, reflect_dom_object};
10
11use crate::dom::bindings::codegen::Bindings::NavigationPreloadManagerBinding::{
12    NavigationPreloadManagerMethods, NavigationPreloadState,
13};
14use crate::dom::bindings::reflector::DomGlobal;
15use crate::dom::bindings::root::{Dom, DomRoot};
16use crate::dom::bindings::str::ByteString;
17use crate::dom::domexception::{DOMErrorName, DOMException};
18use crate::dom::globalscope::GlobalScope;
19use crate::dom::promise::Promise;
20use crate::dom::serviceworkerregistration::ServiceWorkerRegistration;
21use crate::realms::InRealm;
22use crate::script_runtime::CanGc;
23
24#[dom_struct]
25pub(crate) struct NavigationPreloadManager {
26    reflector_: Reflector,
27    serviceworker_registration: Dom<ServiceWorkerRegistration>,
28}
29
30impl NavigationPreloadManager {
31    fn new_inherited(registration: &ServiceWorkerRegistration) -> NavigationPreloadManager {
32        NavigationPreloadManager {
33            reflector_: Reflector::new(),
34            serviceworker_registration: Dom::from_ref(registration),
35        }
36    }
37
38    #[cfg_attr(crown, expect(crown::unrooted_must_root))]
39    pub(crate) fn new(
40        global: &GlobalScope,
41        registration: &ServiceWorkerRegistration,
42        can_gc: CanGc,
43    ) -> DomRoot<NavigationPreloadManager> {
44        let manager = NavigationPreloadManager::new_inherited(registration);
45        reflect_dom_object(Box::new(manager), global, can_gc)
46    }
47}
48
49impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreloadManager {
50    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable>
51    fn Enable(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
52        let promise = Promise::new_in_current_realm(comp, can_gc);
53
54        // 2.
55        if self.serviceworker_registration.is_active() {
56            promise.reject_native(
57                &DOMException::new(&self.global(), DOMErrorName::InvalidStateError, can_gc),
58                can_gc,
59            );
60        } else {
61            // 3.
62            self.serviceworker_registration
63                .set_navigation_preload_enabled(true);
64
65            // 4.
66            promise.resolve_native(&UndefinedValue(), can_gc);
67        }
68
69        promise
70    }
71
72    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-disable>
73    fn Disable(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
74        let promise = Promise::new_in_current_realm(comp, can_gc);
75
76        // 2.
77        if self.serviceworker_registration.is_active() {
78            promise.reject_native(
79                &DOMException::new(&self.global(), DOMErrorName::InvalidStateError, can_gc),
80                can_gc,
81            );
82        } else {
83            // 3.
84            self.serviceworker_registration
85                .set_navigation_preload_enabled(false);
86
87            // 4.
88            promise.resolve_native(&UndefinedValue(), can_gc);
89        }
90
91        promise
92    }
93
94    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-setheadervalue>
95    fn SetHeaderValue(&self, value: ByteString, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
96        let promise = Promise::new_in_current_realm(comp, can_gc);
97
98        // 2.
99        if self.serviceworker_registration.is_active() {
100            promise.reject_native(
101                &DOMException::new(&self.global(), DOMErrorName::InvalidStateError, can_gc),
102                can_gc,
103            );
104        } else {
105            // 3.
106            self.serviceworker_registration
107                .set_navigation_preload_header_value(value);
108
109            // 4.
110            promise.resolve_native(&UndefinedValue(), can_gc);
111        }
112
113        promise
114    }
115
116    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-getstate>
117    fn GetState(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
118        let promise = Promise::new_in_current_realm(comp, can_gc);
119        // 2.
120        let mut state = NavigationPreloadState::empty();
121
122        // 3.
123        if self.serviceworker_registration.is_active() &&
124            self.serviceworker_registration
125                .get_navigation_preload_enabled()
126        {
127            state.enabled = true;
128        }
129
130        // 4.
131        state.headerValue = self
132            .serviceworker_registration
133            .get_navigation_preload_header_value();
134
135        // 5.
136        promise.resolve_native(&state, can_gc);
137
138        promise
139    }
140}