<!doctype html>
<html>
    <head>
        <title>Set/Release 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>
        <!-- Additional helper script for common checks across event types -->
        <script type="text/javascript" src="pointerevent_support.js"></script>
    </head>
    <body>
        <h1>Pointer Events capture test</h1>
        <h4>
            Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
            <ol>
                <li> Move your mouse over the black rectangle. pointermove event should be logged in the black rectangle</li>
                <li> Move your mouse over the purple rectangle. pointerover event should be logged in the purple rectangle</li>
                <li> Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged in the black rectangle</li>
                <li> Move your mouse anywhere. pointermove should be logged in the black rectangle</li>
                <li> Move your mouse over the purple rectangle. Nothig should happen</li>
                <li> Move your mouse over the black rectangle. pointermove should be logged in the black rectangle</li>
                <li> Release left mouse button. "lostpointercapture" should be logged in the black rectangle</li>
            </ol>
        </h4>
        Test passes if the proper behaviour of the events is observed.
        <div id="target0"></div>
        <br>
        <div id="target1"></div>
        <br>
        <input type="button" id="btnCapture" value="Set Capture">
        <script type='text/javascript'>
            var isPointerCapture = false;
            var pointermoveNoCaptureGot0 = false;
            var pointermoveCaptureGot0 = false;
            var pointermoveNoCaptureGot1 = false;
            var ownEventForTheCapturedTargetGot = false;
            var count=0;

            var detected_pointertypes = {};
            add_completion_callback(showPointerTypes);

            var target0 = document.getElementById('target0');
            var target1 = document.getElementById('target1');
            var captureButton = document.getElementById('btnCapture');

            var test_gotpointercapture = async_test("gotpointercapture event received");
            var test_lostpointercapture = async_test("lostpointercapture event received");

            window.onload = function() {
                on_event(captureButton, 'pointerdown', function(e) {
                    if(isPointerCapture == false) {
                        isPointerCapture = true;
                        sPointerCapture(e);
                    }
                });

                on_event(target0, 'gotpointercapture', function(e) {
                    test_gotpointercapture.done();
                    log("gotpointercapture", target0);
                });

                on_event(target0, 'lostpointercapture', function(e) {
                    test_lostpointercapture.done();
                    isPointerCapture = false;
                    log("lostpointercapture", target0);
                });

                run();
            }

            function run() {
                var test_pointermove0 = async_test("pointerover event for black rectangle received")
                var test_pointermove1 = async_test("pointerover event for purple rectangle received")

                on_event(target0, "pointermove", function (event) {
                    detected_pointertypes[ event.pointerType ] = true;
                    if(!pointermoveNoCaptureGot0) {
                        test_pointermove0.done();
                        log("pointermove", document.getElementById('target0'));
                        pointermoveNoCaptureGot0 = true;
                    }
                    if(isPointerCapture) {
                        if(!pointermoveCaptureGot0) {
                            test(function() {
                                assert_true(event.relatedTarget==null, "relatedTarget is null when the capture is set")
                            }, "relatedTarget is null when the capture is set. relatedTarget is " + event.relatedTarget);
                            test(function() {
                                assert_true((event.clientX < target0.getBoundingClientRect().left)||
                                (event.clientX > target0.getBoundingClientRect().right)||
                                (event.clientY < target0.getBoundingClientRect().top)||
                                (event.clientY > target0.getBoundingClientRect().bottom),
                                "pointermove received for captured element while out of it")
                            }, "pointermove received for captured element while out of it");
                            log("pointermove", document.getElementById('target0'));
                            pointermoveCaptureGot0 = true;
                        }
                        if((event.clientX > target0.getBoundingClientRect().left)&&
                            (event.clientX < target0.getBoundingClientRect().right)&&
                            (event.clientY > target0.getBoundingClientRect().top)&&
                            (event.clientY < target0.getBoundingClientRect().bottom)&&
                            !ownEventForTheCapturedTargetGot) {
                                test(function() {
                                    assert_true(true, "pointermove received for captured element while inside of it");
                                }, "pointermove received for captured element while inside of it");
                            log("pointermove", document.getElementById('target0'));
                            ownEventForTheCapturedTargetGot = true;
                        }
                    }
                });

                on_event(target1, "pointermove", function (event) {
                        if(isPointerCapture == true) {
                            test(function() {
                                assert_unreached("pointermove shouldn't trigger for this target when capture is enabled");
                            }, "pointermove shouldn't trigger for the purple rectangle while the black rectangle has capture");
                        }
                    if(!pointermoveNoCaptureGot1) {
                        test_pointermove1.done();
                        log("pointermove", document.getElementById('target1'));
                        pointermoveNoCaptureGot1 = true;
                    }
                });
            }
        </script>
        <h1>Pointer Events Capture Test</h1>
        <div id="complete-notice">
            <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
        </div>
        <div id="log"></div>
    </body>
</html>