Commit 841f50b5 authored by Stone Shih's avatar Stone Shih
Browse files

Bug 1421482 Part2: Replace test utility synthesizePointer with synthesizeMouse. r=smaug.

We should follow the real use cases to synthesize mouse or touch events to generate pointer events so that the related logic is covered by these test cases.

MozReview-Commit-ID: 9xSgjSL0Azt
parent fd4bca04
Loading
Loading
Loading
Loading
+0 −150
Original line number Diff line number Diff line
@@ -774,156 +774,6 @@ nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
      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,
+0 −20
Original line number Diff line number Diff line
@@ -100,26 +100,6 @@ protected:
                                  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,
+21 −21
Original line number Diff line number Diff line
@@ -43,9 +43,9 @@ var pointerleavecount = 0;
var pointerovercount = 0;
var pointeroutcount = 0;

function sendPointerEvent(t, elem) {
function sendMouseEventToElement(t, elem) {
  var r = elem.getBoundingClientRect();
  synthesizePointer(elem, r.width / 2, r.height / 2, {type: t});
  synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t});
}

var expectedPointerEnterTargets = [];
@@ -68,7 +68,7 @@ function runTests() {
  iframe.addEventListener("pointerover", pover);

  // Make sure ESM thinks pointer is outside the test elements.
  sendPointerEvent("pointermove", outside);
  sendMouseEventToElement("mousemove", outside);

  pointerentercount = 0;
  pointerleavecount = 0;
@@ -78,7 +78,7 @@ function runTests() {
  expectedRelatedEnter = outside;
  expectedRelatedLeave = inner;
  expectedPointerEnterTargets = ["outertest", "middletest", "innertest"];
  sendPointerEvent("pointermove", inner);
  sendMouseEventToElement("mousemove", inner);
  is(pointerentercount, 3, "Unexpected pointerenter event count!");
  is(pointerovercount, 1, "Unexpected pointerover event count!");
  is(pointeroutcount, 0, "Unexpected pointerout event count!");
@@ -86,7 +86,7 @@ function runTests() {
  expectedRelatedEnter = inner;
  expectedRelatedLeave = outside;
  expectedPointerLeaveTargets = ["innertest", "middletest", "outertest"];
  sendPointerEvent("pointermove", outside);
  sendMouseEventToElement("mousemove", outside);
  is(pointerentercount, 3, "Unexpected pointerenter event count!");
  is(pointerovercount, 1, "Unexpected pointerover event count!");
  is(pointeroutcount, 1, "Unexpected pointerout event count!");
@@ -96,14 +96,14 @@ function runTests() {
  var r = file.getBoundingClientRect();
  expectedRelatedEnter = outside;
  expectedRelatedLeave = file;
  synthesizePointer(file, r.width / 6, r.height / 2, {type: "pointermove"});
  synthesizeMouse(file, r.width / 6, r.height / 2, {type: "mousemove"});
  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
  synthesizePointer(file, r.width - (r.width / 6), r.height / 2, {type: "pointermove"});
  synthesizeMouse(file, r.width - (r.width / 6), r.height / 2, {type: "mousemove"});
  is(pointerentercount, 4, "Unexpected pointerenter event count!");
  is(pointerovercount, 2, "Unexpected pointerover event count!");
  is(pointeroutcount, 1, "Unexpected pointerout event count!");
@@ -111,7 +111,7 @@ function runTests() {

  expectedRelatedEnter = file;
  expectedRelatedLeave = outside;
  sendPointerEvent("pointermove", outside);
  sendMouseEventToElement("mousemove", outside);
  is(pointerentercount, 4, "Unexpected pointerenter event count!");
  is(pointerovercount, 2, "Unexpected pointerover event count!");
  is(pointeroutcount, 2, "Unexpected pointerout event count!");
@@ -135,17 +135,17 @@ function runTests() {
  expectedRelatedEnter = outside;
  expectedRelatedLeave = iframe;
  // Move pointer inside the iframe.
  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointermove"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousemove"},
                  iframe.contentWindow);
  is(pointerentercount, 6, "Unexpected pointerenter event count!");
  is(pointerleavecount, 4, "Unexpected pointerleave event count!");
  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointermove"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousemove"},
                  iframe.contentWindow);
  is(pointerentercount, 7, "Unexpected pointerenter event count!");
  is(pointerleavecount, 5, "Unexpected pointerleave event count!");
  expectedRelatedEnter = iframe;
  expectedRelatedLeave = outside;
  sendPointerEvent("pointermove", outside);
  sendMouseEventToElement("mousemove", outside);
  is(pointerentercount, 7, "Unexpected pointerenter event count!");
  is(pointerleavecount, 7, "Unexpected pointerleave event count!");

@@ -153,18 +153,18 @@ function runTests() {
  expectedRelatedEnter = outside;
  expectedRelatedLeave = iframe;
  // Move pointer inside the iframe.
  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"},
                  iframe.contentWindow);
  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointerdown"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousedown"},
                  iframe.contentWindow);
  is(pointerentercount, 10, "Unexpected pointerenter event count!");

  // pointerdown + pointermove must produce single pointerenter event
  expectedRelatedEnter = outside;
  expectedRelatedLeave = iframe;
  synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"},
                  iframe.contentWindow);
  synthesizePointer(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "pointermove"},
  synthesizeMouse(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "mousemove"},
                  iframe.contentWindow);
  is(pointerentercount, 11, "Unexpected pointerenter event count!");

+0 −88
Original line number Diff line number Diff line
@@ -342,73 +342,6 @@ interface nsIDOMWindowUtils : nsISupports {
                         [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
   *
@@ -465,27 +398,6 @@ interface nsIDOMWindowUtils : nsISupports {
                              [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.
   */
+8 −8
Original line number Diff line number Diff line
@@ -74,14 +74,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327
      var rect_t = target.getBoundingClientRect();
      var rect_m = mediator.getBoundingClientRect();
      var rect_l = listener.getBoundingClientRect();
      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"});
      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"});
      finishTest();
    }
    function finishTest() {
Loading