1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/workers/URL.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,969 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "URL.h" 1.10 + 1.11 +#include "nsIDocument.h" 1.12 +#include "nsIDOMFile.h" 1.13 +#include "nsIIOService.h" 1.14 +#include "nsPIDOMWindow.h" 1.15 + 1.16 +#include "mozilla/dom/URL.h" 1.17 +#include "mozilla/dom/URLBinding.h" 1.18 +#include "mozilla/dom/URLSearchParams.h" 1.19 +#include "nsGlobalWindow.h" 1.20 +#include "nsHostObjectProtocolHandler.h" 1.21 +#include "nsNetCID.h" 1.22 +#include "nsServiceManagerUtils.h" 1.23 +#include "nsThreadUtils.h" 1.24 + 1.25 +#include "File.h" 1.26 +#include "WorkerPrivate.h" 1.27 +#include "WorkerRunnable.h" 1.28 + 1.29 +BEGIN_WORKERS_NAMESPACE 1.30 +using mozilla::dom::GlobalObject; 1.31 + 1.32 +class URLProxy MOZ_FINAL 1.33 +{ 1.34 +public: 1.35 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy) 1.36 + 1.37 + URLProxy(mozilla::dom::URL* aURL) 1.38 + : mURL(aURL) 1.39 + { 1.40 + AssertIsOnMainThread(); 1.41 + } 1.42 + 1.43 + mozilla::dom::URL* URL() 1.44 + { 1.45 + return mURL; 1.46 + } 1.47 + 1.48 + nsIURI* URI() 1.49 + { 1.50 + return mURL->GetURI(); 1.51 + } 1.52 + 1.53 + void ReleaseURI() 1.54 + { 1.55 + AssertIsOnMainThread(); 1.56 + mURL = nullptr; 1.57 + } 1.58 + 1.59 +private: 1.60 + // Private destructor, to discourage deletion outside of Release(): 1.61 + ~URLProxy() 1.62 + { 1.63 + MOZ_ASSERT(!mURL); 1.64 + } 1.65 + 1.66 + nsRefPtr<mozilla::dom::URL> mURL; 1.67 +}; 1.68 + 1.69 +// Base class for the URL runnable objects. 1.70 +class URLRunnable : public nsRunnable 1.71 +{ 1.72 +protected: 1.73 + WorkerPrivate* mWorkerPrivate; 1.74 + nsCOMPtr<nsIEventTarget> mSyncLoopTarget; 1.75 + 1.76 +protected: 1.77 + URLRunnable(WorkerPrivate* aWorkerPrivate) 1.78 + : mWorkerPrivate(aWorkerPrivate) 1.79 + { 1.80 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.81 + } 1.82 + 1.83 +public: 1.84 + bool 1.85 + Dispatch(JSContext* aCx) 1.86 + { 1.87 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.88 + 1.89 + AutoSyncLoopHolder syncLoop(mWorkerPrivate); 1.90 + 1.91 + mSyncLoopTarget = syncLoop.EventTarget(); 1.92 + 1.93 + if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) { 1.94 + JS_ReportError(aCx, "Failed to dispatch to main thread!"); 1.95 + return false; 1.96 + } 1.97 + 1.98 + return syncLoop.Run(); 1.99 + } 1.100 + 1.101 +private: 1.102 + NS_IMETHOD Run() 1.103 + { 1.104 + AssertIsOnMainThread(); 1.105 + 1.106 + MainThreadRun(); 1.107 + 1.108 + nsRefPtr<MainThreadStopSyncLoopRunnable> response = 1.109 + new MainThreadStopSyncLoopRunnable(mWorkerPrivate, 1.110 + mSyncLoopTarget.forget(), 1.111 + true); 1.112 + if (!response->Dispatch(nullptr)) { 1.113 + NS_WARNING("Failed to dispatch response!"); 1.114 + } 1.115 + 1.116 + return NS_OK; 1.117 + } 1.118 + 1.119 +protected: 1.120 + virtual void 1.121 + MainThreadRun() = 0; 1.122 +}; 1.123 + 1.124 +// This class creates an URL from a DOM Blob on the main thread. 1.125 +class CreateURLRunnable : public URLRunnable 1.126 +{ 1.127 +private: 1.128 + nsIDOMBlob* mBlob; 1.129 + nsString& mURL; 1.130 + 1.131 +public: 1.132 + CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob, 1.133 + const mozilla::dom::objectURLOptions& aOptions, 1.134 + nsString& aURL) 1.135 + : URLRunnable(aWorkerPrivate), 1.136 + mBlob(aBlob), 1.137 + mURL(aURL) 1.138 + { 1.139 + MOZ_ASSERT(aBlob); 1.140 + } 1.141 + 1.142 + void 1.143 + MainThreadRun() 1.144 + { 1.145 + AssertIsOnMainThread(); 1.146 + 1.147 + nsCOMPtr<nsIPrincipal> principal; 1.148 + nsIDocument* doc = nullptr; 1.149 + 1.150 + nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow(); 1.151 + if (window) { 1.152 + doc = window->GetExtantDoc(); 1.153 + if (!doc) { 1.154 + SetDOMStringToNull(mURL); 1.155 + return; 1.156 + } 1.157 + 1.158 + principal = doc->NodePrincipal(); 1.159 + } else { 1.160 + MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker()); 1.161 + principal = mWorkerPrivate->GetPrincipal(); 1.162 + } 1.163 + 1.164 + nsCString url; 1.165 + nsresult rv = nsHostObjectProtocolHandler::AddDataEntry( 1.166 + NS_LITERAL_CSTRING(BLOBURI_SCHEME), 1.167 + mBlob, principal, url); 1.168 + 1.169 + if (NS_FAILED(rv)) { 1.170 + NS_WARNING("Failed to add data entry for the blob!"); 1.171 + SetDOMStringToNull(mURL); 1.172 + return; 1.173 + } 1.174 + 1.175 + if (doc) { 1.176 + doc->RegisterHostObjectUri(url); 1.177 + } else { 1.178 + mWorkerPrivate->RegisterHostObjectURI(url); 1.179 + } 1.180 + 1.181 + mURL = NS_ConvertUTF8toUTF16(url); 1.182 + } 1.183 +}; 1.184 + 1.185 +// This class revokes an URL on the main thread. 1.186 +class RevokeURLRunnable : public URLRunnable 1.187 +{ 1.188 +private: 1.189 + const nsString mURL; 1.190 + 1.191 +public: 1.192 + RevokeURLRunnable(WorkerPrivate* aWorkerPrivate, 1.193 + const nsAString& aURL) 1.194 + : URLRunnable(aWorkerPrivate), 1.195 + mURL(aURL) 1.196 + {} 1.197 + 1.198 + void 1.199 + MainThreadRun() 1.200 + { 1.201 + AssertIsOnMainThread(); 1.202 + 1.203 + nsCOMPtr<nsIPrincipal> principal; 1.204 + nsIDocument* doc = nullptr; 1.205 + 1.206 + nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow(); 1.207 + if (window) { 1.208 + doc = window->GetExtantDoc(); 1.209 + if (!doc) { 1.210 + return; 1.211 + } 1.212 + 1.213 + principal = doc->NodePrincipal(); 1.214 + } else { 1.215 + MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker()); 1.216 + principal = mWorkerPrivate->GetPrincipal(); 1.217 + } 1.218 + 1.219 + NS_ConvertUTF16toUTF8 url(mURL); 1.220 + 1.221 + nsIPrincipal* urlPrincipal = 1.222 + nsHostObjectProtocolHandler::GetDataEntryPrincipal(url); 1.223 + 1.224 + bool subsumes; 1.225 + if (urlPrincipal && 1.226 + NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) && 1.227 + subsumes) { 1.228 + if (doc) { 1.229 + doc->UnregisterHostObjectUri(url); 1.230 + } 1.231 + 1.232 + nsHostObjectProtocolHandler::RemoveDataEntry(url); 1.233 + } 1.234 + 1.235 + if (!window) { 1.236 + mWorkerPrivate->UnregisterHostObjectURI(url); 1.237 + } 1.238 + } 1.239 +}; 1.240 + 1.241 +// This class creates a URL object on the main thread. 1.242 +class ConstructorRunnable : public URLRunnable 1.243 +{ 1.244 +private: 1.245 + const nsString mURL; 1.246 + 1.247 + const nsString mBase; 1.248 + nsRefPtr<URLProxy> mBaseProxy; 1.249 + mozilla::ErrorResult& mRv; 1.250 + 1.251 + nsRefPtr<URLProxy> mRetval; 1.252 + 1.253 +public: 1.254 + ConstructorRunnable(WorkerPrivate* aWorkerPrivate, 1.255 + const nsAString& aURL, const nsAString& aBase, 1.256 + mozilla::ErrorResult& aRv) 1.257 + : URLRunnable(aWorkerPrivate) 1.258 + , mURL(aURL) 1.259 + , mBase(aBase) 1.260 + , mRv(aRv) 1.261 + { 1.262 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.263 + } 1.264 + 1.265 + ConstructorRunnable(WorkerPrivate* aWorkerPrivate, 1.266 + const nsAString& aURL, URLProxy* aBaseProxy, 1.267 + mozilla::ErrorResult& aRv) 1.268 + : URLRunnable(aWorkerPrivate) 1.269 + , mURL(aURL) 1.270 + , mBaseProxy(aBaseProxy) 1.271 + , mRv(aRv) 1.272 + { 1.273 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.274 + } 1.275 + 1.276 + void 1.277 + MainThreadRun() 1.278 + { 1.279 + AssertIsOnMainThread(); 1.280 + 1.281 + nsresult rv; 1.282 + nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv)); 1.283 + if (NS_FAILED(rv)) { 1.284 + mRv.Throw(rv); 1.285 + return; 1.286 + } 1.287 + 1.288 + nsCOMPtr<nsIURI> baseURL; 1.289 + 1.290 + if (!mBaseProxy) { 1.291 + rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mBase), nullptr, nullptr, 1.292 + getter_AddRefs(baseURL)); 1.293 + if (NS_FAILED(rv)) { 1.294 + mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); 1.295 + return; 1.296 + } 1.297 + } else { 1.298 + baseURL = mBaseProxy->URI(); 1.299 + } 1.300 + 1.301 + nsCOMPtr<nsIURI> url; 1.302 + rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mURL), nullptr, baseURL, 1.303 + getter_AddRefs(url)); 1.304 + if (NS_FAILED(rv)) { 1.305 + mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); 1.306 + return; 1.307 + } 1.308 + 1.309 + mRetval = new URLProxy(new mozilla::dom::URL(url)); 1.310 + } 1.311 + 1.312 + URLProxy* 1.313 + GetURLProxy() 1.314 + { 1.315 + return mRetval; 1.316 + } 1.317 +}; 1.318 + 1.319 +class TeardownURLRunnable : public nsRunnable 1.320 +{ 1.321 +public: 1.322 + TeardownURLRunnable(URLProxy* aURLProxy) 1.323 + : mURLProxy(aURLProxy) 1.324 + { 1.325 + } 1.326 + 1.327 + NS_IMETHOD Run() 1.328 + { 1.329 + AssertIsOnMainThread(); 1.330 + 1.331 + mURLProxy->ReleaseURI(); 1.332 + mURLProxy = nullptr; 1.333 + 1.334 + return NS_OK; 1.335 + } 1.336 + 1.337 +private: 1.338 + nsRefPtr<URLProxy> mURLProxy; 1.339 +}; 1.340 + 1.341 +// This class is the generic getter for any URL property. 1.342 +class GetterRunnable : public URLRunnable 1.343 +{ 1.344 +public: 1.345 + enum GetterType { 1.346 + GetterHref, 1.347 + GetterOrigin, 1.348 + GetterProtocol, 1.349 + GetterUsername, 1.350 + GetterPassword, 1.351 + GetterHost, 1.352 + GetterHostname, 1.353 + GetterPort, 1.354 + GetterPathname, 1.355 + GetterSearch, 1.356 + GetterHash, 1.357 + }; 1.358 + 1.359 + GetterRunnable(WorkerPrivate* aWorkerPrivate, 1.360 + GetterType aType, nsString& aValue, 1.361 + URLProxy* aURLProxy) 1.362 + : URLRunnable(aWorkerPrivate) 1.363 + , mValue(aValue) 1.364 + , mType(aType) 1.365 + , mURLProxy(aURLProxy) 1.366 + { 1.367 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.368 + } 1.369 + 1.370 + void 1.371 + MainThreadRun() 1.372 + { 1.373 + AssertIsOnMainThread(); 1.374 + 1.375 + switch (mType) { 1.376 + case GetterHref: 1.377 + mURLProxy->URL()->GetHref(mValue); 1.378 + break; 1.379 + 1.380 + case GetterOrigin: 1.381 + mURLProxy->URL()->GetOrigin(mValue); 1.382 + break; 1.383 + 1.384 + case GetterProtocol: 1.385 + mURLProxy->URL()->GetProtocol(mValue); 1.386 + break; 1.387 + 1.388 + case GetterUsername: 1.389 + mURLProxy->URL()->GetUsername(mValue); 1.390 + break; 1.391 + 1.392 + case GetterPassword: 1.393 + mURLProxy->URL()->GetPassword(mValue); 1.394 + break; 1.395 + 1.396 + case GetterHost: 1.397 + mURLProxy->URL()->GetHost(mValue); 1.398 + break; 1.399 + 1.400 + case GetterHostname: 1.401 + mURLProxy->URL()->GetHostname(mValue); 1.402 + break; 1.403 + 1.404 + case GetterPort: 1.405 + mURLProxy->URL()->GetPort(mValue); 1.406 + break; 1.407 + 1.408 + case GetterPathname: 1.409 + mURLProxy->URL()->GetPathname(mValue); 1.410 + break; 1.411 + 1.412 + case GetterSearch: 1.413 + mURLProxy->URL()->GetSearch(mValue); 1.414 + break; 1.415 + 1.416 + case GetterHash: 1.417 + mURLProxy->URL()->GetHash(mValue); 1.418 + break; 1.419 + } 1.420 + } 1.421 + 1.422 +private: 1.423 + nsString& mValue; 1.424 + GetterType mType; 1.425 + nsRefPtr<URLProxy> mURLProxy; 1.426 +}; 1.427 + 1.428 +// This class is the generic setter for any URL property. 1.429 +class SetterRunnable : public URLRunnable 1.430 +{ 1.431 +public: 1.432 + enum SetterType { 1.433 + SetterHref, 1.434 + SetterProtocol, 1.435 + SetterUsername, 1.436 + SetterPassword, 1.437 + SetterHost, 1.438 + SetterHostname, 1.439 + SetterPort, 1.440 + SetterPathname, 1.441 + SetterSearch, 1.442 + SetterHash, 1.443 + }; 1.444 + 1.445 + SetterRunnable(WorkerPrivate* aWorkerPrivate, 1.446 + SetterType aType, const nsAString& aValue, 1.447 + URLProxy* aURLProxy, mozilla::ErrorResult& aRv) 1.448 + : URLRunnable(aWorkerPrivate) 1.449 + , mValue(aValue) 1.450 + , mType(aType) 1.451 + , mURLProxy(aURLProxy) 1.452 + , mRv(aRv) 1.453 + { 1.454 + mWorkerPrivate->AssertIsOnWorkerThread(); 1.455 + } 1.456 + 1.457 + void 1.458 + MainThreadRun() 1.459 + { 1.460 + AssertIsOnMainThread(); 1.461 + 1.462 + switch (mType) { 1.463 + case SetterHref: 1.464 + mURLProxy->URL()->SetHref(mValue, mRv); 1.465 + break; 1.466 + 1.467 + case SetterProtocol: 1.468 + mURLProxy->URL()->SetProtocol(mValue); 1.469 + break; 1.470 + 1.471 + case SetterUsername: 1.472 + mURLProxy->URL()->SetUsername(mValue); 1.473 + break; 1.474 + 1.475 + case SetterPassword: 1.476 + mURLProxy->URL()->SetPassword(mValue); 1.477 + break; 1.478 + 1.479 + case SetterHost: 1.480 + mURLProxy->URL()->SetHost(mValue); 1.481 + break; 1.482 + 1.483 + case SetterHostname: 1.484 + mURLProxy->URL()->SetHostname(mValue); 1.485 + break; 1.486 + 1.487 + case SetterPort: 1.488 + mURLProxy->URL()->SetPort(mValue); 1.489 + break; 1.490 + 1.491 + case SetterPathname: 1.492 + mURLProxy->URL()->SetPathname(mValue); 1.493 + break; 1.494 + 1.495 + case SetterSearch: 1.496 + mURLProxy->URL()->SetSearch(mValue); 1.497 + break; 1.498 + 1.499 + case SetterHash: 1.500 + mURLProxy->URL()->SetHash(mValue); 1.501 + break; 1.502 + } 1.503 + } 1.504 + 1.505 +private: 1.506 + const nsString mValue; 1.507 + SetterType mType; 1.508 + nsRefPtr<URLProxy> mURLProxy; 1.509 + mozilla::ErrorResult& mRv; 1.510 +}; 1.511 + 1.512 +NS_IMPL_CYCLE_COLLECTION(URL, mSearchParams) 1.513 + 1.514 +// The reason for using worker::URL is to have different refcnt logging than 1.515 +// for main thread URL. 1.516 +NS_IMPL_CYCLE_COLLECTING_ADDREF(workers::URL) 1.517 +NS_IMPL_CYCLE_COLLECTING_RELEASE(workers::URL) 1.518 + 1.519 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL) 1.520 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.521 +NS_INTERFACE_MAP_END 1.522 + 1.523 +// static 1.524 +URL* 1.525 +URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, 1.526 + URL& aBase, ErrorResult& aRv) 1.527 +{ 1.528 + JSContext* cx = aGlobal.GetContext(); 1.529 + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); 1.530 + 1.531 + nsRefPtr<ConstructorRunnable> runnable = 1.532 + new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv); 1.533 + 1.534 + if (!runnable->Dispatch(cx)) { 1.535 + JS_ReportPendingException(cx); 1.536 + } 1.537 + 1.538 + nsRefPtr<URLProxy> proxy = runnable->GetURLProxy(); 1.539 + if (!proxy) { 1.540 + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); 1.541 + return nullptr; 1.542 + } 1.543 + 1.544 + return new URL(workerPrivate, proxy); 1.545 +} 1.546 + 1.547 +// static 1.548 +URL* 1.549 +URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, 1.550 + const nsAString& aBase, ErrorResult& aRv) 1.551 +{ 1.552 + JSContext* cx = aGlobal.GetContext(); 1.553 + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); 1.554 + 1.555 + nsRefPtr<ConstructorRunnable> runnable = 1.556 + new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv); 1.557 + 1.558 + if (!runnable->Dispatch(cx)) { 1.559 + JS_ReportPendingException(cx); 1.560 + } 1.561 + 1.562 + nsRefPtr<URLProxy> proxy = runnable->GetURLProxy(); 1.563 + if (!proxy) { 1.564 + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); 1.565 + return nullptr; 1.566 + } 1.567 + 1.568 + return new URL(workerPrivate, proxy); 1.569 +} 1.570 + 1.571 +URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy) 1.572 + : mWorkerPrivate(aWorkerPrivate) 1.573 + , mURLProxy(aURLProxy) 1.574 +{ 1.575 + MOZ_COUNT_CTOR(workers::URL); 1.576 +} 1.577 + 1.578 +URL::~URL() 1.579 +{ 1.580 + MOZ_COUNT_DTOR(workers::URL); 1.581 + 1.582 + if (mURLProxy) { 1.583 + nsRefPtr<TeardownURLRunnable> runnable = 1.584 + new TeardownURLRunnable(mURLProxy); 1.585 + mURLProxy = nullptr; 1.586 + 1.587 + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { 1.588 + NS_ERROR("Failed to dispatch teardown runnable!"); 1.589 + } 1.590 + } 1.591 +} 1.592 + 1.593 +JSObject* 1.594 +URL::WrapObject(JSContext* aCx) 1.595 +{ 1.596 + return URLBinding_workers::Wrap(aCx, this); 1.597 +} 1.598 + 1.599 +void 1.600 +URL::GetHref(nsString& aHref) const 1.601 +{ 1.602 + nsRefPtr<GetterRunnable> runnable = 1.603 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref, 1.604 + mURLProxy); 1.605 + 1.606 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.607 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.608 + } 1.609 +} 1.610 + 1.611 +void 1.612 +URL::SetHref(const nsAString& aHref, ErrorResult& aRv) 1.613 +{ 1.614 + nsRefPtr<SetterRunnable> runnable = 1.615 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref, 1.616 + mURLProxy, aRv); 1.617 + 1.618 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.619 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.620 + } 1.621 + 1.622 + UpdateURLSearchParams(); 1.623 +} 1.624 + 1.625 +void 1.626 +URL::GetOrigin(nsString& aOrigin) const 1.627 +{ 1.628 + nsRefPtr<GetterRunnable> runnable = 1.629 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin, 1.630 + mURLProxy); 1.631 + 1.632 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.633 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.634 + } 1.635 +} 1.636 + 1.637 +void 1.638 +URL::GetProtocol(nsString& aProtocol) const 1.639 +{ 1.640 + nsRefPtr<GetterRunnable> runnable = 1.641 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol, 1.642 + mURLProxy); 1.643 + 1.644 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.645 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.646 + } 1.647 +} 1.648 + 1.649 +void 1.650 +URL::SetProtocol(const nsAString& aProtocol) 1.651 +{ 1.652 + ErrorResult rv; 1.653 + nsRefPtr<SetterRunnable> runnable = 1.654 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol, 1.655 + aProtocol, mURLProxy, rv); 1.656 + 1.657 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.658 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.659 + } 1.660 +} 1.661 + 1.662 +void 1.663 +URL::GetUsername(nsString& aUsername) const 1.664 +{ 1.665 + nsRefPtr<GetterRunnable> runnable = 1.666 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername, 1.667 + mURLProxy); 1.668 + 1.669 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.670 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.671 + } 1.672 +} 1.673 + 1.674 +void 1.675 +URL::SetUsername(const nsAString& aUsername) 1.676 +{ 1.677 + ErrorResult rv; 1.678 + nsRefPtr<SetterRunnable> runnable = 1.679 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername, 1.680 + aUsername, mURLProxy, rv); 1.681 + 1.682 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.683 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.684 + } 1.685 +} 1.686 + 1.687 +void 1.688 +URL::GetPassword(nsString& aPassword) const 1.689 +{ 1.690 + nsRefPtr<GetterRunnable> runnable = 1.691 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword, 1.692 + mURLProxy); 1.693 + 1.694 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.695 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.696 + } 1.697 +} 1.698 + 1.699 +void 1.700 +URL::SetPassword(const nsAString& aPassword) 1.701 +{ 1.702 + ErrorResult rv; 1.703 + nsRefPtr<SetterRunnable> runnable = 1.704 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword, 1.705 + aPassword, mURLProxy, rv); 1.706 + 1.707 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.708 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.709 + } 1.710 +} 1.711 + 1.712 +void 1.713 +URL::GetHost(nsString& aHost) const 1.714 +{ 1.715 + nsRefPtr<GetterRunnable> runnable = 1.716 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost, 1.717 + mURLProxy); 1.718 + 1.719 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.720 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.721 + } 1.722 +} 1.723 + 1.724 +void 1.725 +URL::SetHost(const nsAString& aHost) 1.726 +{ 1.727 + ErrorResult rv; 1.728 + nsRefPtr<SetterRunnable> runnable = 1.729 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost, 1.730 + aHost, mURLProxy, rv); 1.731 + 1.732 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.733 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.734 + } 1.735 +} 1.736 + 1.737 +void 1.738 +URL::GetHostname(nsString& aHostname) const 1.739 +{ 1.740 + nsRefPtr<GetterRunnable> runnable = 1.741 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname, 1.742 + mURLProxy); 1.743 + 1.744 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.745 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.746 + } 1.747 +} 1.748 + 1.749 +void 1.750 +URL::SetHostname(const nsAString& aHostname) 1.751 +{ 1.752 + ErrorResult rv; 1.753 + nsRefPtr<SetterRunnable> runnable = 1.754 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname, 1.755 + aHostname, mURLProxy, rv); 1.756 + 1.757 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.758 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.759 + } 1.760 +} 1.761 + 1.762 +void 1.763 +URL::GetPort(nsString& aPort) const 1.764 +{ 1.765 + nsRefPtr<GetterRunnable> runnable = 1.766 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort, 1.767 + mURLProxy); 1.768 + 1.769 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.770 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.771 + } 1.772 +} 1.773 + 1.774 +void 1.775 +URL::SetPort(const nsAString& aPort) 1.776 +{ 1.777 + ErrorResult rv; 1.778 + nsRefPtr<SetterRunnable> runnable = 1.779 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort, 1.780 + aPort, mURLProxy, rv); 1.781 + 1.782 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.783 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.784 + } 1.785 +} 1.786 + 1.787 +void 1.788 +URL::GetPathname(nsString& aPathname) const 1.789 +{ 1.790 + nsRefPtr<GetterRunnable> runnable = 1.791 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname, 1.792 + mURLProxy); 1.793 + 1.794 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.795 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.796 + } 1.797 +} 1.798 + 1.799 +void 1.800 +URL::SetPathname(const nsAString& aPathname) 1.801 +{ 1.802 + ErrorResult rv; 1.803 + nsRefPtr<SetterRunnable> runnable = 1.804 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname, 1.805 + aPathname, mURLProxy, rv); 1.806 + 1.807 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.808 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.809 + } 1.810 +} 1.811 + 1.812 +void 1.813 +URL::GetSearch(nsString& aSearch) const 1.814 +{ 1.815 + nsRefPtr<GetterRunnable> runnable = 1.816 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch, 1.817 + mURLProxy); 1.818 + 1.819 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.820 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.821 + } 1.822 +} 1.823 + 1.824 +void 1.825 +URL::SetSearch(const nsAString& aSearch) 1.826 +{ 1.827 + SetSearchInternal(aSearch); 1.828 + UpdateURLSearchParams(); 1.829 +} 1.830 + 1.831 +void 1.832 +URL::SetSearchInternal(const nsAString& aSearch) 1.833 +{ 1.834 + ErrorResult rv; 1.835 + nsRefPtr<SetterRunnable> runnable = 1.836 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch, 1.837 + aSearch, mURLProxy, rv); 1.838 + 1.839 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.840 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.841 + } 1.842 +} 1.843 + 1.844 +mozilla::dom::URLSearchParams* 1.845 +URL::SearchParams() 1.846 +{ 1.847 + CreateSearchParamsIfNeeded(); 1.848 + return mSearchParams; 1.849 +} 1.850 + 1.851 +void 1.852 +URL::SetSearchParams(URLSearchParams& aSearchParams) 1.853 +{ 1.854 + if (mSearchParams) { 1.855 + mSearchParams->RemoveObserver(this); 1.856 + } 1.857 + 1.858 + mSearchParams = &aSearchParams; 1.859 + mSearchParams->AddObserver(this); 1.860 + 1.861 + nsString search; 1.862 + mSearchParams->Serialize(search); 1.863 + SetSearchInternal(search); 1.864 +} 1.865 + 1.866 +void 1.867 +URL::GetHash(nsString& aHash) const 1.868 +{ 1.869 + nsRefPtr<GetterRunnable> runnable = 1.870 + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash, 1.871 + mURLProxy); 1.872 + 1.873 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.874 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.875 + } 1.876 +} 1.877 + 1.878 +void 1.879 +URL::SetHash(const nsAString& aHash) 1.880 +{ 1.881 + ErrorResult rv; 1.882 + nsRefPtr<SetterRunnable> runnable = 1.883 + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash, 1.884 + aHash, mURLProxy, rv); 1.885 + 1.886 + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { 1.887 + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); 1.888 + } 1.889 +} 1.890 + 1.891 +// static 1.892 +void 1.893 +URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob, 1.894 + const mozilla::dom::objectURLOptions& aOptions, 1.895 + nsString& aResult, mozilla::ErrorResult& aRv) 1.896 +{ 1.897 + JSContext* cx = aGlobal.GetContext(); 1.898 + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); 1.899 + 1.900 + nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob); 1.901 + if (!blob) { 1.902 + SetDOMStringToNull(aResult); 1.903 + 1.904 + NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL"); 1.905 + NS_NAMED_LITERAL_STRING(blobStr, "Blob"); 1.906 + aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr); 1.907 + return; 1.908 + } 1.909 + 1.910 + nsRefPtr<CreateURLRunnable> runnable = 1.911 + new CreateURLRunnable(workerPrivate, blob, aOptions, aResult); 1.912 + 1.913 + if (!runnable->Dispatch(cx)) { 1.914 + JS_ReportPendingException(cx); 1.915 + } 1.916 +} 1.917 + 1.918 +// static 1.919 +void 1.920 +URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject& aBlob, 1.921 + const mozilla::dom::objectURLOptions& aOptions, 1.922 + nsString& aResult, mozilla::ErrorResult& aRv) 1.923 +{ 1.924 + return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv); 1.925 +} 1.926 + 1.927 +// static 1.928 +void 1.929 +URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl) 1.930 +{ 1.931 + JSContext* cx = aGlobal.GetContext(); 1.932 + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); 1.933 + 1.934 + nsRefPtr<RevokeURLRunnable> runnable = 1.935 + new RevokeURLRunnable(workerPrivate, aUrl); 1.936 + 1.937 + if (!runnable->Dispatch(cx)) { 1.938 + JS_ReportPendingException(cx); 1.939 + } 1.940 +} 1.941 + 1.942 +void 1.943 +URL::URLSearchParamsUpdated() 1.944 +{ 1.945 + MOZ_ASSERT(mSearchParams); 1.946 + 1.947 + nsString search; 1.948 + mSearchParams->Serialize(search); 1.949 + SetSearchInternal(search); 1.950 +} 1.951 + 1.952 +void 1.953 +URL::UpdateURLSearchParams() 1.954 +{ 1.955 + if (mSearchParams) { 1.956 + nsString search; 1.957 + GetSearch(search); 1.958 + mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)), this); 1.959 + } 1.960 +} 1.961 + 1.962 +void 1.963 +URL::CreateSearchParamsIfNeeded() 1.964 +{ 1.965 + if (!mSearchParams) { 1.966 + mSearchParams = new URLSearchParams(); 1.967 + mSearchParams->AddObserver(this); 1.968 + UpdateURLSearchParams(); 1.969 + } 1.970 +} 1.971 + 1.972 +END_WORKERS_NAMESPACE