Bug 1003432: Expose CustomEvent in Worker. r=smaug

This commit is contained in:
Jocelyn Liu 2016-03-09 18:13:12 +08:00
parent 888399c632
commit b382b4642e
9 changed files with 128 additions and 26 deletions

View File

@ -17,21 +17,30 @@ using namespace mozilla::dom;
CustomEvent::CustomEvent(mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetEvent* aEvent)
: Event(aOwner, aPresContext, aEvent)
: Event(aOwner, aPresContext, aEvent)
, mDetail(JS::NullValue())
{
mozilla::HoldJSObjects(this);
}
CustomEvent::~CustomEvent() {}
CustomEvent::~CustomEvent()
{
mozilla::DropJSObjects(this);
}
NS_IMPL_CYCLE_COLLECTION_CLASS(CustomEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CustomEvent, Event)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDetail)
tmp->mDetail.setUndefined();
mozilla::DropJSObjects(this);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CustomEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDetail)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CustomEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(CustomEvent, Event)
NS_IMPL_RELEASE_INHERITED(CustomEvent, Event)
@ -66,8 +75,21 @@ CustomEvent::InitCustomEvent(const nsAString& aType,
bool aCancelable,
nsIVariant* aDetail)
{
AutoJSAPI jsapi;
NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> detail(cx);
if (!aDetail) {
detail = JS::NullValue();
} else if (NS_WARN_IF(!VariantToJsval(cx, aDetail, &detail))) {
JS_ClearPendingException(cx);
return NS_ERROR_FAILURE;
}
Event::InitEvent(aType, aCanBubble, aCancelable);
mDetail = aDetail;
mDetail = detail;
return NS_OK;
}
@ -79,35 +101,36 @@ CustomEvent::InitCustomEvent(JSContext* aCx,
JS::Handle<JS::Value> aDetail,
ErrorResult& aRv)
{
nsCOMPtr<nsIVariant> detail;
if (nsIXPConnect* xpc = nsContentUtils::XPConnect()) {
xpc->JSToVariant(aCx, aDetail, getter_AddRefs(detail));
}
if (!detail) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
InitCustomEvent(aType, aCanBubble, aCancelable, detail);
Event::InitEvent(aType, aCanBubble, aCancelable);
mDetail = aDetail;
}
NS_IMETHODIMP
CustomEvent::GetDetail(nsIVariant** aDetail)
{
NS_IF_ADDREF(*aDetail = mDetail);
return NS_OK;
if (mDetail.isNull()) {
*aDetail = nullptr;
return NS_OK;
}
AutoJSAPI jsapi;
NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> detail(cx, mDetail);
nsIXPConnect* xpc = nsContentUtils::XPConnect();
if (NS_WARN_IF(!xpc)) {
return NS_ERROR_FAILURE;
}
return xpc->JSToVariant(cx, detail, aDetail);
}
void
CustomEvent::GetDetail(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval)
{
if (!mDetail) {
aRetval.setNull();
return;
}
VariantToJsval(aCx, mDetail, aRetval);
aRetval.set(mDetail);
}
already_AddRefed<CustomEvent>

View File

@ -21,7 +21,7 @@ class CustomEvent final : public Event,
private:
virtual ~CustomEvent();
nsCOMPtr<nsIVariant> mDetail;
JS::Heap<JS::Value> mDetail;
public:
explicit CustomEvent(mozilla::dom::EventTarget* aOwner,
@ -29,7 +29,7 @@ public:
mozilla::WidgetEvent* aEvent = nullptr);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CustomEvent, Event)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CustomEvent, Event)
NS_FORWARD_TO_EVENT
NS_DECL_NSIDOMCUSTOMEVENT

View File

@ -46,6 +46,8 @@ skip-if = buildapp == 'b2g' # b2g(2 failures out of 8, mousewheel test) b2g-debu
[test_bug426082.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || os == "win" || toolkit == 'android' || e10s # Intermittent failures, bug 921693 # b2g(1 failure out of 6, Moving the mouse down from the label should have unpressed the button) b2g-debug(1 failure out of 6, Moving the mouse down from the label should have unpressed the button) b2g-desktop(1 failure out of 6, Moving the mouse down from the label should have unpressed the button)
[test_bug427537.html]
[test_bug1003432.html]
support-files = test_bug1003432.js
[test_bug428988.html]
[test_bug432698.html]
skip-if = buildapp == 'mulet'

View File

@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1003432
-->
<head>
<title>Test for Bug 1003432</title>
<script type="application/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=1003432">Mozilla Bug 1003432</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1003432 **/
// Test CustomEvent on worker
SimpleTest.waitForExplicitFinish();
var worker = new Worker("test_bug1003432.js");
ok(worker, "Should have worker!");
var count = 0;
worker.onmessage = function(evt) {
is(evt.data.type, "foobar", "Should get 'foobar' event!");
is(evt.data.detail, "test", "Detail should be 'test'.");
ok(evt.data.bubbles, "Event should bubble!");
ok(evt.data.cancelable, "Event should be cancelable.");
// wait for test results of constructor and initCustomEvent
if (++count == 2) {
worker.terminate();
SimpleTest.finish();
}
};
worker.postMessage("");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,23 @@
addEventListener("foobar",
function(evt) {
postMessage(
{
type: evt.type,
bubbles: evt.bubbles,
cancelable: evt.cancelable,
detail: evt.detail
});
}, true);
addEventListener("message",
function(evt) {
// Test the constructor of CustomEvent
var e = new CustomEvent("foobar",
{bubbles:true, cancelable: true, detail:"test"});
dispatchEvent(e);
// Test initCustomEvent
e = new CustomEvent("foobar");
e.initCustomEvent("foobar", true, true, "test");
dispatchEvent(e);
}, true);

View File

@ -39,6 +39,10 @@ document.addEventListener("foobar",
document.dispatchEvent(e);
ok(didCallListener, "Should have called listener!");
e = document.createEvent("CustomEvent");
e.initEvent("foo", true, true);
is(e.detail, null, "Default detail should be null.");
e = document.createEvent("CustomEvent");
e.initCustomEvent("foobar", true, true, 1);
is(e.detail, 1, "Detail should be 1.");

View File

@ -10,7 +10,8 @@
* liability, trademark and document use rules apply.
*/
[Constructor(DOMString type, optional CustomEventInit eventInitDict)]
[Constructor(DOMString type, optional CustomEventInit eventInitDict),
Exposed=(Window, Worker)]
interface CustomEvent : Event
{
readonly attribute any detail;

View File

@ -88,6 +88,8 @@ var interfaceNamesInGlobalScope =
"Client",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Clients",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CustomEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "DataStore", b2g: true },
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -84,6 +84,8 @@ var interfaceNamesInGlobalScope =
"Cache",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CacheStorage",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CustomEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"DedicatedWorkerGlobalScope",
// IMPORTANT: Do not change this list without review from a DOM peer!