Bug 1164981 - Add MouseEvent.movementX/Y, r=masayuki,ehsan
☠☠ backed out by e63bc65a7ded ☠ ☠
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 19 May 2015 19:57:24 +0300
changeset 244655 2ac9fe6d2333c1b93856f6f868d352e4c94bdead
parent 244654 f0af05d88416e68592e63b389f329212b527f1b6
child 244656 006a48240dfd928f5890277f262866047884b425
push id28786
push usercbook@mozilla.com
push dateWed, 20 May 2015 13:54:15 +0000
treeherdermozilla-central@8d8df22fe72d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, ehsan
bugs1164981
milestone41.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 1164981 - Add MouseEvent.movementX/Y, r=masayuki,ehsan
dom/events/DragEvent.cpp
dom/events/MouseEvent.cpp
dom/events/MouseEvent.h
dom/events/PointerEvent.cpp
dom/events/UIEvent.cpp
dom/events/WheelEvent.cpp
dom/events/test/test_dom_mouse_event.html
dom/events/test/test_eventctors.html
dom/webidl/MouseEvent.webidl
testing/web-platform/meta/pointerlock/constructor.html.ini
testing/web-platform/meta/pointerlock/idlharness.html.ini
--- a/dom/events/DragEvent.cpp
+++ b/dom/events/DragEvent.cpp
@@ -143,16 +143,17 @@ DragEvent::Constructor(const GlobalObjec
   nsRefPtr<DragEvent> e = new DragEvent(t, nullptr, nullptr);
   bool trusted = e->Init(t);
   aRv = e->InitDragEvent(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,
                          aParam.mDataTransfer);
+  e->InitializeExtraMouseEventDictionaryMembers(aParam);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
--- a/dom/events/MouseEvent.cpp
+++ b/dom/events/MouseEvent.cpp
@@ -133,36 +133,42 @@ MouseEvent::InitMouseEvent(const nsAStri
     case eSimpleGestureEventClass:
       mEvent->AsInputEvent()->modifiers = modifiers;
       return NS_OK;
     default:
       MOZ_CRASH("There is no space to store the modifiers");
   }
 }
 
+void
+MouseEvent::InitializeExtraMouseEventDictionaryMembers(const MouseEventInit& aParam)
+{
+  InitModifiers(aParam);
+  mEvent->AsMouseEventBase()->buttons = aParam.mButtons;
+  mMovementPoint.x = aParam.mMovementX;
+  mMovementPoint.y = aParam.mMovementY;
+}
+
 already_AddRefed<MouseEvent>
 MouseEvent::Constructor(const GlobalObject& aGlobal,
                         const nsAString& aType,
                         const MouseEventInit& aParam,
                         ErrorResult& aRv)
 {
   nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
   nsRefPtr<MouseEvent> e = new MouseEvent(t, nullptr, nullptr);
   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->InitModifiers(aParam);
+  e->InitializeExtraMouseEventDictionaryMembers(aParam);
   e->SetTrusted(trusted);
-  MOZ_RELEASE_ASSERT(e->mEvent->AsMouseEventBase(),
-                     "mEvent of MouseEvent must inherit WidgetMouseEventBase");
-  e->mEvent->AsMouseEventBase()->buttons = aParam.mButtons;
 
   return e.forget();
 }
 
 NS_IMETHODIMP
 MouseEvent::InitNSMouseEvent(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
@@ -300,26 +306,26 @@ MouseEvent::GetRegion(nsAString& aRegion
     aRegion = mouseEventBase->region;
   }
 }
 
 NS_IMETHODIMP
 MouseEvent::GetMozMovementX(int32_t* aMovementX)
 {
   NS_ENSURE_ARG_POINTER(aMovementX);
-  *aMovementX = MozMovementX();
+  *aMovementX = MovementX();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MouseEvent::GetMozMovementY(int32_t* aMovementY)
 {
   NS_ENSURE_ARG_POINTER(aMovementY);
-  *aMovementY = MozMovementY();
+  *aMovementY = MovementY();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MouseEvent::GetScreenX(int32_t* aScreenX)
 {
   NS_ENSURE_ARG_POINTER(aScreenX);
--- a/dom/events/MouseEvent.h
+++ b/dom/events/MouseEvent.h
@@ -64,29 +64,32 @@ public:
                       EventTarget* aRelatedTarget, ErrorResult& aRv)
   {
     aRv = InitMouseEvent(aType, aCanBubble, aCancelable,
                          aView, aDetail, aScreenX, aScreenY,
                          aClientX, aClientY, aCtrlKey, aAltKey,
                          aShiftKey, aMetaKey, aButton,
                          aRelatedTarget);
   }
+
+  void InitializeExtraMouseEventDictionaryMembers(const MouseEventInit& aParam);
+
   bool GetModifierState(const nsAString& aKeyArg)
   {
     return GetModifierStateInternal(aKeyArg);
   }
   static already_AddRefed<MouseEvent> Constructor(const GlobalObject& aGlobal,
                                                   const nsAString& aType,
                                                   const MouseEventInit& aParam,
                                                   ErrorResult& aRv);
-  int32_t MozMovementX()
+  int32_t MovementX()
   {
     return GetMovementPoint().x;
   }
-  int32_t MozMovementY()
+  int32_t MovementY()
   {
     return GetMovementPoint().y;
   }
   float MozPressure() const;
   bool HitCluster() const;
   uint16_t MozInputSource() const;
   void InitNSMouseEvent(const nsAString& aType,
                         bool aCanBubble, bool aCancelable,
--- a/dom/events/PointerEvent.cpp
+++ b/dom/events/PointerEvent.cpp
@@ -77,17 +77,17 @@ PointerEvent::Constructor(EventTarget* a
   nsRefPtr<PointerEvent> e = new PointerEvent(aOwner, nullptr, nullptr);
   bool trusted = e->Init(aOwner);
 
   e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
                     aParam.mView, aParam.mDetail, aParam.mScreenX,
                     aParam.mScreenY, aParam.mClientX, aParam.mClientY,
                     false, false, false, false, aParam.mButton,
                     aParam.mRelatedTarget);
-  e->InitModifiers(aParam);
+  e->InitializeExtraMouseEventDictionaryMembers(aParam);
 
   WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
   widgetEvent->pointerId = aParam.mPointerId;
   widgetEvent->width = aParam.mWidth;
   widgetEvent->height = aParam.mHeight;
   widgetEvent->pressure = aParam.mPressure;
   widgetEvent->tiltX = aParam.mTiltX;
   widgetEvent->tiltY = aParam.mTiltY;
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -109,17 +109,17 @@ DevPixelsToCSSPixels(const LayoutDeviceI
 {
   return nsIntPoint(aContext->DevPixelsToIntCSSPixels(aPoint.x),
                     aContext->DevPixelsToIntCSSPixels(aPoint.y));
 }
 
 nsIntPoint
 UIEvent::GetMovementPoint()
 {
-  if (mPrivateDataDuplicated) {
+  if (mPrivateDataDuplicated || mEventIsInternal) {
     return mMovementPoint;
   }
 
   if (!mEvent ||
       (mEvent->mClass != eMouseEventClass &&
        mEvent->mClass != eMouseScrollEventClass &&
        mEvent->mClass != eWheelEventClass &&
        mEvent->mClass != eDragEventClass &&
--- a/dom/events/WheelEvent.cpp
+++ b/dom/events/WheelEvent.cpp
@@ -159,18 +159,17 @@ WheelEvent::Constructor(const GlobalObje
   bool trusted = e->Init(t);
   aRv = e->InitWheelEvent(aType, aParam.mBubbles, aParam.mCancelable,
                           aParam.mView, aParam.mDetail,
                           aParam.mScreenX, aParam.mScreenY,
                           aParam.mClientX, aParam.mClientY,
                           aParam.mButton, aParam.mRelatedTarget,
                           EmptyString(), aParam.mDeltaX,
                           aParam.mDeltaY, aParam.mDeltaZ, aParam.mDeltaMode);
-  e->InitModifiers(aParam);
-  e->mEvent->AsWheelEvent()->buttons = aParam.mButtons;
+  e->InitializeExtraMouseEventDictionaryMembers(aParam);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
--- a/dom/events/test/test_dom_mouse_event.html
+++ b/dom/events/test/test_dom_mouse_event.html
@@ -102,16 +102,20 @@ function testInitializingUntrustedEvent(
     for (var attr in kTest) {
       if (attr == "createEventArg") {
         continue;
       }
       is(e[attr], kTest[attr], description + attr + " returns wrong value");
     }
     is(e.isTrusted, false, description + "isTrusted returns wrong value");
     is(e.buttons, 0, description + "buttons returns wrong value");
+    is(e.movementX, 0, description + "movementX returns wrong value");
+    is(e.movementY, 0, description + "movementY returns wrong value");
+    is(e.movementX, e.mozMovementX);
+    is(e.movementY, e.mozMovementY);
 
     // getModifierState() tests
     is(e.getModifierState("Shift"), kTest.shiftKey,
        description + "getModifierState(\"Shift\") returns wrong value");
     is(e.getModifierState("Control"), kTest.ctrlKey,
        description + "getModifierState(\"Control\") returns wrong value");
     is(e.getModifierState("Alt"), kTest.altKey,
        description + "getModifierState(\"Alt\") returns wrong value");
--- a/dom/events/test/test_eventctors.html
+++ b/dom/events/test/test_eventctors.html
@@ -691,21 +691,24 @@ is(receivedEvent, e, "Wrong event!");
 try {
   e = new MouseEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "MouseEvent: First parameter is required!");
 ex = false;
 
-e = new MouseEvent("hello");
+e = new MouseEvent("hello",  { buttons: 1, movementX: 2, movementY: 3});
 is(e.type, "hello", "MouseEvent: Wrong event type!");
 ok(!e.isTrusted, "MouseEvent: Event shouldn't be trusted!");
 ok(!e.bubbles, "MouseEvent: Event shouldn't bubble!");
 ok(!e.cancelable, "MouseEvent: Event shouldn't be cancelable!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
 document.dispatchEvent(e);
 is(receivedEvent, e, "MouseEvent: Wrong event!");
 
 var mouseEventProps =
 [ { screenX: 0 },
   { screenY: 0 },
   { clientX: 0 },
   { clientY: 0 },
@@ -719,17 +722,17 @@ var mouseEventProps =
   { modifierFnLock: false },
   { modifierNumLock: false },
   { modifierOS: false },
   { modifierScrollLock: false },
   { modifierSymbol: false },
   { modifierSymbolLock: false },
   { button: 0 },
   { buttons: 0 },
-  { relatedTarget: null }
+  { relatedTarget: null },
 ];
 
 var testProps =
 [
   { screenX: 1 },
   { screenY: 2 },
   { clientX: 3 },
   { clientY: 4 },
@@ -806,18 +809,21 @@ is(e.popupWindowName, "name");
 try {
   e = new WheelEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "WheelEvent: First parameter is required!");
 ex = false;
 
-e = new WheelEvent("hello");
+e = new WheelEvent("hello",  { buttons: 1, movementX: 2, movementY: 3});
 is(e.type, "hello", "WheelEvent: Wrong event type!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
 ok(!e.isTrusted, "WheelEvent: Event shouldn't be trusted!");
 ok(!e.bubbles, "WheelEvent: Event shouldn't bubble!");
 ok(!e.cancelable, "WheelEvent: Event shouldn't be cancelable!");
 document.dispatchEvent(e);
 is(receivedEvent, e, "WheelEvent: Wrong event!");
 
 var wheelEventProps =
 [ { screenX: 0 },
@@ -902,18 +908,21 @@ while (testWheelProps.length) {
 try {
   e = new DragEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "DragEvent: First parameter is required!");
 ex = false;
 
-e = new DragEvent("hello");
+e = new DragEvent("hello", { buttons: 1, movementX: 2, movementY: 3});
 is(e.type, "hello", "DragEvent: Wrong event type!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
 document.dispatchEvent(e);
 is(receivedEvent, e, "DragEvent: Wrong event!");
 
 // TransitionEvent
 e = new TransitionEvent("hello", { propertyName: "color", elapsedTime: 3.5, pseudoElement: "", foobar: "baz" })
 is("propertyName" in e, true, "Transition events have propertyName property");
 is("foobar" in e, false, "Transition events do not copy random properties from event init");
 is(e.propertyName, "color", "Transition event copies propertyName from TransitionEventInit");
--- a/dom/webidl/MouseEvent.webidl
+++ b/dom/webidl/MouseEvent.webidl
@@ -5,31 +5,37 @@
  *
  * 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.
  */
 
+[Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)]
 interface MouseEvent : UIEvent {
   readonly attribute long           screenX;
   readonly attribute long           screenY;
   readonly attribute long           clientX;
   readonly attribute long           clientY;
   readonly attribute long           offsetX;
   readonly attribute long           offsetY;
   readonly attribute boolean        ctrlKey;
   readonly attribute boolean        shiftKey;
   readonly attribute boolean        altKey;
   readonly attribute boolean        metaKey;
   readonly attribute short          button;
   readonly attribute unsigned short buttons;
   readonly attribute EventTarget?   relatedTarget;
   readonly attribute DOMString?     region;
+
+  // Pointer Lock
+  readonly attribute long           movementX;
+  readonly attribute long           movementY;
+
   // Deprecated in DOM Level 3:
   [Throws]
   void                              initMouseEvent(DOMString typeArg, 
                                                    boolean canBubbleArg, 
                                                    boolean cancelableArg, 
                                                    Window? viewArg,
                                                    long detailArg, 
                                                    long screenXArg, 
@@ -41,40 +47,39 @@ interface MouseEvent : UIEvent {
                                                    boolean shiftKeyArg, 
                                                    boolean metaKeyArg, 
                                                    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 : EventModifierInit {
   // Attributes for MouseEvent:
   long           screenX       = 0;
   long           screenY       = 0;
   long           clientX       = 0;
   long           clientY       = 0;
   short          button        = 0;
   // Note: "buttons" was not previously initializable through initMouseEvent!
   unsigned short buttons       = 0;
   EventTarget?   relatedTarget = null;
+
+  // Pointer Lock
+  long           movementX = 0;
+  long           movementY = 0;
 };
 
 // Mozilla extensions
 partial interface MouseEvent
 {
+  [BinaryName="movementX"]
   readonly attribute long mozMovementX;
+  [BinaryName="movementY"]
   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;
deleted file mode 100644
--- a/testing/web-platform/meta/pointerlock/constructor.html.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[constructor.html]
-  type: testharness
-  [Default event values for mouse event interface and its pointer lock extensions.]
-    expected: FAIL
-
-  [Default event values for pointerlockerror using a dictionary]
-    expected: FAIL
-
--- a/testing/web-platform/meta/pointerlock/idlharness.html.ini
+++ b/testing/web-platform/meta/pointerlock/idlharness.html.ini
@@ -37,26 +37,8 @@
     expected: FAIL
 
   [Document interface: window.document must inherit property "pointerLockElement" with the proper type (2)]
     expected: FAIL
 
   [Document interface: window.document must inherit property "exitPointerLock" with the proper type (3)]
     expected: FAIL
 
-  [MouseEvent interface: attribute movementX]
-    expected: FAIL
-
-  [MouseEvent interface: attribute movementY]
-    expected: FAIL
-
-  [MouseEvent interface: new MouseEvent('mousemove') must inherit property "movementX" with the proper type (0)]
-    expected: FAIL
-
-  [MouseEvent interface: new MouseEvent('mousemove') must inherit property "movementY" with the proper type (1)]
-    expected: FAIL
-
-  [MouseEvent interface: new MouseEvent('pointerlockchange') must inherit property "movementX" with the proper type (0)]
-    expected: FAIL
-
-  [MouseEvent interface: new MouseEvent('pointerlockchange') must inherit property "movementY" with the proper type (1)]
-    expected: FAIL
-