зеркало из https://github.com/mozilla/pjs.git
Bug 450452 - "Implement XHR ('minus X') for worker threads". r+sr=jst.
This commit is contained in:
Родитель
a04e2e37a1
Коммит
4f737aafd3
|
@ -101,7 +101,7 @@ interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
|
||||||
* you're aware of all the security implications. And then think twice about
|
* you're aware of all the security implications. And then think twice about
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(acda85ab-d06c-4176-b834-6d129ca97ca3)]
|
[scriptable, uuid(ae8f1468-cd7f-4aea-9c40-a3f085db9369)]
|
||||||
interface nsIXMLHttpRequest : nsISupports
|
interface nsIXMLHttpRequest : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -334,78 +334,11 @@ interface nsIXMLHttpRequest : nsISupports
|
||||||
[noscript] void init(in nsIPrincipal principal,
|
[noscript] void init(in nsIPrincipal principal,
|
||||||
in nsIScriptContext scriptContext,
|
in nsIScriptContext scriptContext,
|
||||||
in nsPIDOMWindow ownerWindow);
|
in nsPIDOMWindow ownerWindow);
|
||||||
};
|
|
||||||
|
|
||||||
[scriptable, uuid(6e127bd2-b4c1-4a82-be0d-012bd24efb37)]
|
|
||||||
interface nsIXMLHttpRequestUploadGetter : nsISupports {
|
|
||||||
/**
|
/**
|
||||||
* Upload process can be tracked by adding event listener to |upload|.
|
* Upload process can be tracked by adding event listener to |upload|.
|
||||||
*/
|
*/
|
||||||
readonly attribute nsIXMLHttpRequestUpload upload;
|
readonly attribute nsIXMLHttpRequestUpload upload;
|
||||||
};
|
|
||||||
|
|
||||||
[scriptable, uuid(261676b4-d508-43bf-b099-74635a0ee2e9)]
|
|
||||||
interface nsIJSXMLHttpRequest : nsISupports {
|
|
||||||
/**
|
|
||||||
* Meant to be a script-only mechanism for setting a load event listener.
|
|
||||||
* The attribute is expected to be JavaScript function object. When
|
|
||||||
* the load event occurs, the function is invoked.
|
|
||||||
* This attribute should not be used from native code!!
|
|
||||||
*
|
|
||||||
* After the initial response, all event listeners will be cleared.
|
|
||||||
* // XXXbz what does that mean, exactly?
|
|
||||||
*
|
|
||||||
* Call open() before setting an onload listener.
|
|
||||||
*
|
|
||||||
* Mozilla only.
|
|
||||||
*/
|
|
||||||
attribute nsIDOMEventListener onload;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meant to be a script-only mechanism for setting an error event listener.
|
|
||||||
* The attribute is expected to be JavaScript function object. When
|
|
||||||
* the error event occurs, the function is invoked.
|
|
||||||
* This attribute should not be used from native code!!
|
|
||||||
*
|
|
||||||
* After the initial response, all event listeners will be cleared.
|
|
||||||
* // XXXbz what does that mean, exactly?
|
|
||||||
*
|
|
||||||
* Call open() before setting an onerror listener.
|
|
||||||
*
|
|
||||||
* Mozilla only.
|
|
||||||
*/
|
|
||||||
attribute nsIDOMEventListener onerror;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meant to be a script-only mechanism for setting a progress event listener.
|
|
||||||
* The attribute is expected to be JavaScript function object. When
|
|
||||||
* the error event occurs, the function is invoked.
|
|
||||||
* This attribute should not be used from native code!!
|
|
||||||
* This event listener may be called multiple times during the open request.
|
|
||||||
*
|
|
||||||
* After the initial response, all event listeners will be cleared.
|
|
||||||
* // XXXbz what does that mean, exactly?
|
|
||||||
*
|
|
||||||
* This event listener must be set BEFORE calling open().
|
|
||||||
*
|
|
||||||
* Mozilla only.
|
|
||||||
*/
|
|
||||||
attribute nsIDOMEventListener onprogress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meant to be a script-only mechanism for setting an upload progress event
|
|
||||||
* listener.
|
|
||||||
* This attribute should not be used from native code!!
|
|
||||||
* This event listener may be called multiple times during the upload..
|
|
||||||
*
|
|
||||||
* After the initial response, all event listeners will be cleared.
|
|
||||||
* // XXXbz what does that mean, exactly?
|
|
||||||
*
|
|
||||||
* This event listener must be set BEFORE calling open().
|
|
||||||
*
|
|
||||||
* Mozilla only.
|
|
||||||
*/
|
|
||||||
attribute nsIDOMEventListener onuploadprogress;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Meant to be a script-only mechanism for setting a callback function.
|
* Meant to be a script-only mechanism for setting a callback function.
|
||||||
|
@ -421,6 +354,27 @@ interface nsIJSXMLHttpRequest : nsISupports {
|
||||||
attribute nsIDOMEventListener onreadystatechange;
|
attribute nsIDOMEventListener onreadystatechange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED.
|
||||||
|
*/
|
||||||
|
[scriptable, uuid(261676b4-d508-43bf-b099-74635a0ee2e9)]
|
||||||
|
interface nsIJSXMLHttpRequest : nsISupports {
|
||||||
|
/**
|
||||||
|
* Meant to be a script-only mechanism for setting an upload progress event
|
||||||
|
* listener.
|
||||||
|
* This attribute should not be used from native code!!
|
||||||
|
* This event listener may be called multiple times during the upload..
|
||||||
|
*
|
||||||
|
* After the initial response, all event listeners will be cleared.
|
||||||
|
* // XXXbz what does that mean, exactly?
|
||||||
|
*
|
||||||
|
* This event listener must be set BEFORE calling open().
|
||||||
|
*
|
||||||
|
* Mozilla only.
|
||||||
|
*/
|
||||||
|
attribute nsIDOMEventListener onuploadprogress;
|
||||||
|
};
|
||||||
|
|
||||||
%{ C++
|
%{ C++
|
||||||
#define NS_XMLHTTPREQUEST_CID \
|
#define NS_XMLHTTPREQUEST_CID \
|
||||||
{ /* d164e770-4157-11d4-9a42-000064657374 */ \
|
{ /* d164e770-4157-11d4-9a42-000064657374 */ \
|
||||||
|
|
|
@ -611,8 +611,9 @@ nsXMLHttpRequestUpload::GetContextForEventHandlers(nsIScriptContext** aContext)
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
|
|
||||||
nsXMLHttpRequest::nsXMLHttpRequest()
|
nsXMLHttpRequest::nsXMLHttpRequest()
|
||||||
: mState(XML_HTTP_REQUEST_UNINITIALIZED), mUploadTransferred(0),
|
: mRequestObserver(nsnull), mState(XML_HTTP_REQUEST_UNINITIALIZED),
|
||||||
mUploadTotal(0), mUploadComplete(PR_TRUE), mErrorLoad(PR_FALSE)
|
mUploadTransferred(0), mUploadTotal(0), mUploadComplete(PR_TRUE),
|
||||||
|
mErrorLoad(PR_FALSE), mFirstStartRequestSeen(PR_FALSE)
|
||||||
{
|
{
|
||||||
nsLayoutStatics::AddRef();
|
nsLayoutStatics::AddRef();
|
||||||
}
|
}
|
||||||
|
@ -727,6 +728,12 @@ nsXMLHttpRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXMLHttpRequest::SetRequestObserver(nsIRequestObserver* aObserver)
|
||||||
|
{
|
||||||
|
mRequestObserver = aObserver;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequest)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequest)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||||
|
@ -776,7 +783,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIJSXMLHttpRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIJSXMLHttpRequest)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUploadGetter)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
|
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||||
|
@ -1565,6 +1571,11 @@ IsSameOrBaseChannel(nsIRequest* aPossibleBase, nsIChannel* aChannel)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
{
|
{
|
||||||
|
if (!mFirstStartRequestSeen && mRequestObserver) {
|
||||||
|
mFirstStartRequestSeen = PR_TRUE;
|
||||||
|
mRequestObserver->OnStartRequest(request, ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsSameOrBaseChannel(request, mChannel)) {
|
if (!IsSameOrBaseChannel(request, mChannel)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1785,6 +1796,12 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
|
||||||
|
|
||||||
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
||||||
|
|
||||||
|
if (mRequestObserver && mState & XML_HTTP_REQUEST_GOT_FINAL_STOP) {
|
||||||
|
NS_ASSERTION(mFirstStartRequestSeen, "Inconsistent state!");
|
||||||
|
mFirstStartRequestSeen = PR_FALSE;
|
||||||
|
mRequestObserver->OnStopRequest(request, ctxt, status);
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,8 +165,7 @@ class nsXMLHttpRequest : public nsXHREventTarget,
|
||||||
public nsIProgressEventSink,
|
public nsIProgressEventSink,
|
||||||
public nsIInterfaceRequestor,
|
public nsIInterfaceRequestor,
|
||||||
public nsSupportsWeakReference,
|
public nsSupportsWeakReference,
|
||||||
public nsIJSNativeInitializer,
|
public nsIJSNativeInitializer
|
||||||
public nsIXMLHttpRequestUploadGetter
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsXMLHttpRequest();
|
nsXMLHttpRequest();
|
||||||
|
@ -180,17 +179,12 @@ public:
|
||||||
// nsIJSXMLHttpRequest
|
// nsIJSXMLHttpRequest
|
||||||
NS_IMETHOD GetOnuploadprogress(nsIDOMEventListener** aOnuploadprogress);
|
NS_IMETHOD GetOnuploadprogress(nsIDOMEventListener** aOnuploadprogress);
|
||||||
NS_IMETHOD SetOnuploadprogress(nsIDOMEventListener* aOnuploadprogress);
|
NS_IMETHOD SetOnuploadprogress(nsIDOMEventListener* aOnuploadprogress);
|
||||||
NS_IMETHOD GetOnreadystatechange(nsIDOMEventListener** aOnreadystatechange);
|
|
||||||
NS_IMETHOD SetOnreadystatechange(nsIDOMEventListener* aOnreadystatechange);
|
|
||||||
|
|
||||||
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
|
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
|
||||||
|
|
||||||
// nsIDOMEventListener
|
// nsIDOMEventListener
|
||||||
NS_DECL_NSIDOMEVENTLISTENER
|
NS_DECL_NSIDOMEVENTLISTENER
|
||||||
|
|
||||||
// nsIXMLHttpRequestUploadGetter
|
|
||||||
NS_DECL_NSIXMLHTTPREQUESTUPLOADGETTER
|
|
||||||
|
|
||||||
// nsIDOMLoadListener
|
// nsIDOMLoadListener
|
||||||
NS_IMETHOD Load(nsIDOMEvent* aEvent);
|
NS_IMETHOD Load(nsIDOMEvent* aEvent);
|
||||||
NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent);
|
NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent);
|
||||||
|
@ -250,6 +244,8 @@ public:
|
||||||
// This is called by the factory constructor.
|
// This is called by the factory constructor.
|
||||||
nsresult Init();
|
nsresult Init();
|
||||||
|
|
||||||
|
void SetRequestObserver(nsIRequestObserver* aObserver);
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequest,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequest,
|
||||||
nsXHREventTarget)
|
nsXHREventTarget)
|
||||||
|
|
||||||
|
@ -345,6 +341,8 @@ protected:
|
||||||
nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
|
nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
|
||||||
nsCOMPtr<nsIProgressEventSink> mProgressEventSink;
|
nsCOMPtr<nsIProgressEventSink> mProgressEventSink;
|
||||||
|
|
||||||
|
nsIRequestObserver* mRequestObserver;
|
||||||
|
|
||||||
PRUint32 mState;
|
PRUint32 mState;
|
||||||
|
|
||||||
// List of potentially dangerous headers explicitly set using
|
// List of potentially dangerous headers explicitly set using
|
||||||
|
@ -357,6 +355,8 @@ protected:
|
||||||
PRPackedBool mUploadComplete;
|
PRPackedBool mUploadComplete;
|
||||||
|
|
||||||
PRPackedBool mErrorLoad;
|
PRPackedBool mErrorLoad;
|
||||||
|
|
||||||
|
PRPackedBool mFirstStartRequestSeen;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper class to expose a progress DOM Event
|
// helper class to expose a progress DOM Event
|
||||||
|
|
|
@ -3385,7 +3385,6 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequest)
|
DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequest)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIJSXMLHttpRequest)
|
DOM_CLASSINFO_MAP_ENTRY(nsIJSXMLHttpRequest)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
|
DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestUploadGetter)
|
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor)
|
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
|
@ -68,6 +68,8 @@
|
||||||
|
|
||||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||||
|
|
||||||
|
nsIExceptionProvider* gExceptionProvider = nsnull;
|
||||||
|
|
||||||
nsDOMScriptObjectFactory::nsDOMScriptObjectFactory() :
|
nsDOMScriptObjectFactory::nsDOMScriptObjectFactory() :
|
||||||
mLoadedAllLanguages(PR_FALSE)
|
mLoadedAllLanguages(PR_FALSE)
|
||||||
{
|
{
|
||||||
|
@ -78,18 +80,25 @@ nsDOMScriptObjectFactory::nsDOMScriptObjectFactory() :
|
||||||
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIExceptionService> xs =
|
nsCOMPtr<nsIExceptionProvider> provider(new nsDOMExceptionProvider());
|
||||||
do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
|
if (provider) {
|
||||||
|
nsCOMPtr<nsIExceptionService> xs =
|
||||||
|
do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
|
||||||
|
|
||||||
if (xs) {
|
if (xs) {
|
||||||
xs->RegisterExceptionProvider(this, NS_ERROR_MODULE_DOM);
|
xs->RegisterExceptionProvider(provider, NS_ERROR_MODULE_DOM);
|
||||||
xs->RegisterExceptionProvider(this, NS_ERROR_MODULE_DOM_RANGE);
|
xs->RegisterExceptionProvider(provider, NS_ERROR_MODULE_DOM_RANGE);
|
||||||
#ifdef MOZ_SVG
|
#ifdef MOZ_SVG
|
||||||
xs->RegisterExceptionProvider(this, NS_ERROR_MODULE_SVG);
|
xs->RegisterExceptionProvider(provider, NS_ERROR_MODULE_SVG);
|
||||||
#endif
|
#endif
|
||||||
xs->RegisterExceptionProvider(this, NS_ERROR_MODULE_DOM_XPATH);
|
xs->RegisterExceptionProvider(provider, NS_ERROR_MODULE_DOM_XPATH);
|
||||||
xs->RegisterExceptionProvider(this, NS_ERROR_MODULE_XPCONNECT);
|
xs->RegisterExceptionProvider(provider, NS_ERROR_MODULE_XPCONNECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(!gExceptionProvider, "Registered twice?!");
|
||||||
|
provider.swap(gExceptionProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// And pre-create the javascript language.
|
// And pre-create the javascript language.
|
||||||
NS_CreateJSRuntime(getter_AddRefs(mLanguageArray[NS_STID_INDEX(nsIProgrammingLanguage::JAVASCRIPT)]));
|
NS_CreateJSRuntime(getter_AddRefs(mLanguageArray[NS_STID_INDEX(nsIProgrammingLanguage::JAVASCRIPT)]));
|
||||||
}
|
}
|
||||||
|
@ -97,7 +106,6 @@ nsDOMScriptObjectFactory::nsDOMScriptObjectFactory() :
|
||||||
NS_INTERFACE_MAP_BEGIN(nsDOMScriptObjectFactory)
|
NS_INTERFACE_MAP_BEGIN(nsDOMScriptObjectFactory)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMScriptObjectFactory)
|
NS_INTERFACE_MAP_ENTRY(nsIDOMScriptObjectFactory)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIExceptionProvider)
|
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMScriptObjectFactory)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMScriptObjectFactory)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
@ -287,17 +295,26 @@ nsDOMScriptObjectFactory::Observe(nsISupports *aSubject,
|
||||||
nsGlobalWindow::ShutDown();
|
nsGlobalWindow::ShutDown();
|
||||||
nsDOMClassInfo::ShutDown();
|
nsDOMClassInfo::ShutDown();
|
||||||
|
|
||||||
nsCOMPtr<nsIExceptionService> xs =
|
if (gExceptionProvider) {
|
||||||
do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
|
nsCOMPtr<nsIExceptionService> xs =
|
||||||
|
do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
|
||||||
|
|
||||||
if (xs) {
|
if (xs) {
|
||||||
xs->UnregisterExceptionProvider(this, NS_ERROR_MODULE_DOM);
|
xs->UnregisterExceptionProvider(gExceptionProvider,
|
||||||
xs->UnregisterExceptionProvider(this, NS_ERROR_MODULE_DOM_RANGE);
|
NS_ERROR_MODULE_DOM);
|
||||||
|
xs->UnregisterExceptionProvider(gExceptionProvider,
|
||||||
|
NS_ERROR_MODULE_DOM_RANGE);
|
||||||
#ifdef MOZ_SVG
|
#ifdef MOZ_SVG
|
||||||
xs->UnregisterExceptionProvider(this, NS_ERROR_MODULE_SVG);
|
xs->UnregisterExceptionProvider(gExceptionProvider,
|
||||||
|
NS_ERROR_MODULE_SVG);
|
||||||
#endif
|
#endif
|
||||||
xs->UnregisterExceptionProvider(this, NS_ERROR_MODULE_DOM_XPATH);
|
xs->UnregisterExceptionProvider(gExceptionProvider,
|
||||||
xs->UnregisterExceptionProvider(this, NS_ERROR_MODULE_XPCONNECT);
|
NS_ERROR_MODULE_DOM_XPATH);
|
||||||
|
xs->UnregisterExceptionProvider(gExceptionProvider,
|
||||||
|
NS_ERROR_MODULE_XPCONNECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_RELEASE(gExceptionProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,30 +342,6 @@ CreateXPConnectException(nsresult aResult, nsIException *aDefaultException,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsDOMScriptObjectFactory::GetException(nsresult result,
|
|
||||||
nsIException *aDefaultException,
|
|
||||||
nsIException **_retval)
|
|
||||||
{
|
|
||||||
switch (NS_ERROR_GET_MODULE(result))
|
|
||||||
{
|
|
||||||
case NS_ERROR_MODULE_DOM_RANGE:
|
|
||||||
return NS_NewRangeException(result, aDefaultException, _retval);
|
|
||||||
#ifdef MOZ_SVG
|
|
||||||
case NS_ERROR_MODULE_SVG:
|
|
||||||
return NS_NewSVGException(result, aDefaultException, _retval);
|
|
||||||
#endif
|
|
||||||
case NS_ERROR_MODULE_DOM_XPATH:
|
|
||||||
return NS_NewXPathException(result, aDefaultException, _retval);
|
|
||||||
case NS_ERROR_MODULE_XPCONNECT:
|
|
||||||
return CreateXPConnectException(result, aDefaultException, _retval);
|
|
||||||
case NS_ERROR_MODULE_DOM_FILE:
|
|
||||||
return NS_NewFileException(result, aDefaultException, _retval);
|
|
||||||
default:
|
|
||||||
return NS_NewDOMException(result, aDefaultException, _retval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMScriptObjectFactory::RegisterDOMClassInfo(const char *aName,
|
nsDOMScriptObjectFactory::RegisterDOMClassInfo(const char *aName,
|
||||||
nsDOMClassInfoExternalConstructorFnc aConstructorFptr,
|
nsDOMClassInfoExternalConstructorFnc aConstructorFptr,
|
||||||
|
@ -394,3 +387,31 @@ nsresult NS_GetScriptRuntimeByID(PRUint32 aScriptTypeID,
|
||||||
return rv;
|
return rv;
|
||||||
return factory->GetScriptRuntimeByID(aScriptTypeID, aLanguage);
|
return factory->GetScriptRuntimeByID(aScriptTypeID, aLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsDOMExceptionProvider, nsIExceptionProvider)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMExceptionProvider::GetException(nsresult result,
|
||||||
|
nsIException *aDefaultException,
|
||||||
|
nsIException **_retval)
|
||||||
|
{
|
||||||
|
switch (NS_ERROR_GET_MODULE(result))
|
||||||
|
{
|
||||||
|
case NS_ERROR_MODULE_DOM_RANGE:
|
||||||
|
return NS_NewRangeException(result, aDefaultException, _retval);
|
||||||
|
#ifdef MOZ_SVG
|
||||||
|
case NS_ERROR_MODULE_SVG:
|
||||||
|
return NS_NewSVGException(result, aDefaultException, _retval);
|
||||||
|
#endif
|
||||||
|
case NS_ERROR_MODULE_DOM_XPATH:
|
||||||
|
return NS_NewXPathException(result, aDefaultException, _retval);
|
||||||
|
case NS_ERROR_MODULE_XPCONNECT:
|
||||||
|
return CreateXPConnectException(result, aDefaultException, _retval);
|
||||||
|
case NS_ERROR_MODULE_DOM_FILE:
|
||||||
|
return NS_NewFileException(result, aDefaultException, _retval);
|
||||||
|
default:
|
||||||
|
return NS_NewDOMException(result, aDefaultException, _retval);
|
||||||
|
}
|
||||||
|
NS_NOTREACHED("Not reached");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@
|
||||||
#include "nsIScriptGlobalObject.h" // for misplaced NS_STID_ macros.
|
#include "nsIScriptGlobalObject.h" // for misplaced NS_STID_ macros.
|
||||||
|
|
||||||
class nsDOMScriptObjectFactory : public nsIDOMScriptObjectFactory,
|
class nsDOMScriptObjectFactory : public nsIDOMScriptObjectFactory,
|
||||||
public nsIObserver,
|
public nsIObserver
|
||||||
public nsIExceptionProvider
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsDOMScriptObjectFactory();
|
nsDOMScriptObjectFactory();
|
||||||
|
@ -68,9 +67,6 @@ public:
|
||||||
// nsIObserver
|
// nsIObserver
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
// nsIExceptionProvider
|
|
||||||
NS_DECL_NSIEXCEPTIONPROVIDER
|
|
||||||
|
|
||||||
// nsIDOMScriptObjectFactory
|
// nsIDOMScriptObjectFactory
|
||||||
NS_IMETHOD GetScriptRuntime(const nsAString &aLanguageName,
|
NS_IMETHOD GetScriptRuntime(const nsAString &aLanguageName,
|
||||||
nsIScriptRuntime **aLanguage);
|
nsIScriptRuntime **aLanguage);
|
||||||
|
@ -100,3 +96,10 @@ protected:
|
||||||
PRBool mLoadedAllLanguages;
|
PRBool mLoadedAllLanguages;
|
||||||
nsCOMPtr<nsIScriptRuntime> mLanguageArray[NS_STID_ARRAY_UBOUND];
|
nsCOMPtr<nsIScriptRuntime> mLanguageArray[NS_STID_ARRAY_UBOUND];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class nsDOMExceptionProvider : public nsIExceptionProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIEXCEPTIONPROVIDER
|
||||||
|
};
|
||||||
|
|
|
@ -867,6 +867,14 @@ nsGlobalWindow::FreeInnerObjects(PRBool aClearScope)
|
||||||
// Kill all of the workers for this window.
|
// Kill all of the workers for this window.
|
||||||
nsDOMThreadService* dts = nsDOMThreadService::get();
|
nsDOMThreadService* dts = nsDOMThreadService::get();
|
||||||
if (dts) {
|
if (dts) {
|
||||||
|
nsIScriptContext *scx = GetContextInternal();
|
||||||
|
|
||||||
|
JSContext *cx = scx ? (JSContext *)scx->GetNativeContext() : nsnull;
|
||||||
|
|
||||||
|
// Have to suspend this request here because CancelWorkersForGlobal will
|
||||||
|
// lock until the worker has died and that could cause a deadlock.
|
||||||
|
JSAutoSuspendRequest asr(cx);
|
||||||
|
|
||||||
dts->CancelWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
|
dts->CancelWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,14 @@ FORCE_STATIC_LIB = 1
|
||||||
REQUIRES = \
|
REQUIRES = \
|
||||||
caps \
|
caps \
|
||||||
content \
|
content \
|
||||||
|
gfx \
|
||||||
js \
|
js \
|
||||||
layout \
|
layout \
|
||||||
|
locale \
|
||||||
necko \
|
necko \
|
||||||
pref \
|
pref \
|
||||||
string \
|
string \
|
||||||
|
thebes \
|
||||||
widget \
|
widget \
|
||||||
xpcom \
|
xpcom \
|
||||||
xpconnect \
|
xpconnect \
|
||||||
|
@ -69,10 +72,14 @@ CPPSRCS = \
|
||||||
nsDOMWorkerSecurityManager.cpp \
|
nsDOMWorkerSecurityManager.cpp \
|
||||||
nsDOMWorkerThread.cpp \
|
nsDOMWorkerThread.cpp \
|
||||||
nsDOMWorkerTimeout.cpp \
|
nsDOMWorkerTimeout.cpp \
|
||||||
|
nsDOMWorkerXHR.cpp \
|
||||||
|
nsDOMWorkerXHRProxy.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
LOCAL_INCLUDES = \
|
LOCAL_INCLUDES = \
|
||||||
-I$(topsrcdir)/dom/src/base \
|
-I$(topsrcdir)/dom/src/base \
|
||||||
|
-I$(topsrcdir)/content/base/src \
|
||||||
|
-I$(topsrcdir)/content/events/src \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifdef ENABLE_TESTS
|
ifdef ENABLE_TESTS
|
||||||
|
@ -80,3 +87,5 @@ DIRS += test
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
#CXXFLAGS += $(WARNINGS_AS_ERRORS)
|
||||||
|
|
|
@ -478,6 +478,13 @@ DOMWorkerErrorReporter(JSContext* aCx,
|
||||||
|
|
||||||
nsDOMWorkerThread* worker = (nsDOMWorkerThread*)JS_GetContextPrivate(aCx);
|
nsDOMWorkerThread* worker = (nsDOMWorkerThread*)JS_GetContextPrivate(aCx);
|
||||||
|
|
||||||
|
if (worker->IsCanceled()) {
|
||||||
|
// We don't want to report errors from canceled workers. It's very likely
|
||||||
|
// that we only returned an error in the first place because the worker was
|
||||||
|
// already canceled.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIScriptError> errorObject =
|
nsCOMPtr<nsIScriptError> errorObject =
|
||||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||||
|
|
|
@ -78,6 +78,8 @@ class nsDOMThreadService : public nsIEventTarget,
|
||||||
friend class nsDOMWorkerRunnable;
|
friend class nsDOMWorkerRunnable;
|
||||||
friend class nsDOMWorkerThread;
|
friend class nsDOMWorkerThread;
|
||||||
friend class nsDOMWorkerTimeout;
|
friend class nsDOMWorkerTimeout;
|
||||||
|
friend class nsDOMWorkerXHR;
|
||||||
|
friend class nsDOMWorkerXHRProxy;
|
||||||
friend class nsLayoutStatics;
|
friend class nsLayoutStatics;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -92,12 +92,16 @@ public:
|
||||||
getter_AddRefs(targetIsPool));
|
getter_AddRefs(targetIsPool));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG(("Posting message '%s' from %s [0x%p] to %s [0x%p]",
|
if (!(mTarget->IsCanceled() || mSource->IsCanceled())) {
|
||||||
utf8Message.get(), sourceIsPool ? poolStr : workerStr,
|
LOG(("Posting message '%s' from %s [0x%p] to %s [0x%p]",
|
||||||
static_cast<void*>(mSource.get()), targetIsPool ? poolStr : workerStr,
|
utf8Message.get(),
|
||||||
static_cast<void*>(mTarget.get())));
|
sourceIsPool ? poolStr : workerStr,
|
||||||
|
static_cast<void*>(mSource.get()),
|
||||||
|
targetIsPool ? poolStr : workerStr,
|
||||||
|
static_cast<void*>(mTarget.get())));
|
||||||
|
|
||||||
mTarget->HandleMessage(mMessage, mSource);
|
mTarget->HandleMessage(mMessage, mSource);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "nsDOMWorkerPool.h"
|
#include "nsDOMWorkerPool.h"
|
||||||
|
|
||||||
// Interfaces
|
// Interfaces
|
||||||
|
#include "nsIDocument.h"
|
||||||
#include "nsIDOMClassInfo.h"
|
#include "nsIDOMClassInfo.h"
|
||||||
#include "nsIJSContextStack.h"
|
#include "nsIJSContextStack.h"
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
|
@ -102,15 +103,8 @@ nsDOMWorkerPool::Init()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
// GetCurrentJSContext () can return a null context... We shouldn't
|
nsIScriptGlobalObject* globalObject =
|
||||||
// ever see that here.
|
mParentDocument->GetScriptGlobalObject();
|
||||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
|
||||||
NS_ENSURE_TRUE(cx, NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
|
|
||||||
NS_ENSURE_STATE(scriptContext);
|
|
||||||
|
|
||||||
nsIScriptGlobalObject* globalObject = scriptContext->GetGlobalObject();
|
|
||||||
NS_ENSURE_STATE(globalObject);
|
NS_ENSURE_STATE(globalObject);
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> domWindow(do_QueryInterface(globalObject));
|
nsCOMPtr<nsPIDOMWindow> domWindow(do_QueryInterface(globalObject));
|
||||||
|
@ -237,13 +231,22 @@ nsDOMWorkerPool::ResumeWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument*
|
nsIDocument*
|
||||||
nsDOMWorkerPool::GetParentDocument()
|
nsDOMWorkerPool::ParentDocument()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(),
|
NS_ASSERTION(NS_IsMainThread(),
|
||||||
"Don't touch the non-threadsafe document off the main thread!");
|
"Don't touch the non-threadsafe document off the main thread!");
|
||||||
return mParentDocument;
|
return mParentDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIScriptContext*
|
||||||
|
nsDOMWorkerPool::ScriptContext()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(),
|
||||||
|
"Don't touch the non-threadsafe script context off the main "
|
||||||
|
"thread!");
|
||||||
|
return mParentDocument->GetScriptGlobalObject()->GetContext();
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWorkerPool::PostMessage(const nsAString& aMessage)
|
nsDOMWorkerPool::PostMessage(const nsAString& aMessage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
class nsDOMWorkerThread;
|
class nsDOMWorkerThread;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
|
class nsIScriptContext;
|
||||||
class nsIScriptError;
|
class nsIScriptError;
|
||||||
class nsIScriptGlobalObject;
|
class nsIScriptGlobalObject;
|
||||||
|
|
||||||
|
@ -84,6 +85,9 @@ public:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIDocument* ParentDocument();
|
||||||
|
nsIScriptContext* ScriptContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~nsDOMWorkerPool();
|
virtual ~nsDOMWorkerPool();
|
||||||
|
|
||||||
|
@ -109,8 +113,6 @@ private:
|
||||||
return mMonitor;
|
return mMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument* GetParentDocument();
|
|
||||||
|
|
||||||
// Weak reference to the window that created and owns this pool.
|
// Weak reference to the window that created and owns this pool.
|
||||||
nsISupports* mParentGlobal;
|
nsISupports* mParentGlobal;
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,13 @@ nsDOMWorkerScriptLoader::LoadScripts(nsDOMWorkerThread* aWorker,
|
||||||
|
|
||||||
{
|
{
|
||||||
JSAutoSuspendRequest asr(aCx);
|
JSAutoSuspendRequest asr(aCx);
|
||||||
|
|
||||||
nsAutoLock lock(mWorker->Lock());
|
nsAutoLock lock(mWorker->Lock());
|
||||||
|
|
||||||
|
if (mWorker->IsCanceled()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
mTrackedByWorker = nsnull != mWorker->mScriptLoaders.AppendElement(this);
|
mTrackedByWorker = nsnull != mWorker->mScriptLoaders.AppendElement(this);
|
||||||
NS_ASSERTION(mTrackedByWorker, "Failed to add loader to worker's array!");
|
NS_ASSERTION(mTrackedByWorker, "Failed to add loader to worker's array!");
|
||||||
}
|
}
|
||||||
|
@ -442,7 +448,7 @@ nsDOMWorkerScriptLoader::RunInternal()
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
// Things we need to make all this work...
|
// Things we need to make all this work...
|
||||||
nsIDocument* parentDoc = mWorker->Pool()->GetParentDocument();
|
nsIDocument* parentDoc = mWorker->Pool()->ParentDocument();
|
||||||
NS_ASSERTION(parentDoc, "Null parent document?!");
|
NS_ASSERTION(parentDoc, "Null parent document?!");
|
||||||
|
|
||||||
// All of these can potentially be null, but that should be ok. We'll either
|
// All of these can potentially be null, but that should be ok. We'll either
|
||||||
|
@ -578,7 +584,7 @@ nsDOMWorkerScriptLoader::OnStreamCompleteInternal(nsIStreamLoader* aLoader,
|
||||||
return rv = NS_ERROR_UNEXPECTED;
|
return rv = NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument* parentDoc = mWorker->Pool()->GetParentDocument();
|
nsIDocument* parentDoc = mWorker->Pool()->ParentDocument();
|
||||||
NS_ASSERTION(parentDoc, "Null parent document?!");
|
NS_ASSERTION(parentDoc, "Null parent document?!");
|
||||||
|
|
||||||
// Use the regular nsScriptLoader for this grunt work! Should be just fine
|
// Use the regular nsScriptLoader for this grunt work! Should be just fine
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
#include "nsDOMWorkerSecurityManager.h"
|
#include "nsDOMWorkerSecurityManager.h"
|
||||||
#include "nsDOMThreadService.h"
|
#include "nsDOMThreadService.h"
|
||||||
#include "nsDOMWorkerTimeout.h"
|
#include "nsDOMWorkerTimeout.h"
|
||||||
|
#include "nsDOMWorkerXHR.h"
|
||||||
|
|
||||||
#define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args)
|
#define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args)
|
||||||
|
|
||||||
|
@ -100,6 +101,9 @@ public:
|
||||||
static JSBool LoadScripts(JSContext* aCx, JSObject* aObj, uintN aArgc,
|
static JSBool LoadScripts(JSContext* aCx, JSObject* aObj, uintN aArgc,
|
||||||
jsval* aArgv, jsval* aRval);
|
jsval* aArgv, jsval* aRval);
|
||||||
|
|
||||||
|
static JSBool NewXMLHttpRequest(JSContext* aCx, JSObject* aObj, uintN aArgc,
|
||||||
|
jsval* aArgv, jsval* aRval);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal helper for SetTimeout and SetInterval.
|
// Internal helper for SetTimeout and SetInterval.
|
||||||
static JSBool MakeTimeout(JSContext* aCx, JSObject* aObj, uintN aArgc,
|
static JSBool MakeTimeout(JSContext* aCx, JSObject* aObj, uintN aArgc,
|
||||||
|
@ -303,6 +307,63 @@ nsDOMWorkerFunctions::LoadScripts(JSContext* aCx,
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSBool
|
||||||
|
nsDOMWorkerFunctions::NewXMLHttpRequest(JSContext* aCx,
|
||||||
|
JSObject* aObj,
|
||||||
|
uintN aArgc,
|
||||||
|
jsval* /* aArgv */,
|
||||||
|
jsval* aRval)
|
||||||
|
{
|
||||||
|
nsDOMWorkerThread* worker =
|
||||||
|
static_cast<nsDOMWorkerThread*>(JS_GetContextPrivate(aCx));
|
||||||
|
NS_ASSERTION(worker, "This should be set by the DOM thread service!");
|
||||||
|
|
||||||
|
if (worker->IsCanceled()) {
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aArgc) {
|
||||||
|
JS_ReportError(aCx, "Constructor takes no arguments!");
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerXHR> xhr = new nsDOMWorkerXHR(worker);
|
||||||
|
if (!xhr) {
|
||||||
|
JS_ReportOutOfMemory(aCx);
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = xhr->Init();
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
JS_ReportError(aCx, "Failed to construct XHR!");
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> xhrSupports;
|
||||||
|
xhr->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(xhrSupports));
|
||||||
|
NS_ASSERTION(xhrSupports, "Impossible!");
|
||||||
|
|
||||||
|
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXPConnectJSObjectHolder> xhrWrapped;
|
||||||
|
rv = xpc->WrapNative(aCx, aObj, xhrSupports, NS_GET_IID(nsIXMLHttpRequest),
|
||||||
|
getter_AddRefs(xhrWrapped));
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
JS_ReportError(aCx, "Failed to wrap XHR!");
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* xhrJSObj;
|
||||||
|
rv = xhrWrapped->GetJSObject(&xhrJSObj);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
JS_ReportError(aCx, "Failed to get JSObject!");
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aRval = OBJECT_TO_JSVAL(xhrJSObj);
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
JSFunctionSpec gDOMWorkerFunctions[] = {
|
JSFunctionSpec gDOMWorkerFunctions[] = {
|
||||||
{ "dump", nsDOMWorkerFunctions::Dump, 1, 0, 0 },
|
{ "dump", nsDOMWorkerFunctions::Dump, 1, 0, 0 },
|
||||||
{ "debug", nsDOMWorkerFunctions::DebugDump, 1, 0, 0 },
|
{ "debug", nsDOMWorkerFunctions::DebugDump, 1, 0, 0 },
|
||||||
|
@ -312,6 +373,7 @@ JSFunctionSpec gDOMWorkerFunctions[] = {
|
||||||
{ "setInterval", nsDOMWorkerFunctions::SetInterval, 1, 0, 0 },
|
{ "setInterval", nsDOMWorkerFunctions::SetInterval, 1, 0, 0 },
|
||||||
{ "clearInterval", nsDOMWorkerFunctions::KillTimeout, 1, 0, 0 },
|
{ "clearInterval", nsDOMWorkerFunctions::KillTimeout, 1, 0, 0 },
|
||||||
{ "loadScripts", nsDOMWorkerFunctions::LoadScripts, 1, 0, 0 },
|
{ "loadScripts", nsDOMWorkerFunctions::LoadScripts, 1, 0, 0 },
|
||||||
|
{ "XMLHttpRequest", nsDOMWorkerFunctions::NewXMLHttpRequest, 0, 0, 0 },
|
||||||
#ifdef MOZ_SHARK
|
#ifdef MOZ_SHARK
|
||||||
{ "startShark", js_StartShark, 0, 0, 0 },
|
{ "startShark", js_StartShark, 0, 0, 0 },
|
||||||
{ "stopShark", js_StopShark, 0, 0, 0 },
|
{ "stopShark", js_StopShark, 0, 0, 0 },
|
||||||
|
@ -551,6 +613,7 @@ nsDOMWorkerThread::Cancel()
|
||||||
|
|
||||||
// Do this before waiting on the thread service below!
|
// Do this before waiting on the thread service below!
|
||||||
CancelScriptLoaders();
|
CancelScriptLoaders();
|
||||||
|
CancelXHRs();
|
||||||
|
|
||||||
// If we're suspended there's a good chance that we're already paused waiting
|
// If we're suspended there's a good chance that we're already paused waiting
|
||||||
// on the pool's monitor. Waiting on the thread service's lock will deadlock.
|
// on the pool's monitor. Waiting on the thread service's lock will deadlock.
|
||||||
|
@ -717,7 +780,7 @@ nsDOMWorkerThread::NextTimeout(nsDOMWorkerTimeout* aTimeout)
|
||||||
return next == &mTimeouts ? nsnull : next;
|
return next == &mTimeouts ? nsnull : next;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
PRBool
|
||||||
nsDOMWorkerThread::AddTimeout(nsDOMWorkerTimeout* aTimeout)
|
nsDOMWorkerThread::AddTimeout(nsDOMWorkerTimeout* aTimeout)
|
||||||
{
|
{
|
||||||
// This should only ever be called on the worker thread... but there's no way
|
// This should only ever be called on the worker thread... but there's no way
|
||||||
|
@ -733,6 +796,10 @@ nsDOMWorkerThread::AddTimeout(nsDOMWorkerTimeout* aTimeout)
|
||||||
|
|
||||||
nsAutoLock lock(mLock);
|
nsAutoLock lock(mLock);
|
||||||
|
|
||||||
|
if (IsCanceled()) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// XXX Currently stored in the order that they should execute (like the window
|
// XXX Currently stored in the order that they should execute (like the window
|
||||||
// timeouts are) but we don't flush all expired timeouts the same way that
|
// timeouts are) but we don't flush all expired timeouts the same way that
|
||||||
// the window does... Either we should or this is unnecessary.
|
// the window does... Either we should or this is unnecessary.
|
||||||
|
@ -741,11 +808,12 @@ nsDOMWorkerThread::AddTimeout(nsDOMWorkerTimeout* aTimeout)
|
||||||
timeout = NextTimeout(timeout)) {
|
timeout = NextTimeout(timeout)) {
|
||||||
if (timeout->GetInterval() > newInterval) {
|
if (timeout->GetInterval() > newInterval) {
|
||||||
PR_INSERT_BEFORE(aTimeout, timeout);
|
PR_INSERT_BEFORE(aTimeout, timeout);
|
||||||
return;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_APPEND_LINK(aTimeout, &mTimeouts);
|
PR_APPEND_LINK(aTimeout, &mTimeouts);
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -859,6 +927,54 @@ nsDOMWorkerThread::CancelScriptLoaders()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsDOMWorkerThread::AddXHR(nsDOMWorkerXHR* aXHR)
|
||||||
|
{
|
||||||
|
nsAutoLock lock(mLock);
|
||||||
|
|
||||||
|
if (IsCanceled()) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool contains = mXHRs.Contains(aXHR);
|
||||||
|
NS_ASSERTION(!contains, "Adding an XHR twice!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsDOMWorkerXHR** newElement = mXHRs.AppendElement(aXHR);
|
||||||
|
NS_ENSURE_TRUE(newElement, PR_FALSE);
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDOMWorkerThread::RemoveXHR(nsDOMWorkerXHR* aXHR)
|
||||||
|
{
|
||||||
|
nsAutoLock lock(mLock);
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool removed =
|
||||||
|
#endif
|
||||||
|
mXHRs.RemoveElement(aXHR);
|
||||||
|
NS_WARN_IF_FALSE(removed, "Removed an XHR that was never added?!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDOMWorkerThread::CancelXHRs()
|
||||||
|
{
|
||||||
|
nsAutoTArray<nsDOMWorkerXHR*, 20> xhrs;
|
||||||
|
|
||||||
|
// Must call Cancel outside the lock!
|
||||||
|
{
|
||||||
|
nsAutoLock lock(mLock);
|
||||||
|
xhrs.AppendElements(mXHRs);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 xhrCount = xhrs.Length();
|
||||||
|
for (PRUint32 index = 0; index < xhrCount; index++) {
|
||||||
|
xhrs[index]->Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWorkerThread::PostMessage(const nsAString& aMessage)
|
nsDOMWorkerThread::PostMessage(const nsAString& aMessage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,6 +117,7 @@ _class::GetClassIDNoAlloc(nsCID* _classIDNoAlloc) \
|
||||||
class nsDOMWorkerPool;
|
class nsDOMWorkerPool;
|
||||||
class nsDOMWorkerScriptLoader;
|
class nsDOMWorkerScriptLoader;
|
||||||
class nsDOMWorkerTimeout;
|
class nsDOMWorkerTimeout;
|
||||||
|
class nsDOMWorkerXHR;
|
||||||
|
|
||||||
class nsDOMWorkerThread : public nsDOMWorkerBase,
|
class nsDOMWorkerThread : public nsDOMWorkerBase,
|
||||||
public nsIDOMWorkerThread,
|
public nsIDOMWorkerThread,
|
||||||
|
@ -128,6 +129,7 @@ class nsDOMWorkerThread : public nsDOMWorkerBase,
|
||||||
friend class nsDOMWorkerRunnable;
|
friend class nsDOMWorkerRunnable;
|
||||||
friend class nsDOMWorkerScriptLoader;
|
friend class nsDOMWorkerScriptLoader;
|
||||||
friend class nsDOMWorkerTimeout;
|
friend class nsDOMWorkerTimeout;
|
||||||
|
friend class nsDOMWorkerXHR;
|
||||||
|
|
||||||
friend JSBool DOMWorkerOperationCallback(JSContext* aCx);
|
friend JSBool DOMWorkerOperationCallback(JSContext* aCx);
|
||||||
|
|
||||||
|
@ -167,7 +169,7 @@ private:
|
||||||
inline nsDOMWorkerTimeout* FirstTimeout();
|
inline nsDOMWorkerTimeout* FirstTimeout();
|
||||||
inline nsDOMWorkerTimeout* NextTimeout(nsDOMWorkerTimeout* aTimeout);
|
inline nsDOMWorkerTimeout* NextTimeout(nsDOMWorkerTimeout* aTimeout);
|
||||||
|
|
||||||
void AddTimeout(nsDOMWorkerTimeout* aTimeout);
|
PRBool AddTimeout(nsDOMWorkerTimeout* aTimeout);
|
||||||
void RemoveTimeout(nsDOMWorkerTimeout* aTimeout);
|
void RemoveTimeout(nsDOMWorkerTimeout* aTimeout);
|
||||||
void ClearTimeouts();
|
void ClearTimeouts();
|
||||||
void CancelTimeout(PRUint32 aId);
|
void CancelTimeout(PRUint32 aId);
|
||||||
|
@ -176,6 +178,10 @@ private:
|
||||||
|
|
||||||
void CancelScriptLoaders();
|
void CancelScriptLoaders();
|
||||||
|
|
||||||
|
PRBool AddXHR(nsDOMWorkerXHR* aXHR);
|
||||||
|
void RemoveXHR(nsDOMWorkerXHR* aXHR);
|
||||||
|
void CancelXHRs();
|
||||||
|
|
||||||
PRLock* Lock() {
|
PRLock* Lock() {
|
||||||
return mLock;
|
return mLock;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +201,7 @@ private:
|
||||||
PRCList mTimeouts;
|
PRCList mTimeouts;
|
||||||
|
|
||||||
nsTArray<nsDOMWorkerScriptLoader*> mScriptLoaders;
|
nsTArray<nsDOMWorkerScriptLoader*> mScriptLoaders;
|
||||||
|
nsTArray<nsDOMWorkerXHR*> mXHRs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __NSDOMWORKERTHREAD_H__ */
|
#endif /* __NSDOMWORKERTHREAD_H__ */
|
||||||
|
|
|
@ -329,19 +329,26 @@ nsDOMWorkerTimeout::Init(JSContext* aCx, PRUint32 aArgc, jsval* aArgv,
|
||||||
}
|
}
|
||||||
mIsInterval = aIsInterval;
|
mIsInterval = aIsInterval;
|
||||||
|
|
||||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
|
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsIEventTarget* target =
|
nsIEventTarget* target =
|
||||||
static_cast<nsIEventTarget*>(nsDOMThreadService::get());
|
static_cast<nsIEventTarget*>(nsDOMThreadService::get());
|
||||||
|
|
||||||
rv = mTimer->SetTarget(target);
|
rv = timer->SetTarget(target);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = mTimer->InitWithCallback(this, interval, type);
|
rv = timer->InitWithCallback(this, interval, type);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
mWorker->AddTimeout(this);
|
mTimer.swap(timer);
|
||||||
|
|
||||||
|
if (!mWorker->AddTimeout(this)) {
|
||||||
|
// Must have been canceled.
|
||||||
|
mTimer->Cancel();
|
||||||
|
mTimer = nsnull;
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,915 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is worker threads.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsDOMWorkerXHR.h"
|
||||||
|
|
||||||
|
// Interfaces
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMEvent.h"
|
||||||
|
#include "nsIThread.h"
|
||||||
|
#include "nsIXPConnect.h"
|
||||||
|
|
||||||
|
// Other includes
|
||||||
|
#include "nsAutoLock.h"
|
||||||
|
#include "nsAXPCNativeCallContext.h"
|
||||||
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsIClassInfoImpl.h"
|
||||||
|
#include "nsJSUtils.h"
|
||||||
|
#include "nsProxyRelease.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
// DOMWorker includes
|
||||||
|
#include "nsDOMThreadService.h"
|
||||||
|
#include "nsDOMWorkerPool.h"
|
||||||
|
#include "nsDOMWorkerXHRProxy.h"
|
||||||
|
|
||||||
|
// The list of event types that we support. This list and the defines based on
|
||||||
|
// it determine the sizes of the listener arrays in nsDOMWorkerXHRProxy. Make
|
||||||
|
// sure that any event types shared by both the XHR and Upload objects are
|
||||||
|
// together at the beginning of the list. Any changes made to this list may
|
||||||
|
// affect sMaxUploadEventTypes, so make sure that it is adjusted accordingly or
|
||||||
|
// things will break!
|
||||||
|
const char* const nsDOMWorkerXHREventTarget::sListenerTypes[] = {
|
||||||
|
// nsIXMLHttpRequestEventTarget listeners.
|
||||||
|
"abort", /* LISTENER_TYPE_ABORT */
|
||||||
|
"error", /* LISTENER_TYPE_ERROR */
|
||||||
|
"load", /* LISTENER_TYPE_LOAD */
|
||||||
|
"loadstart", /* LISTENER_TYPE_LOADSTART */
|
||||||
|
"progress", /* LISTENER_TYPE_PROGRESS */
|
||||||
|
|
||||||
|
// nsIXMLHttpRequest listeners.
|
||||||
|
"readystatechange" /* LISTENER_TYPE_READYSTATECHANGE */
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convenience defines for event *indexes* in the sListenerTypes array.
|
||||||
|
#define LISTENER_TYPE_ABORT 0
|
||||||
|
#define LISTENER_TYPE_ERROR 1
|
||||||
|
#define LISTENER_TYPE_LOAD 2
|
||||||
|
#define LISTENER_TYPE_LOADSTART 3
|
||||||
|
#define LISTENER_TYPE_PROGRESS 4
|
||||||
|
#define LISTENER_TYPE_READYSTATECHANGE 5
|
||||||
|
|
||||||
|
// This should always be set to the length of sListenerTypes.
|
||||||
|
const PRUint32 nsDOMWorkerXHREventTarget::sMaxXHREventTypes =
|
||||||
|
NS_ARRAY_LENGTH(nsDOMWorkerXHREventTarget::sListenerTypes);
|
||||||
|
|
||||||
|
// This should be set to the index of the first event type that is *not*
|
||||||
|
// supported by the Upload object.
|
||||||
|
const PRUint32 nsDOMWorkerXHREventTarget::sMaxUploadEventTypes =
|
||||||
|
LISTENER_TYPE_READYSTATECHANGE;
|
||||||
|
|
||||||
|
// Enforce the invariant that the upload object supports no more event types
|
||||||
|
// than the xhr object.
|
||||||
|
PR_STATIC_ASSERT(nsDOMWorkerXHREventTarget::sMaxXHREventTypes >=
|
||||||
|
nsDOMWorkerXHREventTarget::sMaxUploadEventTypes);
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDOMWorkerXHREventTarget,
|
||||||
|
nsIDOMEventTarget,
|
||||||
|
nsIXMLHttpRequestEventTarget)
|
||||||
|
|
||||||
|
PRUint32
|
||||||
|
nsDOMWorkerXHREventTarget::GetListenerTypeFromString(const nsAString& aString)
|
||||||
|
{
|
||||||
|
for (PRUint32 index = 0; index < sMaxXHREventTypes; index++) {
|
||||||
|
if (aString.EqualsASCII(sListenerTypes[index])) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::GetOnabort(nsIDOMEventListener** aOnabort)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnabort);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener = GetOnXListener(LISTENER_TYPE_ABORT);
|
||||||
|
listener.forget(aOnabort);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::SetOnabort(nsIDOMEventListener* aOnabort)
|
||||||
|
{
|
||||||
|
return SetEventListener(LISTENER_TYPE_ABORT, aOnabort, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::GetOnerror(nsIDOMEventListener** aOnerror)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnerror);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener = GetOnXListener(LISTENER_TYPE_ERROR);
|
||||||
|
listener.forget(aOnerror);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::SetOnerror(nsIDOMEventListener* aOnerror)
|
||||||
|
{
|
||||||
|
return SetEventListener(LISTENER_TYPE_ERROR, aOnerror, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::GetOnload(nsIDOMEventListener** aOnload)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnload);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener = GetOnXListener(LISTENER_TYPE_LOAD);
|
||||||
|
listener.forget(aOnload);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::SetOnload(nsIDOMEventListener* aOnload)
|
||||||
|
{
|
||||||
|
return SetEventListener(LISTENER_TYPE_LOAD, aOnload, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::GetOnloadstart(nsIDOMEventListener** aOnloadstart)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnloadstart);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener =
|
||||||
|
GetOnXListener(LISTENER_TYPE_LOADSTART);
|
||||||
|
listener.forget(aOnloadstart);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::SetOnloadstart(nsIDOMEventListener* aOnloadstart)
|
||||||
|
{
|
||||||
|
return SetEventListener(LISTENER_TYPE_LOADSTART, aOnloadstart, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::GetOnprogress(nsIDOMEventListener** aOnprogress)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnprogress);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener =
|
||||||
|
GetOnXListener(LISTENER_TYPE_PROGRESS);
|
||||||
|
listener.forget(aOnprogress);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::SetOnprogress(nsIDOMEventListener* aOnprogress)
|
||||||
|
{
|
||||||
|
return SetEventListener(LISTENER_TYPE_PROGRESS, aOnprogress, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::AddEventListener(const nsAString& aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aUseCapture)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aListener);
|
||||||
|
|
||||||
|
PRUint32 type = GetListenerTypeFromString(aType);
|
||||||
|
if (type > sMaxXHREventTypes) {
|
||||||
|
// Silently ignore junk events.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetEventListener(type, aListener, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::RemoveEventListener(const nsAString& aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aUseCapture)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aListener);
|
||||||
|
|
||||||
|
PRUint32 type = GetListenerTypeFromString(aType);
|
||||||
|
if (type > sMaxXHREventTypes) {
|
||||||
|
// Silently ignore junk events.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnsetEventListener(type, aListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ec702b78-c30f-439f-9a9b-a5dae17ee0fc */
|
||||||
|
#define NS_IPRIVATEWORKERXHREVENT_IID \
|
||||||
|
{ \
|
||||||
|
0xec702b78, \
|
||||||
|
0xc30f, \
|
||||||
|
0x439f, \
|
||||||
|
{ 0x9a, 0x9b, 0xa5, 0xda, 0xe1, 0x7e, 0xe0, 0xfc } \
|
||||||
|
}
|
||||||
|
|
||||||
|
class nsIPrivateWorkerXHREvent : public nsIDOMEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATEWORKERXHREVENT_IID)
|
||||||
|
virtual PRBool PreventDefaultCalled() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateWorkerXHREvent,
|
||||||
|
NS_IPRIVATEWORKERXHREVENT_IID)
|
||||||
|
|
||||||
|
#define NS_FORWARD_NSIDOMEVENT_SPECIAL \
|
||||||
|
NS_IMETHOD GetType(nsAString& aType) \
|
||||||
|
{ return mEvent->GetType(aType); } \
|
||||||
|
NS_IMETHOD GetTarget(nsIDOMEventTarget** aTarget) \
|
||||||
|
{ return mEvent->GetTarget(aTarget); } \
|
||||||
|
NS_IMETHOD GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget) \
|
||||||
|
{ return mEvent->GetCurrentTarget(aCurrentTarget); } \
|
||||||
|
NS_IMETHOD GetEventPhase(PRUint16* aEventPhase) \
|
||||||
|
{ return mEvent->GetEventPhase(aEventPhase); } \
|
||||||
|
NS_IMETHOD GetBubbles(PRBool* aBubbles) \
|
||||||
|
{ return mEvent->GetBubbles(aBubbles); } \
|
||||||
|
NS_IMETHOD GetCancelable(PRBool* aCancelable) \
|
||||||
|
{ return mEvent->GetCancelable(aCancelable); } \
|
||||||
|
NS_IMETHOD GetTimeStamp(DOMTimeStamp* aTimeStamp) \
|
||||||
|
{ return mEvent->GetTimeStamp(aTimeStamp); } \
|
||||||
|
NS_IMETHOD StopPropagation() \
|
||||||
|
{ return mEvent->StopPropagation(); }
|
||||||
|
|
||||||
|
class nsDOMWorkerXHREventWrapper : public nsIPrivateWorkerXHREvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_FORWARD_NSIDOMEVENT_SPECIAL
|
||||||
|
|
||||||
|
nsDOMWorkerXHREventWrapper(nsIDOMEvent* aEvent)
|
||||||
|
: mEvent(aEvent), mPreventDefaultCalled(PR_FALSE) {
|
||||||
|
NS_ASSERTION(aEvent, "Null pointer!");
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD PreventDefault() {
|
||||||
|
mPreventDefaultCalled = PR_TRUE;
|
||||||
|
return mEvent->PreventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD InitEvent(const nsAString& aEventType, PRBool aCanBubble,
|
||||||
|
PRBool aCancelable) {
|
||||||
|
mPreventDefaultCalled = PR_FALSE;
|
||||||
|
return mEvent->InitEvent(aEventType, aCanBubble, aCancelable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nsIPrivateWorkerXHREvent
|
||||||
|
virtual PRBool PreventDefaultCalled() {
|
||||||
|
return mPreventDefaultCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCOMPtr<nsIDOMEvent> mEvent;
|
||||||
|
PRBool mPreventDefaultCalled;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDOMWorkerXHREventWrapper,
|
||||||
|
nsIDOMEvent,
|
||||||
|
nsIPrivateWorkerXHREvent)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHREventTarget::DispatchEvent(nsIDOMEvent* aEvent,
|
||||||
|
PRBool* _retval)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aEvent);
|
||||||
|
NS_ENSURE_ARG_POINTER(_retval);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrivateWorkerXHREvent> wrapper(do_QueryInterface(aEvent));
|
||||||
|
if (!wrapper) {
|
||||||
|
wrapper = new nsDOMWorkerXHREventWrapper(aEvent);
|
||||||
|
NS_ENSURE_TRUE(wrapper, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = HandleWorkerEvent(wrapper);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
*_retval = wrapper->PreventDefaultCalled();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDOMWorkerXHRUpload::nsDOMWorkerXHRUpload(nsDOMWorkerXHR* aWorkerXHR)
|
||||||
|
: mWorkerXHR(aWorkerXHR)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aWorkerXHR, "Must have a worker XHR!");
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED2(nsDOMWorkerXHRUpload, nsDOMWorkerXHREventTarget,
|
||||||
|
nsIXMLHttpRequestUpload,
|
||||||
|
nsIClassInfo)
|
||||||
|
|
||||||
|
NS_IMPL_CI_INTERFACE_GETTER3(nsDOMWorkerXHRUpload, nsIDOMEventTarget,
|
||||||
|
nsIXMLHttpRequestEventTarget,
|
||||||
|
nsIXMLHttpRequestUpload)
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_CI(nsDOMWorkerXHRUpload)
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHRUpload::SetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener)
|
||||||
|
{
|
||||||
|
if (mWorkerXHR->mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mWorkerXHR->mXHRProxy->AddEventListener(aType, aListener, aOnXListener,
|
||||||
|
PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHRUpload::UnsetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener)
|
||||||
|
{
|
||||||
|
if (mWorkerXHR->mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mWorkerXHR->mXHRProxy->RemoveEventListener(aType, aListener, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHRUpload::HandleWorkerEvent(nsIDOMEvent* aEvent)
|
||||||
|
{
|
||||||
|
if (mWorkerXHR->mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mWorkerXHR->mXHRProxy->HandleWorkerEvent(aEvent, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDOMEventListener>
|
||||||
|
nsDOMWorkerXHRUpload::GetOnXListener(PRUint32 aType)
|
||||||
|
{
|
||||||
|
if (mWorkerXHR->mCanceled) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mWorkerXHR->mXHRProxy->GetOnXListener(aType, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDOMWorkerXHR::nsDOMWorkerXHR(nsDOMWorkerThread* aWorker)
|
||||||
|
: mWorker(aWorker),
|
||||||
|
mCanceled(PR_TRUE)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ASSERTION(aWorker, "Must have a worker!");
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDOMWorkerXHR::~nsDOMWorkerXHR()
|
||||||
|
{
|
||||||
|
if (!mCanceled) {
|
||||||
|
mWorker->RemoveXHR(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED2(nsDOMWorkerXHR, nsDOMWorkerXHREventTarget,
|
||||||
|
nsIXMLHttpRequest,
|
||||||
|
nsIClassInfo)
|
||||||
|
|
||||||
|
NS_IMPL_CI_INTERFACE_GETTER3(nsDOMWorkerXHR, nsIDOMEventTarget,
|
||||||
|
nsIXMLHttpRequestEventTarget,
|
||||||
|
nsIXMLHttpRequest)
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_CI(nsDOMWorkerXHR)
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHR::Init()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (!mWorker->AddXHR(this)) {
|
||||||
|
// Must have been canceled.
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
mCanceled = PR_FALSE;
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> proxy = new nsDOMWorkerXHRProxy(this);
|
||||||
|
NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
nsresult rv = proxy->Init();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
proxy.swap(mXHRProxy);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDOMWorkerXHR::Cancel()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
// Just in case mUpload holds the only ref to this object we make sure to stay
|
||||||
|
// alive through this call.
|
||||||
|
nsRefPtr<nsDOMWorkerXHR> kungFuDeathGrip(this);
|
||||||
|
|
||||||
|
{
|
||||||
|
// This lock is here to prevent a race between Cancel and GetUpload, not to
|
||||||
|
// protect mCanceled.
|
||||||
|
nsAutoLock lock(mWorker->Lock());
|
||||||
|
|
||||||
|
mCanceled = PR_TRUE;
|
||||||
|
mUpload = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mXHRProxy) {
|
||||||
|
mXHRProxy->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
mWorker->RemoveXHR(this);
|
||||||
|
mWorker = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHR::SetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mXHRProxy->AddEventListener(aType, aListener, aOnXListener, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHR::UnsetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mXHRProxy->RemoveEventListener(aType, aListener, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDOMWorkerXHR::HandleWorkerEvent(nsIDOMEvent* aEvent)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mXHRProxy->HandleWorkerEvent(aEvent, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDOMEventListener>
|
||||||
|
nsDOMWorkerXHR::GetOnXListener(PRUint32 aType)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mXHRProxy->GetOnXListener(aType, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetChannel(nsIChannel** aChannel)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetResponseXML(nsIDOMDocument** aResponseXML)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetResponseText(nsAString& aResponseText)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetResponseText(aResponseText);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetStatus(PRUint32* aStatus)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ENSURE_ARG_POINTER(aStatus);
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetStatus(aStatus);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetStatusText(nsACString& aStatusText)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetStatusText(aStatusText);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::Abort()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->Abort();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetAllResponseHeaders(char** _retval)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ENSURE_ARG_POINTER(_retval);
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetAllResponseHeaders(_retval);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetResponseHeader(const nsACString& aHeader,
|
||||||
|
nsACString& _retval)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetResponseHeader(aHeader, _retval);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::OpenRequest(const nsACString& aMethod,
|
||||||
|
const nsACString& aUrl,
|
||||||
|
PRBool aAsync,
|
||||||
|
const nsAString& aUser,
|
||||||
|
const nsAString& aPassword)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->OpenRequest(aMethod, aUrl, aAsync, aUser, aPassword);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::Open(const nsACString& aMethod,
|
||||||
|
const nsACString& aUrl)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool async = PR_TRUE;
|
||||||
|
nsAutoString user, password;
|
||||||
|
|
||||||
|
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||||
|
NS_ENSURE_TRUE(xpc, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
|
nsAXPCNativeCallContext* cc;
|
||||||
|
nsresult rv = xpc->GetCurrentNativeCallContext(&cc);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (NS_FAILED(rv) || !cc) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 argc;
|
||||||
|
rv = cc->GetArgc(&argc);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsval* argv;
|
||||||
|
rv = cc->GetArgvPtr(&argv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
JSContext* cx;
|
||||||
|
rv = cc->GetJSContext(&cx);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
JSAutoRequest ar(cx);
|
||||||
|
|
||||||
|
JSBool asyncBool;
|
||||||
|
JS_ValueToBoolean(cx, argv[2], &asyncBool);
|
||||||
|
async = (PRBool)asyncBool;
|
||||||
|
|
||||||
|
// XXX Remove me once we support sync XHR
|
||||||
|
NS_ENSURE_TRUE(async, NS_ERROR_INVALID_ARG);
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSString* argStr;
|
||||||
|
if (!JSVAL_IS_NULL(argv[3]) && !JSVAL_IS_VOID(argv[3])) {
|
||||||
|
argStr = JS_ValueToString(cx, argv[3]);
|
||||||
|
if (argStr) {
|
||||||
|
user.Assign(nsDependentJSString(argStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 5) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!JSVAL_IS_NULL(argv[4]) && !JSVAL_IS_VOID(argv[4])) {
|
||||||
|
argStr = JS_ValueToString(cx, argv[4]);
|
||||||
|
if (argStr) {
|
||||||
|
password.Assign(nsDependentJSString(argStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (PR_FALSE);
|
||||||
|
|
||||||
|
return OpenRequest(aMethod, aUrl, async, user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::Send(nsIVariant* aBody)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->Send(aBody);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::SendAsBinary(const nsAString& aBody)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->SendAsBinary(aBody);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::SetRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->SetRequestHeader(aHeader, aValue);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetReadyState(PRInt32* aReadyState)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aReadyState);
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetReadyState(aReadyState);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::OverrideMimeType(const nsACString& aMimetype)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->OverrideMimeType(aMimetype);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetMultipart(PRBool* aMultipart)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aMultipart);
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->GetMultipart(aMultipart);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::SetMultipart(PRBool aMultipart)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mXHRProxy->SetMultipart(aMultipart);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetMozBackgroundRequest(PRBool* aMozBackgroundRequest)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aMozBackgroundRequest);
|
||||||
|
|
||||||
|
*aMozBackgroundRequest = PR_FALSE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::SetMozBackgroundRequest(PRBool aMozBackgroundRequest)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (aMozBackgroundRequest) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::Init(nsIPrincipal* aPrincipal,
|
||||||
|
nsIScriptContext* aScriptContext,
|
||||||
|
nsPIDOMWindow* aOwnerWindow)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetUpload(nsIXMLHttpRequestUpload** aUpload)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerThread> worker = mWorker;
|
||||||
|
if (!worker) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoLock lock(worker->Lock());
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aUpload);
|
||||||
|
|
||||||
|
if (!mUpload) {
|
||||||
|
mUpload = new nsDOMWorkerXHRUpload(this);
|
||||||
|
NS_ENSURE_TRUE(mUpload, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aUpload = mUpload);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::GetOnreadystatechange(nsIDOMEventListener** aOnreadystatechange)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aOnreadystatechange);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventListener> listener =
|
||||||
|
mXHRProxy->GetOnXListener(LISTENER_TYPE_READYSTATECHANGE, PR_FALSE);
|
||||||
|
|
||||||
|
listener.forget(aOnreadystatechange);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWorkerXHR::SetOnreadystatechange(nsIDOMEventListener* aOnreadystatechange)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (mCanceled) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mXHRProxy->AddEventListener(LISTENER_TYPE_READYSTATECHANGE,
|
||||||
|
aOnreadystatechange, PR_TRUE, PR_FALSE);
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is worker threads.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef __NSDOMWORKERXHR_H__
|
||||||
|
#define __NSDOMWORKERXHR_H__
|
||||||
|
|
||||||
|
// Bases
|
||||||
|
#include "nsIXMLHttpRequest.h"
|
||||||
|
#include "nsIClassInfo.h"
|
||||||
|
|
||||||
|
// Interfaces
|
||||||
|
|
||||||
|
// Other includes
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "prlock.h"
|
||||||
|
|
||||||
|
// DOMWorker includes
|
||||||
|
#include "nsDOMWorkerThread.h"
|
||||||
|
|
||||||
|
class nsDOMWorkerXHRProxy;
|
||||||
|
|
||||||
|
class nsDOMWorkerXHREventTarget : public nsIXMLHttpRequestEventTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIDOMEVENTTARGET
|
||||||
|
NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET
|
||||||
|
|
||||||
|
static const char* const sListenerTypes[];
|
||||||
|
static const PRUint32 sMaxXHREventTypes;
|
||||||
|
static const PRUint32 sMaxUploadEventTypes;
|
||||||
|
|
||||||
|
static PRUint32 GetListenerTypeFromString(const nsAString& aString);
|
||||||
|
|
||||||
|
virtual nsresult SetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener) = 0;
|
||||||
|
|
||||||
|
virtual nsresult UnsetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener) = 0;
|
||||||
|
|
||||||
|
virtual nsresult HandleWorkerEvent(nsIDOMEvent* aEvent) = 0;
|
||||||
|
|
||||||
|
virtual already_AddRefed<nsIDOMEventListener>
|
||||||
|
GetOnXListener(PRUint32 aType) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~nsDOMWorkerXHREventTarget() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDOMWorkerXHR;
|
||||||
|
|
||||||
|
class nsDOMWorkerXHRUpload : public nsDOMWorkerXHREventTarget,
|
||||||
|
public nsIXMLHttpRequestUpload,
|
||||||
|
public nsIClassInfo
|
||||||
|
{
|
||||||
|
friend class nsDOMWorkerXHR;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMWorkerXHREventTarget::)
|
||||||
|
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsDOMWorkerXHREventTarget::)
|
||||||
|
NS_DECL_NSIXMLHTTPREQUESTUPLOAD
|
||||||
|
NS_DECL_NSICLASSINFO
|
||||||
|
|
||||||
|
nsDOMWorkerXHRUpload(nsDOMWorkerXHR* aWorkerXHR);
|
||||||
|
|
||||||
|
virtual nsresult SetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener);
|
||||||
|
|
||||||
|
virtual nsresult UnsetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener);
|
||||||
|
|
||||||
|
virtual nsresult HandleWorkerEvent(nsIDOMEvent* aEvent);
|
||||||
|
|
||||||
|
virtual already_AddRefed<nsIDOMEventListener>
|
||||||
|
GetOnXListener(PRUint32 aType);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~nsDOMWorkerXHRUpload() { }
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerXHR> mWorkerXHR;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDOMWorkerXHR : public nsDOMWorkerXHREventTarget,
|
||||||
|
public nsIXMLHttpRequest,
|
||||||
|
public nsIClassInfo
|
||||||
|
{
|
||||||
|
friend class nsDOMWorkerXHRProxy;
|
||||||
|
friend class nsDOMWorkerXHRUpload;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIXMLHTTPREQUEST
|
||||||
|
NS_DECL_NSICLASSINFO
|
||||||
|
|
||||||
|
nsDOMWorkerXHR(nsDOMWorkerThread* aWorker);
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
|
void Cancel();
|
||||||
|
|
||||||
|
virtual nsresult SetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener);
|
||||||
|
|
||||||
|
virtual nsresult UnsetEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener);
|
||||||
|
|
||||||
|
virtual nsresult HandleWorkerEvent(nsIDOMEvent* aEvent);
|
||||||
|
|
||||||
|
virtual already_AddRefed<nsIDOMEventListener>
|
||||||
|
GetOnXListener(PRUint32 aType);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~nsDOMWorkerXHR();
|
||||||
|
|
||||||
|
PRLock* Lock() {
|
||||||
|
return mWorker->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerThread> mWorker;
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHRProxy;
|
||||||
|
nsRefPtr<nsDOMWorkerXHRUpload> mUpload;
|
||||||
|
|
||||||
|
volatile PRBool mCanceled;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __NSDOMWORKERXHR_H__ */
|
|
@ -0,0 +1,248 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is worker threads.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef __NSDOMWORKERXHRPROXIEDFUNCTIONS_H__
|
||||||
|
#define __NSDOMWORKERXHRPROXIEDFUNCTIONS_H__
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION0(_name) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR) \
|
||||||
|
: mXHR(aXHR) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION1(_name, _arg1) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR, _arg1 aArg1) \
|
||||||
|
: mXHR(aXHR), mArg1(aArg1) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (mArg1); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
_arg1 mArg1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION2(_name, _arg1, _arg2) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR, _arg1 aArg1, _arg2 aArg2) \
|
||||||
|
: mXHR(aXHR), mArg1(aArg1), mArg2(aArg2) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (mArg1, mArg2); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
_arg1 mArg1; \
|
||||||
|
_arg2 mArg2; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION3(_name, _arg1, _arg2, _arg3) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR, _arg1 aArg1, _arg2 aArg2, _arg3 aArg3) \
|
||||||
|
: mXHR(aXHR), mArg1(aArg1), mArg2(aArg2), mArg3(aArg3) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (mArg1, mArg2, mArg3); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
_arg1 mArg1; \
|
||||||
|
_arg2 mArg2; \
|
||||||
|
_arg3 mArg3; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION4(_name, _arg1, _arg2, _arg3, _arg4) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR, _arg1 aArg1, _arg2 aArg2, _arg3 aArg3, \
|
||||||
|
_arg4 aArg4) \
|
||||||
|
: mXHR(aXHR), mArg1(aArg1), mArg2(aArg2), mArg3(aArg3), mArg4(aArg4) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (mArg1, mArg2, mArg3, mArg4); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
_arg1 mArg1; \
|
||||||
|
_arg2 mArg2; \
|
||||||
|
_arg3 mArg3; \
|
||||||
|
_arg4 mArg4; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_PROXIED_FUNCTION5(_name, _arg1, _arg2, _arg3, _arg4, _arg5) \
|
||||||
|
class _name : public nsRunnable \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
_name (nsDOMWorkerXHRProxy* aXHR, _arg1 aArg1, _arg2 aArg2, _arg3 aArg3, \
|
||||||
|
_arg4 aArg4, _arg5 aArg5) \
|
||||||
|
: mXHR(aXHR), mArg1(aArg1), mArg2(aArg2), mArg3(aArg3), mArg4(aArg4), \
|
||||||
|
mArg5(aArg5) \
|
||||||
|
{ \
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
NS_IMETHOD Run() \
|
||||||
|
{ \
|
||||||
|
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
|
||||||
|
if (xhr) { \
|
||||||
|
return xhr-> _name (mArg1, mArg2, mArg3, mArg4, mArg5); \
|
||||||
|
} \
|
||||||
|
return NS_OK; \
|
||||||
|
} \
|
||||||
|
private: \
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR; \
|
||||||
|
_arg1 mArg1; \
|
||||||
|
_arg2 mArg2; \
|
||||||
|
_arg3 mArg3; \
|
||||||
|
_arg4 mArg4; \
|
||||||
|
_arg5 mArg5; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RUN_PROXIED_FUNCTION(_name, _args) \
|
||||||
|
PR_BEGIN_MACRO \
|
||||||
|
if (mCanceled) { \
|
||||||
|
return NS_ERROR_ABORT; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
nsCOMPtr<nsIRunnable> method = new :: _name _args; \
|
||||||
|
NS_ENSURE_TRUE(method, NS_ERROR_OUT_OF_MEMORY); \
|
||||||
|
\
|
||||||
|
nsRefPtr<nsResultReturningRunnable> runnable = \
|
||||||
|
new nsResultReturningRunnable(mMainThread, method, mWorkerXHR->mWorker); \
|
||||||
|
NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY); \
|
||||||
|
\
|
||||||
|
nsresult _rv = runnable->Dispatch(); \
|
||||||
|
if (NS_FAILED(_rv)) { \
|
||||||
|
return _rv; \
|
||||||
|
} \
|
||||||
|
PR_END_MACRO
|
||||||
|
|
||||||
|
namespace nsDOMWorkerProxiedXHRFunctions
|
||||||
|
{
|
||||||
|
class Abort : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Abort (nsDOMWorkerXHRProxy* aXHR)
|
||||||
|
: mXHR(aXHR)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aXHR, "Null pointer!");
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD Run() {
|
||||||
|
return mXHR->Abort();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
nsRefPtr<nsDOMWorkerXHRProxy> mXHR;
|
||||||
|
};
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION1(GetAllResponseHeaders, char**);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION2(GetResponseHeader, const nsACString&, nsACString&);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION5(OpenRequest, const nsACString&, const nsACString&,
|
||||||
|
PRBool, const nsAString&, const nsAString&);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION1(Send, nsIVariant*);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION1(SendAsBinary, const nsAString&);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION2(SetRequestHeader, const nsACString&,
|
||||||
|
const nsACString&);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION1(OverrideMimeType, const nsACString&);
|
||||||
|
|
||||||
|
MAKE_PROXIED_FUNCTION1(SetMultipart, PRBool);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __NSDOMWORKERXHRPROXIEDFUNCTIONS_H__ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,173 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is worker threads.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef __NSDOMWORKERXHRPROXY_H__
|
||||||
|
#define __NSDOMWORKERXHRPROXY_H__
|
||||||
|
|
||||||
|
// Bases
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
#include "nsIDOMEventListener.h"
|
||||||
|
#include "nsIRequestObserver.h"
|
||||||
|
|
||||||
|
// Other includes
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsStringGlue.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
// DOMWorker includes
|
||||||
|
#include "nsDOMWorkerXHR.h"
|
||||||
|
|
||||||
|
class nsIJSXMLHttpRequest;
|
||||||
|
class nsIThread;
|
||||||
|
class nsIVariant;
|
||||||
|
class nsIXMLHttpRequest;
|
||||||
|
class nsDOMWorkerXHREvent;
|
||||||
|
class nsDOMWorkerXHRWrappedListener;
|
||||||
|
class nsXMLHttpRequest;
|
||||||
|
|
||||||
|
class nsDOMWorkerXHRProxy : public nsRunnable,
|
||||||
|
public nsIDOMEventListener,
|
||||||
|
public nsIRequestObserver
|
||||||
|
{
|
||||||
|
|
||||||
|
friend class nsDOMWorkerXHREvent;
|
||||||
|
friend class nsDOMWorkerXHR;
|
||||||
|
friend class nsDOMWorkerXHRUpload;
|
||||||
|
|
||||||
|
typedef nsCOMPtr<nsIDOMEventListener> Listener;
|
||||||
|
typedef nsTArray<Listener> ListenerArray;
|
||||||
|
|
||||||
|
typedef nsRefPtr<nsDOMWorkerXHRWrappedListener> WrappedListener;
|
||||||
|
|
||||||
|
typedef nsresult (NS_STDCALL nsIDOMEventTarget::*AddRemoveFunction)
|
||||||
|
(const nsAString&, nsIDOMEventListener*, PRBool);
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIDOMEVENTLISTENER
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
|
|
||||||
|
nsDOMWorkerXHRProxy(nsDOMWorkerXHR* aWorkerXHR);
|
||||||
|
virtual ~nsDOMWorkerXHRProxy();
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
|
nsIXMLHttpRequest* GetXMLHttpRequest();
|
||||||
|
|
||||||
|
nsresult Abort();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult InitInternal();
|
||||||
|
void DestroyInternal();
|
||||||
|
|
||||||
|
nsresult Destroy();
|
||||||
|
|
||||||
|
void FlipOwnership();
|
||||||
|
|
||||||
|
nsresult AddEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aOnXListener,
|
||||||
|
PRBool aUploadListener);
|
||||||
|
|
||||||
|
nsresult RemoveEventListener(PRUint32 aType,
|
||||||
|
nsIDOMEventListener* aListener,
|
||||||
|
PRBool aUploadListener);
|
||||||
|
|
||||||
|
already_AddRefed<nsIDOMEventListener> GetOnXListener(PRUint32 aType,
|
||||||
|
PRBool aUploadListener);
|
||||||
|
|
||||||
|
nsresult HandleWorkerEvent(nsDOMWorkerXHREvent* aEvent, PRBool aUploadEvent);
|
||||||
|
|
||||||
|
nsresult HandleWorkerEvent(nsIDOMEvent* aEvent, PRBool aUploadEvent);
|
||||||
|
|
||||||
|
nsresult HandleEventInternal(PRUint32 aType,
|
||||||
|
nsIDOMEvent* aEvent,
|
||||||
|
PRBool aUploadEvent);
|
||||||
|
|
||||||
|
void ClearEventListeners();
|
||||||
|
|
||||||
|
// Methods of nsIXMLHttpRequest that we implement
|
||||||
|
nsresult GetAllResponseHeaders(char** _retval);
|
||||||
|
nsresult GetResponseHeader(const nsACString& aHeader,
|
||||||
|
nsACString& _retval);
|
||||||
|
nsresult OpenRequest(const nsACString& aMethod,
|
||||||
|
const nsACString& aUrl,
|
||||||
|
PRBool aAsync,
|
||||||
|
const nsAString& aUser,
|
||||||
|
const nsAString& aPassword);
|
||||||
|
nsresult Send(nsIVariant* aBody);
|
||||||
|
nsresult SendAsBinary(const nsAString& aBody);
|
||||||
|
nsresult GetResponseText(nsAString& _retval);
|
||||||
|
nsresult GetStatusText(nsACString& _retval);
|
||||||
|
nsresult GetStatus(nsresult* _retval);
|
||||||
|
nsresult GetReadyState(PRInt32* _retval);
|
||||||
|
nsresult SetRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue);
|
||||||
|
nsresult OverrideMimeType(const nsACString& aMimetype);
|
||||||
|
nsresult GetMultipart(PRBool* aMultipart);
|
||||||
|
nsresult SetMultipart(PRBool aMultipart);
|
||||||
|
|
||||||
|
// May be weak or strong, check mOwnedByXHR.
|
||||||
|
nsDOMWorkerXHR* mWorkerXHR;
|
||||||
|
|
||||||
|
// Always weak!
|
||||||
|
nsIXMLHttpRequest* mXHR;
|
||||||
|
nsXMLHttpRequest* mConcreteXHR;
|
||||||
|
|
||||||
|
// May be weak or strong, check mOwnedByXHR.
|
||||||
|
nsIXMLHttpRequestUpload* mUpload;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIThread> mMainThread;
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMWorkerXHREvent> mLastXHREvent;
|
||||||
|
|
||||||
|
nsTArray<ListenerArray> mXHRListeners;
|
||||||
|
nsTArray<WrappedListener> mXHROnXListeners;
|
||||||
|
|
||||||
|
nsTArray<ListenerArray> mUploadListeners;
|
||||||
|
nsTArray<WrappedListener> mUploadOnXListeners;
|
||||||
|
|
||||||
|
// Whether or not this object is owned by the real XHR object.
|
||||||
|
PRPackedBool mOwnedByXHR;
|
||||||
|
|
||||||
|
PRPackedBool mMultipart;
|
||||||
|
PRPackedBool mCanceled;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __NSDOMWORKERXHRPROXY_H__ */
|
|
@ -57,6 +57,8 @@ _TEST_FILES = \
|
||||||
test_threadErrors.html \
|
test_threadErrors.html \
|
||||||
test_threadTimeouts.html \
|
test_threadTimeouts.html \
|
||||||
test_longThread.html \
|
test_longThread.html \
|
||||||
|
test_xhr.html \
|
||||||
|
testXHR.txt \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
A noisy noise annoys an oyster.
|
|
@ -0,0 +1,114 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
Tests of DOM Worker Threads XHR(Bug 450452 )
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for DOM Worker Threads XHR (Bug 450452 )</title>
|
||||||
|
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450452">DOM Worker Threads XHR (Bug 450452)</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
function workerScript() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
function onload(event) {
|
||||||
|
if (event.target.status == 200) {
|
||||||
|
var message = { type: "error",
|
||||||
|
error: event.target.status };
|
||||||
|
postMessageToPool(message.toSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
var message = { type: "load",
|
||||||
|
data: xhr.responseText };
|
||||||
|
postMessageToPool(message.toSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onload = onload;
|
||||||
|
xhr.addEventListener("load", onload, false);
|
||||||
|
xhr.removeEventListener("load", onload, false);
|
||||||
|
if (!xhr.onload) {
|
||||||
|
var message = { type: "error",
|
||||||
|
error: "Lost message listener!" };
|
||||||
|
postMessageToPool(message.toSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.addEventListener("error", function(event) {
|
||||||
|
var message = { type: "error",
|
||||||
|
error: event.target.status };
|
||||||
|
postMessageToPool(message.toSource());
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function onprogress(event) {
|
||||||
|
var message = { type: "progress",
|
||||||
|
current: event.position,
|
||||||
|
total: event.totalSize };
|
||||||
|
postMessageToPool(message.toSource());
|
||||||
|
}
|
||||||
|
xhr.addEventListener("progress", onprogress, false);
|
||||||
|
|
||||||
|
xhr.addEventListener("foopety", function(event) {}, false);
|
||||||
|
xhr.removeEventListener("doopety", function(event) {}, false);
|
||||||
|
|
||||||
|
var upload = xhr.upload;
|
||||||
|
upload.onprogress = function(event) { };
|
||||||
|
upload.addEventListener("readystatechange", function(event) { }, false);
|
||||||
|
upload.removeEventListener("readystatechange", function(event) { }, false);
|
||||||
|
upload.addEventListener("load", function(event) { }, false);
|
||||||
|
upload.removeEventListener("readystatechange", function(event) { }, false);
|
||||||
|
|
||||||
|
this.messageListener = function(message, source) {
|
||||||
|
if (xhr.readystate > 0) {
|
||||||
|
throw "XHR already running!";
|
||||||
|
}
|
||||||
|
xhr.open("GET", message);
|
||||||
|
xhr.send(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pool = navigator.newWorkerPool();
|
||||||
|
pool.messageListener = function(message, source) {
|
||||||
|
var args = eval(message);
|
||||||
|
switch (args.type) {
|
||||||
|
case "progress": {
|
||||||
|
ok(parseInt(args.current) <= parseInt(args.total));
|
||||||
|
} break;
|
||||||
|
case "error": {
|
||||||
|
ok(false, "XHR error: " + args.error);
|
||||||
|
} break;
|
||||||
|
case "load": {
|
||||||
|
is(args.data, "A noisy noise annoys an oyster.");
|
||||||
|
document.getElementById("content").textContent = args.data;
|
||||||
|
SimpleTest.finish();
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
ok(false, "Unexpected message");
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pool.errorListener = function(error, source) {
|
||||||
|
ok(false, "Worker had an error:" + error);
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
var worker = pool.createWorker("(" + workerScript + ")();");
|
||||||
|
worker.postMessage("testXHR.txt");
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -3647,8 +3647,8 @@ public:
|
||||||
* @param cx The JSContext, this can be null, we don't do anything then
|
* @param cx The JSContext, this can be null, we don't do anything then
|
||||||
*/
|
*/
|
||||||
AutoScriptEvaluate(JSContext * cx)
|
AutoScriptEvaluate(JSContext * cx)
|
||||||
: mJSContext(cx), mState(0), mEvaluated(PR_FALSE),
|
: mJSContext(cx), mState(0), mErrorReporterSet(PR_FALSE),
|
||||||
mContextHasThread(0) {}
|
mEvaluated(PR_FALSE), mContextHasThread(0) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the pre script evaluation and sets the error reporter if given
|
* Does the pre script evaluation and sets the error reporter if given
|
||||||
|
@ -3665,7 +3665,7 @@ public:
|
||||||
private:
|
private:
|
||||||
JSContext* mJSContext;
|
JSContext* mJSContext;
|
||||||
JSExceptionState* mState;
|
JSExceptionState* mState;
|
||||||
JSErrorReporter mOldErrorReporter;
|
PRBool mErrorReporterSet;
|
||||||
PRBool mEvaluated;
|
PRBool mEvaluated;
|
||||||
jsword mContextHasThread;
|
jsword mContextHasThread;
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,11 @@ void AutoScriptEvaluate::StartEvaluating(JSErrorReporter errorReporter)
|
||||||
if(!mJSContext)
|
if(!mJSContext)
|
||||||
return;
|
return;
|
||||||
mEvaluated = PR_TRUE;
|
mEvaluated = PR_TRUE;
|
||||||
mOldErrorReporter = JS_SetErrorReporter(mJSContext, errorReporter);
|
if(!mJSContext->errorReporter)
|
||||||
|
{
|
||||||
|
JS_SetErrorReporter(mJSContext, errorReporter);
|
||||||
|
mErrorReporterSet = PR_TRUE;
|
||||||
|
}
|
||||||
mContextHasThread = JS_GetContextThread(mJSContext);
|
mContextHasThread = JS_GetContextThread(mJSContext);
|
||||||
if (mContextHasThread)
|
if (mContextHasThread)
|
||||||
JS_BeginRequest(mJSContext);
|
JS_BeginRequest(mJSContext);
|
||||||
|
@ -105,7 +109,9 @@ AutoScriptEvaluate::~AutoScriptEvaluate()
|
||||||
if(scriptNotify)
|
if(scriptNotify)
|
||||||
scriptNotify->ScriptExecuted();
|
scriptNotify->ScriptExecuted();
|
||||||
}
|
}
|
||||||
JS_SetErrorReporter(mJSContext, mOldErrorReporter);
|
|
||||||
|
if(mErrorReporterSet)
|
||||||
|
JS_SetErrorReporter(mJSContext, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It turns out that some errors may be not worth reporting. So, this
|
// It turns out that some errors may be not worth reporting. So, this
|
||||||
|
@ -906,6 +912,15 @@ nsXPCWrappedJSClass::CleanupPointerTypeObject(const nsXPTType& type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AutoClearPendingException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoClearPendingException(JSContext *cx) : mCx(cx) { }
|
||||||
|
~AutoClearPendingException() { JS_ClearPendingException(mCx); }
|
||||||
|
private:
|
||||||
|
JSContext* mCx;
|
||||||
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
|
nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
|
||||||
const char * aPropertyName,
|
const char * aPropertyName,
|
||||||
|
@ -926,8 +941,10 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
|
||||||
nsresult pending_result = xpcc->GetPendingResult();
|
nsresult pending_result = xpcc->GetPendingResult();
|
||||||
|
|
||||||
jsval js_exception;
|
jsval js_exception;
|
||||||
|
JSBool is_js_exception = JS_GetPendingException(cx, &js_exception);
|
||||||
|
|
||||||
/* JS might throw an expection whether the reporter was called or not */
|
/* JS might throw an expection whether the reporter was called or not */
|
||||||
if(JS_GetPendingException(cx, &js_exception))
|
if(is_js_exception)
|
||||||
{
|
{
|
||||||
if(!xpc_exception)
|
if(!xpc_exception)
|
||||||
XPCConvert::JSValToXPCException(ccx, js_exception, anInterfaceName,
|
XPCConvert::JSValToXPCException(ccx, js_exception, anInterfaceName,
|
||||||
|
@ -939,9 +956,10 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
|
||||||
{
|
{
|
||||||
ccx.GetThreadData()->SetException(nsnull); // XXX necessary?
|
ccx.GetThreadData()->SetException(nsnull); // XXX necessary?
|
||||||
}
|
}
|
||||||
JS_ClearPendingException(cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoClearPendingException acpe(cx);
|
||||||
|
|
||||||
if(xpc_exception)
|
if(xpc_exception)
|
||||||
{
|
{
|
||||||
nsresult e_result;
|
nsresult e_result;
|
||||||
|
@ -992,6 +1010,14 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to use the error reporter set on the context to handle this
|
||||||
|
// error if it came from a JS exception.
|
||||||
|
if(reportable && is_js_exception &&
|
||||||
|
cx->errorReporter != xpcWrappedJSErrorReporter)
|
||||||
|
{
|
||||||
|
reportable = !JS_ReportPendingException(cx);
|
||||||
|
}
|
||||||
|
|
||||||
if(reportable)
|
if(reportable)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Загрузка…
Ссылка в новой задаче