1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "NavigationPreloadManager.h"
8 #include "ServiceWorkerUtils.h"
10 #include "mozilla/StaticPrefs_dom.h"
11 #include "mozilla/dom/NavigationPreloadManagerBinding.h"
12 #include "mozilla/dom/Promise.h"
13 #include "mozilla/dom/ServiceWorker.h"
14 #include "mozilla/ipc/MessageChannel.h"
16 namespace mozilla::dom
{
18 NS_IMPL_CYCLE_COLLECTING_ADDREF(NavigationPreloadManager
)
19 NS_IMPL_CYCLE_COLLECTING_RELEASE(NavigationPreloadManager
)
21 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NavigationPreloadManager
)
22 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
23 NS_INTERFACE_MAP_ENTRY(nsISupports
)
26 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(NavigationPreloadManager
,
27 mServiceWorkerRegistration
)
30 bool NavigationPreloadManager::IsValidHeader(const nsACString
& aHeader
) {
31 return NS_IsReasonableHTTPHeaderValue(aHeader
);
34 bool NavigationPreloadManager::IsEnabled(JSContext
* aCx
, JSObject
* aGlobal
) {
35 return StaticPrefs::dom_serviceWorkers_navigationPreload_enabled() &&
36 ServiceWorkerVisible(aCx
, aGlobal
);
39 NavigationPreloadManager::NavigationPreloadManager(
40 RefPtr
<ServiceWorkerRegistration
>& aServiceWorkerRegistration
)
41 : mServiceWorkerRegistration(aServiceWorkerRegistration
) {}
43 JSObject
* NavigationPreloadManager::WrapObject(
44 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
45 return NavigationPreloadManager_Binding::Wrap(aCx
, this, aGivenProto
);
48 already_AddRefed
<Promise
> NavigationPreloadManager::SetEnabled(
49 bool aEnabled
, ErrorResult
& aError
) {
50 RefPtr
<Promise
> promise
= Promise::Create(GetParentObject(), aError
);
52 if (NS_WARN_IF(aError
.Failed())) {
56 if (!mServiceWorkerRegistration
) {
57 promise
->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR
);
58 return promise
.forget();
61 mServiceWorkerRegistration
->SetNavigationPreloadEnabled(
63 [promise
](bool aSuccess
) {
65 promise
->MaybeResolveWithUndefined();
68 promise
->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR
);
70 [promise
](ErrorResult
&& aRv
) { promise
->MaybeReject(std::move(aRv
)); });
72 return promise
.forget();
75 already_AddRefed
<Promise
> NavigationPreloadManager::Enable(
76 ErrorResult
& aError
) {
77 return SetEnabled(true, aError
);
80 already_AddRefed
<Promise
> NavigationPreloadManager::Disable(
81 ErrorResult
& aError
) {
82 return SetEnabled(false, aError
);
85 already_AddRefed
<Promise
> NavigationPreloadManager::SetHeaderValue(
86 const nsACString
& aHeader
, ErrorResult
& aError
) {
87 RefPtr
<Promise
> promise
= Promise::Create(GetParentObject(), aError
);
89 if (NS_WARN_IF(aError
.Failed())) {
93 if (!IsValidHeader(aHeader
)) {
94 promise
->MaybeRejectWithTypeError
<MSG_INVALID_HEADER_VALUE
>(aHeader
);
95 return promise
.forget();
98 if (!mServiceWorkerRegistration
) {
99 promise
->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR
);
100 return promise
.forget();
103 mServiceWorkerRegistration
->SetNavigationPreloadHeader(
104 nsAutoCString(aHeader
),
105 [promise
](bool aSuccess
) {
107 promise
->MaybeResolveWithUndefined();
110 promise
->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR
);
112 [promise
](ErrorResult
&& aRv
) { promise
->MaybeReject(std::move(aRv
)); });
114 return promise
.forget();
117 already_AddRefed
<Promise
> NavigationPreloadManager::GetState(
118 ErrorResult
& aError
) {
119 RefPtr
<Promise
> promise
= Promise::Create(GetParentObject(), aError
);
121 if (NS_WARN_IF(aError
.Failed())) {
125 if (!mServiceWorkerRegistration
) {
126 promise
->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR
);
127 return promise
.forget();
130 mServiceWorkerRegistration
->GetNavigationPreloadState(
131 [promise
](NavigationPreloadState
&& aState
) {
132 promise
->MaybeResolve(std::move(aState
));
134 [promise
](ErrorResult
&& aRv
) { promise
->MaybeReject(std::move(aRv
)); });
136 return promise
.forget();
139 } // namespace mozilla::dom