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 : }
|