Bug 870219. Add a way for chrome JS that's implementing a WebIDL interface to get/set event handlers sanely on content objects. r=smaug
☠☠ backed out by 10cb7bc4cc58 ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 09 May 2013 13:07:16 -0400
changeset 142355 52f646b2055c3af052d40060a85bbca741622687
parent 142354 59c279d93f8e268449e5153b1330e9d254ea4f8a
child 142356 9f5dee705c5ef948fc41a20f5de541d3a7f4e21a
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs870219
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 870219. Add a way for chrome JS that's implementing a WebIDL interface to get/set event handlers sanely on content objects. r=smaug
content/events/public/EventTarget.h
content/events/src/EventTarget.cpp
content/events/src/nsDOMEventTargetHelper.h
dom/webidl/EventTarget.webidl
dom/workers/EventTarget.h
--- a/content/events/public/EventTarget.h
+++ b/content/events/public/EventTarget.h
@@ -6,22 +6,25 @@
 #ifndef mozilla_dom_EventTarget_h_
 #define mozilla_dom_EventTarget_h_
 
 #include "nsIDOMEventTarget.h"
 #include "nsWrapperCache.h"
 #include "nsIDOMEventListener.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Nullable.h"
+#include "nsIAtom.h"
+
 class nsDOMEvent;
 
 namespace mozilla {
 namespace dom {
 
 class EventListener;
+class EventHandlerNonNull;
 
 // IID for the dom::EventTarget interface
 #define NS_EVENTTARGET_IID \
 { 0x0a5aed21, 0x0bab, 0x48b3, \
  { 0xbe, 0x4b, 0xd4, 0xf9, 0xd4, 0xea, 0xc7, 0xdb } }
 
 class EventTarget : public nsIDOMEventTarget,
                     public nsWrapperCache
@@ -38,16 +41,34 @@ public:
                                 bool aCapture,
                                 const Nullable<bool>& aWantsUntrusted,
                                 ErrorResult& aRv) = 0;
   virtual void RemoveEventListener(const nsAString& aType,
                                    nsIDOMEventListener* aCallback,
                                    bool aCapture,
                                    ErrorResult& aRv);
   bool DispatchEvent(nsDOMEvent& aEvent, ErrorResult& aRv);
+
+  EventHandlerNonNull* GetEventHandler(const nsAString& aType)
+  {
+    nsCOMPtr<nsIAtom> type = do_GetAtom(aType);
+    return GetEventHandler(type);
+  }
+
+  void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler,
+                       ErrorResult& rv)
+  {
+    nsCOMPtr<nsIAtom> type = do_GetAtom(aType);
+    return SetEventHandler(type, aHandler, rv);
+  }
+
+protected:
+  EventHandlerNonNull* GetEventHandler(nsIAtom* aType);
+  void SetEventHandler(nsIAtom* aType, EventHandlerNonNull* aHandler,
+                       ErrorResult& rv);
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(EventTarget, NS_EVENTTARGET_IID)
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_EventTarget_h_
--- a/content/events/src/EventTarget.cpp
+++ b/content/events/src/EventTarget.cpp
@@ -17,10 +17,24 @@ EventTarget::RemoveEventListener(const n
                                  ErrorResult& aRv)
 {
   nsEventListenerManager* elm = GetListenerManager(false);
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
 }
 
+EventHandlerNonNull*
+EventTarget::GetEventHandler(nsIAtom* aType)
+{
+  nsEventListenerManager* elm = GetListenerManager(false);
+  return elm ? elm->GetEventHandler(aType) : nullptr;
+}
+
+void
+EventTarget::SetEventHandler(nsIAtom* aType, EventHandlerNonNull* aHandler,
+                             ErrorResult& rv)
+{
+  rv = GetListenerManager(true)->SetEventHandler(aType, aHandler);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -85,30 +85,21 @@ public:
   bool HasListenersFor(nsIAtom* aTypeWithOn)
   {
     return mListenerManager && mListenerManager->HasListenersFor(aTypeWithOn);
   }
 
   nsresult SetEventHandler(nsIAtom* aType,
                            JSContext* aCx,
                            const JS::Value& aValue);
-  void SetEventHandler(nsIAtom* aType,
-                       mozilla::dom::EventHandlerNonNull* aHandler,
-                       mozilla::ErrorResult& rv)
-  {
-    rv = GetListenerManager(true)->SetEventHandler(aType, aHandler);
-  }
+  using mozilla::dom::EventTarget::SetEventHandler;
   void GetEventHandler(nsIAtom* aType,
                        JSContext* aCx,
                        JS::Value* aValue);
-  mozilla::dom::EventHandlerNonNull* GetEventHandler(nsIAtom* aType)
-  {
-    nsEventListenerManager* elm = GetListenerManager(false);
-    return elm ? elm->GetEventHandler(aType) : nullptr;
-  }
+  using mozilla::dom::EventTarget::GetEventHandler;
 
   nsresult CheckInnerWindowCorrectness()
   {
     NS_ENSURE_STATE(!mHasOrHasHadOwnerWindow || mOwnerWindow);
     if (mOwnerWindow) {
       NS_ASSERTION(mOwnerWindow->IsInnerWindow(), "Should have inner window here!\n");
       nsPIDOMWindow* outer = mOwnerWindow->GetOuterWindow();
       if (!outer || outer->GetCurrentInnerWindow() != mOwnerWindow) {
--- a/dom/webidl/EventTarget.webidl
+++ b/dom/webidl/EventTarget.webidl
@@ -22,8 +22,18 @@ interface EventTarget {
                         optional boolean? wantsUntrusted = null);
   [Throws]
   void removeEventListener(DOMString type,
                            EventListener? listener,
                            optional boolean capture = false);
   [Throws]
   boolean dispatchEvent(Event event);
 };
+
+// Mozilla extensions for use by JS-implemented event targets to
+// implement on* properties.
+partial interface EventTarget {
+  [ChromeOnly, Throws]
+  void setEventHandler(DOMString type, EventHandler handler);
+
+  [ChromeOnly]
+  EventHandler getEventHandler(DOMString type);
+};
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -58,13 +58,24 @@ public:
   SetEventListener(const nsAString& aType, JSObject* aListener,
                    ErrorResult& aRv);
 
   bool
   HasListeners() const
   {
     return mListenerManager.HasListeners();
   }
+
+  void SetEventHandler(JSContext*, const nsAString& aType, JSObject* aHandler,
+                       ErrorResult& rv)
+  {
+    rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  }
+
+  JSObject* GetEventHandler(JSContext*, const nsAString& aType)
+  {
+    return nullptr;
+  }
 };
 
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_eventtarget_h__