Bug 1071029 - Fix 'contextmenu' events in Marionette. r=mdas
authorChris Lord <chrislord.net@gmail.com>
Mon, 22 Sep 2014 16:41:51 +0100
changeset 206608 5d90266605a1bc4842e79d662f1a592bfb0b9a08
parent 206607 2b69b1ccded0e8e7ba08138eeb1368253c83c1ef
child 206609 245c55cc9ccfd8a4749ade4308a73cd6309f7a6c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmdas
bugs1071029
milestone35.0a1
Bug 1071029 - Fix 'contextmenu' events in Marionette. r=mdas Marionette 'contextmenu' events were missing various properties that mouse events should have.
testing/marionette/marionette-listener.js
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -887,24 +887,30 @@ function generateEvents(type, x, y, touc
       else {
         touch = createATouch(touchIds[touchId].target, x, y, touchId);
         touchIds[touchId] = touch;
         emitTouchEvent('touchmove', touch);
       }
       break;
     case 'contextmenu':
       isTap = false;
-      let event = curFrame.document.createEvent('HTMLEvents');
-      event.initEvent('contextmenu', true, true);
+      let event = curFrame.document.createEvent('MouseEvents');
       if (mouseEventsOnly) {
         target = doc.elementFromPoint(lastCoordinates[0], lastCoordinates[1]);
       }
       else {
         target = touchIds[touchId].target;
       }
+      let [ clientX, clientY,
+            pageX, pageY,
+            screenX, screenY ] = getCoordinateInfo(target, x, y);
+      event.initMouseEvent('contextmenu', true, true,
+                           target.ownerDocument.defaultView, 1,
+                           screenX, screenY, clientX, clientY,
+                           false, false, false, false, 0, null);
       target.dispatchEvent(event);
       break;
     default:
       throw {message:"Unknown event type: " + type, code: 500, stack:null};
   }
   if (wasInterrupted()) {
     if (previousFrame) {
       //if previousFrame is set, then we're in a single process environment
@@ -940,28 +946,39 @@ function singleTap(msg) {
     sendOk(msg.json.command_id);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack, msg.json.command_id);
   }
 }
 
 /**
+ * Given an element and a pair of coordinates, returns an array of the form
+ * [ clientX, clientY, pageX, pageY, screenX, screenY ]
+ */
+function getCoordinateInfo(el, corx, cory) {
+  let win = el.ownerDocument.defaultView;
+  return [ corx, // clientX
+           cory, // clientY
+           corx + win.pageXOffset, // pageX
+           cory + win.pageYOffset, // pageY
+           corx + win.mozInnerScreenX, // screenX
+           cory + win.mozInnerScreenY // screenY
+         ];
+}
+
+/**
  * Function to create a touch based on the element
  * corx and cory are relative to the viewport, id is the touchId
  */
 function createATouch(el, corx, cory, touchId) {
   let doc = el.ownerDocument;
   let win = doc.defaultView;
-  let clientX = corx;
-  let clientY = cory;
-  let pageX = clientX + win.pageXOffset,
-      pageY = clientY + win.pageYOffset;
-  let screenX = clientX + win.mozInnerScreenX,
-      screenY = clientY + win.mozInnerScreenY;
+  let [clientX, clientY, pageX, pageY, screenX, screenY] =
+    getCoordinateInfo(el, corx, cory);
   let atouch = doc.createTouch(win, el, touchId, pageX, pageY, screenX, screenY, clientX, clientY);
   return atouch;
 }
 
 /**
  * Function to emit touch events for each finger. e.g. finger=[['press', id], ['wait', 5], ['release']]
  * touchId represents the finger id, i keeps track of the current action of the chain
  */