mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 887364 - URL API for Workers. r=khuey
This commit is contained in:
parent
4715ba2404
commit
5300eb05e8
@ -26,6 +26,10 @@ class MediaSource;
|
||||
class GlobalObject;
|
||||
struct objectURLOptions;
|
||||
|
||||
namespace workers {
|
||||
class URLProxy;
|
||||
}
|
||||
|
||||
class URL MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
@ -124,6 +128,8 @@ private:
|
||||
|
||||
nsRefPtr<nsPIDOMWindow> mWindow;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
friend class mozilla::dom::workers::URLProxy;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/dom/XMLHttpRequestUploadBinding.h"
|
||||
#include "mozilla/dom/WorkerLocationBinding.h"
|
||||
#include "mozilla/dom/WorkerNavigatorBinding.h"
|
||||
#include "mozilla/dom/URLBinding.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
@ -21,6 +22,7 @@ class XMLHttpRequest;
|
||||
class XMLHttpRequestUpload;
|
||||
class WorkerLocation;
|
||||
class WorkerNavigator;
|
||||
class URL;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -54,6 +56,7 @@ SPECIALIZE_PROTO_TRAITS(XMLHttpRequest)
|
||||
SPECIALIZE_PROTO_TRAITS(XMLHttpRequestUpload)
|
||||
SPECIALIZE_PROTO_TRAITS(WorkerLocation)
|
||||
SPECIALIZE_PROTO_TRAITS(WorkerNavigator)
|
||||
SPECIALIZE_PROTO_TRAITS(URL)
|
||||
|
||||
#undef SPECIALIZE_PROTO_TRAITS
|
||||
|
||||
|
@ -14,14 +14,56 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMFile.h"
|
||||
|
||||
USING_WORKERS_NAMESPACE
|
||||
#include "DOMBindingInlines.h"
|
||||
#include "mozilla/dom/URL.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
using mozilla::dom::GlobalObject;
|
||||
|
||||
// Base class for the Revoke and Create runnable objects.
|
||||
class URLProxy MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
|
||||
|
||||
URLProxy(mozilla::dom::URL* aURL)
|
||||
: mURL(aURL)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
~URLProxy()
|
||||
{
|
||||
MOZ_ASSERT(!mURL);
|
||||
}
|
||||
|
||||
mozilla::dom::URL* URL()
|
||||
{
|
||||
return mURL;
|
||||
}
|
||||
|
||||
nsIURI* URI()
|
||||
{
|
||||
return mURL->GetURI();
|
||||
}
|
||||
|
||||
void ReleaseURI()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mURL = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<mozilla::dom::URL> mURL;
|
||||
};
|
||||
|
||||
// Base class for the URL runnable objects.
|
||||
class URLRunnable : public nsRunnable
|
||||
{
|
||||
protected:
|
||||
@ -225,13 +267,306 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// This class creates a URL object on the main thread.
|
||||
class ConstructorRunnable : public URLRunnable
|
||||
{
|
||||
private:
|
||||
const nsString mURL;
|
||||
|
||||
const nsString mBase;
|
||||
nsRefPtr<URLProxy> mBaseProxy;
|
||||
mozilla::ErrorResult& mRv;
|
||||
|
||||
nsRefPtr<URLProxy> mRetval;
|
||||
|
||||
public:
|
||||
ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aURL, const nsAString& aBase,
|
||||
mozilla::ErrorResult& aRv)
|
||||
: URLRunnable(aWorkerPrivate)
|
||||
, mURL(aURL)
|
||||
, mBase(aBase)
|
||||
, mRv(aRv)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aURL, URLProxy* aBaseProxy,
|
||||
mozilla::ErrorResult& aRv)
|
||||
: URLRunnable(aWorkerPrivate)
|
||||
, mURL(aURL)
|
||||
, mBaseProxy(aBaseProxy)
|
||||
, mRv(aRv)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
void
|
||||
MainThreadRun()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
mRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
|
||||
if (!mBaseProxy) {
|
||||
rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mBase), nullptr, nullptr,
|
||||
getter_AddRefs(baseURL));
|
||||
if (NS_FAILED(rv)) {
|
||||
mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
baseURL = mBaseProxy->URI();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mURL), nullptr, baseURL,
|
||||
getter_AddRefs(url));
|
||||
if (NS_FAILED(rv)) {
|
||||
mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
mRetval = new URLProxy(new mozilla::dom::URL(nullptr, url));
|
||||
}
|
||||
|
||||
URLProxy*
|
||||
GetURLProxy()
|
||||
{
|
||||
return mRetval;
|
||||
}
|
||||
};
|
||||
|
||||
class TeardownRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
TeardownRunnable(URLProxy* aURLProxy)
|
||||
: mURLProxy(aURLProxy)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mURLProxy->ReleaseURI();
|
||||
mURLProxy = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<URLProxy> mURLProxy;
|
||||
};
|
||||
|
||||
// This class is the generic getter for any URL property.
|
||||
class GetterRunnable : public URLRunnable
|
||||
{
|
||||
public:
|
||||
enum GetterType {
|
||||
GetterHref,
|
||||
GetterOrigin,
|
||||
GetterProtocol,
|
||||
GetterUsername,
|
||||
GetterPassword,
|
||||
GetterHost,
|
||||
GetterHostname,
|
||||
GetterPort,
|
||||
GetterPathname,
|
||||
GetterSearch,
|
||||
GetterHash,
|
||||
};
|
||||
|
||||
GetterRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
GetterType aType, nsString& aValue,
|
||||
URLProxy* aURLProxy)
|
||||
: URLRunnable(aWorkerPrivate)
|
||||
, mValue(aValue)
|
||||
, mType(aType)
|
||||
, mURLProxy(aURLProxy)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
void
|
||||
MainThreadRun()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
switch (mType) {
|
||||
case GetterHref:
|
||||
mURLProxy->URL()->GetHref(mValue);
|
||||
break;
|
||||
|
||||
case GetterOrigin:
|
||||
mURLProxy->URL()->GetOrigin(mValue);
|
||||
break;
|
||||
|
||||
case GetterProtocol:
|
||||
mURLProxy->URL()->GetProtocol(mValue);
|
||||
break;
|
||||
|
||||
case GetterUsername:
|
||||
mURLProxy->URL()->GetUsername(mValue);
|
||||
break;
|
||||
|
||||
case GetterPassword:
|
||||
mURLProxy->URL()->GetPassword(mValue);
|
||||
break;
|
||||
|
||||
case GetterHost:
|
||||
mURLProxy->URL()->GetHost(mValue);
|
||||
break;
|
||||
|
||||
case GetterHostname:
|
||||
mURLProxy->URL()->GetHostname(mValue);
|
||||
break;
|
||||
|
||||
case GetterPort:
|
||||
mURLProxy->URL()->GetPort(mValue);
|
||||
break;
|
||||
|
||||
case GetterPathname:
|
||||
mURLProxy->URL()->GetPathname(mValue);
|
||||
break;
|
||||
|
||||
case GetterSearch:
|
||||
mURLProxy->URL()->GetSearch(mValue);
|
||||
break;
|
||||
|
||||
case GetterHash:
|
||||
mURLProxy->URL()->GetHash(mValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsString& mValue;
|
||||
GetterType mType;
|
||||
nsRefPtr<URLProxy> mURLProxy;
|
||||
};
|
||||
|
||||
// This class is the generic setter for any URL property.
|
||||
class SetterRunnable : public URLRunnable
|
||||
{
|
||||
public:
|
||||
enum SetterType {
|
||||
SetterHref,
|
||||
SetterProtocol,
|
||||
SetterUsername,
|
||||
SetterPassword,
|
||||
SetterHost,
|
||||
SetterHostname,
|
||||
SetterPort,
|
||||
SetterPathname,
|
||||
SetterSearch,
|
||||
SetterHash,
|
||||
};
|
||||
|
||||
SetterRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
SetterType aType, const nsAString& aValue,
|
||||
URLProxy* aURLProxy, mozilla::ErrorResult& aRv)
|
||||
: URLRunnable(aWorkerPrivate)
|
||||
, mValue(aValue)
|
||||
, mType(aType)
|
||||
, mURLProxy(aURLProxy)
|
||||
, mRv(aRv)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
void
|
||||
MainThreadRun()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
switch (mType) {
|
||||
case SetterHref:
|
||||
mURLProxy->URL()->SetHref(mValue, mRv);
|
||||
break;
|
||||
|
||||
case SetterProtocol:
|
||||
mURLProxy->URL()->SetProtocol(mValue);
|
||||
break;
|
||||
|
||||
case SetterUsername:
|
||||
mURLProxy->URL()->SetUsername(mValue);
|
||||
break;
|
||||
|
||||
case SetterPassword:
|
||||
mURLProxy->URL()->SetPassword(mValue);
|
||||
break;
|
||||
|
||||
case SetterHost:
|
||||
mURLProxy->URL()->SetHost(mValue);
|
||||
break;
|
||||
|
||||
case SetterHostname:
|
||||
mURLProxy->URL()->SetHostname(mValue);
|
||||
break;
|
||||
|
||||
case SetterPort:
|
||||
mURLProxy->URL()->SetPort(mValue);
|
||||
break;
|
||||
|
||||
case SetterPathname:
|
||||
mURLProxy->URL()->SetPathname(mValue);
|
||||
break;
|
||||
|
||||
case SetterSearch:
|
||||
mURLProxy->URL()->SetSearch(mValue);
|
||||
break;
|
||||
|
||||
case SetterHash:
|
||||
mURLProxy->URL()->SetHash(mValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const nsString mValue;
|
||||
SetterType mType;
|
||||
nsRefPtr<URLProxy> mURLProxy;
|
||||
mozilla::ErrorResult& mRv;
|
||||
};
|
||||
|
||||
// static
|
||||
URL*
|
||||
URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
URL& aBase, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
JSContext* cx = aGlobal.GetContext();
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
|
||||
nsRefPtr<ConstructorRunnable> runnable =
|
||||
new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv);
|
||||
|
||||
if (!runnable->Dispatch(cx)) {
|
||||
JS_ReportPendingException(cx);
|
||||
}
|
||||
|
||||
nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
|
||||
if (!proxy) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<URL> url = new URL(workerPrivate, proxy);
|
||||
|
||||
if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), url)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -239,113 +574,322 @@ URL*
|
||||
URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
const nsAString& aBase, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
JSContext* cx = aGlobal.GetContext();
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
|
||||
nsRefPtr<ConstructorRunnable> runnable =
|
||||
new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv);
|
||||
|
||||
if (!runnable->Dispatch(cx)) {
|
||||
JS_ReportPendingException(cx);
|
||||
}
|
||||
|
||||
nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
|
||||
if (!proxy) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<URL> url = new URL(workerPrivate, proxy);
|
||||
|
||||
if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), url)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
|
||||
: DOMBindingBase(aWorkerPrivate->GetJSContext())
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
, mURLProxy(aURLProxy)
|
||||
{
|
||||
}
|
||||
|
||||
URL::~URL()
|
||||
{
|
||||
if (mURLProxy) {
|
||||
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mURLProxy);
|
||||
mURLProxy = nullptr;
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
NS_ERROR("Failed to dispatch teardown runnable!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::_trace(JSTracer* aTrc)
|
||||
{
|
||||
DOMBindingBase::_trace(aTrc);
|
||||
}
|
||||
|
||||
void
|
||||
URL::_finalize(JSFreeOp* aFop)
|
||||
{
|
||||
DOMBindingBase::_finalize(aFop);
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetHref(nsString& aHref) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
|
||||
mURLProxy, aRv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetOrigin(nsString& aOrigin) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetProtocol(nsString& aProtocol) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetProtocol(const nsAString& aProtocol)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
|
||||
aProtocol, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetUsername(nsString& aUsername) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetUsername(const nsAString& aUsername)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
|
||||
aUsername, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetPassword(nsString& aPassword) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetPassword(const nsAString& aPassword)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
|
||||
aPassword, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetHost(nsString& aHost) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetHost(const nsAString& aHost)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
|
||||
aHost, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetHostname(nsString& aHostname) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetHostname(const nsAString& aHostname)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
|
||||
aHostname, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetPort(nsString& aPort) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetPort(const nsAString& aPort)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
|
||||
aPort, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetPathname(nsString& aPathname) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetPathname(const nsAString& aPathname)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
|
||||
aPathname, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetSearch(nsString& aSearch) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetSearch(const nsAString& aSearch)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
|
||||
aSearch, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::GetHash(nsString& aHash) const
|
||||
{
|
||||
nsRefPtr<GetterRunnable> runnable =
|
||||
new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
|
||||
mURLProxy);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
URL::SetHash(const nsAString& aHash)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsRefPtr<SetterRunnable> runnable =
|
||||
new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
|
||||
aHash, mURLProxy, rv);
|
||||
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
JS_ReportPendingException(mWorkerPrivate->GetJSContext());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@ -399,3 +943,4 @@ URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl)
|
||||
}
|
||||
}
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
@ -7,15 +7,30 @@
|
||||
#ifndef mozilla_dom_workers_url_h__
|
||||
#define mozilla_dom_workers_url_h__
|
||||
|
||||
#include "mozilla/dom/workers/bindings/DOMBindingBase.h"
|
||||
#include "mozilla/dom/URLBinding.h"
|
||||
|
||||
#include "EventTarget.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class URL : public EventTarget
|
||||
class URLProxy;
|
||||
|
||||
class URL MOZ_FINAL : public DOMBindingBase
|
||||
{
|
||||
public: // Methods for WebIDL
|
||||
public:
|
||||
|
||||
URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
|
||||
~URL();
|
||||
|
||||
virtual void
|
||||
_trace(JSTracer* aTrc) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
_finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
|
||||
|
||||
// Methods for WebIDL
|
||||
|
||||
static URL*
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
URL& aBase, ErrorResult& aRv);
|
||||
@ -79,12 +94,13 @@ public: // Methods for WebIDL
|
||||
void SetHash(const nsAString& aHash);
|
||||
|
||||
private:
|
||||
mozilla::dom::URL* GetURL() const
|
||||
URLProxy* GetURLProxy() const
|
||||
{
|
||||
return mURL;
|
||||
return mURLProxy;
|
||||
}
|
||||
|
||||
nsRefPtr<mozilla::dom::URL> mURL;
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsRefPtr<URLProxy> mURLProxy;
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
@ -108,6 +108,8 @@ MOCHITEST_FILES = \
|
||||
url_worker.js \
|
||||
test_bug911085.html \
|
||||
bug911085_worker.js \
|
||||
test_urlApi.html \
|
||||
urlApi_worker.js \
|
||||
$(NULL)
|
||||
|
||||
# Bug 842386 - Disabled on OSX due to intermittent failures.
|
||||
|
45
dom/workers/test/test_urlApi.html
Normal file
45
dom/workers/test/test_urlApi.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for URL API object in workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var worker = new Worker("urlApi_worker.js");
|
||||
|
||||
worker.onmessage = function(event) {
|
||||
is(event.target, worker);
|
||||
|
||||
if (event.data.type == 'finish') {
|
||||
SimpleTest.finish();
|
||||
} else if (event.data.type == 'status') {
|
||||
ok(event.data.status, event.data.msg);
|
||||
}
|
||||
};
|
||||
|
||||
worker.onerror = function(event) {
|
||||
is(event.target, worker);
|
||||
ok(false, "Worker had an error: " + event.data);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
worker.postMessage(true);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
270
dom/workers/test/urlApi_worker.js
Normal file
270
dom/workers/test/urlApi_worker.js
Normal file
@ -0,0 +1,270 @@
|
||||
function ok(a, msg) {
|
||||
dump("OK: " + !!a + " => " + a + " " + msg + "\n");
|
||||
postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n");
|
||||
postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
|
||||
}
|
||||
|
||||
onmessage = function() {
|
||||
status = false;
|
||||
try {
|
||||
if ((URL instanceof Object)) {
|
||||
status = true;
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{ url: 'http://www.abc.com',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://www.abc.com/',
|
||||
origin: 'http://www.abc.com',
|
||||
protocol: 'http:',
|
||||
username: '',
|
||||
password: '',
|
||||
host: 'www.abc.com',
|
||||
hostname: 'www.abc.com',
|
||||
port: '',
|
||||
pathname: '/',
|
||||
search: '',
|
||||
hash: ''
|
||||
},
|
||||
{ url: 'ftp://auser:apw@www.abc.com',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'ftp://auser:apw@www.abc.com/',
|
||||
origin: 'ftp://www.abc.com',
|
||||
protocol: 'ftp:',
|
||||
username: 'auser',
|
||||
password: 'apw',
|
||||
host: 'www.abc.com',
|
||||
hostname: 'www.abc.com',
|
||||
port: '',
|
||||
pathname: '/',
|
||||
search: '',
|
||||
hash: ''
|
||||
},
|
||||
{ url: 'http://www.abc.com:90/apath/',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://www.abc.com:90/apath/',
|
||||
origin: 'http://www.abc.com:90',
|
||||
protocol: 'http:',
|
||||
username: '',
|
||||
password: '',
|
||||
host: 'www.abc.com:90',
|
||||
hostname: 'www.abc.com',
|
||||
port: '90',
|
||||
pathname: '/apath/',
|
||||
search: '',
|
||||
hash: ''
|
||||
},
|
||||
{ url: 'http://www.abc.com/apath/afile.txt#ahash',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://www.abc.com/apath/afile.txt#ahash',
|
||||
origin: 'http://www.abc.com',
|
||||
protocol: 'http:',
|
||||
username: '',
|
||||
password: '',
|
||||
host: 'www.abc.com',
|
||||
hostname: 'www.abc.com',
|
||||
port: '',
|
||||
pathname: '/apath/afile.txt',
|
||||
search: '',
|
||||
hash: '#ahash'
|
||||
},
|
||||
{ url: 'http://example.com/?test#hash',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://example.com/?test#hash',
|
||||
origin: 'http://example.com',
|
||||
protocol: 'http:',
|
||||
username: '',
|
||||
password: '',
|
||||
host: 'example.com',
|
||||
hostname: 'example.com',
|
||||
port: '',
|
||||
pathname: '/',
|
||||
search: '?test',
|
||||
hash: '#hash'
|
||||
},
|
||||
{ url: 'http://example.com/?test',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://example.com/?test',
|
||||
origin: 'http://example.com',
|
||||
protocol: 'http:',
|
||||
username: '',
|
||||
password: '',
|
||||
host: 'example.com',
|
||||
hostname: 'example.com',
|
||||
port: '',
|
||||
pathname: '/',
|
||||
search: '?test',
|
||||
hash: ''
|
||||
},
|
||||
{ url: 'http://example.com/carrot#question%3f',
|
||||
base: undefined,
|
||||
error: false,
|
||||
hash: '#question?'
|
||||
},
|
||||
{ url: 'https://example.com:4443?',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'https:',
|
||||
port: '4443',
|
||||
pathname: '/',
|
||||
hash: '',
|
||||
search: ''
|
||||
},
|
||||
{ url: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
|
||||
protocol: 'http:',
|
||||
pathname: '/apath/afile.txt',
|
||||
hash: '#ahash?asearch',
|
||||
search: ''
|
||||
},
|
||||
{ url: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
|
||||
base: undefined,
|
||||
error: false,
|
||||
href: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
|
||||
protocol: 'http:',
|
||||
pathname: '/apath/afile.txt',
|
||||
hash: '#ahash',
|
||||
search: '?asearch'
|
||||
},
|
||||
{ url: 'http://abc.com/apath/afile.txt?#ahash',
|
||||
base: undefined,
|
||||
error: false,
|
||||
pathname: '/apath/afile.txt',
|
||||
hash: '#ahash',
|
||||
search: ''
|
||||
},
|
||||
{ url: 'http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'http:',
|
||||
username: 'auser',
|
||||
password: 'apassword',
|
||||
host: 'www.abc.com:90',
|
||||
hostname: 'www.abc.com',
|
||||
port: '90',
|
||||
pathname: '/apath/afile.txt',
|
||||
hash: '#ahash',
|
||||
search: '?asearch',
|
||||
origin: 'http://www.abc.com:90'
|
||||
},
|
||||
|
||||
{ url: '/foo#bar',
|
||||
base: 'www.test.org',
|
||||
error: true,
|
||||
},
|
||||
{ url: '/foo#bar',
|
||||
base: null,
|
||||
error: true,
|
||||
},
|
||||
{ url: '/foo#bar',
|
||||
base: 42,
|
||||
error: true,
|
||||
},
|
||||
{ url: 'ftp://ftp.something.net',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'ftp:',
|
||||
},
|
||||
{ url: 'file:///tmp/file',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'file:',
|
||||
},
|
||||
{ url: 'gopher://gopher.something.net',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'gopher:',
|
||||
},
|
||||
{ url: 'ws://ws.something.net',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'ws:',
|
||||
},
|
||||
{ url: 'wss://ws.something.net',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'wss:',
|
||||
},
|
||||
{ url: 'foo://foo.something.net',
|
||||
base: undefined,
|
||||
error: false,
|
||||
protocol: 'foo:',
|
||||
},
|
||||
];
|
||||
|
||||
while(tests.length) {
|
||||
var test = tests.shift();
|
||||
|
||||
var error = false;
|
||||
var url;
|
||||
try {
|
||||
if (test.base) {
|
||||
url = new URL(test.url, test.base);
|
||||
} else {
|
||||
url = new URL(test.url);
|
||||
}
|
||||
} catch(e) {
|
||||
error = true;
|
||||
}
|
||||
|
||||
is(test.error, error, "Error creating URL");
|
||||
if (test.error) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('href' in test) is(url.href, test.href, "href");
|
||||
if ('origin' in test) is(url.origin, test.origin, "origin");
|
||||
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
|
||||
if ('username' in test) is(url.username, test.username, "username");
|
||||
if ('password' in test) is(url.password, test.password, "password");
|
||||
if ('host' in test) is(url.host, test.host, "host");
|
||||
if ('hostname' in test) is(url.hostname, test.hostname, "hostname");
|
||||
if ('port' in test) is(url.port, test.port, "port");
|
||||
if ('pathname' in test) is(url.pathname, test.pathname, "pathname");
|
||||
if ('search' in test) is(url.search, test.search, "search");
|
||||
if ('hash' in test) is(url.hash, test.hash, "hash");
|
||||
|
||||
url = new URL('https://www.example.net/what#foo?bar');
|
||||
ok(url, "Url exists!");
|
||||
|
||||
if ('href' in test) url.href = test.href;
|
||||
if ('protocol' in test) url.protocol = test.protocol;
|
||||
if ('username' in test && test.username) url.username = test.username;
|
||||
if ('password' in test && test.password) url.password = test.password;
|
||||
if ('host' in test) url.host = test.host;
|
||||
if ('hostname' in test) url.hostname = test.hostname;
|
||||
if ('port' in test) url.port = test.port;
|
||||
if ('pathname' in test) url.pathname = test.pathname;
|
||||
if ('search' in test) url.search = test.search;
|
||||
if ('hash' in test) url.hash = test.hash;
|
||||
|
||||
if ('href' in test) is(url.href, test.href, "href");
|
||||
if ('origin' in test) is(url.origin, test.origin, "origin");
|
||||
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
|
||||
if ('username' in test) is(url.username, test.username, "username");
|
||||
if ('password' in test) is(url.password, test.password, "password");
|
||||
if ('host' in test) is(url.host, test.host, "host");
|
||||
if ('hostname' in test) is(test.hostname, url.hostname, "hostname");
|
||||
if ('port' in test) is(test.port, url.port, "port");
|
||||
if ('pathname' in test) is(test.pathname, url.pathname, "pathname");
|
||||
if ('search' in test) is(test.search, url.search, "search");
|
||||
if ('hash' in test) is(test.hash, url.hash, "hash");
|
||||
}
|
||||
|
||||
postMessage({type: 'finish' });
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user