Backed out 2 changesets (bug 1421482) for failing modified mochitest layout/base/tests/test_bug1078327.html. r=backout a=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 12 Dec 2017 19:03:49 +0200
changeset 447818 554fbb5c6e5ba9645c42a0cffe08d623df9e7488
parent 447817 a16f868d488b41c6871c705b0a15c1b5b3deb4ce
child 447819 aeab475db7f391b426816f43b58cc6cf5befc37d
child 447849 7bb298321aa6cc72c6c698e7cdc70bc674591a79
child 447861 c7429a95d308108ad4a38bd7bc665d050fea7686
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout, backout
bugs1421482, 1078327
milestone59.0a1
backs outa8701e1bd012dab4f95f25df677a25e459d8e473
d774f5fe6e948d73ac15f66bff3e64499c04eb25
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
Backed out 2 changesets (bug 1421482) for failing modified mochitest layout/base/tests/test_bug1078327.html. r=backout a=backout Backed out changeset a8701e1bd012 (bug 1421482) Backed out changeset d774f5fe6e94 (bug 1421482)
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDOMWindowUtils.h
dom/events/test/test_bug967796.html
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/tests/bug1078327_inner.html
layout/base/tests/bug1080360_inner.html
layout/base/tests/bug1080361_inner.html
layout/base/tests/bug1153130_inner.html
layout/base/tests/bug1162990_inner_1.html
layout/base/tests/bug1162990_inner_2.html
layout/base/tests/bug968148_inner.html
layout/base/tests/bug968148_inner2.html
layout/base/tests/bug977003_inner_1.html
layout/base/tests/bug977003_inner_2.html
layout/base/tests/bug977003_inner_3.html
layout/base/tests/bug977003_inner_4.html
layout/base/tests/bug977003_inner_5.html
layout/base/tests/bug977003_inner_6.html
layout/base/tests/mochitest.ini
layout/base/tests/test_bug968148.html
testing/mochitest/tests/SimpleTest/EventUtils.js
widget/tests/test_assign_event_data.html
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -770,16 +770,166 @@ nsDOMWindowUtils::SendMouseEventCommon(c
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton,
       aButtons, aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure,
       aInputSourceArg, aPointerId, aToWindow, aPreventDefault,
       aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
+                                         float aX,
+                                         float aY,
+                                         int32_t aButton,
+                                         int32_t aClickCount,
+                                         int32_t aModifiers,
+                                         bool aIgnoreRootScrollFrame,
+                                         float aPressure,
+                                         unsigned short aInputSourceArg,
+                                         int32_t aPointerId,
+                                         int32_t aWidth,
+                                         int32_t aHeight,
+                                         int32_t aTiltX,
+                                         int32_t aTiltY,
+                                         bool aIsPrimary,
+                                         bool aIsSynthesized,
+                                         uint8_t aOptionalArgCount,
+                                         bool aToWindow,
+                                         bool* aPreventDefault)
+{
+  // get the widget to send the event to
+  nsPoint offset;
+  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
+  if (!widget) {
+    return NS_ERROR_FAILURE;
+  }
+
+  EventMessage msg;
+  if (aType.EqualsLiteral("pointerdown")) {
+    msg = ePointerDown;
+  } else if (aType.EqualsLiteral("pointerup")) {
+    msg = ePointerUp;
+  } else if (aType.EqualsLiteral("pointermove")) {
+    msg = ePointerMove;
+  } else if (aType.EqualsLiteral("pointerover")) {
+    msg = ePointerOver;
+  } else if (aType.EqualsLiteral("pointerout")) {
+    msg = ePointerOut;
+  } else {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
+    aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
+  }
+
+  WidgetPointerEvent event(true, msg, widget);
+  event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
+  event.button = aButton;
+  event.buttons = nsContentUtils::GetButtonsFlagForButton(aButton);
+  event.pressure = aPressure;
+  event.inputSource = aInputSourceArg;
+  event.pointerId = aPointerId;
+  event.mWidth = aWidth;
+  event.mHeight = aHeight;
+  event.tiltX = aTiltX;
+  event.tiltY = aTiltY;
+  event.mIsPrimary =
+    (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
+  event.mClickCount = aClickCount;
+  event.mTime = PR_IntervalNow();
+  event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
+
+  nsPresContext* presContext = GetPresContext();
+  if (!presContext) {
+    return NS_ERROR_FAILURE;
+  }
+
+  event.mRefPoint =
+    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
+  event.mIgnoreRootScrollFrame = aIgnoreRootScrollFrame;
+
+  nsEventStatus status;
+  if (aToWindow) {
+    nsCOMPtr<nsIPresShell> presShell;
+    nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
+    if (!presShell || !view) {
+      return NS_ERROR_FAILURE;
+    }
+    status = nsEventStatus_eIgnore;
+    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
+  }
+  nsresult rv = widget->DispatchEvent(&event, status);
+  if (aPreventDefault) {
+    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendPointerEvent(const nsAString& aType,
+                                   float aX,
+                                   float aY,
+                                   int32_t aButton,
+                                   int32_t aClickCount,
+                                   int32_t aModifiers,
+                                   bool aIgnoreRootScrollFrame,
+                                   float aPressure,
+                                   unsigned short aInputSourceArg,
+                                   int32_t aPointerId,
+                                   int32_t aWidth,
+                                   int32_t aHeight,
+                                   int32_t aTiltX,
+                                   int32_t aTiltY,
+                                   bool aIsPrimary,
+                                   bool aIsSynthesized,
+                                   uint8_t aOptionalArgCount,
+                                   bool* aPreventDefault)
+{
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendPointerEvent", EVENTS);
+
+  return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
+                                aModifiers, aIgnoreRootScrollFrame,
+                                aPressure, aInputSourceArg, aPointerId,
+                                aWidth, aHeight, aTiltX, aTiltY,
+                                aIsPrimary, aIsSynthesized,
+                                aOptionalArgCount, false, aPreventDefault);
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendPointerEventToWindow(const nsAString& aType,
+                                           float aX,
+                                           float aY,
+                                           int32_t aButton,
+                                           int32_t aClickCount,
+                                           int32_t aModifiers,
+                                           bool aIgnoreRootScrollFrame,
+                                           float aPressure,
+                                           unsigned short aInputSourceArg,
+                                           int32_t aPointerId,
+                                           int32_t aWidth,
+                                           int32_t aHeight,
+                                           int32_t aTiltX,
+                                           int32_t aTiltY,
+                                           bool aIsPrimary,
+                                           bool aIsSynthesized,
+                                           uint8_t aOptionalArgCount)
+{
+  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendPointerEventToWindow", EVENTS);
+
+  return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
+                                aModifiers, aIgnoreRootScrollFrame,
+                                aPressure, aInputSourceArg, aPointerId,
+                                aWidth, aHeight, aTiltX, aTiltY,
+                                aIsPrimary, aIsSynthesized,
+                                aOptionalArgCount, true, nullptr);
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::SendWheelEvent(float aX,
                                  float aY,
                                  double aDeltaX,
                                  double aDeltaY,
                                  double aDeltaZ,
                                  uint32_t aDeltaMode,
                                  int32_t aModifiers,
                                  int32_t aLineOrPageDeltaX,
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -95,16 +95,36 @@ protected:
                                   unsigned short aInputSourceArg,
                                   uint32_t aIdentifier,
                                   bool aToWindow,
                                   bool *aPreventDefault,
                                   bool aIsDOMEventSynthesized,
                                   bool aIsWidgetEventSynthesized,
                                   int32_t aButtons);
 
+  NS_IMETHOD SendPointerEventCommon(const nsAString& aType,
+                                    float aX,
+                                    float aY,
+                                    int32_t aButton,
+                                    int32_t aClickCount,
+                                    int32_t aModifiers,
+                                    bool aIgnoreRootScrollFrame,
+                                    float aPressure,
+                                    unsigned short aInputSourceArg,
+                                    int32_t aPointerId,
+                                    int32_t aWidth,
+                                    int32_t aHeight,
+                                    int32_t aTiltX,
+                                    int32_t aTiltY,
+                                    bool aIsPrimary,
+                                    bool aIsSynthesized,
+                                    uint8_t aOptionalArgCount,
+                                    bool aToWindow,
+                                    bool* aPreventDefault);
+
   NS_IMETHOD SendTouchEventCommon(const nsAString& aType,
                                   uint32_t* aIdentifiers,
                                   int32_t* aXs,
                                   int32_t* aYs,
                                   uint32_t* aRxs,
                                   uint32_t* aRys,
                                   float* aRotationAngles,
                                   float* aForces,
--- a/dom/events/test/test_bug967796.html
+++ b/dom/events/test/test_bug967796.html
@@ -38,19 +38,19 @@ var iframe;
 var checkRelatedTarget = false;
 var expectedRelatedEnter = null;
 var expectedRelatedLeave = null;
 var pointerentercount = 0;
 var pointerleavecount = 0;
 var pointerovercount = 0;
 var pointeroutcount = 0;
 
-function sendMouseEventToElement(t, elem) {
+function sendPointerEvent(t, elem) {
   var r = elem.getBoundingClientRect();
-  synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t});
+  synthesizePointer(elem, r.width / 2, r.height / 2, {type: t});
 }
 
 var expectedPointerEnterTargets = [];
 var expectedPointerLeaveTargets = [];
 
 function runTests() {
   outer = document.getElementById("outertest");
   middle = document.getElementById("middletest");
@@ -63,60 +63,60 @@ function runTests() {
   iframe.height=50;
   container.appendChild(iframe);
   iframe.addEventListener("pointerenter", penter);
   iframe.addEventListener("pointerleave", pleave);
   iframe.addEventListener("pointerout", pout);
   iframe.addEventListener("pointerover", pover);
 
   // Make sure ESM thinks pointer is outside the test elements.
-  sendMouseEventToElement("mousemove", outside);
+  sendPointerEvent("pointermove", outside);
 
   pointerentercount = 0;
   pointerleavecount = 0;
   pointerovercount = 0;
   pointeroutcount = 0;
   checkRelatedTarget = true;
   expectedRelatedEnter = outside;
   expectedRelatedLeave = inner;
   expectedPointerEnterTargets = ["outertest", "middletest", "innertest"];
-  sendMouseEventToElement("mousemove", inner);
+  sendPointerEvent("pointermove", inner);
   is(pointerentercount, 3, "Unexpected pointerenter event count!");
   is(pointerovercount, 1, "Unexpected pointerover event count!");
   is(pointeroutcount, 0, "Unexpected pointerout event count!");
   is(pointerleavecount, 0, "Unexpected pointerleave event count!");
   expectedRelatedEnter = inner;
   expectedRelatedLeave = outside;
   expectedPointerLeaveTargets = ["innertest", "middletest", "outertest"];
-  sendMouseEventToElement("mousemove", outside);
+  sendPointerEvent("pointermove", outside);
   is(pointerentercount, 3, "Unexpected pointerenter event count!");
   is(pointerovercount, 1, "Unexpected pointerover event count!");
   is(pointeroutcount, 1, "Unexpected pointerout event count!");
   is(pointerleavecount, 3, "Unexpected pointerleave event count!");
 
   // Event handling over native anonymous content.
   var r = file.getBoundingClientRect();
   expectedRelatedEnter = outside;
   expectedRelatedLeave = file;
-  synthesizeMouse(file, r.width / 6, r.height / 2, {type: "mousemove"});
+  synthesizePointer(file, r.width / 6, r.height / 2, {type: "pointermove"});
   is(pointerentercount, 4, "Unexpected pointerenter event count!");
   is(pointerovercount, 2, "Unexpected pointerover event count!");
   is(pointeroutcount, 1, "Unexpected pointerout event count!");
   is(pointerleavecount, 3, "Unexpected pointerleave event count!");
 
   // Moving pointer over type="file" shouldn't cause pointerover/out/enter/leave events
-  synthesizeMouse(file, r.width - (r.width / 6), r.height / 2, {type: "mousemove"});
+  synthesizePointer(file, r.width - (r.width / 6), r.height / 2, {type: "pointermove"});
   is(pointerentercount, 4, "Unexpected pointerenter event count!");
   is(pointerovercount, 2, "Unexpected pointerover event count!");
   is(pointeroutcount, 1, "Unexpected pointerout event count!");
   is(pointerleavecount, 3, "Unexpected pointerleave event count!");
 
   expectedRelatedEnter = file;
   expectedRelatedLeave = outside;
-  sendMouseEventToElement("mousemove", outside);
+  sendPointerEvent("pointermove", outside);
   is(pointerentercount, 4, "Unexpected pointerenter event count!");
   is(pointerovercount, 2, "Unexpected pointerover event count!");
   is(pointeroutcount, 2, "Unexpected pointerout event count!");
   is(pointerleavecount, 4, "Unexpected pointerleave event count!");
 
   // Initialize iframe
   iframe.contentDocument.documentElement.style.overflow = "hidden";
   iframe.contentDocument.body.style.margin = "0px";
@@ -130,47 +130,47 @@ function runTests() {
   iframe.contentDocument.body.firstChild.onpointerenter = penter;
   iframe.contentDocument.body.firstChild.onpointerleave = pleave;
   iframe.contentDocument.body.lastChild.onpointerenter = penter;
   iframe.contentDocument.body.lastChild.onpointerleave = pleave;
   r = iframe.getBoundingClientRect();
   expectedRelatedEnter = outside;
   expectedRelatedLeave = iframe;
   // Move pointer inside the iframe.
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousemove"},
-                  iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointermove"},
+                    iframe.contentWindow);
   is(pointerentercount, 6, "Unexpected pointerenter event count!");
   is(pointerleavecount, 4, "Unexpected pointerleave event count!");
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousemove"},
-                  iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointermove"},
+                    iframe.contentWindow);
   is(pointerentercount, 7, "Unexpected pointerenter event count!");
   is(pointerleavecount, 5, "Unexpected pointerleave event count!");
   expectedRelatedEnter = iframe;
   expectedRelatedLeave = outside;
-  sendMouseEventToElement("mousemove", outside);
+  sendPointerEvent("pointermove", outside);
   is(pointerentercount, 7, "Unexpected pointerenter event count!");
   is(pointerleavecount, 7, "Unexpected pointerleave event count!");
 
   // pointerdown must produce pointerenter event
   expectedRelatedEnter = outside;
   expectedRelatedLeave = iframe;
   // Move pointer inside the iframe.
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"},
-                  iframe.contentWindow);
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousedown"},
-                  iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
+                    iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointerdown"},
+                    iframe.contentWindow);
   is(pointerentercount, 10, "Unexpected pointerenter event count!");
 
   // pointerdown + pointermove must produce single pointerenter event
   expectedRelatedEnter = outside;
   expectedRelatedLeave = iframe;
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"},
-                  iframe.contentWindow);
-  synthesizeMouse(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "mousemove"},
-                  iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
+                    iframe.contentWindow);
+  synthesizePointer(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "pointermove"},
+                    iframe.contentWindow);
   is(pointerentercount, 11, "Unexpected pointerenter event count!");
 
   Array.from(document.querySelectorAll('*'))
     .concat([iframe.contentDocument.body.firstChild, iframe.contentDocument.body.lastChild])
     .forEach((elt) => {
       elt.onpointerenter = null;
       elt.onpointerleave = null;
       elt.onpointerenter = null;
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -337,16 +337,83 @@ interface nsIDOMWindowUtils : nsISupport
                          [optional] in boolean aIgnoreRootScrollFrame,
                          [optional] in float aPressure,
                          [optional] in unsigned short aInputSourceArg,
                          [optional] in boolean aIsDOMEventSynthesized,
                          [optional] in boolean aIsWidgetEventSynthesized,
                          [optional] in long aButtons,
                          [optional] in unsigned long aIdentifier);
 
+
+  /** Synthesize a pointer event. The event types supported are:
+   *    pointerdown, pointerup, pointermove, pointerover, pointerout
+   *
+   * Events are sent in coordinates offset by aX and aY from the window.
+   *
+   * Note that additional events may be fired as a result of this call. For
+   * instance, typically a click event will be fired as a result of a
+   * mousedown and mouseup in sequence.
+   *
+   * Normally at this level of events, the pointerover and pointerout events are
+   * only fired when the window is entered or exited. For inter-element
+   * pointerover and pointerout events, a movemove event fired on the new element
+   * should be sufficient to generate the correct over and out events as well.
+   *
+   * Cannot be accessed from unprivileged context (not content-accessible)
+   * Will throw a DOM security error if called without chrome privileges.
+   *
+   * The event is dispatched via the toplevel window, so it could go to any
+   * window under the toplevel window, in some cases it could never reach this
+   * window at all.
+   *
+   * @param aType event type
+   * @param aX x offset in CSS pixels
+   * @param aY y offset in CSS pixels
+   * @param aButton button to synthesize
+   * @param aClickCount number of clicks that have been performed
+   * @param aModifiers modifiers pressed, using constants defined as MODIFIER_*
+   * @param aIgnoreRootScrollFrame whether the event should ignore viewport bounds
+   *                           during dispatch
+   * @param aPressure touch input pressure: 0.0 -> 1.0
+   * @param aInputSourceArg input source, see nsIDOMMouseEvent for values,
+   *        defaults to mouse input.
+   * @param aPointerId A unique identifier for the pointer causing the event,
+   *                   defaulting to nsIDOMWindowUtils::DEFAULT_MOUSE_POINTER_ID.
+   * @param aWidth The width (magnitude on the X axis), default is 0
+   * @param aHeight The height (magnitude on the Y axis), default is 0
+   * @param aTilt The plane angle between the Y-Z plane
+   *        and the plane containing both the transducer (e.g. pen stylus) axis and the Y axis. default is 0
+   * @param aTiltX The plane angle between the X-Z plane
+   *        and the plane containing both the transducer (e.g. pen stylus) axis and the X axis. default is 0
+   * @param aIsPrimary  Indicates if the pointer represents the primary pointer of this pointer type.
+   * @param aIsSynthesized controls nsIDOMEvent.isSynthesized value
+   *                       that helps identifying test related events,
+   *                       defaults to true
+   *
+   * returns true if the page called prevent default on this event
+   */
+
+  [optional_argc]
+  boolean sendPointerEvent(in AString aType,
+                           in float aX,
+                           in float aY,
+                           in long aButton,
+                           in long aClickCount,
+                           in long aModifiers,
+                           [optional] in boolean aIgnoreRootScrollFrame,
+                           [optional] in float aPressure,
+                           [optional] in unsigned short aInputSourceArg,
+                           [optional] in long aPointerId,
+                           [optional] in long aWidth,
+                           [optional] in long aHeight,
+                           [optional] in long aTiltX,
+                           [optional] in long aTiltY,
+                           [optional] in boolean aIsPrimary,
+                           [optional] in boolean aIsSynthesized);
+
   /** Synthesize a touch event. The event types supported are:
    *    touchstart, touchend, touchmove, and touchcancel
    *
    * Events are sent in coordinates offset by aX and aY from the window.
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without chrome privileges.
    *
@@ -393,16 +460,37 @@ interface nsIDOMWindowUtils : nsISupport
                               [optional] in boolean aIgnoreRootScrollFrame,
                               [optional] in float aPressure,
                               [optional] in unsigned short aInputSourceArg,
                               [optional] in boolean aIsDOMEventSynthesized,
                               [optional] in boolean aIsWidgetEventSynthesized,
                               [optional] in long aButtons,
                               [optional] in unsigned long aIdentifier);
 
+  /** The same as sendPointerEvent but ensures that the event
+   *  is dispatched to this DOM window or one of its children.
+   */
+  [optional_argc]
+  void sendPointerEventToWindow(in AString aType,
+                                in float aX,
+                                in float aY,
+                                in long aButton,
+                                in long aClickCount,
+                                in long aModifiers,
+                                [optional] in boolean aIgnoreRootScrollFrame,
+                                [optional] in float aPressure,
+                                [optional] in unsigned short aInputSourceArg,
+                                [optional] in long aPointerId,
+                                [optional] in long aWidth,
+                                [optional] in long aHeight,
+                                [optional] in long aTiltX,
+                                [optional] in long aTiltY,
+                                [optional] in boolean aIsPrimary,
+                                [optional] in boolean aIsSynthesized);
+
   /** The same as sendTouchEvent but ensures that the event is dispatched to
    *  this DOM window or one of its children.
    */
   boolean sendTouchEventToWindow(in AString aType,
                                  [array, size_is(count)] in uint32_t aIdentifiers,
                                  [array, size_is(count)] in int32_t aXs,
                                  [array, size_is(count)] in int32_t aYs,
                                  [array, size_is(count)] in uint32_t aRxs,
--- a/layout/base/tests/bug1078327_inner.html
+++ b/layout/base/tests/bug1078327_inner.html
@@ -69,24 +69,24 @@ https://bugzilla.mozilla.org/show_bug.cg
       mediator.addEventListener("pointerover",        MediatorHandler);
       mediator.addEventListener("pointermove",        MediatorHandler);
       mediator.addEventListener("pointerout",         MediatorHandler);
       mediator.addEventListener("lostpointercapture", MediatorHandler);
       listener.addEventListener("pointermove",        ListenerHandler);
       var rect_t = target.getBoundingClientRect();
       var rect_m = mediator.getBoundingClientRect();
       var rect_l = listener.getBoundingClientRect();
-      synthesizeMouse(target,   rect_t.width/2, rect_t.height/20, {type: "mousedown"});
-      synthesizeMouse(target,   rect_t.width/2, rect_t.height/20, {type: "mousemove"});
-      synthesizeMouse(mediator, rect_m.width/2, rect_m.height/20, {type: "mousemove"});
-      synthesizeMouse(listener, rect_l.width/2, rect_l.height/20, {type: "mousemove"});
-      synthesizeMouse(mediator, rect_m.width/2, rect_m.height/20, {type: "mousemove"});
-      synthesizeMouse(target,   rect_t.width/2, rect_t.height/20, {type: "mousemove"});
-      synthesizeMouse(target,   rect_t.width/2, rect_t.height/20, {type: "mouseup"});
-      synthesizeMouse(target,   rect_t.width/2, rect_t.height/20, {type: "mousemove"});
+      synthesizePointer(target,   rect_t.width/2, rect_t.height/20, {type: "pointerdown"});
+      synthesizePointer(target,   rect_t.width/2, rect_t.height/20, {type: "pointermove"});
+      synthesizePointer(mediator, rect_m.width/2, rect_m.height/20, {type: "pointermove"});
+      synthesizePointer(listener, rect_l.width/2, rect_l.height/20, {type: "pointermove"});
+      synthesizePointer(mediator, rect_m.width/2, rect_m.height/20, {type: "pointermove"});
+      synthesizePointer(target,   rect_t.width/2, rect_t.height/20, {type: "pointermove"});
+      synthesizePointer(target,   rect_t.width/2, rect_t.height/20, {type: "pointerup"});
+      synthesizePointer(target,   rect_t.width/2, rect_t.height/20, {type: "pointermove"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_target,        true,   "pointerdown event should be received by target");
       parent.is(test_lost_capture,  true,   "mediator should receive lostpointercapture");
       parent.is(test_mediator_over, 1,      "mediator should receive pointerover event only once");
       parent.is(test_mediator_move, 5,      "mediator should receive pointermove event five times");
       parent.is(test_mediator_out,  1,      "mediator should receive pointerout event only once");
--- a/layout/base/tests/bug1080360_inner.html
+++ b/layout/base/tests/bug1080360_inner.html
@@ -54,19 +54,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       logger("executeTest");
       target = document.getElementById("target");
       listener = document.getElementById("listener");
       target.addEventListener("pointerdown",          TargetHandler);
       listener.addEventListener("gotpointercapture",  ListenerHandler);
       listener.addEventListener("lostpointercapture", ListenerHandler);
       document.addEventListener("lostpointercapture", DocumentHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2,  {type: "mousedown"});
-      synthesizeMouse(target, rect.width/2, rect.height/2,  {type: "mousemove"});
-      synthesizeMouse(target, rect.width/2, rect.height/2,  {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2,  {type: "pointerdown"});
+      synthesizePointer(target, rect.width/2, rect.height/2,  {type: "pointermove"});
+      synthesizePointer(target, rect.width/2, rect.height/2,  {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_target,        true,   "pointerdown event should be received by target");
       parent.is(test_listener_got,  true,   "gotpointercapture event should be received by listener");
       parent.is(test_listener_lost, false,  "listener should not receive lostpointercapture event");
       parent.is(test_document,      true,   "document should receive lostpointercapture event");
       logger("finishTest");
--- a/layout/base/tests/bug1080361_inner.html
+++ b/layout/base/tests/bug1080361_inner.html
@@ -78,19 +78,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       logger("executeTest");
       target = document.getElementById("target");
       mediator = document.getElementById("mediator");
       listener = document.getElementById("listener");
       target.addEventListener("pointerdown",          TargetDownHandler);
       target.addEventListener("pointerup",            TargetUpHandler);
       listener.addEventListener("gotpointercapture",  ListenerHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousemove"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       setTimeout(function() {
         parent.is(test_target_down, true,   "pointerdown event should be received by target");
         parent.is(test_target_up,   true,   "pointerup event should be received by target");
         parent.is(test_first_exc,   true,   "first exception should be thrown");
         parent.is(test_second_exc,  true,   "second exception should be thrown");
--- a/layout/base/tests/bug1153130_inner.html
+++ b/layout/base/tests/bug1153130_inner.html
@@ -41,22 +41,22 @@ https://bugzilla.mozilla.org/show_bug.cg
     }
     function executeTest() {
       logger("executeTest");
       target = document.getElementById("target");
       target.addEventListener("pointerdown",        TargetHandler);
       target.addEventListener("gotpointercapture",  TargetHandler);
       target.addEventListener("pointermove",        TargetHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/5, rect.height/5,  {type: "mousemove"});
-      synthesizeMouse(target, rect.width/5, rect.height/5,  {type: "mousedown"});
-      synthesizeMouse(target, rect.width/4, rect.height/4,  {type: "mousemove"});
-      synthesizeMouse(target, rect.width/3, rect.height/3,  {type: "mousemove"});
-      synthesizeMouse(target, rect.width/3, rect.height/3,  {type: "mouseup"});
-      synthesizeMouse(target, rect.width/2, rect.height/2,  {type: "mousemove"});
+      synthesizePointer(target, rect.width/5, rect.height/5,  {type: "pointermove"});
+      synthesizePointer(target, rect.width/5, rect.height/5,  {type: "pointerdown"});
+      synthesizePointer(target, rect.width/4, rect.height/4,  {type: "pointermove"});
+      synthesizePointer(target, rect.width/3, rect.height/3,  {type: "pointermove"});
+      synthesizePointer(target, rect.width/3, rect.height/3,  {type: "pointerup"});
+      synthesizePointer(target, rect.width/2, rect.height/2,  {type: "pointermove"});
       test_success = true;
       finishTest();
     }
     function finishTest() {
       parent.is(test_down,    true, "pointerdown event should be received by target");
       parent.is(test_capture, true, "gotpointercapture event should be received by target");
       parent.is(test_move,    true, "pointermove event should be received by target while pointer capture is active");
       parent.is(test_success, true, "Firefox should be live!");
--- a/layout/base/tests/bug1162990_inner_1.html
+++ b/layout/base/tests/bug1162990_inner_1.html
@@ -95,23 +95,23 @@ https://bugzilla.mozilla.org/show_bug.cg
     }
 
     function executeTest()
     {
       logger("executeTest");
       setEventHandlers();
       var rectCd = child.getBoundingClientRect();
       var rectLr = listener.getBoundingClientRect();
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/2,  {type: "mousedown"});
-      synthesizeMouse(child,    rectCd.width/3, rectCd.height/2,  {type: "mousemove"});
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/2,  {type: "mousemove"});
-      synthesizeMouse(child,    rectCd.width/3, rectCd.height/2,  {type: "mousemove"});
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/2,  {type: "mousemove"});
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/2,  {type: "mouseup"});
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/3,  {type: "mousemove"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/2,  {type: "pointerdown"});
+      synthesizePointer(child,    rectCd.width/3, rectCd.height/2,  {type: "pointermove"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/2,  {type: "pointermove"});
+      synthesizePointer(child,    rectCd.width/3, rectCd.height/2,  {type: "pointermove"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/2,  {type: "pointermove"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/2,  {type: "pointerup"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/3,  {type: "pointermove"});
       finishTest();
     }
 
     function finishTest() {
       parent.is(test_basketLeave,       1, "Part1: basket should receive pointerleave event after pointer capturing");
       parent.is(test_targetGotCapture,  1, "Part1: target should receive gotpointercapture event");
       parent.is(test_targetLostCapture, 1, "Part1: target should receive lostpointercapture event");
       parent.is(test_targetLeave,       1, "Part1: target should receive pointerleave event only one time");
--- a/layout/base/tests/bug1162990_inner_2.html
+++ b/layout/base/tests/bug1162990_inner_2.html
@@ -96,23 +96,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     function executeTest()
     {
       logger("executeTest");
       setEventHandlers();
       var rectTg = target.getBoundingClientRect();
       var rectCd = child.getBoundingClientRect();
       var rectLr = listener.getBoundingClientRect();
-      synthesizeMouse(target,   rectTg.width/3, rectTg.height/7,  {type: "mousedown"});
-      synthesizeMouse(child,    rectCd.width/3, rectCd.height/2,  {type: "mousemove"});
-      synthesizeMouse(listener, rectLr.width/3, rectLr.height/2,  {type: "mousemove"});
-      synthesizeMouse(child,    rectCd.width/3, rectCd.height/2,  {type: "mousemove"});
-      synthesizeMouse(target,   rectTg.width/3, rectTg.height/7,  {type: "mousemove"});
-      synthesizeMouse(target,   rectTg.width/3, rectTg.height/7,  {type: "mouseup"});
-      synthesizeMouse(target,   rectTg.width/3, rectTg.height/9,  {type: "mousemove"});
+      synthesizePointer(target,   rectTg.width/3, rectTg.height/7,  {type: "pointerdown"});
+      synthesizePointer(child,    rectCd.width/3, rectCd.height/2,  {type: "pointermove"});
+      synthesizePointer(listener, rectLr.width/3, rectLr.height/2,  {type: "pointermove"});
+      synthesizePointer(child,    rectCd.width/3, rectCd.height/2,  {type: "pointermove"});
+      synthesizePointer(target,   rectTg.width/3, rectTg.height/7,  {type: "pointermove"});
+      synthesizePointer(target,   rectTg.width/3, rectTg.height/7,  {type: "pointerup"});
+      synthesizePointer(target,   rectTg.width/3, rectTg.height/9,  {type: "pointermove"});
       finishTest();
     }
 
     function finishTest() {
       parent.is(test_basketLeave,       0, "Part2: basket should not receive pointerleave event after pointer capturing");
       parent.is(test_targetDown,        1, "Part2: target should receive pointerdown event");
       parent.is(test_targetGotCapture,  1, "Part2: target should receive gotpointercapture event");
       parent.is(test_targetLostCapture, 1, "Part2: target should receive lostpointercapture event");
--- a/layout/base/tests/bug968148_inner.html
+++ b/layout/base/tests/bug968148_inner.html
@@ -51,67 +51,67 @@ var test1d2pointerlostcapture = 0;
 var test2d1pointerlostcapture = 0;
 var test2d2pointerlostcapture = 0;
 var test1d1pointergotcapture = 0;
 var test1d2pointergotcapture = 0;
 var test2d1pointergotcapture = 0;
 var test2d2pointergotcapture = 0;
 var test1PointerId = 1;
 var test2PointerId = 2;
-var rx = 1;
-var ry = 1;
-var angle = 0;
-var force = 1;
-var modifiers = 0;
-var utils = SpecialPowers.getDOMWindowUtils(window);
+
+function sendPointerMove(el, id) {
+  var rect = el.getBoundingClientRect();
+  var utils = SpecialPowers.getDOMWindowUtils(window);
+  utils.sendPointerEvent('pointermove', rect.left + 5, rect.top + 5, 0, 0, 0, false, 0, SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH, id);
+}
+
+function sendPointerDown(el, id) {
+  var rect = el.getBoundingClientRect();
+  var utils = SpecialPowers.getDOMWindowUtils(window);
+  utils.sendPointerEvent('pointerdown', rect.left + 5, rect.top + 5, 0, 1, 0, false, 0, SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH, id);
+}
+
+function sendPointerUp(el, id) {
+  var rect = el.getBoundingClientRect();
+  var utils = SpecialPowers.getDOMWindowUtils(window);
+  utils.sendPointerEvent('pointerup', rect.left + 5, rect.top + 5, 0, 1, 0, false, 0, SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH, id);
+}
 
 function log(s) {
   document.getElementById("l").textContent += s + "\n";
 }
 
-function test1d1IncreasePointerMoveCount(e) {
+function test1d2Listener(e) {
   log(e.type + ", " + e.target.id);
-  is(e.target, test1d1, "check target is 1d1.");
-  ++test1d1pointermovecount;
-}
-
-function test1d2IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test1d2, "check target is 1d2.");
+  is(e.target, test1d2, "test1d2 should have got pointermove.");
   ++test1d2pointermovecount;
 }
 
-function test2d1IncreasePointerMoveCount(e) {
+function test2d2Listener(e) {
   log(e.type + ", " + e.target.id);
-  is(e.target, test2d1, "check target is 2d1.");
-  ++test2d1pointermovecount;
-}
-
-function test2d2IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test2d2, "check target is 2d2.");
+  is(e.target, test2d2, "test2d2 should have got pointermove.");
   ++test2d2pointermovecount;
 }
 
-function test1d1CapturePointer(e) {
+function test1d1DownListener(e) {
   log(e.type + ", " + e.target.id);
   test1d1.setPointerCapture(e.pointerId);
 }
 
-function test1d2CapturePointer(e) {
+function test1d1MoveListener(e) {
   log(e.type + ", " + e.target.id);
   test1d2.setPointerCapture(e.pointerId);
 }
 
-function test2d1CapturePointer(e) {
+function test2d1DownListener(e) {
   log(e.type + ", " + e.target.id);
   test2d1.setPointerCapture(e.pointerId);
 }
 
-function test2d2CapturePointer(e) {
+function test2d1MoveListener(e) {
   log(e.type + ", " + e.target.id);
   test2d2.setPointerCapture(e.pointerId);
 }
 
 function test1d1PointerGotCapture(e) {
   log(e.type + ", " + e.target.id);
   ++test1d1pointergotcapture;
 }
@@ -146,157 +146,145 @@ function test2d2PointerGotCapture(e) {
   ++test2d2pointergotcapture;
 }
 
 function test2d2PointerLostCapture(e) {
   log(e.type + ", " + e.target.id);
   ++test2d2pointerlostcapture;
 }
 
+function test1d1PointerMoveListener(e) {
+  log(e.type + ", " + e.target.id);
+  ++test1d1pointermovecount;
+}
+
+function test2d1PointerMoveListener(e) {
+  log(e.type + ", " + e.target.id);
+  ++test2d1pointermovecount;
+}
+
 function runTests() {
   test1d1 = document.getElementById("test1d1");
   test1d2 = document.getElementById("test1d2");
   test2d1 = document.getElementById("test2d1");
   test2d2 = document.getElementById("test2d2");
 
-  var rect1d1 = test1d1.getBoundingClientRect();
-  var rect1d2 = test1d2.getBoundingClientRect();
-  var rect2d1 = test2d1.getBoundingClientRect();
-  var rect2d2 = test2d2.getBoundingClientRect();
-
-  var left1d1 = rect1d1.left + 5;
-  var top1d1 = rect1d1.top + 5;
-  var left1d2 = rect1d2.left + 5;
-  var top1d2 = rect1d2.top + 5;
-  var left2d1 = rect2d1.left + 5;
-  var top2d1 = rect2d1.top + 5;
-  var left2d2 = rect2d2.left + 5;
-  var top2d2 = rect2d2.top + 5;
-
-  test1d1.addEventListener("pointermove", test1d1IncreasePointerMoveCount, true);
-  test1d2.addEventListener("pointermove", test1d2IncreasePointerMoveCount, true);
-  test2d1.addEventListener("pointermove", test2d1IncreasePointerMoveCount, true);
-  test2d2.addEventListener("pointermove", test2d2IncreasePointerMoveCount, true);
+  test1d2.addEventListener("pointermove", test1d2Listener, true);
+  test2d2.addEventListener("pointermove", test2d2Listener, true);
 
   test1d1.addEventListener("gotpointercapture", test1d1PointerGotCapture, true);
   test1d1.addEventListener("lostpointercapture", test1d1PointerLostCapture, true);
 
   test2d1.addEventListener("gotpointercapture", test2d1PointerGotCapture, true);
   test2d1.addEventListener("lostpointercapture", test2d1PointerLostCapture, true);
 
   test1d2.addEventListener("gotpointercapture", test1d2PointerGotCapture, true);
   test1d2.addEventListener("lostpointercapture", test1d2PointerLostCapture, true);
 
   test2d2.addEventListener("gotpointercapture", test2d2PointerGotCapture, true);
   test2d2.addEventListener("lostpointercapture", test2d2PointerLostCapture, true);
 
   document.body.offsetLeft;
+  sendPointerMove(test1d2, test1PointerId);
+  sendPointerMove(test2d2, test2PointerId);
+  is(test1d2pointermovecount, 1, "Should have got pointermove");
+  is(test2d2pointermovecount, 1, "Should have got pointermove");
 
   // This shouldn't enable capturing, since we're not in a right kind of 
   // event listener.
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerDown(test1d1, test1PointerId);
+  sendPointerDown(test2d1, test2PointerId);
 
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerMove(test1d2, test1PointerId);
+  sendPointerMove(test2d2, test2PointerId);
 
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerUp(test1d1, test1PointerId);
+  sendPointerUp(test2d1, test2PointerId);
 
-  // No implicitly / explicitly pointer capture. pointermove should be
-  // dispatched to 1d2, 2d2
-  is(test1d1pointermovecount, 0, "1d1 shouldn't have got pointermove");
-  is(test2d1pointermovecount, 0, "2d1 shouldn't have got pointermove");
-  is(test1d2pointermovecount, 1, "1d2 should have got pointermove");
-  is(test2d2pointermovecount, 1, "2d2 should have got pointermove");
+  is(test1d2pointermovecount, 2, "Should have got pointermove");
+  is(test2d2pointermovecount, 2, "Should have got pointermove");
+
+  test1d1.addEventListener("pointerdown", test1d1DownListener, true);
+  test1d1.addEventListener("pointermove", test1d1PointerMoveListener, true);
+  test2d1.addEventListener("pointerdown", test2d1DownListener, true);
+  test2d1.addEventListener("pointermove", test2d1PointerMoveListener, true);
 
-  // Explicitly capture pointer to 1d1, 2d1
-  test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointerdown", test2d1CapturePointer, {capture: true, once: true});
-
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerDown(test1d1, test1PointerId);
+  sendPointerDown(test2d1, test2PointerId);
+  sendPointerMove(test1d2, test1PointerId);
+  sendPointerMove(test2d2, test2PointerId);
+  is(test1d2pointermovecount, 2, "Shouldn't have got pointermove");
+  is(test1d1pointermovecount, 1, "Should have got pointermove");
+  is(test1d1pointergotcapture, 1, "Should have got pointergotcapture");
 
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  is(test2d2pointermovecount, 2, "Shouldn't have got pointermove");
+  is(test2d1pointermovecount, 1, "Should have got pointermove");
+  is(test2d1pointergotcapture, 1, "Should have got pointergotcapture");
 
-  // Explicitly capture pointer to 1d1, 2d1. pointermove, gotpointercapture
-  // should be dispatched to 1d1, 2d1
-  is(test1d1pointermovecount, 1, "1d1 should have got pointermove");
-  is(test1d1pointergotcapture, 1, "1d1 should have got pointergotcapture");
-  is(test1d2pointermovecount, 1, "1d2 shouldn't have got pointermove");
-  is(test1d2pointergotcapture, 0, "1d2 shouldn't have got pointergotcapture");
+  sendPointerUp(test1d1, test1PointerId);
+  sendPointerUp(test2d1, test2PointerId);
+  test1d1.removeEventListener("pointerdown", test1d1DownListener, true);
+  test1d1.removeEventListener("pointermove", test1d1PointerMoveListener, true);
+  test2d1.removeEventListener("pointerdown", test2d1DownListener, true);
+  test2d1.removeEventListener("pointermove", test2d1PointerMoveListener, true);
 
-  is(test2d1pointermovecount, 1, "2d1 should have got pointermove");
-  is(test2d1pointergotcapture, 1, "2d1 should have got pointergotcapture");
-  is(test2d2pointermovecount, 1, "2d2 shouldn't have got pointermove");
-  is(test2d2pointergotcapture, 0, "2d2 shouldn't have got pointergotcapture");
+  // Nothing should be capturing the event.
+  sendPointerMove(test1d2, test1PointerId);
+  sendPointerMove(test2d2, test2PointerId);
 
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  is(test1d2pointermovecount, 3, "Should have got pointermove");
+  is(test1d1pointerlostcapture, 1, "Should have got pointerlostcapture");
+  is(test2d2pointermovecount, 3, "Should have got pointermove");
+  is(test2d1pointerlostcapture, 1, "Should have got pointerlostcapture");
 
-  // Explicitly capture pointer to 1d1, 2d1 when pointerdown
-  test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointerdown", test2d1CapturePointer, {capture: true, once: true});
+  test1d1.addEventListener("pointermove", test1d1MoveListener, true);
+  test2d1.addEventListener("pointermove", test2d1MoveListener, true);
 
-  // Explicitly capture pointer to 1d2, 2d2 when pointermove
-  test1d1.addEventListener("pointermove", test1d2CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointermove", test2d2CapturePointer, {capture: true, once: true});
+  sendPointerDown(test1d1, test1PointerId);
+  sendPointerDown(test2d1, test2PointerId);
 
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerMove(test1d1, test1PointerId); // This should call setPointerCapture to test1d2!
+  sendPointerMove(test2d1, test2PointerId); // This should call setPointerCapture to test2d2!
 
-  // This should send pointer event to test1d1, test2d1.
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  test1d1.removeEventListener("pointermove", test1d1MoveListener, true);
+  test1d1.addEventListener("pointermove", test1d1PointerMoveListener, true);
 
-  // This should send pointer event to test1d2, test2d2.
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  test2d1.removeEventListener("pointermove", test2d1MoveListener, true);
+  test2d1.addEventListener("pointermove", test2d1PointerMoveListener, true);
+
+  sendPointerMove(test1d1, test1PointerId); // This should send pointer event to test1d2.
+  sendPointerMove(test2d1, test2PointerId); // This should send pointer event to test2d2.
 
-  is(test1d1pointermovecount, 2, "1d1 should have got pointermove");
-  is(test1d1pointergotcapture, 2, "1d1 should have got pointergotcapture");
-  is(test1d2pointermovecount, 2, "1d2 should have got pointermove");
-  is(test1d2pointergotcapture, 1, "1d2 should have got pointergotcapture");
+  is(test1d1pointermovecount, 1, "Shouldn't have got pointermove");
+  is(test1d2pointermovecount, 4, "Should have got pointermove");
+  is(test1d2pointergotcapture, 1, "Should have got pointergotcapture");
 
-  is(test2d1pointermovecount, 2, "2d1 should have got pointermove");
-  is(test2d1pointergotcapture, 2, "2d1 should have got pointergotcapture");
-  is(test2d2pointermovecount, 2, "2d2 should have got pointermove");
-  is(test2d2pointergotcapture, 1, "2d2 should have got pointergotcapture");
+  is(test2d1pointermovecount, 1, "Shouldn't have got pointermove");
+  is(test2d2pointermovecount, 4, "Should have got pointermove");
+  is(test2d2pointergotcapture, 1, "Should have got pointergotcapture");
 
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
+  sendPointerUp(test1d1, test1PointerId);
+  sendPointerUp(test2d1, test2PointerId);
 
   finishTest();
 }
 
 function finishTest() {
   // Let window.onerror have a chance to fire
   setTimeout(function() {
     setTimeout(function() {
-      window.parent.postMessage("run next", "*");
+      window.parent.postMessage("SimpleTest.finish();", "*");
     }, 0);
   }, 0);
 }
 
 window.onload = function () {
   SpecialPowers.pushPrefEnv({
     "set": [
       ["dom.w3c_pointer_events.enabled", true],
-      ["dom.w3c_pointer_events.implicit_capture", false]
     ]
   }, runTests);
 }
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
deleted file mode 100644
--- a/layout/base/tests/bug968148_inner2.html
+++ /dev/null
@@ -1,306 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=968148
--->
-<head>
-  <title>Test for Bug 968148</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <style>
-  .test {
-    width: 20px;
-    height: 20px;
-    border: 1px solid black;
-    -moz-user-select: none;
-  }
-  </style>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968148">Mozilla Bug 968148</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/**
- * Test for Bug 968148, test orignally copied from test_bug582771.html.
- * Mouse functionality converted to pointer and all steps duplicated in order to run them in parallel for two different pointer Id's
-**/
-
-function ok(condition, msg) {
-  parent.ok(condition, msg);
-}
-
-function is(a, b, msg) {
-  parent.is(a, b, msg);
-}
-
-var test1d1;
-var test1d2;
-var test2d1;
-var test2d2;
-var test1d1pointermovecount = 0;
-var test1d2pointermovecount = 0;
-var test2d1pointermovecount = 0;
-var test2d2pointermovecount = 0;
-
-var test1d1pointerlostcapture = 0;
-var test1d2pointerlostcapture = 0;
-var test2d1pointerlostcapture = 0;
-var test2d2pointerlostcapture = 0;
-var test1d1pointergotcapture = 0;
-var test1d2pointergotcapture = 0;
-var test2d1pointergotcapture = 0;
-var test2d2pointergotcapture = 0;
-var test1PointerId = 1;
-var test2PointerId = 2;
-var rx = 1;
-var ry = 1;
-var angle = 0;
-var force = 1;
-var modifiers = 0;
-var utils = SpecialPowers.getDOMWindowUtils(window);
-
-function log(s) {
-  document.getElementById("l").textContent += s + "\n";
-}
-
-function test1d1IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test1d1, "check target is 1d1.");
-  ++test1d1pointermovecount;
-}
-
-function test1d2IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test1d2, "check target is 1d2.");
-  ++test1d2pointermovecount;
-}
-
-function test2d1IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test2d1, "check target is 2d1.");
-  ++test2d1pointermovecount;
-}
-
-function test2d2IncreasePointerMoveCount(e) {
-  log(e.type + ", " + e.target.id);
-  is(e.target, test2d2, "check target is 2d2.");
-  ++test2d2pointermovecount;
-}
-
-function test1d1CapturePointer(e) {
-  log(e.type + ", " + e.target.id);
-  test1d1.setPointerCapture(e.pointerId);
-}
-
-function test1d2CapturePointer(e) {
-  log(e.type + ", " + e.target.id);
-  test1d2.setPointerCapture(e.pointerId);
-}
-
-function test2d1CapturePointer(e) {
-  log(e.type + ", " + e.target.id);
-  test2d1.setPointerCapture(e.pointerId);
-}
-
-function test2d2CapturePointer(e) {
-  log(e.type + ", " + e.target.id);
-  test2d2.setPointerCapture(e.pointerId);
-}
-
-function test1d1PointerGotCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test1d1pointergotcapture;
-}
-
-function test1d1PointerLostCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test1d1pointerlostcapture;
-}
-
-function test2d1PointerGotCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test2d1pointergotcapture;
-}
-
-function test2d1PointerLostCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test2d1pointerlostcapture;
-}
-
-function test1d2PointerGotCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test1d2pointergotcapture;
-}
-
-function test1d2PointerLostCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test1d2pointerlostcapture;
-}
-
-function test2d2PointerGotCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test2d2pointergotcapture;
-}
-
-function test2d2PointerLostCapture(e) {
-  log(e.type + ", " + e.target.id);
-  ++test2d2pointerlostcapture;
-}
-
-function runTests() {
-  test1d1 = document.getElementById("test1d1");
-  test1d2 = document.getElementById("test1d2");
-  test2d1 = document.getElementById("test2d1");
-  test2d2 = document.getElementById("test2d2");
-
-  var rect1d1 = test1d1.getBoundingClientRect();
-  var rect1d2 = test1d2.getBoundingClientRect();
-  var rect2d1 = test2d1.getBoundingClientRect();
-  var rect2d2 = test2d2.getBoundingClientRect();
-
-  var left1d1 = rect1d1.left + 5;
-  var top1d1 = rect1d1.top + 5;
-  var left1d2 = rect1d2.left + 5;
-  var top1d2 = rect1d2.top + 5;
-  var left2d1 = rect2d1.left + 5;
-  var top2d1 = rect2d1.top + 5;
-  var left2d2 = rect2d2.left + 5;
-  var top2d2 = rect2d2.top + 5;
-
-  test1d1.addEventListener("pointermove", test1d1IncreasePointerMoveCount, true);
-  test1d2.addEventListener("pointermove", test1d2IncreasePointerMoveCount, true);
-  test2d1.addEventListener("pointermove", test2d1IncreasePointerMoveCount, true);
-  test2d2.addEventListener("pointermove", test2d2IncreasePointerMoveCount, true);
-
-  test1d1.addEventListener("gotpointercapture", test1d1PointerGotCapture, true);
-  test1d1.addEventListener("lostpointercapture", test1d1PointerLostCapture, true);
-
-  test2d1.addEventListener("gotpointercapture", test2d1PointerGotCapture, true);
-  test2d1.addEventListener("lostpointercapture", test2d1PointerLostCapture, true);
-
-  test1d2.addEventListener("gotpointercapture", test1d2PointerGotCapture, true);
-  test1d2.addEventListener("lostpointercapture", test1d2PointerLostCapture, true);
-
-  test2d2.addEventListener("gotpointercapture", test2d2PointerGotCapture, true);
-  test2d2.addEventListener("lostpointercapture", test2d2PointerLostCapture, true);
-
-  document.body.offsetLeft;
-
-  // This shouldn't enable capturing, since we're not in a right kind of
-  // event listener.
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  // Implicitly pointer capture. pointermove should be dispatched to 1d1, 2d1
-  is(test1d1pointermovecount, 1, "1d1 should have got pointermove");
-  is(test2d1pointermovecount, 1, "2d1 should have got pointermove");
-  is(test1d2pointermovecount, 0, "1d2 shouldn't have got pointermove");
-  is(test2d2pointermovecount, 0, "2d2 shouldn't have got pointermove");
-
-  // Explicitly capture pointer to 1d1, 2d1
-  test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointerdown", test2d1CapturePointer, {capture: true, once: true});
-
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  // Explicitly capture pointer to 1d1, 2d1. pointermove, gotpointercapture
-  // should be dispatched to 1d1, 2d1
-  is(test1d1pointermovecount, 2, "1d1 should have got pointermove");
-  is(test1d1pointergotcapture, 2, "1d1 should have got pointergotcapture");
-  is(test1d2pointermovecount, 0, "1d2 shouldn't have got pointermove");
-  is(test1d2pointergotcapture, 0, "1d2 shouldn't have got pointergotcapture");
-
-  is(test2d1pointermovecount, 2, "2d1 should have got pointermove");
-  is(test2d1pointergotcapture, 2, "2d1 should have got pointergotcapture");
-  is(test2d2pointermovecount, 0, "2d2 shouldn't have got pointermove");
-  is(test2d2pointergotcapture, 0, "2d2 shouldn't have got pointergotcapture");
-
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  // Explicitly capture pointer to 1d1, 2d1 when pointerdown
-  test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointerdown", test2d1CapturePointer, {capture: true, once: true});
-
-  // Explicitly capture pointer to 1d2, 2d2 when pointermove
-  test1d1.addEventListener("pointermove", test1d2CapturePointer, {capture: true, once: true});
-  test2d1.addEventListener("pointermove", test2d2CapturePointer, {capture: true, once: true});
-
-  utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  // This should send pointer event to test1d1, test2d1.
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  // This should send pointer event to test1d2, test2d2.
-  utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  is(test1d1pointermovecount, 3, "1d1 shouldn't have got pointermove");
-  is(test1d1pointergotcapture, 3, "1d1 should have got pointergotcapture");
-  is(test1d2pointermovecount, 1, "1d2 should have got pointermove");
-  is(test1d2pointergotcapture, 1, "1d2 should have got pointergotcapture");
-
-  is(test2d1pointermovecount, 3, "2d1 shouldn't have got pointermove");
-  is(test2d1pointergotcapture, 3, "2d1 should have got pointergotcapture");
-  is(test2d2pointermovecount, 1, "2d2 should have got pointermove");
-  is(test2d2pointergotcapture, 1, "2d2 should have got pointergotcapture");
-
-  utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId],
-                       [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry],
-                       [angle, angle], [force, force], 2, modifiers);
-
-  finishTest();
-}
-
-function finishTest() {
-  // Let window.onerror have a chance to fire
-  setTimeout(function() {
-    setTimeout(function() {
-      window.parent.postMessage("finishTest", "*");
-    }, 0);
-  }, 0);
-}
-
-window.onload = function () {
-  SpecialPowers.pushPrefEnv({
-    "set": [
-      ["dom.w3c_pointer_events.enabled", true],
-      ["dom.w3c_pointer_events.implicit_capture", true]
-    ]
-  }, runTests);
-}
-
-SimpleTest.waitForExplicitFinish();
-
-</script>
-</pre>
-<div class="test" id="test1d1">&nbsp;</div><br><div class="test" id="test1d2">&nbsp;</div>
-<div class="test" id="test2d1">&nbsp;</div><br><div class="test" id="test2d2">&nbsp;</div>
-<pre id="l"></pre>
-</body>
-</html>
--- a/layout/base/tests/bug977003_inner_1.html
+++ b/layout/base/tests/bug977003_inner_1.html
@@ -63,18 +63,18 @@ https://bugzilla.mozilla.org/show_bug.cg
     function executeTest()
     {
       logger("executeTest");
       target = document.getElementById("target");
       target.addEventListener("pointerdown",        DownHandler);
       target.addEventListener("gotpointercapture",  GotPCHandler);
       target.addEventListener("lostpointercapture", LostPCHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_send_got,        1, "Part 1: gotpointercapture event should be sent once");
       parent.is(test_got_async,       1, "Part 1: gotpointercapture event should be asynchronous");
       parent.is(test_got_type,  "mouse", "Part 1: gotpointercapture event should have pointerType mouse");
       parent.is(test_got_primary,  true, "Part 1: gotpointercapture event should have isPrimary as true");
       parent.is(test_send_lost,       1, "Part 1: lostpointercapture event should be sent once");
--- a/layout/base/tests/bug977003_inner_2.html
+++ b/layout/base/tests/bug977003_inner_2.html
@@ -45,18 +45,18 @@ https://bugzilla.mozilla.org/show_bug.cg
     {
       logger("executeTest");
       target = document.getElementById("target");
       listener = document.getElementById("listener");
       target.addEventListener("pointerdown",          TargetDownHandler);
       listener.addEventListener("gotpointercapture",  ListenerHandler);
       listener.addEventListener("lostpointercapture", ListenerHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_down_got,  true,  "Part 2: pointerdown event should be received by target");
       parent.is(test_listener,  false, "Part 2: listener should not receive any events");
       logger("finishTest");
       parent.finishTest();
     }
--- a/layout/base/tests/bug977003_inner_3.html
+++ b/layout/base/tests/bug977003_inner_3.html
@@ -61,19 +61,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       mediator = document.getElementById("mediator");
       listener = document.getElementById("listener");
       target.addEventListener("pointerdown",          TargetDownHandler);
       mediator.addEventListener("gotpointercapture",  MediatorGotPCHandler);
       mediator.addEventListener("lostpointercapture", MediatorLostPCHandler);
       listener.addEventListener("gotpointercapture",  ListenerHandler);
       listener.addEventListener("lostpointercapture", ListenerHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/3, rect.height/3, {type: "mousemove"});
-      synthesizeMouse(target, rect.width/4, rect.height/4, {type: "mousemove"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/3, rect.height/3, {type: "pointermove"});
+      synthesizePointer(target, rect.width/4, rect.height/4, {type: "pointermove"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_down_got,      true,  "Part 3: pointerdown event should be received");
       parent.is(test_mediator_got,  true,  "Part 3: gotpointercapture event should be received by Mediator");
       parent.is(test_mediator_lost, true,  "Part 3: lostpointercapture event should be received by Mediator");
       parent.is(test_listener,      false, "Part 3: listener should not receive any events");
       logger("finishTest");
--- a/layout/base/tests/bug977003_inner_4.html
+++ b/layout/base/tests/bug977003_inner_4.html
@@ -64,20 +64,20 @@ https://bugzilla.mozilla.org/show_bug.cg
       mediator = document.getElementById("mediator");
       listener = document.getElementById("listener");
       target.addEventListener("pointerdown",          TargetDownHandler);
       mediator.addEventListener("gotpointercapture",  MediatorGotPCHandler);
       mediator.addEventListener("lostpointercapture", MediatorLostPCHandler);
       listener.addEventListener("gotpointercapture",  ListenerGotHandler);
       listener.addEventListener("lostpointercapture", ListenerLostHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/3, rect.height/3, {type: "mousemove"});
-      synthesizeMouse(target, rect.width/4, rect.height/4, {type: "mousemove"});
-      synthesizeMouse(target, rect.width/4, rect.height/4, {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/3, rect.height/3, {type: "pointermove"});
+      synthesizePointer(target, rect.width/4, rect.height/4, {type: "pointermove"});
+      synthesizePointer(target, rect.width/4, rect.height/4, {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_down_got,      true,  "Part 4: pointerdown event should be received");
       parent.is(test_mediator_got,  true,  "Part 4: gotpointercapture event should be received by Mediator");
       parent.is(test_mediator_lost, true,  "Part 4: lostpointercapture event should be received by Mediator");
       parent.is(test_listener_got,  true,  "Part 4: gotpointercapture event should be received by listener");
       parent.is(test_listener_lost, true,  "Part 4: lostpointercapture event should be received by listener");
--- a/layout/base/tests/bug977003_inner_5.html
+++ b/layout/base/tests/bug977003_inner_5.html
@@ -79,19 +79,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       target.addEventListener("pointerdown",          TargetDownHandler);
       listener.addEventListener("gotpointercapture",  ListenerGotPCHandler);
       listener.addEventListener("lostpointercapture", ListenerLostPCHandler);
       listener.addEventListener("pointerover",        ListenerOverHandler);
       listener.addEventListener("pointermove",        ListenerMoveHandler);
       listener.addEventListener("pointerup",          ListenerHandler);
       listener.addEventListener("pointerout",         ListenerHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown", isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousemove", isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mouseup",   isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown", isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove", isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup",   isPrimary: true, inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH});
       finishTest();
     }
     function finishTest() {
       parent.is(test_down_target,     true, "Part 5: pointerdown event should be received by target");
       parent.is(test_got_listener,    true, "Part 5: listener should receive gotpointercapture event");
       parent.is(test_got_type,     "touch", "Part 5: gotpointercapture event should have pointerType touch");
       parent.is(test_got_primary,     true, "Part 5: gotpointercapture event should have isPrimary as true");
       parent.is(test_lost_listener,   true, "Part 5: listener should receive lostpointercapture event");
--- a/layout/base/tests/bug977003_inner_6.html
+++ b/layout/base/tests/bug977003_inner_6.html
@@ -69,19 +69,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       listener.addEventListener("gotpointercapture",  ListenerHandler);
       listener.addEventListener("pointerdown",        ListenerHandler);
       listener.addEventListener("pointerover",        ListenerHandler);
       listener.addEventListener("pointermove",        ListenerHandler);
       listener.addEventListener("pointerup",          ListenerHandler);
       listener.addEventListener("pointerout",         ListenerHandler);
       listener.addEventListener("lostpointercapture", ListenerHandler);
       var rect = target.getBoundingClientRect();
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousedown"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mousemove"});
-      synthesizeMouse(target, rect.width/2, rect.height/2, {type: "mouseup"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"});
+      synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"});
       finishTest();
     }
     function finishTest() {
       parent.is(test_target,    true,   "Part 6: pointerdown event should be received by target");
       // PE level 2 defines that the pending pointer capture is processed when firing next pointer events.
       // In this test case, pointer capture release is processed when firing pointermove
       parent.is(test_move,      true,   "Part 6: gotpointercapture should be triggered by pointermove");
       parent.is(test_over,      true,   "Part 6: pointerover should be received when capturing pointer");
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -95,19 +95,17 @@ skip-if = toolkit == 'android' # Bug 135
 skip-if = toolkit == 'android' # Bug 1355821
 support-files = bug851445_helper.html
 [test_bug851485.html]
 skip-if = toolkit == 'android' # Bug 1355821
 [test_bug858459.html]
 skip-if = toolkit == 'android' # Bug 1355822
 [test_bug968148.html]
 skip-if = toolkit == 'android' # Bug 1355829
-support-files =
-  bug968148_inner.html
-  bug968148_inner2.html
+support-files = bug968148_inner.html
 [test_bug970964.html]
 skip-if = toolkit == 'android' # Bug 1355829
 support-files = bug970964_inner.html
 [test_bug977003.html]
 support-files =
   bug977003_inner_1.html
   bug977003_inner_2.html
   bug977003_inner_3.html
--- a/layout/base/tests/test_bug968148.html
+++ b/layout/base/tests/test_bug968148.html
@@ -3,46 +3,34 @@
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=968148
 -->
 <head>
   <title>Test for Bug 968148</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript">
-    function testWithoutImplicitPointerCapture() {
+    function setRemoteFrame() {
       var iframe = document.getElementById("testFrame");
       iframe.src = "bug968148_inner.html";
-    }
 
-    function testWithImplicitPointerCapture() {
-      var iframe = document.getElementById("testFrame");
-      iframe.src = "bug968148_inner2.html";
+      function messageListener(event) {
+        eval(event.data);
+      }
+
+      window.addEventListener("message", messageListener);
     }
 
     function runTest() {
       SimpleTest.waitForExplicitFinish();
-      window.addEventListener("message", (event) => {
-        if (event.data == "finishTest") {
-          SimpleTest.finish();
-        } else if (event.data == "run next") {
-          SpecialPowers.pushPrefEnv({
-            "set": [
-              ["dom.w3c_pointer_events.enabled", true],
-              ["dom.w3c_pointer_events.implicit_capture", true]
-            ]
-          }, testWithImplicitPointerCapture);
-        }
-      });
 
       SpecialPowers.pushPrefEnv({
         "set": [
-          ["dom.w3c_pointer_events.enabled", true],
-          ["dom.w3c_pointer_events.implicit_capture", false]
+          ["dom.w3c_pointer_events.enabled", true]
         ]
-      }, testWithoutImplicitPointerCapture);
+      }, setRemoteFrame);
     }
   </script>
 </head>
 <body onload="runTest();">
   <iframe id="testFrame" height="500" width="500"></iframe>
 </body>
 
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -5,16 +5,17 @@
  *  sendDragEvent
  *  sendChar
  *  sendString
  *  sendKey
  *  sendWheelAndPaint
  *  sendWheelAndPaintNoFlush
  *  synthesizeMouse
  *  synthesizeMouseAtCenter
+ *  synthesizePointer
  *  synthesizeWheel
  *  synthesizeWheelAtPoint
  *  synthesizeKey
  *  synthesizeNativeKey
  *  synthesizeMouseExpectEvent
  *  synthesizeKeyExpectEvent
  *  synthesizeNativeOSXClick
  *  synthesizeDragOver
@@ -357,16 +358,22 @@ function synthesizeMouse(aTarget, aOffse
        aEvent, aWindow);
 }
 function synthesizeTouch(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
 {
   var rect = aTarget.getBoundingClientRect();
   synthesizeTouchAtPoint(rect.left + aOffsetX, rect.top + aOffsetY,
        aEvent, aWindow);
 }
+function synthesizePointer(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
+{
+  var rect = aTarget.getBoundingClientRect();
+  return synthesizePointerAtPoint(rect.left + aOffsetX, rect.top + aOffsetY,
+       aEvent, aWindow);
+}
 
 /*
  * Synthesize a mouse event at a particular point in aWindow.
  *
  * aEvent is an object which may contain the properties:
  *   shiftKey, ctrlKey, altKey, metaKey, accessKey, clickCount, button, type
  *
  * If the type is specified, an mouse event of that type is fired. Otherwise,
@@ -442,16 +449,45 @@ function synthesizeTouchAtPoint(left, to
     }
     else {
       utils.sendTouchEvent("touchstart", [id], [left], [top], [rx], [ry], [angle], [force], 1, modifiers);
       utils.sendTouchEvent("touchend", [id], [left], [top], [rx], [ry], [angle], [force], 1, modifiers);
     }
   }
 }
 
+function synthesizePointerAtPoint(left, top, aEvent, aWindow = window)
+{
+  var utils = _getDOMWindowUtils(aWindow);
+  var defaultPrevented = false;
+
+  if (utils) {
+    var button = computeButton(aEvent);
+    var clickCount = aEvent.clickCount || 1;
+    var modifiers = _parseModifiers(aEvent, aWindow);
+    var pressure = ("pressure" in aEvent) ? aEvent.pressure : 0;
+    var inputSource = ("inputSource" in aEvent) ? aEvent.inputSource : 0;
+    var synthesized = ("isSynthesized" in aEvent) ? aEvent.isSynthesized : true;
+    var isPrimary = ("isPrimary" in aEvent) ? aEvent.isPrimary : false;
+
+    if (("type" in aEvent) && aEvent.type) {
+      defaultPrevented = utils.sendPointerEventToWindow(aEvent.type, left, top, button,
+                                                        clickCount, modifiers, false,
+                                                        pressure, inputSource,
+                                                        synthesized, 0, 0, 0, 0, isPrimary);
+    }
+    else {
+      utils.sendPointerEventToWindow("pointerdown", left, top, button, clickCount, modifiers, false, pressure, inputSource);
+      utils.sendPointerEventToWindow("pointerup", left, top, button, clickCount, modifiers, false, pressure, inputSource);
+    }
+  }
+
+  return defaultPrevented;
+}
+
 // Call synthesizeMouse with coordinates at the center of aTarget.
 function synthesizeMouseAtCenter(aTarget, aEvent, aWindow)
 {
   var rect = aTarget.getBoundingClientRect();
   return synthesizeMouse(aTarget, rect.width / 2, rect.height / 2, aEvent,
                          aWindow);
 }
 function synthesizeTouchAtCenter(aTarget, aEvent, aWindow)
--- a/widget/tests/test_assign_event_data.html
+++ b/widget/tests/test_assign_event_data.html
@@ -618,35 +618,35 @@ const kTests = [
       document.getElementById("animated-div").removeChild(document.getElementById("inserted-div"));
     },
     canRun: function () {
       return true;
     },
     todoMismatch: [],
   },
   { description: "PointerEvent (pointerdown)",
-    targetID: "pointer-target", eventType: "mousedown",
+    targetID: "pointer-target", eventType: "pointerdown",
     dispatchEvent: function () {
       var elem = document.getElementById(this.targetID);
       var rect = elem.getBoundingClientRect();
-      synthesizeMouse(elem, rect.width/2, rect.height/2,
-                      { type: this.eventType, button: 1, clickCount: 1, inputSource: 2, pressure: 0.25, isPrimary: true });
+      synthesizePointer(elem, rect.width/2, rect.height/2,
+                        { type: this.eventType, button: 1, clickCount: 1, inputSource: 2, pressure: 0.25, isPrimary: true });
     },
     canRun: function () {
       return true;
     },
     todoMismatch: [],
   },
   { description: "PointerEvent (pointerup)",
-    targetID: "pointer-target", eventType: "mouseup",
+    targetID: "pointer-target", eventType: "pointerup",
     dispatchEvent: function () {
       var elem = document.getElementById(this.targetID);
       var rect = elem.getBoundingClientRect();
-      synthesizeMouse(elem, rect.width/2, rect.height/2,
-                      { type: this.eventType, button: -1, ctrlKey: true, shiftKey: true, altKey: true, isSynthesized: false });
+      synthesizePointer(elem, rect.width/2, rect.height/2,
+                        { type: this.eventType, button: -1, ctrlKey: true, shiftKey: true, altKey: true, isSynthesized: false });
     },
     canRun: function () {
       return true;
     },
     todoMismatch: [],
   },
 ];