<!doctype html>
<html>
  <head>
    <title>Pointer Event: Suppress compatibility mouse events on click</title>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
    <link rel="author" title="Google" href="http://www.google.com "/>
    <meta name="assert" content="When a pointerdown is canceled, a click/tap shouldn't fire any compatibility mouse events."/>
    <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/resources/testdriver.js"></script>
    <script src="/resources/testdriver-actions.js"></script>
    <script src="/resources/testdriver-vendor.js"></script>
    <script type="text/javascript" src="pointerevent_support.js"></script>
    <script type="text/javascript">
      var test_pointerEvent = async_test("Suppress compat mouse events on click");
      add_completion_callback(end_of_test);
      var actions_promise;

      var detected_pointertypes = {};
      var event_log = [];

      function end_of_test() {
          showLoggedEvents();
          showPointerTypes();
      }

      function end_of_interaction() {
          test(function () {
              assert_equals(event_log.join(", "),
                  "click@target0, mousedown@target1, mouseup@target1, click@target1");
          }, "Event log");

          // Make sure the test finishes after all the input actions are completed.
          actions_promise.then( () => {
              test_pointerEvent.done();
          });
      }

      function run() {
          var targetDone = document.getElementById('done');
          on_event(targetDone, "click", end_of_interaction);

          var target_list = ["target0", "target1"];
          var pointer_event_list = ["pointerdown"];
          var mouse_event_list = ["mousedown", "mouseup", "click"];

          target_list.forEach(function(targetId) {
              var target = document.getElementById(targetId);

              pointer_event_list.forEach(function(eventName) {
                  on_event(target, eventName, function (event) {
                      detected_pointertypes[event.pointerType] = true;
                      var label = event.type + "@" + targetId;

                      test(function () {
                          assert_true(event.isPrimary);
                      }, "primary pointer " + label);

                      if (label === "pointerdown@target0")
                          event.preventDefault();
                  });
              });

              mouse_event_list.forEach(function(eventName) {
                  on_event(target, eventName, function (event) {
                      event_log.push(event.type + "@" + targetId);
                  });
              });
          });

          // Inject mouse inputs.
          actions_promise = new test_driver.Actions()
              .pointerMove(0, 0, {origin: target0})
              .pointerDown()
              .pointerUp()
              .pointerMove(0, 0, {origin: target1})
              .pointerDown()
              .pointerUp()
              .pointerMove(0, 0, {origin: targetDone})
              .pointerDown()
              .pointerUp()
              .send();
      }
    </script>
    <style>
      #target0, #target1 {
        margin: 20px;
      }

      #done {
        margin: 20px;
        border: 2px solid black;
      }
    </style>
  </head>
  <body onload="run()">
    <h1>Pointer Event: Suppress compatibility mouse events on click</h1>
    <h4>
      When a pointerdown is canceled, a click/tap shouldn't fire any compatibility mouse events except click event.
    </h4>
    <ol>
      <li> Click or tap on Target0.</li>
      <li> Click or tap on Target1.</li>
      <li> Click Done.</li>
    </ol>
    <div id="target0">
      Target0
    </div>
    <div id="target1">
      Target1
    </div>
    <div id="done">
      Done
    </div>
    <div id="complete-notice">
      <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
      <p>The following events were logged: <span id="event-log"></span>.</p>
    </div>
    <div id="log"></div>
  </body>
</html>
