<!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 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>
            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");
                var actions_promise;

                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");
                    });
                    // Make sure the test finishes after all the input actions are completed.
                    actions_promise.then( () => {
                        test_pointerEvent.done();
                    });
                });

                // Inject mouse inputs.
                actions_promise = new test_driver.Actions()
                    .pointerMove(0, 0, {origin: target0})
                    .pointerDown()
                    .pointerMove(0, 10, {origin: target0})
                    .pointerMove(0, 20, {origin: target0})
                    .pointerMove(0, -10, {origin: target1})
                    .pointerMove(0, 0, {origin: target1})
                    .pointerMove(0, 10, {origin: target1})
                    .pointerUp()
                    .pointerMove(0, 0, {origin: target1})
                    .pointerDown()
                    .pointerUp()
                    .send();
            }
        </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>
