Bug 1501761 - Fix EventUtils.synthesizePlainDragAndDrop to enable simulating tab detaching. r=florian
authorFelipe Gomes <felipc@gmail.com>
Wed, 24 Oct 2018 17:59:54 -0300
changeset 442892 0a2a9b94714f0f16a3af50a444e7555ddf6a4e38
parent 442891 eff78d899e015488e1e384c24b249c2daadc990a
child 442893 bcc643fef1568b22e72e51501608ac4498c6d0be
push id34927
push userncsoregi@mozilla.com
push dateThu, 25 Oct 2018 04:45:44 +0000
treeherdermozilla-central@76d5b62fb151 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1501761
milestone65.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 1501761 - Fix EventUtils.synthesizePlainDragAndDrop to enable simulating tab detaching. r=florian This fixes several problems with this function: - the parameters destX and destY were advertised but were actually unused - added support for dropping on an invalid drop target (by passing destElement = null) - implements the dragend event - stale documentation mentioned mouseup event
testing/mochitest/tests/SimpleTest/EventUtils.js
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -2381,47 +2381,48 @@ function synthesizeDrop(aSrcElement, aDe
                                        aDestWindow, aDragEvent);
   } finally {
     ds.endDragSession(true, _parseModifiers(aDragEvent));
   }
 }
 
 /**
  * Emulate a drag and drop by emulating a dragstart by mousedown and mousemove,
- * and firing events dragenter, dragover, drop, and mouseup.
+ * and firing events dragenter, dragover, drop, and dragend.
  * This does not modify dataTransfer and tries to emulate the plain drag and
  * drop as much as possible, compared to synthesizeDrop.
  *
  * @param aParams
  *        {
  *          srcElement:   The element to start dragging
- *          destElement:  The element to drop on
+ *          destElement:  The element to drop on. Pass null to emulate
+ *                        a drop on an invalid target.
  *          srcX:         The initial x coordinate inside srcElement
  *          srcY:         The initial y coordinate inside srcElement
  *          stepX:        The x-axis step for mousemove inside srcElement
  *          stepY:        The y-axis step for mousemove inside srcElement
- *          destX:        The x coordinate inside destElement
- *          destY:        The x coordinate inside destElement
+ *          finalX:       The final x coordinate inside srcElement
+ *          finalY:       The final x coordinate inside srcElement
  *          srcWindow:    The window for dispatching event on srcElement,
  *                        defaults to the current window object
  *          destWindow:   The window for dispatching event on destElement,
  *                        defaults to the current window object
  *        }
  */
 async function synthesizePlainDragAndDrop(aParams)
 {
   let {
     srcElement,
     destElement,
     srcX = 2,
     srcY = 2,
     stepX = 9,
     stepY = 9,
-    destX = 2,
-    destY = 2,
+    finalX = srcX + stepX * 2,
+    finalY = srcY + stepY * 2,
     srcWindow = window,
     destWindow = window,
   } = aParams;
 
   const ds = _EU_Cc["@mozilla.org/widget/dragservice;1"]
         .getService(_EU_Ci.nsIDragService);
   ds.startDragSession();
 
@@ -2446,25 +2447,36 @@ async function synthesizePlainDragAndDro
     synthesizeMouse(srcElement, srcX, srcY, { type: "mousemove" }, srcWindow);
 
     await new Promise(r => setTimeout(r, 0));
 
     srcElement.removeEventListener("dragstart", trapDrag, true);
 
     await new Promise(r => setTimeout(r, 0));
 
-    let event = createDragEventObject("dragover", destElement, destWindow,
-                                      dataTransfer, {});
-    sendDragEvent(event, destElement, destWindow);
+    let event;
+    if (destElement) {
+      // dragover and drop are only fired to a valid drop target. If the
+      // destElement parameter is null, this function is being used to
+      // simulate a drag'n'drop over an invalid drop target.
+      event = createDragEventObject("dragover", destElement, destWindow,
+                                        dataTransfer, {});
+      sendDragEvent(event, destElement, destWindow);
 
-    await new Promise(r => setTimeout(r, 0));
+      await new Promise(r => setTimeout(r, 0));
 
-    event = createDragEventObject("drop", destElement, destWindow,
-                                  dataTransfer, {});
-    sendDragEvent(event, destElement, destWindow);
+      event = createDragEventObject("drop", destElement, destWindow,
+                                    dataTransfer, {});
+      sendDragEvent(event, destElement, destWindow);
+    }
+
+    // dragend is fired, by definition, on the srcElement
+    event = createDragEventObject("dragend", srcElement, srcWindow,
+                                  dataTransfer, {clientX: finalX, clientY: finalY});
+    sendDragEvent(event, srcElement, srcWindow);
 
     await new Promise(r => setTimeout(r, 0));
 
   } finally {
     ds.endDragSession(true, 0);
   }
 }