<!doctype html>
<html>
    <head>
        <title>Element.hasPointerCapture test</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 type="text/javascript" src="pointerevent_support.js"></script>
        <script>
            var detected_pointertypes = {};
            add_completion_callback(showPointerTypes);
            var test_pointerEvent = async_test("hasPointerCapture");
            var listening_events = [
                "pointerover",
                "pointerenter",
                "pointerout",
                "pointerleave",
                "pointermove",
                "gotpointercapture"
            ];
            var set_capture_to_target0 = false;

            function run() {
                var target0 = document.getElementById("target0");
                var target1 = document.getElementById("target1");

                on_event(target0, "pointerdown", function (e) {
                    detected_pointertypes[e.pointerType] = true;
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), false,
                                      "before target0.setPointerCapture, target0.hasPointerCapture should be false");
                    });
                    target1.setPointerCapture(e.pointerId);
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), false,
                                      "after target1.setPointerCapture, target0.hasPointerCapture should be false");
                        assert_equals(target1.hasPointerCapture(e.pointerId), true,
                                      "after target1.setPointerCapture, target1.hasPointerCapture should be true");
                    });
                    target0.setPointerCapture(e.pointerId);
                    set_capture_to_target0 = true;
                    // hasPointerCapture will return true immediately after a call to setPointerCapture
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), true,
                                      "after target0.setPointerCapture, target0.hasPointerCapture should be true");
                    });
                    // hasPointerCapture will return false immediately after a call to releasePointerCapture
                    target0.releasePointerCapture(e.pointerId);
                    set_capture_to_target0 = false;
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), false,
                                      "after target0.releasePointerCapture, target0.hasPointerCapture should be false");
                        assert_equals(target1.hasPointerCapture(e.pointerId), false,
                                      "after target0.releasePointerCapture, target1.hasPointerCapture should be false");
                    });
                    target0.setPointerCapture(e.pointerId);
                    set_capture_to_target0 = true;
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), true,
                                      "after target0.setPointerCapture, target0.hasPointerCapture should be true");
                    });
                    // If the element.hasPointerCapture is false element.releasePointerCapture does nothing
                    target1.releasePointerCapture(e.pointerId);
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), true,
                                      "while target1.hasPointerCapture is false, target1.releasePointerCapture should not change hasPointerCapture");
                    });
                });

                for (var i = 0; i < listening_events.length; i++) {
                    on_event(target0, listening_events[i], function (e) {
                        test_pointerEvent.step(function () {
                            assert_equals(target0.hasPointerCapture(e.pointerId), set_capture_to_target0,
                                          "Received " + e.type + " target0.hasPointerCapture should be " + set_capture_to_target0);
                        });
                    });
                }

                on_event(target0, "pointerup", function (e) {
                    // Immediately after firing the pointerup or pointercancel events, a user agent must clear
                    // the pending pointer capture target override for the pointerId, and then run
                    // "Process Pending Pointer Capture" steps to fire lostpointercapture if necessary.
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), true,
                                      "pointerup target0.hasPointerCapture should be true");
                    });
                    set_capture_to_target0 = false;
                });

                on_event(target0, "lostpointercapture", function (e) {
                    test_pointerEvent.step(function () {
                        assert_equals(target0.hasPointerCapture(e.pointerId), false,
                                      "pointerup target0.hasPointerCapture should be false");
                    });
                });

                on_event(target1, "pointerup", function (e) {
                    test_pointerEvent.step(function () {
                        assert_equals(target1.hasPointerCapture(e.pointerId), false,
                                      "pointerup target1.hasPointerCapture should be false");
                    });
                    test_pointerEvent.done();
                });
            }
        </script>
    </head>
    <body onload="run()">
        <h1>Element.hasPointerCapture test</h1>
        <h4>
            Test Description: This test checks if Element.hasPointerCapture returns value correctly
            <ol>
                <li> Press black rectangle and do not release
                <li> Move your pointer to purple rectangle
                <li> Release the pointer
                <li> Click purple rectangle
            </ol>
        </h4>
        <p>
        <div id="target0" touch-action:none></div>
        <div id="target1" touch-action:none></div>
        <div id="complete-notice">
            <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
        </div>
        <div id="log"></div>
    </body>
</html>
