<html>
    <head>
        <script>
            function test()
            {
                if (window.testRunner) {
                    testRunner.waitUntilDone();
                    setTimeout(autoscrollTestPart1, 0);
                }
            }
            function autoscrollTestPart1()
            {
                var tf = document.getElementById('tf');
                if (window.eventSender) {
                    tf.scrollIntoView();
                    var h = tf.offsetTop - document.scrollingElement.scrollTop + 10;
                    eventSender.dragMode = false;
                    eventSender.mouseMoveTo(20, h);
                    eventSender.mouseDown();
                    eventSender.mouseMoveTo(20, h);
                    eventSender.mouseMoveTo(300, h);
                }
                setTimeout(autoscrollTestPart2, 100);
            }
            function autoscrollTestPart2()
            {
                if (window.eventSender)
                    eventSender.mouseUp();
                log("ScrollLeft: " + document.getElementById('tf').scrollLeft);
                if (window.testRunner)
                    testRunner.notifyDone();
            }
            function log(msg)
            {
                var res = document.getElementById('res');
                res.innerHTML = res.innerHTML + msg + "<br>";
            }
        </script>
    </head>
    <body onload="test()">
        <p>Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=11534">bug 11534</a>.</p>
        <p>Readonly text fields don't scroll when selecting content.</p>
        <input id="tf" readonly value="abcdefghijklmnopqrstuvwxyz"></input>
        <div id="res"></div>
    </body>
</html>
