<html dir=rtl>
    <head>
        <script language="javascript">
            function log(str)
            {
                var li = document.createElement("li");
                li.appendChild(document.createTextNode(str));
                var console = document.getElementById("console");
                console.appendChild(li);
            }
            
            function assertEqual(message, actual, expected)
            {
                if (actual != expected)
                    log("\n" + message + ": Failure, actual: " + actual + "; expected: " + expected);
                else
                    log("\n" + message + ": Success");
            }
            
            function assertClose(message, actual, expected)
            {
                if ((actual >= expected && actual - expected < 5) ||
                    (expected >= actual && expected - actual < 5))
                    log("\n" + message + ": Success");
                else
                    log("\n" + message + ": Failure, actual: " + actual + "; expected: " + expected);
            }
            
            var expectedScrollX = -1000;
            var expectedScrollY = 500;

            onload = function()
            {
                if (window.testRunner)
                    testRunner.dumpAsText();

                // Test horizontal scroll bar presents and was initially at the right for RTL page.
                assertEqual("original scroll x for RTL page ", window.scrollX, 0);
            
                // Test horizontal scroll.
                window.scrollTo(expectedScrollX, expectedScrollY);
                assertEqual("horizontal scroll: ", window.scrollX, expectedScrollX);
                // Test calling window.scrollX continuously wont change the scrollX position.
                assertEqual("continuously call window.scrollX ", window.scrollX, expectedScrollX);
            

                // Test zooming wont reset scroll position.
                if (window.eventSender) {
                    window.scrollTo(expectedScrollX, expectedScrollY);
                    eventSender.zoomPageIn();
                    eventSender.zoomPageOut();
                    assertClose("zoom in and out preserve scroll position", window.scrollX,expectedScrollX);
                }
               
                // Test resize wont reset scroll position.
                window.resizeTo(1000, window.innerHeight);
                window.scrollTo(expectedScrollX, expectedScrollY);
                window.resizeTo(2000, window.innerHeight);
                assertEqual("resize preserves scroll position", window.scrollX, expectedScrollX);
                // Test HOME/END operation.
                if (window.eventSender) {
                    // Not using assert equal here since the behavior is different in each port. 
                    // For example, in Mac, HOME/END key reset both x and y scroll position. 
                    // In Chromium, HOME/END key only reset y scroll position, and x scroll position is preserved.
                    window.scrollTo(expectedScrollX, expectedScrollY);
                    eventSender.keyDown("home");
                    log("KeyDown HOME move x-scroll position to right for RTL page: " + window.scrollX, 0);
                    window.scrollTo(expectedScrollX, expectedScrollY);
                    eventSender.keyDown("end");
                    log("KeyDown END move x-scroll position to right for RTL page: " + window.scrollX, 0);
                }
            
                // Test select all selects all document content.
                window.resizeTo(500, 500);
                var div = document.getElementById("div");
                div.focus();
                document.execCommand("SelectAll");
                var selection = window.getSelection();
                assertEqual("selectAll selects all document", selection.toString().substring(0, div.innerHTML.length), div.innerHTML);

                div.style.display = "none";
               
            }
        </script>
    </head>
    <body>
        <div id="div" style="whitespace:nowrap; width: 4000px; height: 1000px; border: 1px solid red;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>
        <ul id="console" dir=ltr></ul>
    </body>
</html>
