<html>
<head>
    <title></title>
    <script type="text/javascript">
        if (window.testRunner) {
            testRunner.dumpAsText();
            testRunner.dumpEditingCallbacks();
        }

        function kill_event(event)
        {
           event.preventDefault();
        }

        var y;
        var x1;
        var x2;

        function finish()
        {
            eventSender.mouseMoveTo(x2, y);
            eventSender.mouseUp();

            var result = document.getElementById("result");
            result.innerText = getSelection().baseNode ? "FAIL" : "PASS";

            testRunner.notifyDone();
        }

        function test()
        {
            if (!window.eventSender)
                return;

            testRunner.waitUntilDone();

            var target = document.getElementById("target");
            y = target.offsetTop + target.offsetHeight / 2;
            x1 = target.offsetLeft + 10;
            x2 = x1 + 100;

            eventSender.dragMode = false;
            eventSender.mouseMoveTo(x1, y);
            eventSender.mouseDown();
            // Get the autoscroll timer started
            eventSender.mouseMoveTo(x1, y);

            // Wait the autoscroll timer interval
            setTimeout(finish, 100);
        }

        addEventListener("selectstart", kill_event, true);
    </script>
</head>
<body onload="test()">
    <p>
        Test for <i><a href="http://bugs.webkit.org/show_bug.cgi?id=12823">http://bugs.webkit.org/show_bug.cgi?id=12823</a>
        REGRESSION(r16968-16977): unable to prevent selection by cancelling "selectstart" event</i>.
    </p>
    <p id="target">
        You should not be able to select this text by clicking or dragging across it.
    </p>
    <p id="result">
    </p>
</body>
</html>
