<!doctype html>
<html>
    <head>
        <title>Pointer Events pointer lock 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>
        <!-- Additional helper script for common checks across event types -->
        <script type="text/javascript" src="../pointerevent_support.js"></script>
        <script>
            var got_capture = false;
            var lost_capture = false;
            var lock_requested = false;

            function resetTestState() {
            }

            function run() {
                var test_pointerEvent = setup_pointerevent_test("no pointercapture while pointerlock", ['mouse']);
                var div1 = document.getElementById("div1");
                var div2 = document.getElementById("div2");

                on_event(div1, 'pointerdown', function(event) {
                    div2.setPointerCapture(event.pointerId);
                });
                on_event(document, 'contextmenu', function(event) {
                    event.preventDefault();
                });
                on_event(div2, 'pointermove', function(event) {
                    if (event.button == 2 && got_capture && !lock_requested) {
                        div1.requestPointerLock();
                        lock_requested = true;
                    }
                });
                on_event(div2, 'gotpointercapture', function(event) {
                    got_capture = true;
                });
                on_event(div2, 'lostpointercapture', function(event) {
                    lost_capture = true;
                });
                on_event(document,"pointerlockerror", function() {
                    assert_unreached("Pointer lock error");
                })

                injectInput().then(function(){
                    test_pointerEvent.step(function(){
                        assert_true(lost_capture, "Pointer capture was lost after got a pointer lock.");
                        assert_equals(document.pointerLockElement, div1, "document.pointerLockElement should be div1.");
                    });
                    test_pointerEvent.done();
                })
            }

            // Inject mouse input
            function injectInput() {
                var actions = new test_driver.Actions();
                return actions.pointerMove(0, 0, {origin: div1})
                              .pointerDown({button: actions.ButtonType.LEFT})
                              .pointerMove(30, 30, {origin: div1})
                              .pointerMove(30, 0, {origin: div1})
                              .pointerDown({button: actions.ButtonType.RIGHT})
                              .pointerMove(60, 30, {origin: div1})
                              .pointerMove(20, 20, {origin: div1})
                              .pointerUp({button: actions.ButtonType.RIGHT})
                              .pointerUp({button: actions.ButtonType.LEFT})
                              .send();
            }
        </script>
    </head>
    <body onload="run()">
        <h1>Pointer Events pointer lock test</h1>
        <h2 id="pointerTypeDescription"></h2>
        <h4>
            Test Description: This test checks that we release the exsiting pointer capture when any element in the page gets a pointer lock.
            <ol>
                 <li>Press left button down on the green rectangle and hold it.</li>
                 <li>Move the mouse inside the green rectangle.</li>
                 <li>Click right button while keeping left button down</li>
                 <li>Keep moving the mouse inside the green rectangle.</li>
            </ol>

            Test passes if the pointer capture is released on the yellow rectangle when the green rectangle gets the pointer lock.
        </h4>
        <div id="testContainer">
            <div id="div1" style="width:800px;height:250px;background:green"></div>
            <div id="div2" style="width:800px;height:250px;background:yellow"></div>
        </div>
        <div class="spacer"></div>
    </body>
</html>
