Merge m-c to b2g-inbound.
[gecko.git] / dom / workers / URL.cpp
blobe2f0cb21040fd355329a8fd0aad5091ef5743793
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "URL.h"
7 #include "File.h"
9 #include "WorkerPrivate.h"
10 #include "nsThreadUtils.h"
12 #include "nsPIDOMWindow.h"
13 #include "nsGlobalWindow.h"
14 #include "nsHostObjectProtocolHandler.h"
15 #include "nsServiceManagerUtils.h"
17 #include "nsIDocument.h"
18 #include "nsIDOMFile.h"
20 #include "mozilla/dom/URL.h"
21 #include "mozilla/dom/URLBinding.h"
22 #include "nsIIOService.h"
23 #include "nsNetCID.h"
25 BEGIN_WORKERS_NAMESPACE
26 using mozilla::dom::GlobalObject;
28 class URLProxy MOZ_FINAL
30 public:
31 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
33 URLProxy(mozilla::dom::URL* aURL)
34 : mURL(aURL)
36 AssertIsOnMainThread();
39 ~URLProxy()
41 MOZ_ASSERT(!mURL);
44 mozilla::dom::URL* URL()
46 return mURL;
49 nsIURI* URI()
51 return mURL->GetURI();
54 void ReleaseURI()
56 AssertIsOnMainThread();
57 mURL = nullptr;
60 private:
61 nsRefPtr<mozilla::dom::URL> mURL;
64 // Base class for the URL runnable objects.
65 class URLRunnable : public nsRunnable
67 protected:
68 WorkerPrivate* mWorkerPrivate;
69 uint32_t mSyncQueueKey;
71 private:
72 class ResponseRunnable : public WorkerSyncRunnable
74 uint32_t mSyncQueueKey;
76 public:
77 ResponseRunnable(WorkerPrivate* aWorkerPrivate,
78 uint32_t aSyncQueueKey)
79 : WorkerSyncRunnable(aWorkerPrivate, aSyncQueueKey, false),
80 mSyncQueueKey(aSyncQueueKey)
82 NS_ASSERTION(aWorkerPrivate, "Don't hand me a null WorkerPrivate!");
85 bool
86 WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
88 aWorkerPrivate->StopSyncLoop(mSyncQueueKey, true);
89 return true;
92 bool
93 PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
95 AssertIsOnMainThread();
96 return true;
99 void
100 PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
101 bool aDispatchResult)
103 AssertIsOnMainThread();
107 protected:
108 URLRunnable(WorkerPrivate* aWorkerPrivate)
109 : mWorkerPrivate(aWorkerPrivate)
111 mWorkerPrivate->AssertIsOnWorkerThread();
114 public:
115 bool
116 Dispatch(JSContext* aCx)
118 mWorkerPrivate->AssertIsOnWorkerThread();
119 AutoSyncLoopHolder syncLoop(mWorkerPrivate);
120 mSyncQueueKey = syncLoop.SyncQueueKey();
122 if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
123 JS_ReportError(aCx, "Failed to dispatch to main thread!");
124 return false;
127 return syncLoop.RunAndForget(aCx);
130 private:
131 NS_IMETHOD Run()
133 AssertIsOnMainThread();
135 MainThreadRun();
137 nsRefPtr<ResponseRunnable> response =
138 new ResponseRunnable(mWorkerPrivate, mSyncQueueKey);
139 if (!response->Dispatch(nullptr)) {
140 NS_WARNING("Failed to dispatch response!");
143 return NS_OK;
146 protected:
147 virtual void
148 MainThreadRun() = 0;
151 // This class creates an URL from a DOM Blob on the main thread.
152 class CreateURLRunnable : public URLRunnable
154 private:
155 nsIDOMBlob* mBlob;
156 nsString& mURL;
158 public:
159 CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob,
160 const mozilla::dom::objectURLOptions& aOptions,
161 nsString& aURL)
162 : URLRunnable(aWorkerPrivate),
163 mBlob(aBlob),
164 mURL(aURL)
166 MOZ_ASSERT(aBlob);
169 void
170 MainThreadRun()
172 AssertIsOnMainThread();
174 nsCOMPtr<nsIPrincipal> principal;
175 nsIDocument* doc = nullptr;
177 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
178 if (window) {
179 doc = window->GetExtantDoc();
180 if (!doc) {
181 SetDOMStringToNull(mURL);
182 return;
185 principal = doc->NodePrincipal();
186 } else {
187 MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker());
188 principal = mWorkerPrivate->GetPrincipal();
191 nsCString url;
192 nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
193 NS_LITERAL_CSTRING(BLOBURI_SCHEME),
194 mBlob, principal, url);
196 if (NS_FAILED(rv)) {
197 NS_WARNING("Failed to add data entry for the blob!");
198 SetDOMStringToNull(mURL);
199 return;
202 if (doc) {
203 doc->RegisterHostObjectUri(url);
204 } else {
205 mWorkerPrivate->RegisterHostObjectURI(url);
208 mURL = NS_ConvertUTF8toUTF16(url);
212 // This class revokes an URL on the main thread.
213 class RevokeURLRunnable : public URLRunnable
215 private:
216 const nsString mURL;
218 public:
219 RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
220 const nsAString& aURL)
221 : URLRunnable(aWorkerPrivate),
222 mURL(aURL)
225 void
226 MainThreadRun()
228 AssertIsOnMainThread();
230 nsCOMPtr<nsIPrincipal> principal;
231 nsIDocument* doc = nullptr;
233 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
234 if (window) {
235 doc = window->GetExtantDoc();
236 if (!doc) {
237 return;
240 principal = doc->NodePrincipal();
241 } else {
242 MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker());
243 principal = mWorkerPrivate->GetPrincipal();
246 NS_ConvertUTF16toUTF8 url(mURL);
248 nsIPrincipal* urlPrincipal =
249 nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
251 bool subsumes;
252 if (urlPrincipal &&
253 NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
254 subsumes) {
255 if (doc) {
256 doc->UnregisterHostObjectUri(url);
259 nsHostObjectProtocolHandler::RemoveDataEntry(url);
262 if (!window) {
263 mWorkerPrivate->UnregisterHostObjectURI(url);
268 // This class creates a URL object on the main thread.
269 class ConstructorRunnable : public URLRunnable
271 private:
272 const nsString mURL;
274 const nsString mBase;
275 nsRefPtr<URLProxy> mBaseProxy;
276 mozilla::ErrorResult& mRv;
278 nsRefPtr<URLProxy> mRetval;
280 public:
281 ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
282 const nsAString& aURL, const nsAString& aBase,
283 mozilla::ErrorResult& aRv)
284 : URLRunnable(aWorkerPrivate)
285 , mURL(aURL)
286 , mBase(aBase)
287 , mRv(aRv)
289 mWorkerPrivate->AssertIsOnWorkerThread();
292 ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
293 const nsAString& aURL, URLProxy* aBaseProxy,
294 mozilla::ErrorResult& aRv)
295 : URLRunnable(aWorkerPrivate)
296 , mURL(aURL)
297 , mBaseProxy(aBaseProxy)
298 , mRv(aRv)
300 mWorkerPrivate->AssertIsOnWorkerThread();
303 void
304 MainThreadRun()
306 AssertIsOnMainThread();
308 nsresult rv;
309 nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
310 if (NS_FAILED(rv)) {
311 mRv.Throw(rv);
312 return;
315 nsCOMPtr<nsIURI> baseURL;
317 if (!mBaseProxy) {
318 rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mBase), nullptr, nullptr,
319 getter_AddRefs(baseURL));
320 if (NS_FAILED(rv)) {
321 mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
322 return;
324 } else {
325 baseURL = mBaseProxy->URI();
328 nsCOMPtr<nsIURI> url;
329 rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mURL), nullptr, baseURL,
330 getter_AddRefs(url));
331 if (NS_FAILED(rv)) {
332 mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
333 return;
336 mRetval = new URLProxy(new mozilla::dom::URL(url));
339 URLProxy*
340 GetURLProxy()
342 return mRetval;
346 class TeardownRunnable : public nsRunnable
348 public:
349 TeardownRunnable(URLProxy* aURLProxy)
350 : mURLProxy(aURLProxy)
354 NS_IMETHOD Run()
356 AssertIsOnMainThread();
358 mURLProxy->ReleaseURI();
359 mURLProxy = nullptr;
361 return NS_OK;
364 private:
365 nsRefPtr<URLProxy> mURLProxy;
368 // This class is the generic getter for any URL property.
369 class GetterRunnable : public URLRunnable
371 public:
372 enum GetterType {
373 GetterHref,
374 GetterOrigin,
375 GetterProtocol,
376 GetterUsername,
377 GetterPassword,
378 GetterHost,
379 GetterHostname,
380 GetterPort,
381 GetterPathname,
382 GetterSearch,
383 GetterHash,
386 GetterRunnable(WorkerPrivate* aWorkerPrivate,
387 GetterType aType, nsString& aValue,
388 URLProxy* aURLProxy)
389 : URLRunnable(aWorkerPrivate)
390 , mValue(aValue)
391 , mType(aType)
392 , mURLProxy(aURLProxy)
394 mWorkerPrivate->AssertIsOnWorkerThread();
397 void
398 MainThreadRun()
400 AssertIsOnMainThread();
402 switch (mType) {
403 case GetterHref:
404 mURLProxy->URL()->GetHref(mValue);
405 break;
407 case GetterOrigin:
408 mURLProxy->URL()->GetOrigin(mValue);
409 break;
411 case GetterProtocol:
412 mURLProxy->URL()->GetProtocol(mValue);
413 break;
415 case GetterUsername:
416 mURLProxy->URL()->GetUsername(mValue);
417 break;
419 case GetterPassword:
420 mURLProxy->URL()->GetPassword(mValue);
421 break;
423 case GetterHost:
424 mURLProxy->URL()->GetHost(mValue);
425 break;
427 case GetterHostname:
428 mURLProxy->URL()->GetHostname(mValue);
429 break;
431 case GetterPort:
432 mURLProxy->URL()->GetPort(mValue);
433 break;
435 case GetterPathname:
436 mURLProxy->URL()->GetPathname(mValue);
437 break;
439 case GetterSearch:
440 mURLProxy->URL()->GetSearch(mValue);
441 break;
443 case GetterHash:
444 mURLProxy->URL()->GetHash(mValue);
445 break;
449 private:
450 nsString& mValue;
451 GetterType mType;
452 nsRefPtr<URLProxy> mURLProxy;
455 // This class is the generic setter for any URL property.
456 class SetterRunnable : public URLRunnable
458 public:
459 enum SetterType {
460 SetterHref,
461 SetterProtocol,
462 SetterUsername,
463 SetterPassword,
464 SetterHost,
465 SetterHostname,
466 SetterPort,
467 SetterPathname,
468 SetterSearch,
469 SetterHash,
472 SetterRunnable(WorkerPrivate* aWorkerPrivate,
473 SetterType aType, const nsAString& aValue,
474 URLProxy* aURLProxy, mozilla::ErrorResult& aRv)
475 : URLRunnable(aWorkerPrivate)
476 , mValue(aValue)
477 , mType(aType)
478 , mURLProxy(aURLProxy)
479 , mRv(aRv)
481 mWorkerPrivate->AssertIsOnWorkerThread();
484 void
485 MainThreadRun()
487 AssertIsOnMainThread();
489 switch (mType) {
490 case SetterHref:
491 mURLProxy->URL()->SetHref(mValue, mRv);
492 break;
494 case SetterProtocol:
495 mURLProxy->URL()->SetProtocol(mValue);
496 break;
498 case SetterUsername:
499 mURLProxy->URL()->SetUsername(mValue);
500 break;
502 case SetterPassword:
503 mURLProxy->URL()->SetPassword(mValue);
504 break;
506 case SetterHost:
507 mURLProxy->URL()->SetHost(mValue);
508 break;
510 case SetterHostname:
511 mURLProxy->URL()->SetHostname(mValue);
512 break;
514 case SetterPort:
515 mURLProxy->URL()->SetPort(mValue);
516 break;
518 case SetterPathname:
519 mURLProxy->URL()->SetPathname(mValue);
520 break;
522 case SetterSearch:
523 mURLProxy->URL()->SetSearch(mValue);
524 break;
526 case SetterHash:
527 mURLProxy->URL()->SetHash(mValue);
528 break;
532 private:
533 const nsString mValue;
534 SetterType mType;
535 nsRefPtr<URLProxy> mURLProxy;
536 mozilla::ErrorResult& mRv;
539 // static
540 URL*
541 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
542 URL& aBase, ErrorResult& aRv)
544 JSContext* cx = aGlobal.GetContext();
545 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
547 nsRefPtr<ConstructorRunnable> runnable =
548 new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv);
550 if (!runnable->Dispatch(cx)) {
551 JS_ReportPendingException(cx);
554 nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
555 if (!proxy) {
556 aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
557 return nullptr;
560 return new URL(workerPrivate, proxy);
563 // static
564 URL*
565 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
566 const nsAString& aBase, ErrorResult& aRv)
568 JSContext* cx = aGlobal.GetContext();
569 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
571 nsRefPtr<ConstructorRunnable> runnable =
572 new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv);
574 if (!runnable->Dispatch(cx)) {
575 JS_ReportPendingException(cx);
578 nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
579 if (!proxy) {
580 aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
581 return nullptr;
584 return new URL(workerPrivate, proxy);
587 URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
588 : mWorkerPrivate(aWorkerPrivate)
589 , mURLProxy(aURLProxy)
591 MOZ_COUNT_CTOR(workers::URL);
594 URL::~URL()
596 MOZ_COUNT_DTOR(workers::URL);
598 if (mURLProxy) {
599 nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mURLProxy);
600 mURLProxy = nullptr;
602 if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
603 NS_ERROR("Failed to dispatch teardown runnable!");
608 JSObject*
609 URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope,
610 bool* aTookOwnership)
612 return URLBinding_workers::Wrap(aCx, aScope, this, aTookOwnership);
615 void
616 URL::GetHref(nsString& aHref) const
618 nsRefPtr<GetterRunnable> runnable =
619 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
620 mURLProxy);
622 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
623 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
627 void
628 URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
630 nsRefPtr<SetterRunnable> runnable =
631 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
632 mURLProxy, aRv);
634 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
635 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
639 void
640 URL::GetOrigin(nsString& aOrigin) const
642 nsRefPtr<GetterRunnable> runnable =
643 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
644 mURLProxy);
646 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
647 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
651 void
652 URL::GetProtocol(nsString& aProtocol) const
654 nsRefPtr<GetterRunnable> runnable =
655 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
656 mURLProxy);
658 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
659 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
663 void
664 URL::SetProtocol(const nsAString& aProtocol)
666 ErrorResult rv;
667 nsRefPtr<SetterRunnable> runnable =
668 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
669 aProtocol, mURLProxy, rv);
671 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
672 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
676 void
677 URL::GetUsername(nsString& aUsername) const
679 nsRefPtr<GetterRunnable> runnable =
680 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
681 mURLProxy);
683 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
684 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
688 void
689 URL::SetUsername(const nsAString& aUsername)
691 ErrorResult rv;
692 nsRefPtr<SetterRunnable> runnable =
693 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
694 aUsername, mURLProxy, rv);
696 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
697 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
701 void
702 URL::GetPassword(nsString& aPassword) const
704 nsRefPtr<GetterRunnable> runnable =
705 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
706 mURLProxy);
708 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
709 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
713 void
714 URL::SetPassword(const nsAString& aPassword)
716 ErrorResult rv;
717 nsRefPtr<SetterRunnable> runnable =
718 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
719 aPassword, mURLProxy, rv);
721 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
722 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
726 void
727 URL::GetHost(nsString& aHost) const
729 nsRefPtr<GetterRunnable> runnable =
730 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
731 mURLProxy);
733 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
734 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
738 void
739 URL::SetHost(const nsAString& aHost)
741 ErrorResult rv;
742 nsRefPtr<SetterRunnable> runnable =
743 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
744 aHost, mURLProxy, rv);
746 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
747 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
751 void
752 URL::GetHostname(nsString& aHostname) const
754 nsRefPtr<GetterRunnable> runnable =
755 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
756 mURLProxy);
758 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
759 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
763 void
764 URL::SetHostname(const nsAString& aHostname)
766 ErrorResult rv;
767 nsRefPtr<SetterRunnable> runnable =
768 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
769 aHostname, mURLProxy, rv);
771 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
772 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
776 void
777 URL::GetPort(nsString& aPort) const
779 nsRefPtr<GetterRunnable> runnable =
780 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
781 mURLProxy);
783 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
784 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
788 void
789 URL::SetPort(const nsAString& aPort)
791 ErrorResult rv;
792 nsRefPtr<SetterRunnable> runnable =
793 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
794 aPort, mURLProxy, rv);
796 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
797 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
801 void
802 URL::GetPathname(nsString& aPathname) const
804 nsRefPtr<GetterRunnable> runnable =
805 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname,
806 mURLProxy);
808 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
809 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
813 void
814 URL::SetPathname(const nsAString& aPathname)
816 ErrorResult rv;
817 nsRefPtr<SetterRunnable> runnable =
818 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
819 aPathname, mURLProxy, rv);
821 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
822 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
826 void
827 URL::GetSearch(nsString& aSearch) const
829 nsRefPtr<GetterRunnable> runnable =
830 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
831 mURLProxy);
833 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
834 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
838 void
839 URL::SetSearch(const nsAString& aSearch)
841 ErrorResult rv;
842 nsRefPtr<SetterRunnable> runnable =
843 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
844 aSearch, mURLProxy, rv);
846 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
847 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
851 void
852 URL::GetHash(nsString& aHash) const
854 nsRefPtr<GetterRunnable> runnable =
855 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
856 mURLProxy);
858 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
859 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
863 void
864 URL::SetHash(const nsAString& aHash)
866 ErrorResult rv;
867 nsRefPtr<SetterRunnable> runnable =
868 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
869 aHash, mURLProxy, rv);
871 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
872 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
876 // static
877 void
878 URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob,
879 const mozilla::dom::objectURLOptions& aOptions,
880 nsString& aResult, mozilla::ErrorResult& aRv)
882 JSContext* cx = aGlobal.GetContext();
883 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
885 nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob);
886 if (!blob) {
887 SetDOMStringToNull(aResult);
889 NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL");
890 NS_NAMED_LITERAL_STRING(blobStr, "Blob");
891 aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr);
892 return;
895 nsRefPtr<CreateURLRunnable> runnable =
896 new CreateURLRunnable(workerPrivate, blob, aOptions, aResult);
898 if (!runnable->Dispatch(cx)) {
899 JS_ReportPendingException(cx);
903 // static
904 void
905 URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject& aBlob,
906 const mozilla::dom::objectURLOptions& aOptions,
907 nsString& aResult, mozilla::ErrorResult& aRv)
909 return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv);
912 // static
913 void
914 URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl)
916 JSContext* cx = aGlobal.GetContext();
917 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
919 nsRefPtr<RevokeURLRunnable> runnable =
920 new RevokeURLRunnable(workerPrivate, aUrl);
922 if (!runnable->Dispatch(cx)) {
923 JS_ReportPendingException(cx);
927 END_WORKERS_NAMESPACE