Bug 473861 - 'Workers: Using functions (rather than attributes) for message/error handlers doesn't work'. r+sr=mrbkap, a=sicking

This commit is contained in:
Ben Turner 2009-01-21 15:51:16 -08:00
parent 9c75bee86d
commit d4ef5a62c6
5 changed files with 106 additions and 1 deletions

View File

@ -570,10 +570,66 @@ nsDOMWorkerScope::GetHelperForLanguage(PRUint32 aLanguage,
nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY | \
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES | \
nsIXPCScriptable::WANT_ADDPROPERTY
#define XPC_MAP_WANT_ADDPROPERTY
#include "xpc_map_end.h"
NS_IMETHODIMP
nsDOMWorkerScope::AddProperty(nsIXPConnectWrappedNative* aWrapper,
JSContext* aCx,
JSObject* aObj,
jsval aId,
jsval* aVp,
PRBool* _retval)
{
// We're not going to be setting any exceptions manually so set _retval to
// true in the beginning.
*_retval = PR_TRUE;
// Bail out now if any of our prerequisites are not met. We only care about
// someone making an 'onmessage' or 'onerror' function so aId must be a
// string and aVp must be a function.
JSObject* funObj;
if (!(JSVAL_IS_STRING(aId) &&
JSVAL_IS_OBJECT(*aVp) &&
(funObj = JSVAL_TO_OBJECT(*aVp)) &&
JS_ObjectIsFunction(aCx, funObj))) {
return NS_OK;
}
const char* name = JS_GetStringBytes(JSVAL_TO_STRING(aId));
// Figure out which listener we're setting.
SetListenerFunc func;
if (!strcmp(name, "onmessage")) {
func = &nsDOMWorkerScope::SetOnmessage;
}
else if (!strcmp(name, "onerror")) {
func = &nsDOMWorkerScope::SetOnerror;
}
else {
// Some other function, we don't need to do anything special after all.
return NS_OK;
}
// Wrap the function as an nsIDOMEventListener.
nsCOMPtr<nsIDOMEventListener> listener;
nsresult rv =
nsContentUtils::XPConnect()->WrapJS(aCx, funObj,
NS_GET_IID(nsIDOMEventListener),
getter_AddRefs(listener));
NS_ENSURE_SUCCESS(rv, rv);
// And pass the listener to the appropriate setter.
rv = (this->*func)(listener);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerScope::GetSelf(nsIWorkerGlobalScope** aSelf)
{

View File

@ -71,6 +71,9 @@ class nsDOMWorkerScope : public nsIWorkerScope,
public nsIXPCScriptable,
public nsIClassInfo
{
typedef nsresult (NS_STDCALL nsDOMWorkerScope::*SetListenerFunc)
(nsIDOMEventListener*);
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWORKERGLOBALSCOPE

View File

@ -51,6 +51,8 @@ _TEST_FILES = \
test_errorPropagation.html \
errorPropagation_worker1.js \
errorPropagation_worker2.js \
test_functionHandlers.html \
functionHandlers_worker.js \
test_importScripts.html \
importScripts_worker.js \
importScripts_worker_imported1.js \

View File

@ -0,0 +1,8 @@
function onmessage(event) {
throw event.data;
}
function onerror(event) {
postMessage(event.message);
event.preventDefault();
}

View File

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<!--
Tests of DOM Worker Threads
-->
<head>
<title>Test for DOM Worker Threads Recursion</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>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var worker = new Worker("functionHandlers_worker.js");
var message = "hello!";
worker.onmessage = function(event) {
is(event.data, "uncaught exception: " + message, "Bad message!");
SimpleTest.finish();
};
worker.postMessage(message);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>