From b382b4642e107f7546d080fdb90f217c369f0b8e Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Wed, 9 Mar 2016 18:13:12 +0800 Subject: [PATCH] Bug 1003432: Expose CustomEvent in Worker. r=smaug --- dom/events/CustomEvent.cpp | 69 ++++++++++++------- dom/events/CustomEvent.h | 4 +- dom/events/test/mochitest.ini | 2 + dom/events/test/test_bug1003432.html | 45 ++++++++++++ dom/events/test/test_bug1003432.js | 23 +++++++ dom/events/test/test_bug427537.html | 4 ++ dom/webidl/CustomEvent.webidl | 3 +- .../test_serviceworker_interfaces.js | 2 + dom/workers/test/test_worker_interfaces.js | 2 + 9 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 dom/events/test/test_bug1003432.html create mode 100644 dom/events/test/test_bug1003432.js diff --git a/dom/events/CustomEvent.cpp b/dom/events/CustomEvent.cpp index 0094b4124a93..a6197e0400e3 100644 --- a/dom/events/CustomEvent.cpp +++ b/dom/events/CustomEvent.cpp @@ -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 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 aDetail, ErrorResult& aRv) { - nsCOMPtr 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 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 aRetval) { - if (!mDetail) { - aRetval.setNull(); - return; - } - - VariantToJsval(aCx, mDetail, aRetval); + aRetval.set(mDetail); } already_AddRefed diff --git a/dom/events/CustomEvent.h b/dom/events/CustomEvent.h index 24cd0efa0e12..d14243cff06c 100644 --- a/dom/events/CustomEvent.h +++ b/dom/events/CustomEvent.h @@ -21,7 +21,7 @@ class CustomEvent final : public Event, private: virtual ~CustomEvent(); - nsCOMPtr mDetail; + JS::Heap 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 diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini index b45581db1208..9360f98af791 100644 --- a/dom/events/test/mochitest.ini +++ b/dom/events/test/mochitest.ini @@ -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' diff --git a/dom/events/test/test_bug1003432.html b/dom/events/test/test_bug1003432.html new file mode 100644 index 000000000000..7ffd3f7c4c23 --- /dev/null +++ b/dom/events/test/test_bug1003432.html @@ -0,0 +1,45 @@ + + + + + Test for Bug 1003432 + + + + +Mozilla Bug 1003432 +

+ +
+
+
+ + diff --git a/dom/events/test/test_bug1003432.js b/dom/events/test/test_bug1003432.js new file mode 100644 index 000000000000..1ace8fefd760 --- /dev/null +++ b/dom/events/test/test_bug1003432.js @@ -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); diff --git a/dom/events/test/test_bug427537.html b/dom/events/test/test_bug427537.html index 6ca1a4c8a893..060581f2f636 100644 --- a/dom/events/test/test_bug427537.html +++ b/dom/events/test/test_bug427537.html @@ -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."); diff --git a/dom/webidl/CustomEvent.webidl b/dom/webidl/CustomEvent.webidl index 180159b33ae6..299a41ec098b 100644 --- a/dom/webidl/CustomEvent.webidl +++ b/dom/webidl/CustomEvent.webidl @@ -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; diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js index e10a25f95de2..0a84fb818cd0 100644 --- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js +++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js @@ -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! diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js index db859d237407..0d596b2b647c 100644 --- a/dom/workers/test/test_worker_interfaces.js +++ b/dom/workers/test/test_worker_interfaces.js @@ -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!