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