NavigationPreloadManager.cpp (4370B)
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/. */ 6 7 #include "NavigationPreloadManager.h" 8 9 #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" 15 #include "nsNetUtil.h" 16 17 namespace mozilla::dom { 18 19 NS_IMPL_CYCLE_COLLECTING_ADDREF(NavigationPreloadManager) 20 NS_IMPL_CYCLE_COLLECTING_RELEASE(NavigationPreloadManager) 21 22 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NavigationPreloadManager) 23 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 24 NS_INTERFACE_MAP_ENTRY(nsISupports) 25 NS_INTERFACE_MAP_END 26 27 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(NavigationPreloadManager, 28 mServiceWorkerRegistration) 29 30 /* static */ 31 bool NavigationPreloadManager::IsValidHeader(const nsACString& aHeader) { 32 return NS_IsReasonableHTTPHeaderValue(aHeader); 33 } 34 35 bool NavigationPreloadManager::IsEnabled(JSContext* aCx, JSObject* aGlobal) { 36 return StaticPrefs::dom_serviceWorkers_navigationPreload_enabled() && 37 ServiceWorkersEnabled(aCx, aGlobal); 38 } 39 40 NavigationPreloadManager::NavigationPreloadManager( 41 RefPtr<ServiceWorkerRegistration>& aServiceWorkerRegistration) 42 : mServiceWorkerRegistration(aServiceWorkerRegistration) {} 43 44 JSObject* NavigationPreloadManager::WrapObject( 45 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 46 return NavigationPreloadManager_Binding::Wrap(aCx, this, aGivenProto); 47 } 48 49 already_AddRefed<Promise> NavigationPreloadManager::SetEnabled( 50 bool aEnabled, ErrorResult& aError) { 51 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 52 53 if (NS_WARN_IF(aError.Failed())) { 54 return nullptr; 55 } 56 57 if (!mServiceWorkerRegistration) { 58 promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); 59 return promise.forget(); 60 } 61 62 mServiceWorkerRegistration->SetNavigationPreloadEnabled( 63 aEnabled, 64 [promise](bool aSuccess) { 65 if (aSuccess) { 66 promise->MaybeResolveWithUndefined(); 67 return; 68 } 69 promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); 70 }, 71 [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); }); 72 73 return promise.forget(); 74 } 75 76 already_AddRefed<Promise> NavigationPreloadManager::Enable( 77 ErrorResult& aError) { 78 return SetEnabled(true, aError); 79 } 80 81 already_AddRefed<Promise> NavigationPreloadManager::Disable( 82 ErrorResult& aError) { 83 return SetEnabled(false, aError); 84 } 85 86 already_AddRefed<Promise> NavigationPreloadManager::SetHeaderValue( 87 const nsACString& aHeader, ErrorResult& aError) { 88 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 89 90 if (NS_WARN_IF(aError.Failed())) { 91 return nullptr; 92 } 93 94 if (!IsValidHeader(aHeader)) { 95 promise->MaybeRejectWithTypeError<MSG_INVALID_HEADER_VALUE>(aHeader); 96 return promise.forget(); 97 } 98 99 if (!mServiceWorkerRegistration) { 100 promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); 101 return promise.forget(); 102 } 103 104 mServiceWorkerRegistration->SetNavigationPreloadHeader( 105 nsAutoCString(aHeader), 106 [promise](bool aSuccess) { 107 if (aSuccess) { 108 promise->MaybeResolveWithUndefined(); 109 return; 110 } 111 promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); 112 }, 113 [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); }); 114 115 return promise.forget(); 116 } 117 118 already_AddRefed<Promise> NavigationPreloadManager::GetState( 119 ErrorResult& aError) { 120 RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError); 121 122 if (NS_WARN_IF(aError.Failed())) { 123 return nullptr; 124 } 125 126 if (!mServiceWorkerRegistration) { 127 promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); 128 return promise.forget(); 129 } 130 131 mServiceWorkerRegistration->GetNavigationPreloadState( 132 [promise](NavigationPreloadState&& aState) { 133 promise->MaybeResolve(std::move(aState)); 134 }, 135 [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); }); 136 137 return promise.forget(); 138 } 139 140 } // namespace mozilla::dom