From b5de3264a2008e8532dec2bab4eea91156cc7f94 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 20 Nov 2017 13:59:22 -0500 Subject: [PATCH] Bug 1379688 part 2. Make the EventTarget interface constructible. r=smaug MozReview-Commit-ID: 4xrSSqXna7F --- dom/bindings/Bindings.conf | 1 - dom/events/ConstructibleEventTarget.cpp | 20 ++++++++++ dom/events/ConstructibleEventTarget.h | 35 +++++++++++++++++ dom/events/DOMEventTargetHelper.h | 5 +-- dom/events/EventTarget.cpp | 15 +++++++ dom/events/EventTarget.h | 8 ++++ dom/events/moz.build | 2 + dom/webidl/EventTarget.webidl | 3 +- .../EventTarget-constructible.any.js.ini | 17 -------- .../web-platform/meta/dom/interfaces.html.ini | 39 ------------------- .../tests/eventsource/interfaces.html | 2 +- .../tests/interfaces/dedicated-workers.idl | 2 +- .../resources/interfaces-idls.js | 2 +- .../tests/webrtc/RTCPeerConnection-idl.html | 1 + 14 files changed, 87 insertions(+), 65 deletions(-) create mode 100644 dom/events/ConstructibleEventTarget.cpp create mode 100644 dom/events/ConstructibleEventTarget.h delete mode 100644 testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 1e89b10237a1..96e724a8dae2 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -317,7 +317,6 @@ DOMInterfaces = { # We can also get rid of the UnwrapArg bits in # the dom QueryInterface (in BindingUtils.cpp) at that point. 'hasXPConnectImpls': True, - 'concrete': False, 'jsImplParent': 'mozilla::DOMEventTargetHelper', }, diff --git a/dom/events/ConstructibleEventTarget.cpp b/dom/events/ConstructibleEventTarget.cpp new file mode 100644 index 000000000000..bed718422e38 --- /dev/null +++ b/dom/events/ConstructibleEventTarget.cpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ConstructibleEventTarget.h" +#include "mozilla/dom/EventTargetBinding.h" + +namespace mozilla { +namespace dom { + +JSObject* +ConstructibleEventTarget::WrapObject(JSContext* cx, JS::Handle aGivenProto) +{ + return EventTargetBinding::Wrap(cx, this, aGivenProto); +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/events/ConstructibleEventTarget.h b/dom/events/ConstructibleEventTarget.h new file mode 100644 index 000000000000..ae0c76489c4c --- /dev/null +++ b/dom/events/ConstructibleEventTarget.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ConstructibleEventTarget_h_ +#define mozilla_dom_ConstructibleEventTarget_h_ + +#include "mozilla/DOMEventTargetHelper.h" +#include "js/RootingAPI.h" + +namespace mozilla { +namespace dom { + +class ConstructibleEventTarget : public DOMEventTargetHelper +{ +public: + // Not worrying about isupports and cycle collection here. This does mean + // ConstructibleEventTarget will show up in CC and refcount logs as a + // DOMEventTargetHelper, but that's probably OK. + + explicit ConstructibleEventTarget(nsIGlobalObject* aGlobalObject) + : DOMEventTargetHelper(aGlobalObject) + { + } + + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle aGivenProto) override; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ConstructibleEventTarget_h_ diff --git a/dom/events/DOMEventTargetHelper.h b/dom/events/DOMEventTargetHelper.h index 0097cbcefe39..24de23dd7c29 100644 --- a/dom/events/DOMEventTargetHelper.h +++ b/dom/events/DOMEventTargetHelper.h @@ -143,10 +143,7 @@ public: void BindToOwner(nsPIDOMWindowInner* aOwner); void BindToOwner(DOMEventTargetHelper* aOther); virtual void DisconnectFromOwner(); - nsIGlobalObject* GetParentObject() const - { - return GetOwnerGlobal(); - } + using EventTarget::GetParentObject; virtual nsIGlobalObject* GetOwnerGlobal() const override { nsCOMPtr parentObject = do_QueryReferent(mParentObject); diff --git a/dom/events/EventTarget.cpp b/dom/events/EventTarget.cpp index a5e11344fe33..ed4ac42dcbba 100644 --- a/dom/events/EventTarget.cpp +++ b/dom/events/EventTarget.cpp @@ -7,11 +7,26 @@ #include "mozilla/EventListenerManager.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/dom/EventTargetBinding.h" +#include "mozilla/dom/ConstructibleEventTarget.h" +#include "nsIGlobalObject.h" #include "nsThreadUtils.h" namespace mozilla { namespace dom { +/* static */ +already_AddRefed +EventTarget::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) +{ + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (!global) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + RefPtr target = new ConstructibleEventTarget(global); + return target.forget(); +} + void EventTarget::RemoveEventListener(const nsAString& aType, EventListener* aListener, diff --git a/dom/events/EventTarget.h b/dom/events/EventTarget.h index cd6b57cf730a..379a0851fff1 100644 --- a/dom/events/EventTarget.h +++ b/dom/events/EventTarget.h @@ -28,6 +28,7 @@ class Event; class EventListener; class EventListenerOptionsOrBoolean; class EventHandlerNonNull; +class GlobalObject; template struct Nullable; @@ -43,6 +44,8 @@ public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_EVENTTARGET_IID) // WebIDL API + static already_AddRefed Constructor(const GlobalObject& aGlobal, + ErrorResult& aRv); using nsIDOMEventTarget::AddEventListener; using nsIDOMEventTarget::RemoveEventListener; using nsIDOMEventTarget::DispatchEvent; @@ -57,6 +60,11 @@ public: ErrorResult& aRv); bool DispatchEvent(Event& aEvent, CallerType aCallerType, ErrorResult& aRv); + nsIGlobalObject* GetParentObject() const + { + return GetOwnerGlobal(); + } + // Note, this takes the type in onfoo form! EventHandlerNonNull* GetEventHandler(const nsAString& aType) { diff --git a/dom/events/moz.build b/dom/events/moz.build index 07f64473f74c..267677b382c5 100644 --- a/dom/events/moz.build +++ b/dom/events/moz.build @@ -45,6 +45,7 @@ EXPORTS.mozilla.dom += [ 'ClipboardEvent.h', 'CommandEvent.h', 'CompositionEvent.h', + 'ConstructibleEventTarget.h', 'CustomEvent.h', 'DataTransfer.h', 'DataTransferItem.h', @@ -87,6 +88,7 @@ UNIFIED_SOURCES += [ 'ClipboardEvent.cpp', 'CommandEvent.cpp', 'CompositionEvent.cpp', + 'ConstructibleEventTarget.cpp', 'ContentEventHandler.cpp', 'CustomEvent.cpp', 'DataTransfer.cpp', diff --git a/dom/webidl/EventTarget.webidl b/dom/webidl/EventTarget.webidl index 046987524e12..d5eadf58dae9 100644 --- a/dom/webidl/EventTarget.webidl +++ b/dom/webidl/EventTarget.webidl @@ -23,7 +23,8 @@ dictionary AddEventListenerOptions : EventListenerOptions { boolean once = false; }; -[Exposed=(Window,Worker,WorkerDebugger,System)] +[Constructor, + Exposed=(Window,Worker,WorkerDebugger,System)] interface EventTarget { /* Passing null for wantsUntrusted means "default behavior", which differs in content and chrome. In content that default boolean diff --git a/testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini b/testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini deleted file mode 100644 index 16c19caf0de6..000000000000 --- a/testing/web-platform/meta/dom/events/EventTarget-constructible.any.js.ini +++ /dev/null @@ -1,17 +0,0 @@ -[EventTarget-constructible.any.html] - type: testharness - [A constructed EventTarget can be used as expected] - expected: FAIL - - [EventTarget can be subclassed] - expected: FAIL - - -[EventTarget-constructible.any.worker.html] - type: testharness - [A constructed EventTarget can be used as expected] - expected: FAIL - - [EventTarget can be subclassed] - expected: FAIL - diff --git a/testing/web-platform/meta/dom/interfaces.html.ini b/testing/web-platform/meta/dom/interfaces.html.ini index d079579ea1ef..9c81e6ad5a76 100644 --- a/testing/web-platform/meta/dom/interfaces.html.ini +++ b/testing/web-platform/meta/dom/interfaces.html.ini @@ -22,48 +22,9 @@ [Text interface: document.createTextNode("abc") must inherit property "assignedSlot" with the proper type (2)] expected: FAIL - [EventTarget must be primary interface of new EventTarget()] - expected: FAIL - - [Stringification of new EventTarget()] - expected: FAIL - - [EventTarget interface: new EventTarget() must inherit property "addEventListener" with the proper type (0)] - expected: FAIL - - [EventTarget interface: calling addEventListener(DOMString,EventListener,[object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError] - expected: FAIL - - [EventTarget interface: new EventTarget() must inherit property "removeEventListener" with the proper type (1)] - expected: FAIL - - [EventTarget interface: calling removeEventListener(DOMString,EventListener,[object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError] - expected: FAIL - - [EventTarget interface: new EventTarget() must inherit property "dispatchEvent" with the proper type (2)] - expected: FAIL - - [EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError] - expected: FAIL - [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type (1)] expected: FAIL - [EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type] - expected: FAIL - - [EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError] - expected: FAIL - - [EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type] - expected: FAIL - - [EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new EventTarget() with too few arguments must throw TypeError] - expected: FAIL - - [EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type] - expected: FAIL - [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type] expected: FAIL diff --git a/testing/web-platform/tests/eventsource/interfaces.html b/testing/web-platform/tests/eventsource/interfaces.html index 443d7467e078..2935927fd325 100644 --- a/testing/web-platform/tests/eventsource/interfaces.html +++ b/testing/web-platform/tests/eventsource/interfaces.html @@ -9,7 +9,7 @@