Skip to main content

script/dom/serviceworker/
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::context::JSContext;
9use js::jsval::UndefinedValue;
10use js::realm::CurrentRealm;
11use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
12
13use crate::dom::bindings::codegen::Bindings::NavigationPreloadManagerBinding::{
14    NavigationPreloadManagerMethods, NavigationPreloadState,
15};
16use crate::dom::bindings::reflector::DomGlobal;
17use crate::dom::bindings::root::{Dom, DomRoot};
18use crate::dom::bindings::str::ByteString;
19use crate::dom::domexception::{DOMErrorName, DOMException};
20use crate::dom::globalscope::GlobalScope;
21use crate::dom::promise::Promise;
22use crate::dom::serviceworkerregistration::ServiceWorkerRegistration;
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        cx: &mut JSContext,
41        global: &GlobalScope,
42        registration: &ServiceWorkerRegistration,
43    ) -> DomRoot<NavigationPreloadManager> {
44        let manager = NavigationPreloadManager::new_inherited(registration);
45        reflect_dom_object_with_cx(Box::new(manager), global, cx)
46    }
47}
48
49impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreloadManager {
50    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable>
51    fn Enable(&self, cx: &mut CurrentRealm) -> Rc<Promise> {
52        let promise = Promise::new_in_realm(cx);
53
54        // 2.
55        if self.serviceworker_registration.is_active() {
56            let exception = DOMException::new(cx, &self.global(), DOMErrorName::InvalidStateError);
57            promise.reject_native(cx, &exception);
58        } else {
59            // 3.
60            self.serviceworker_registration
61                .set_navigation_preload_enabled(true);
62
63            // 4.
64            promise.resolve_native(cx, &UndefinedValue());
65        }
66
67        promise
68    }
69
70    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-disable>
71    fn Disable(&self, cx: &mut CurrentRealm) -> Rc<Promise> {
72        let promise = Promise::new_in_realm(cx);
73
74        // 2.
75        if self.serviceworker_registration.is_active() {
76            let exception = DOMException::new(cx, &self.global(), DOMErrorName::InvalidStateError);
77            promise.reject_native(cx, &exception);
78        } else {
79            // 3.
80            self.serviceworker_registration
81                .set_navigation_preload_enabled(false);
82
83            // 4.
84            promise.resolve_native(cx, &UndefinedValue());
85        }
86
87        promise
88    }
89
90    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-setheadervalue>
91    fn SetHeaderValue(&self, cx: &mut CurrentRealm, value: ByteString) -> Rc<Promise> {
92        let promise = Promise::new_in_realm(cx);
93
94        // 2.
95        if self.serviceworker_registration.is_active() {
96            let exception = DOMException::new(cx, &self.global(), DOMErrorName::InvalidStateError);
97            promise.reject_native(cx, &exception);
98        } else {
99            // 3.
100            self.serviceworker_registration
101                .set_navigation_preload_header_value(value);
102
103            // 4.
104            promise.resolve_native(cx, &UndefinedValue());
105        }
106
107        promise
108    }
109
110    /// <https://w3c.github.io/ServiceWorker/#navigation-preload-manager-getstate>
111    fn GetState(&self, cx: &mut CurrentRealm) -> Rc<Promise> {
112        let promise = Promise::new_in_realm(cx);
113        // 2.
114        let mut state = NavigationPreloadState::empty();
115
116        // 3.
117        if self.serviceworker_registration.is_active() &&
118            self.serviceworker_registration
119                .get_navigation_preload_enabled()
120        {
121            state.enabled = true;
122        }
123
124        // 4.
125        state.headerValue = self
126            .serviceworker_registration
127            .get_navigation_preload_header_value();
128
129        // 5.
130        promise.resolve_native(cx, &state);
131
132        promise
133    }
134}