Bug 851073 - Move MouseEvent to Web IDL; r=smaug
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 14 Mar 2013 11:30:47 -0400
changeset 125311 b66cea2dc7d273cb3fbc1cd5ac88fad3853c9277
parent 125310 a23ff3177682f22f6c615365bca1ccc400e1c08f
child 125312 061871df8f9e416fdcac9930ef19819570ee05eb
push idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs851073
milestone22.0a1
Bug 851073 - Move MouseEvent to Web IDL; r=smaug
content/events/src/nsDOMMouseEvent.cpp
content/events/src/nsDOMMouseEvent.h
dom/bindings/Bindings.conf
dom/webidl/MouseEvent.webidl
dom/webidl/WebIDL.mk
--- a/content/events/src/nsDOMMouseEvent.cpp
+++ b/content/events/src/nsDOMMouseEvent.cpp
@@ -175,16 +175,49 @@ nsDOMMouseEvent::InitFromCtor(const nsAS
       break;
     default:
       break;
   }
 
   return NS_OK;
 }
 
+already_AddRefed<nsDOMMouseEvent>
+nsDOMMouseEvent::Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                             const nsAString& aType,
+                             const mozilla::dom::MouseEventInit& aParam,
+                             mozilla::ErrorResult& aRv)
+{
+  nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.Get());
+  nsRefPtr<nsDOMMouseEvent> e = new nsDOMMouseEvent(t, nullptr, nullptr);
+  e->SetIsDOMBinding();
+  bool trusted = e->Init(t);
+  e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
+                    aParam.mView, aParam.mDetail, aParam.mScreenX,
+                    aParam.mScreenY, aParam.mClientX, aParam.mClientY,
+                    aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
+                    aParam.mMetaKey, aParam.mButton, aParam.mRelatedTarget,
+                    aRv);
+  e->SetTrusted(trusted);
+
+  switch (e->mEvent->eventStructType) {
+    case NS_MOUSE_EVENT:
+    case NS_MOUSE_SCROLL_EVENT:
+    case NS_WHEEL_EVENT:
+    case NS_DRAG_EVENT:
+    case NS_SIMPLE_GESTURE_EVENT:
+      static_cast<nsMouseEvent_base*>(e->mEvent)->buttons = aParam.mButtons;
+      break;
+    default:
+      break;
+  }
+
+  return e.forget();
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::InitNSMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
                                   nsIDOMWindow *aView, int32_t aDetail, int32_t aScreenX,
                                   int32_t aScreenY, int32_t aClientX, int32_t aClientY,
                                   bool aCtrlKey, bool aAltKey, bool aShiftKey,
                                   bool aMetaKey, uint16_t aButton, nsIDOMEventTarget *aRelatedTarget,
                                   float aPressure, uint16_t aInputSource)
 {
@@ -198,186 +231,224 @@ nsDOMMouseEvent::InitNSMouseEvent(const 
   static_cast<nsMouseEvent_base*>(mEvent)->inputSource = aInputSource;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetButton(uint16_t* aButton)
 {
   NS_ENSURE_ARG_POINTER(aButton);
+  *aButton = Button();
+  return NS_OK;
+}
+
+uint16_t
+nsDOMMouseEvent::Button()
+{
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      *aButton = static_cast<nsMouseEvent_base*>(mEvent)->button;
-      break;
+      return static_cast<nsMouseEvent_base*>(mEvent)->button;
     default:
       NS_WARNING("Tried to get mouse button for non-mouse event!");
-      *aButton = nsMouseEvent::eLeftButton;
-      break;
+      return nsMouseEvent::eLeftButton;
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetButtons(uint16_t* aButtons)
 {
   NS_ENSURE_ARG_POINTER(aButtons);
+  *aButtons = Buttons();
+  return NS_OK;
+}
+
+uint16_t
+nsDOMMouseEvent::Buttons()
+{
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      *aButtons = static_cast<nsMouseEvent_base*>(mEvent)->buttons;
-      break;
+      return static_cast<nsMouseEvent_base*>(mEvent)->buttons;
     default:
       MOZ_NOT_REACHED("Tried to get mouse buttons for non-mouse event!");
-      *aButtons = 0;
-      break;
+      return 0;
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
 {
   NS_ENSURE_ARG_POINTER(aRelatedTarget);
-  *aRelatedTarget = nullptr;
-  nsISupports* relatedTarget = nullptr;
+  *aRelatedTarget = GetRelatedTarget().get();
+  return NS_OK;
+}
+
+already_AddRefed<mozilla::dom::EventTarget>
+nsDOMMouseEvent::GetRelatedTarget()
+{
+  nsCOMPtr<mozilla::dom::EventTarget> relatedTarget;
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
     case NS_WHEEL_EVENT:
     case NS_DRAG_EVENT:
     case NS_SIMPLE_GESTURE_EVENT:
-      relatedTarget = static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget;
+      relatedTarget = do_QueryInterface(static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget);
       break;
     default:
       break;
   }
 
   if (relatedTarget) {
     nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
     if (content && content->ChromeOnlyAccess() &&
         !nsContentUtils::CanAccessNativeAnon()) {
-      relatedTarget = content->FindFirstNonChromeOnlyAccessContent();
-      if (!relatedTarget) {
-        return NS_OK;
-      }
+      relatedTarget = do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
     }
 
-    CallQueryInterface(relatedTarget, aRelatedTarget);
+    if (relatedTarget) {
+      relatedTarget = relatedTarget->GetTargetForDOMEvent();
+    }
+    return relatedTarget.forget();
   }
-  return NS_OK;
+  return nullptr;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozMovementX(int32_t* aMovementX)
 {
   NS_ENSURE_ARG_POINTER(aMovementX);
-  *aMovementX = GetMovementPoint().x;
+  *aMovementX = MozMovementX();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozMovementY(int32_t* aMovementY)
 {
   NS_ENSURE_ARG_POINTER(aMovementY);
-  *aMovementY = GetMovementPoint().y;
+  *aMovementY = MozMovementY();
 
   return NS_OK;
 }
 
 NS_METHOD nsDOMMouseEvent::GetScreenX(int32_t* aScreenX)
 {
   NS_ENSURE_ARG_POINTER(aScreenX);
-  *aScreenX = nsDOMEvent::GetScreenCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint).x;
+  *aScreenX = ScreenX();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ScreenX()
+{
+  return nsDOMEvent::GetScreenCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint).x;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetScreenY(int32_t* aScreenY)
 {
   NS_ENSURE_ARG_POINTER(aScreenY);
-  *aScreenY = nsDOMEvent::GetScreenCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint).y;
+  *aScreenY = ScreenY();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ScreenY()
+{
+  return nsDOMEvent::GetScreenCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint).y;
+}
+
 
 NS_METHOD nsDOMMouseEvent::GetClientX(int32_t* aClientX)
 {
   NS_ENSURE_ARG_POINTER(aClientX);
-  *aClientX = nsDOMEvent::GetClientCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint,
-                                          mClientPoint).x;
+  *aClientX = ClientX();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ClientX()
+{
+  return nsDOMEvent::GetClientCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint,
+                                     mClientPoint).x;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetClientY(int32_t* aClientY)
 {
   NS_ENSURE_ARG_POINTER(aClientY);
-  *aClientY = nsDOMEvent::GetClientCoords(mPresContext,
-                                          mEvent,
-                                          mEvent->refPoint,
-                                          mClientPoint).y;
+  *aClientY = ClientY();
   return NS_OK;
 }
 
+int32_t
+nsDOMMouseEvent::ClientY()
+{
+  return nsDOMEvent::GetClientCoords(mPresContext,
+                                     mEvent,
+                                     mEvent->refPoint,
+                                     mClientPoint).y;
+}
+
 NS_IMETHODIMP
 nsDOMMouseEvent::GetAltKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsAlt();
+  *aIsDown = AltKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetCtrlKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsControl();
+  *aIsDown = CtrlKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetShiftKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsShift();
+  *aIsDown = ShiftKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMetaKey(bool* aIsDown)
 {
   NS_ENSURE_ARG_POINTER(aIsDown);
-  *aIsDown = static_cast<nsInputEvent*>(mEvent)->IsMeta();
+  *aIsDown = MetaKey();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetModifierState(const nsAString& aKey,
                                   bool* aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
-  *aState = GetModifierStateInternal(aKey);
+  *aState = GetModifierState(aKey);
   return NS_OK;
 }
 
 /* virtual */
 nsresult
 nsDOMMouseEvent::Which(uint32_t* aWhich)
 {
   NS_ENSURE_ARG_POINTER(aWhich);
@@ -386,28 +457,29 @@ nsDOMMouseEvent::Which(uint32_t* aWhich)
   *aWhich = button + 1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozPressure(float* aPressure)
 {
   NS_ENSURE_ARG_POINTER(aPressure);
-  *aPressure = static_cast<nsMouseEvent_base*>(mEvent)->pressure;
+  *aPressure = MozPressure();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetMozInputSource(uint16_t* aInputSource)
 {
   NS_ENSURE_ARG_POINTER(aInputSource);
-  *aInputSource = static_cast<nsMouseEvent_base*>(mEvent)->inputSource;
+  *aInputSource = MozInputSource();
   return NS_OK;
 }
 
 nsresult NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult,
                              mozilla::dom::EventTarget* aOwner,
                              nsPresContext* aPresContext,
                              nsInputEvent *aEvent)
 {
   nsDOMMouseEvent* it = new nsDOMMouseEvent(aOwner, aPresContext, aEvent);
+  it->SetIsDOMBinding();
   return CallQueryInterface(it, aInstancePtrResult);
 }
--- a/content/events/src/nsDOMMouseEvent.h
+++ b/content/events/src/nsDOMMouseEvent.h
@@ -3,16 +3,17 @@
  * 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 nsDOMMouseEvent_h__
 #define nsDOMMouseEvent_h__
 
 #include "nsIDOMMouseEvent.h"
 #include "nsDOMUIEvent.h"
+#include "mozilla/dom/MouseEventBinding.h"
 
 class nsEvent;
 
 class nsDOMMouseEvent : public nsDOMUIEvent,
                         public nsIDOMMouseEvent
 {
 public:
   nsDOMMouseEvent(mozilla::dom::EventTarget* aOwner,
@@ -22,18 +23,102 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseEvent Interface
   NS_DECL_NSIDOMMOUSEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_NSDOMUIEVENT
 
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE
+  {
+    return mozilla::dom::MouseEventBinding::Wrap(aCx, aScope, this);
+  }
+
   virtual nsresult InitFromCtor(const nsAString& aType,
                                 JSContext* aCx, JS::Value* aVal);
+
+  // Web IDL binding methods
+  int32_t ScreenX();
+  int32_t ScreenY();
+  int32_t ClientX();
+  int32_t ClientY();
+  bool CtrlKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsControl();
+  }
+  bool ShiftKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsShift();
+  }
+  bool AltKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsAlt();
+  }
+  bool MetaKey()
+  {
+    return static_cast<nsInputEvent*>(mEvent)->IsMeta();
+  }
+  uint16_t Button();
+  uint16_t Buttons();
+  already_AddRefed<mozilla::dom::EventTarget> GetRelatedTarget();
+  void InitMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
+                      nsIDOMWindow* aView, int32_t aDetail, int32_t aScreenX,
+                      int32_t aScreenY, int32_t aClientX, int32_t aClientY,
+                      bool aCtrlKey, bool aAltKey, bool aShiftKey,
+                      bool aMetaKey, uint16_t aButton,
+                      mozilla::dom::EventTarget *aRelatedTarget,
+                      mozilla::ErrorResult& aRv)
+  {
+    aRv = InitMouseEvent(aType, aCanBubble, aCancelable,
+                         aView, aDetail, aScreenX, aScreenY,
+                         aClientX, aClientY, aCtrlKey, aAltKey,
+                         aShiftKey, aMetaKey, aButton,
+                         aRelatedTarget);
+  }
+  bool GetModifierState(const nsAString& aKeyArg)
+  {
+    return GetModifierStateInternal(aKeyArg);
+  }
+  static already_AddRefed<nsDOMMouseEvent> Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                                                       const nsAString& aType,
+                                                       const mozilla::dom::MouseEventInit& aParam,
+                                                       mozilla::ErrorResult& aRv);
+  int32_t MozMovementX()
+  {
+    return GetMovementPoint().x;
+  }
+  int32_t MozMovementY()
+  {
+    return GetMovementPoint().y;
+  }
+  float MozPressure() const
+  {
+    return static_cast<nsMouseEvent_base*>(mEvent)->pressure;
+  }
+  uint16_t MozInputSource() const
+  {
+    return static_cast<nsMouseEvent_base*>(mEvent)->inputSource;
+  }
+  void InitNSMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
+                        nsIDOMWindow *aView, int32_t aDetail, int32_t aScreenX,
+                        int32_t aScreenY, int32_t aClientX, int32_t aClientY,
+                        bool aCtrlKey, bool aAltKey, bool aShiftKey,
+                        bool aMetaKey, uint16_t aButton,
+                        mozilla::dom::EventTarget *aRelatedTarget,
+                        float aPressure, uint16_t aInputSource,
+                        mozilla::ErrorResult& aRv)
+  {
+    aRv = InitNSMouseEvent(aType, aCanBubble, aCancelable,
+                           aView, aDetail, aScreenX, aScreenY,
+                           aClientX, aClientY, aCtrlKey, aAltKey,
+                           aShiftKey, aMetaKey, aButton,
+                           aRelatedTarget, aPressure, aInputSource);
+  }
+
 protected:
   // Specific implementation for a mouse event.
   virtual nsresult Which(uint32_t* aWhich);
 
   nsresult InitMouseEvent(const nsAString& aType,
                           bool aCanBubble,
                           bool aCancelable,
                           nsIDOMWindow* aView,
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -528,16 +528,20 @@ DOMInterfaces = {
     'resultNotAddRefed': [ '__indexedGetter' ],
     'binaryNames': { '__indexedGetter': 'IndexedGetter' }
 },
 
 'MessageEvent': {
     'nativeType': 'nsDOMMessageEvent',
 },
 
+'MouseEvent': {
+    'nativeType': 'nsDOMMouseEvent',
+},
+
 'MozChannel': [
 {
     'nativeType': 'nsIChannel',
     'notflattened': True
 },
 {
     'workers': True,
 }],
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MouseEvent.webidl
@@ -0,0 +1,118 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * For more information on this interface please see
+ * http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface MouseEvent : UIEvent {
+  readonly attribute long           screenX;
+  readonly attribute long           screenY;
+  readonly attribute long           clientX;
+  readonly attribute long           clientY;
+  readonly attribute boolean        ctrlKey;
+  readonly attribute boolean        shiftKey;
+  readonly attribute boolean        altKey;
+  readonly attribute boolean        metaKey;
+  readonly attribute unsigned short button;
+  readonly attribute unsigned short buttons;
+  readonly attribute EventTarget?   relatedTarget;
+  // Deprecated in DOM Level 3:
+  [Throws]
+  void                              initMouseEvent(DOMString typeArg, 
+                                                   boolean canBubbleArg, 
+                                                   boolean cancelableArg, 
+                                                   WindowProxy? viewArg, 
+                                                   long detailArg, 
+                                                   long screenXArg, 
+                                                   long screenYArg, 
+                                                   long clientXArg, 
+                                                   long clientYArg, 
+                                                   boolean ctrlKeyArg, 
+                                                   boolean altKeyArg, 
+                                                   boolean shiftKeyArg, 
+                                                   boolean metaKeyArg, 
+                                                   unsigned short buttonArg,
+                                                   EventTarget? relatedTargetArg);
+  // Introduced in DOM Level 3:
+  boolean                           getModifierState(DOMString keyArg);
+};
+
+
+// Event Constructor Syntax:
+[Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)]
+partial interface MouseEvent
+{
+};
+
+// Suggested initMouseEvent replacement initializer:
+dictionary MouseEventInit {
+  // Attributes from Event:
+  boolean        bubbles       = false;
+  boolean        cancelable    = false;
+
+  // Attributes from UIEvent:
+  WindowProxy?   view          = null;
+  long           detail        = 0;
+
+  // Attributes for MouseEvent:
+  long           screenX       = 0;
+  long           screenY       = 0;
+  long           clientX       = 0;
+  long           clientY       = 0;
+  boolean        ctrlKey       = false;
+  boolean        shiftKey      = false;
+  boolean        altKey        = false;
+  boolean        metaKey       = false;
+  unsigned short button        = 0;
+  // Note: "buttons" was not previously initializable through initMouseEvent!
+  unsigned short buttons       = 0;
+  EventTarget?   relatedTarget = null;
+};
+
+// Mozilla extensions
+partial interface MouseEvent
+{
+  readonly attribute long mozMovementX;
+  readonly attribute long mozMovementY;
+
+  // Finger or touch pressure event value
+  // ranges between 0.0 and 1.0
+  readonly attribute float mozPressure;
+
+  const unsigned short    MOZ_SOURCE_UNKNOWN    = 0;
+  const unsigned short    MOZ_SOURCE_MOUSE      = 1;
+  const unsigned short    MOZ_SOURCE_PEN        = 2;
+  const unsigned short    MOZ_SOURCE_ERASER     = 3;
+  const unsigned short    MOZ_SOURCE_CURSOR     = 4;
+  const unsigned short    MOZ_SOURCE_TOUCH      = 5;
+  const unsigned short    MOZ_SOURCE_KEYBOARD   = 6;
+
+  readonly attribute unsigned short mozInputSource;
+
+  [Throws]
+  void                initNSMouseEvent(DOMString typeArg,
+                                       boolean canBubbleArg,
+                                       boolean cancelableArg,
+                                       WindowProxy? viewArg,
+                                       long detailArg,
+                                       long screenXArg,
+                                       long screenYArg,
+                                       long clientXArg,
+                                       long clientYArg,
+                                       boolean ctrlKeyArg,
+                                       boolean altKeyArg,
+                                       boolean shiftKeyArg,
+                                       boolean metaKeyArg,
+                                       unsigned short buttonArg,
+                                       EventTarget? relatedTargetArg,
+                                       float pressure,
+                                       unsigned short inputSourceArg);
+
+};
+
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -129,16 +129,17 @@ webidl_files = \
   IDBVersionChangeEvent.webidl \
   ImageData.webidl \
   InspectorUtils.webidl \
   LinkStyle.webidl \
   LocalMediaStream.webidl \
   Location.webidl \
   MediaStream.webidl \
   MessageEvent.webidl \
+  MouseEvent.webidl \
   MozActivity.webidl \
   MutationEvent.webidl \
   MutationObserver.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeIterator.webidl \
   NodeList.webidl \
   Notification.webidl \