LCOV - code coverage report
Current view: top level - dom/workers - ServiceWorkerWindowClient.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 240 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/.
       6             :  */
       7             : 
       8             : #include "ServiceWorkerWindowClient.h"
       9             : 
      10             : #include "js/Value.h"
      11             : #include "mozilla/Mutex.h"
      12             : #include "mozilla/dom/ClientBinding.h"
      13             : #include "mozilla/dom/Promise.h"
      14             : #include "mozilla/dom/PromiseWorkerProxy.h"
      15             : #include "mozilla/UniquePtr.h"
      16             : #include "nsContentUtils.h"
      17             : #include "nsGlobalWindow.h"
      18             : #include "nsIDocShell.h"
      19             : #include "nsIDocShellLoadInfo.h"
      20             : #include "nsIDocument.h"
      21             : #include "nsIGlobalObject.h"
      22             : #include "nsIPrincipal.h"
      23             : #include "nsIScriptSecurityManager.h"
      24             : #include "nsIWebNavigation.h"
      25             : #include "nsIWebProgress.h"
      26             : #include "nsIWebProgressListener.h"
      27             : #include "nsString.h"
      28             : #include "nsWeakReference.h"
      29             : #include "ServiceWorker.h"
      30             : #include "ServiceWorkerInfo.h"
      31             : #include "ServiceWorkerManager.h"
      32             : #include "WorkerPrivate.h"
      33             : #include "WorkerScope.h"
      34             : 
      35             : using namespace mozilla;
      36             : using namespace mozilla::dom;
      37             : using namespace mozilla::dom::workers;
      38             : 
      39             : using mozilla::UniquePtr;
      40             : 
      41             : JSObject*
      42           0 : ServiceWorkerWindowClient::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
      43             : {
      44           0 :   return WindowClientBinding::Wrap(aCx, this, aGivenProto);
      45             : }
      46             : 
      47             : namespace {
      48             : 
      49           0 : class ResolveOrRejectPromiseRunnable final : public WorkerRunnable
      50             : {
      51             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
      52             :   UniquePtr<ServiceWorkerClientInfo> mClientInfo;
      53             :   nsresult mRv;
      54             : 
      55             : public:
      56             :   // Passing a null clientInfo will resolve the promise with a null value.
      57           0 :   ResolveOrRejectPromiseRunnable(
      58             :     WorkerPrivate* aWorkerPrivate, PromiseWorkerProxy* aPromiseProxy,
      59             :     UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
      60           0 :     : WorkerRunnable(aWorkerPrivate)
      61             :     , mPromiseProxy(aPromiseProxy)
      62           0 :     , mClientInfo(Move(aClientInfo))
      63           0 :     , mRv(NS_OK)
      64             :   {
      65           0 :     AssertIsOnMainThread();
      66           0 :   }
      67             : 
      68             :   // Reject the promise with passed nsresult.
      69           0 :   ResolveOrRejectPromiseRunnable(WorkerPrivate* aWorkerPrivate,
      70             :                                  PromiseWorkerProxy* aPromiseProxy,
      71             :                                  nsresult aRv)
      72           0 :     : WorkerRunnable(aWorkerPrivate)
      73             :     , mPromiseProxy(aPromiseProxy)
      74             :     , mClientInfo(nullptr)
      75           0 :     , mRv(aRv)
      76             :   {
      77           0 :     MOZ_ASSERT(NS_FAILED(aRv));
      78           0 :     AssertIsOnMainThread();
      79           0 :   }
      80             : 
      81             :   bool
      82           0 :   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
      83             :   {
      84           0 :     MOZ_ASSERT(aWorkerPrivate);
      85           0 :     aWorkerPrivate->AssertIsOnWorkerThread();
      86             : 
      87           0 :     RefPtr<Promise> promise = mPromiseProxy->WorkerPromise();
      88           0 :     MOZ_ASSERT(promise);
      89             : 
      90           0 :     if (NS_WARN_IF(NS_FAILED(mRv))) {
      91           0 :       promise->MaybeReject(mRv);
      92           0 :     } else if (mClientInfo) {
      93             :       RefPtr<ServiceWorkerWindowClient> client =
      94           0 :         new ServiceWorkerWindowClient(promise->GetParentObject(), *mClientInfo);
      95           0 :       promise->MaybeResolve(client);
      96             :     } else {
      97           0 :       promise->MaybeResolve(JS::NullHandleValue);
      98             :     }
      99             : 
     100             :     // Release the reference on the worker thread.
     101           0 :     mPromiseProxy->CleanUp();
     102             : 
     103           0 :     return true;
     104             :   }
     105             : };
     106             : 
     107           0 : class ClientFocusRunnable final : public Runnable
     108             : {
     109             :   uint64_t mWindowId;
     110             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
     111             : 
     112             : public:
     113           0 :   ClientFocusRunnable(uint64_t aWindowId, PromiseWorkerProxy* aPromiseProxy)
     114           0 :     : mozilla::Runnable("ClientFocusRunnable")
     115             :     , mWindowId(aWindowId)
     116           0 :     , mPromiseProxy(aPromiseProxy)
     117             :   {
     118           0 :     MOZ_ASSERT(mPromiseProxy);
     119           0 :   }
     120             : 
     121             :   NS_IMETHOD
     122           0 :   Run() override
     123             :   {
     124           0 :     AssertIsOnMainThread();
     125           0 :     nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
     126           0 :     UniquePtr<ServiceWorkerClientInfo> clientInfo;
     127             : 
     128           0 :     if (window) {
     129           0 :       nsCOMPtr<nsIDocument> doc = window->GetDocument();
     130           0 :       if (doc) {
     131           0 :         nsContentUtils::DispatchFocusChromeEvent(window->GetOuterWindow());
     132           0 :         clientInfo.reset(new ServiceWorkerClientInfo(doc));
     133             :       }
     134             :     }
     135             : 
     136           0 :     DispatchResult(Move(clientInfo));
     137           0 :     return NS_OK;
     138             :   }
     139             : 
     140             : private:
     141             :   void
     142           0 :   DispatchResult(UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
     143             :   {
     144           0 :     AssertIsOnMainThread();
     145           0 :     MutexAutoLock lock(mPromiseProxy->Lock());
     146           0 :     if (mPromiseProxy->CleanedUp()) {
     147           0 :       return;
     148             :     }
     149             : 
     150           0 :     RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable;
     151           0 :     if (aClientInfo) {
     152             :       resolveRunnable = new ResolveOrRejectPromiseRunnable(
     153           0 :         mPromiseProxy->GetWorkerPrivate(), mPromiseProxy, Move(aClientInfo));
     154             :     } else {
     155             :       resolveRunnable = new ResolveOrRejectPromiseRunnable(
     156           0 :         mPromiseProxy->GetWorkerPrivate(), mPromiseProxy,
     157           0 :         NS_ERROR_DOM_INVALID_ACCESS_ERR);
     158             :     }
     159             : 
     160           0 :     resolveRunnable->Dispatch();
     161             :   }
     162             : };
     163             : 
     164             : } // namespace
     165             : 
     166             : already_AddRefed<Promise>
     167           0 : ServiceWorkerWindowClient::Focus(ErrorResult& aRv) const
     168             : {
     169           0 :   WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     170           0 :   MOZ_ASSERT(workerPrivate);
     171           0 :   workerPrivate->AssertIsOnWorkerThread();
     172             : 
     173           0 :   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
     174           0 :   MOZ_ASSERT(global);
     175             : 
     176           0 :   RefPtr<Promise> promise = Promise::Create(global, aRv);
     177           0 :   if (NS_WARN_IF(aRv.Failed())) {
     178           0 :     return nullptr;
     179             :   }
     180             : 
     181           0 :   if (workerPrivate->GlobalScope()->WindowInteractionAllowed()) {
     182             :     RefPtr<PromiseWorkerProxy> promiseProxy =
     183           0 :       PromiseWorkerProxy::Create(workerPrivate, promise);
     184           0 :     if (promiseProxy) {
     185           0 :       RefPtr<ClientFocusRunnable> r = new ClientFocusRunnable(mWindowId,
     186           0 :                                                               promiseProxy);
     187           0 :       MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
     188             :     } else {
     189           0 :       promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     190             :     }
     191             : 
     192             :   } else {
     193           0 :     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     194             :   }
     195             : 
     196           0 :   return promise.forget();
     197             : }
     198             : 
     199             : class WebProgressListener final : public nsIWebProgressListener,
     200             :                                   public nsSupportsWeakReference
     201             : {
     202             : public:
     203             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     204           0 :   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebProgressListener,
     205             :                                            nsIWebProgressListener)
     206             : 
     207           0 :   WebProgressListener(PromiseWorkerProxy* aPromiseProxy,
     208             :                       ServiceWorkerPrivate* aServiceWorkerPrivate,
     209             :                       nsPIDOMWindowOuter* aWindow, nsIURI* aBaseURI)
     210           0 :     : mPromiseProxy(aPromiseProxy)
     211             :     , mServiceWorkerPrivate(aServiceWorkerPrivate)
     212             :     , mWindow(aWindow)
     213           0 :     , mBaseURI(aBaseURI)
     214             :   {
     215           0 :     MOZ_ASSERT(aPromiseProxy);
     216           0 :     MOZ_ASSERT(aServiceWorkerPrivate);
     217           0 :     MOZ_ASSERT(aWindow);
     218           0 :     MOZ_ASSERT(aWindow->IsOuterWindow());
     219           0 :     MOZ_ASSERT(aBaseURI);
     220           0 :     AssertIsOnMainThread();
     221             : 
     222           0 :     mServiceWorkerPrivate->StoreISupports(static_cast<nsIWebProgressListener*>(this));
     223           0 :   }
     224             : 
     225             :   NS_IMETHOD
     226           0 :   OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
     227             :                 uint32_t aStateFlags, nsresult aStatus) override
     228             :   {
     229           0 :     if (!(aStateFlags & STATE_IS_DOCUMENT) ||
     230           0 :         !(aStateFlags & (STATE_STOP | STATE_TRANSFERRING))) {
     231           0 :       return NS_OK;
     232             :     }
     233             : 
     234             :     // This is safe because our caller holds a strong ref.
     235           0 :     mServiceWorkerPrivate->RemoveISupports(static_cast<nsIWebProgressListener*>(this));
     236           0 :     aWebProgress->RemoveProgressListener(this);
     237             : 
     238             :     WorkerPrivate* workerPrivate;
     239             : 
     240             :     {
     241           0 :       MutexAutoLock lock(mPromiseProxy->Lock());
     242           0 :       if (mPromiseProxy->CleanedUp()) {
     243           0 :         return NS_OK;
     244             :       }
     245             : 
     246           0 :       workerPrivate = mPromiseProxy->GetWorkerPrivate();
     247             :     }
     248             : 
     249           0 :     nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
     250             : 
     251           0 :     RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable;
     252           0 :     UniquePtr<ServiceWorkerClientInfo> clientInfo;
     253           0 :     if (!doc) {
     254             :       resolveRunnable = new ResolveOrRejectPromiseRunnable(
     255           0 :         workerPrivate, mPromiseProxy, NS_ERROR_TYPE_ERR);
     256           0 :       resolveRunnable->Dispatch();
     257             : 
     258           0 :       return NS_OK;
     259             :     }
     260             : 
     261             :     // Check same origin.
     262             :     nsCOMPtr<nsIScriptSecurityManager> securityManager =
     263           0 :       nsContentUtils::GetSecurityManager();
     264           0 :     nsresult rv = securityManager->CheckSameOriginURI(doc->GetOriginalURI(),
     265           0 :                                                       mBaseURI, false);
     266             : 
     267           0 :     if (NS_SUCCEEDED(rv)) {
     268           0 :       nsContentUtils::DispatchFocusChromeEvent(mWindow->GetOuterWindow());
     269           0 :       clientInfo.reset(new ServiceWorkerClientInfo(doc));
     270             :     }
     271             : 
     272             :     resolveRunnable = new ResolveOrRejectPromiseRunnable(
     273           0 :       workerPrivate, mPromiseProxy, Move(clientInfo));
     274           0 :     resolveRunnable->Dispatch();
     275             : 
     276           0 :     return NS_OK;
     277             :   }
     278             : 
     279             :   NS_IMETHOD
     280           0 :   OnProgressChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
     281             :                    int32_t aCurSelfProgress, int32_t aMaxSelfProgress,
     282             :                    int32_t aCurTotalProgress,
     283             :                    int32_t aMaxTotalProgress) override
     284             :   {
     285           0 :     MOZ_CRASH("Unexpected notification.");
     286             :     return NS_OK;
     287             :   }
     288             : 
     289             :   NS_IMETHOD
     290           0 :   OnLocationChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
     291             :                    nsIURI* aLocation, uint32_t aFlags) override
     292             :   {
     293           0 :     MOZ_CRASH("Unexpected notification.");
     294             :     return NS_OK;
     295             :   }
     296             : 
     297             :   NS_IMETHOD
     298           0 :   OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
     299             :                  nsresult aStatus, const char16_t* aMessage) override
     300             :   {
     301           0 :     MOZ_CRASH("Unexpected notification.");
     302             :     return NS_OK;
     303             :   }
     304             : 
     305             :   NS_IMETHOD
     306           0 :   OnSecurityChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
     307             :                    uint32_t aState) override
     308             :   {
     309           0 :     MOZ_CRASH("Unexpected notification.");
     310             :     return NS_OK;
     311             :   }
     312             : 
     313             : private:
     314           0 :   ~WebProgressListener() {}
     315             : 
     316             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
     317             :   RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
     318             :   nsCOMPtr<nsPIDOMWindowOuter> mWindow;
     319             :   nsCOMPtr<nsIURI> mBaseURI;
     320             : };
     321             : 
     322           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(WebProgressListener)
     323           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(WebProgressListener)
     324           0 : NS_IMPL_CYCLE_COLLECTION(WebProgressListener, mPromiseProxy,
     325             :                          mServiceWorkerPrivate, mWindow)
     326             : 
     327           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebProgressListener)
     328           0 :   NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
     329           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     330           0 : NS_INTERFACE_MAP_END
     331             : 
     332           0 : class ClientNavigateRunnable final : public Runnable
     333             : {
     334             :   uint64_t mWindowId;
     335             :   nsString mUrl;
     336             :   nsCString mBaseUrl;
     337             :   nsString mScope;
     338             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
     339             :   MOZ_INIT_OUTSIDE_CTOR WorkerPrivate* mWorkerPrivate;
     340             : 
     341             : public:
     342           0 :   ClientNavigateRunnable(uint64_t aWindowId,
     343             :                          const nsAString& aUrl,
     344             :                          const nsAString& aScope,
     345             :                          PromiseWorkerProxy* aPromiseProxy)
     346           0 :     : mozilla::Runnable("ClientNavigateRunnable")
     347             :     , mWindowId(aWindowId)
     348             :     , mUrl(aUrl)
     349             :     , mScope(aScope)
     350             :     , mPromiseProxy(aPromiseProxy)
     351           0 :     , mWorkerPrivate(nullptr)
     352             :   {
     353           0 :     MOZ_ASSERT(aPromiseProxy);
     354           0 :     MOZ_ASSERT(aPromiseProxy->GetWorkerPrivate());
     355           0 :     aPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
     356           0 :   }
     357             : 
     358             :   NS_IMETHOD
     359           0 :   Run() override
     360             :   {
     361           0 :     AssertIsOnMainThread();
     362             : 
     363           0 :     nsCOMPtr<nsIPrincipal> principal;
     364             : 
     365             :     {
     366           0 :       MutexAutoLock lock(mPromiseProxy->Lock());
     367           0 :       if (mPromiseProxy->CleanedUp()) {
     368           0 :         return NS_OK;
     369             :       }
     370             : 
     371           0 :       mWorkerPrivate = mPromiseProxy->GetWorkerPrivate();
     372           0 :       WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
     373           0 :       mBaseUrl = info.mHref;
     374           0 :       principal = mWorkerPrivate->GetPrincipal();
     375           0 :       MOZ_DIAGNOSTIC_ASSERT(principal);
     376             :     }
     377             : 
     378           0 :     nsCOMPtr<nsIURI> baseUrl;
     379           0 :     nsCOMPtr<nsIURI> url;
     380           0 :     nsresult rv = ParseUrl(getter_AddRefs(baseUrl), getter_AddRefs(url));
     381             : 
     382           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     383           0 :       return RejectPromise(NS_ERROR_TYPE_ERR);
     384             :     }
     385             : 
     386             :     nsGlobalWindow* window;
     387           0 :     rv = Navigate(url, principal, &window);
     388           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     389           0 :       return RejectPromise(rv);
     390             :     }
     391             : 
     392           0 :     nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
     393           0 :     nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
     394           0 :     if (NS_WARN_IF(!webProgress)) {
     395           0 :       return NS_ERROR_FAILURE;
     396             :     }
     397             : 
     398           0 :     RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     399           0 :     if (!swm) {
     400           0 :       return NS_ERROR_FAILURE;
     401             :     }
     402             : 
     403             :     RefPtr<ServiceWorkerRegistrationInfo> registration =
     404           0 :       swm->GetRegistration(principal, NS_ConvertUTF16toUTF8(mScope));
     405           0 :     if (NS_WARN_IF(!registration)) {
     406           0 :       return NS_ERROR_FAILURE;
     407             :     }
     408             :     RefPtr<ServiceWorkerInfo> serviceWorkerInfo =
     409           0 :       registration->GetServiceWorkerInfoById(mWorkerPrivate->ServiceWorkerID());
     410           0 :     if (NS_WARN_IF(!serviceWorkerInfo)) {
     411           0 :       return NS_ERROR_FAILURE;
     412             :     }
     413             : 
     414             :     nsCOMPtr<nsIWebProgressListener> listener =
     415           0 :       new WebProgressListener(mPromiseProxy, serviceWorkerInfo->WorkerPrivate(),
     416           0 :                               window->GetOuterWindow(), baseUrl);
     417             : 
     418           0 :     rv = webProgress->AddProgressListener(
     419           0 :       listener, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
     420             : 
     421           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     422           0 :       return RejectPromise(rv);
     423             :     }
     424             : 
     425           0 :     return NS_OK;
     426             :   }
     427             : 
     428             : private:
     429             :   nsresult
     430           0 :   RejectPromise(nsresult aRv)
     431             :   {
     432           0 :     MOZ_ASSERT(mWorkerPrivate);
     433             :     RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable =
     434           0 :       new ResolveOrRejectPromiseRunnable(mWorkerPrivate, mPromiseProxy, aRv);
     435             : 
     436           0 :     resolveRunnable->Dispatch();
     437           0 :     return NS_OK;
     438             :   }
     439             : 
     440             :   nsresult
     441             :   ResolvePromise(UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
     442             :   {
     443             :     MOZ_ASSERT(mWorkerPrivate);
     444             :     RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable =
     445             :       new ResolveOrRejectPromiseRunnable(mWorkerPrivate, mPromiseProxy,
     446             :                                          Move(aClientInfo));
     447             : 
     448             :     resolveRunnable->Dispatch();
     449             :     return NS_OK;
     450             :   }
     451             : 
     452             :   nsresult
     453           0 :   ParseUrl(nsIURI** aBaseUrl, nsIURI** aUrl)
     454             :   {
     455           0 :     MOZ_ASSERT(aBaseUrl);
     456           0 :     MOZ_ASSERT(aUrl);
     457           0 :     AssertIsOnMainThread();
     458             : 
     459           0 :     nsCOMPtr<nsIURI> baseUrl;
     460           0 :     nsresult rv = NS_NewURI(getter_AddRefs(baseUrl), mBaseUrl);
     461           0 :     NS_ENSURE_SUCCESS(rv, rv);
     462             : 
     463           0 :     nsCOMPtr<nsIURI> url;
     464           0 :     rv = NS_NewURI(getter_AddRefs(url), mUrl, nullptr, baseUrl);
     465           0 :     NS_ENSURE_SUCCESS(rv, rv);
     466             : 
     467           0 :     baseUrl.forget(aBaseUrl);
     468           0 :     url.forget(aUrl);
     469             : 
     470           0 :     return NS_OK;
     471             :   }
     472             : 
     473             :   nsresult
     474           0 :   Navigate(nsIURI* aUrl, nsIPrincipal* aPrincipal, nsGlobalWindow** aWindow)
     475             :   {
     476           0 :     MOZ_ASSERT(aWindow);
     477             : 
     478           0 :     nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
     479           0 :     if (NS_WARN_IF(!window)) {
     480           0 :       return NS_ERROR_TYPE_ERR;
     481             :     }
     482             : 
     483           0 :     nsCOMPtr<nsIDocument> doc = window->GetDocument();
     484           0 :     if (NS_WARN_IF(!doc)) {
     485           0 :       return NS_ERROR_TYPE_ERR;
     486             :     }
     487             : 
     488           0 :     if (NS_WARN_IF(!doc->IsActive())) {
     489           0 :       return NS_ERROR_TYPE_ERR;
     490             :     }
     491             : 
     492           0 :     nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
     493           0 :     if (NS_WARN_IF(!docShell)) {
     494           0 :       return NS_ERROR_TYPE_ERR;
     495             :     }
     496             : 
     497           0 :     nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
     498           0 :     nsresult rv = docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
     499           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     500           0 :       return NS_ERROR_TYPE_ERR;
     501             :     }
     502             : 
     503           0 :     loadInfo->SetTriggeringPrincipal(aPrincipal);
     504           0 :     loadInfo->SetReferrerPolicy(doc->GetReferrerPolicy());
     505           0 :     loadInfo->SetLoadType(nsIDocShellLoadInfo::loadStopContent);
     506           0 :     loadInfo->SetSourceDocShell(docShell);
     507             :     rv =
     508           0 :       docShell->LoadURI(aUrl, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, true);
     509             : 
     510           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     511           0 :       return NS_ERROR_TYPE_ERR;
     512             :     }
     513             : 
     514           0 :     *aWindow = window;
     515           0 :     return NS_OK;
     516             :   }
     517             : };
     518             : 
     519             : already_AddRefed<Promise>
     520           0 : ServiceWorkerWindowClient::Navigate(const nsAString& aUrl, ErrorResult& aRv)
     521             : {
     522           0 :   WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     523           0 :   MOZ_ASSERT(workerPrivate);
     524           0 :   workerPrivate->AssertIsOnWorkerThread();
     525             : 
     526           0 :   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
     527           0 :   MOZ_ASSERT(global);
     528             : 
     529           0 :   RefPtr<Promise> promise = Promise::Create(global, aRv);
     530           0 :   if (NS_WARN_IF(aRv.Failed())) {
     531           0 :     return nullptr;
     532             :   }
     533             : 
     534           0 :   if (aUrl.EqualsLiteral("about:blank")) {
     535           0 :     promise->MaybeReject(NS_ERROR_TYPE_ERR);
     536           0 :     return promise.forget();
     537             :   }
     538             : 
     539             :   ServiceWorkerGlobalScope* globalScope =
     540           0 :     static_cast<ServiceWorkerGlobalScope*>(workerPrivate->GlobalScope());
     541           0 :   nsString scope;
     542           0 :   globalScope->GetScope(scope);
     543             : 
     544             :   RefPtr<PromiseWorkerProxy> promiseProxy =
     545           0 :     PromiseWorkerProxy::Create(workerPrivate, promise);
     546           0 :   if (promiseProxy) {
     547             :     RefPtr<ClientNavigateRunnable> r =
     548           0 :       new ClientNavigateRunnable(mWindowId, aUrl, scope, promiseProxy);
     549           0 :     MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
     550             :   } else {
     551           0 :     promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     552             :   }
     553             : 
     554           0 :   return promise.forget();
     555             : }

Generated by: LCOV version 1.13