<!doctype html>
<html>
    <head>
        <title>click event target during capture</title>
        <meta name="viewport" content="width=device-width">
        <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="pointerevent_support.js"></script>
        <script src="/resources/testdriver.js"></script>
        <script src="/resources/testdriver-actions.js"></script>
        <script src="/resources/testdriver-vendor.js"></script>
        <style>
        .box {
          margin: 10px;
        }
        #grey {
          background: grey;
        }
        #blue {
          background: blue;
        }
        #green {
          background: green;
        }
        </style>
        <script type="text/javascript">
            PhaseEnum = {
              Phase1:               "phase1",
              Phase2:               "phase2",
              Phase1WithCapturing:  "phase1withcapturing",
              Phase2WithCapturing:  "phase2withcapturing",
            }
            var phase;
            var receivedEvents;

            function resetTestState() {
              phase = PhaseEnum.Phase1;
              receivedEvents = [];
            }

            function run() {
                var test_pointerEvent = setup_pointerevent_test("click target during capture", ['mouse']);
                var grey = document.getElementById('grey');
                var blue = document.getElementById('blue');
                var green = document.getElementById('green');

                ['gotpointercapture', 'lostpointercapture', 'pointerdown', 'pointerup', 'click'].forEach(function(eventName) {
                  [grey, blue, green].forEach(function(target) {
                    target.addEventListener(eventName, function(event) {
                      if (event.eventPhase == event.AT_TARGET) {
                        receivedEvents.push(event.type + '@' + target.id);
                        if (phase == PhaseEnum.Phase1 && target == green && event.type == 'click') {
                            test(function() {
                              assert_equals(receivedEvents.join(','), 'pointerdown@green,pointerup@green,click@green', 'An element should only receive click when it is the first common ancestor of pointerdown and pointerup targets');
                            }, "Click target when pointerup/down targeted at the same element with no capture");
                            phase = PhaseEnum.Phase2;
                            receivedEvents = [];
                        }
                        if (phase == PhaseEnum.Phase2 && target == grey && event.type == 'click') {
                            test(function() {
                              assert_equals(receivedEvents.join(','), 'pointerdown@blue,pointerup@green,click@grey', 'An element should only receive click when it is the first common ancestor of pointerdown and pointerup targets');
                            }, "Click target when pointerup/down targeted at different elements with no capture");
                            phase = PhaseEnum.Phase1WithCapturing;
                            receivedEvents = [];
                        }
                        if (target == blue && event.type == 'lostpointercapture') {
                          if (phase == PhaseEnum.Phase1WithCapturing) {
                            test_pointerEvent.step(function() {
                              assert_equals(receivedEvents.join(','), 'pointerdown@green,gotpointercapture@blue,pointerup@blue,click@grey,lostpointercapture@blue', 'An element should only receive click when it is the first common ancestor of pointerdown and pointerup targets');
                            });
                            phase = PhaseEnum.Phase2WithCapturing;
                            receivedEvents = [];
                          } else if (phase == PhaseEnum.Phase2WithCapturing) {
                            test_pointerEvent.step(function() {
                              assert_equals(receivedEvents.join(','), 'pointerdown@blue,gotpointercapture@blue,pointerup@blue,click@blue,lostpointercapture@blue', 'An element should only receive click when it is the first common ancestor of pointerdown and pointerup targets');
                            });
                            test_pointerEvent.done();
                          }
                        }
                        if (event.type == 'pointerdown' && (target == blue || target == green)) {
                          if (phase == PhaseEnum.Phase1WithCapturing || phase == PhaseEnum.Phase2WithCapturing)
                            blue.setPointerCapture(event.pointerId);
                        }
                      }
                    });
                  });
                });

                // Inject mouse inputs.
                var green = document.getElementById('green');
                var blue = document.getElementById('blue');
                new test_driver.Actions()
                    .pointerMove(0, 0, {origin: green})
                    .pointerDown()
                    .pointerUp()
                    .pointerMove(0, 0, {origin: blue})
                    .pointerDown()
                    .pointerMove(0, 0, {origin: green})
                    .pointerUp()
                    .pointerMove(0, 0, {origin: green})
                    .pointerDown()
                    .pointerUp()
                    .pointerMove(0, 0, {origin: blue})
                    .pointerDown()
                    .pointerMove(0, 0, {origin: green})
                    .pointerUp()
                    .send();

            }
        </script>
    </head>
    <body onload="run()">
        <h1>Pointer Event: click event during capture</h1>
        <h2 id="pointerTypeDescription"></h2>
        <h4>Test Description:
            Click event should be sent to the first common ancestor of the pointerdown and pointerup targets.
            <ol>
                 <li>Click on the green box with the left button of mouse.</li>
                 <li>Press down the left button on the blue box and drag to the green box and release the button.</li>
                 <li>Repeat the two steps above once again.</li>
            </ol>
        </h4>
        <br>
        <div>
          <div id="grey" class="box">
            <div id="green" class="box"></div>
            <div id="blue" class="box"></div>
          </div>
        </div>
    </body>
</html>
