<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Click targets the nearest common ancestor</title>
    <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>
    <style>
    div {
      padding: 10px;
      margin: 5px;
    }
    a {
      background: grey;
    }
    </style>
  </head>
  <body id='body'>
    <h1>Click targeting when targets of down and up are child and parents</h1>
    This test verifies that click event always goes to the first common ancestor of down and up event targets.

    <ul>
      <li>Press down the primary button on link 1 and move onto green container and release.</li>
      <li>Press down the primary button on red container and move onto link 2 and release.</li>
      <li>Click done.</li>
    </ul>

    <div id="link_container1" style="background: green">
      <a id="link1" href="#">link1</a>
    </div>

    <div id="link_container2" style="background: red">
      <a id="link2" href="#">link2</a>
    </div>
    <button id="done">Done</button>
    <script>
    var test_click_target = async_test("Click targets the nearest common ancestor");
    var actions_promise;

    // Prevent drag to avoid interfering with the click.
    document.addEventListener('dragstart', (e) => e.preventDefault());

    var events = [];
    var nodes = ['link_container1', 'link1', 'link_container2', 'link2', 'body'];

    for (var i = 0; i < nodes.length; i++) {
     ['mousedown', 'mouseup', 'click'].forEach((eventName) => {
       document.getElementById(nodes[i]).addEventListener(eventName, (e) => {
         if (e.eventPhase == Event.AT_TARGET)
           events.push(e.type + '@' + e.target.id);
        });
      });
    }
    document.getElementById('done').addEventListener('click', () => {
      test_click_target.step(() => {
        assert_equals (events.join(','),
        "mousedown@link1,mouseup@link_container1,click@link_container1,mousedown@link_container2,mouseup@link2,click@link_container2",
        "Click should be sent to the nearest common ancestor");
      });
      // Make sure the test finishes after all the input actions are completed.
      actions_promise.then( () => {
        test_click_target.done();
      });
    });

    // Inject mouse events.
    var actions = new test_driver.Actions();
    actions_promise = actions.pointerMove(0, 0, {origin: document.getElementById('link1')})
           .pointerDown()
           .pointerMove(0, 0, {origin: document.getElementById('link_container1')})
           .pointerUp()
           .pointerMove(0, 0, {origin: document.getElementById('link_container2')})
           .pointerDown()
           .pointerMove(0, 0, {origin: document.getElementById('link2')})
           .pointerUp()
           .pointerMove(0, 0, {origin: document.getElementById('done')})
           .pointerDown()
           .pointerUp()
           .send();
    </script>
  </body>
</html>
