<script src="../../../../resources/js-test-pre.js"></script>
<style>
    #subpixel-test {
        width: 4.5px;
    }
    .test {
        width: 100px;
        font-family: "Ahem";
    }
    .pusher {
        width: 4000px;
        height: 1000px;
        outline: 1px solid black;
    }
</style>

<div id="testArea">
    <div id="test-top" class="test">xxxxx xxxxx xxxxx xxxxx</div>
    <div class="pusher">This box is here to create scrollbars.</div>
    <div id="test-bottom" class="test" style="margin-left: 900px;">xxxxx xxxxx xxxxx xxxxx</div>
    <div class="pusher">This box is here to create additional space for the hit tests which must initially be in the scroll area.</div>
</div>

<p id="description"></p>
<div id="console"></div>
<div id="subpixel-test"></div>

<script>
    if (window.testRunner)
        testRunner.dumpAsText();

    description('This checks for proper behavior of caretRangeFromPoint before and after scrolling.');

    var elementTop = document.getElementById('test-top'),
        elementBottom = document.getElementById('test-bottom');

    function testsWithBaseline(baselinePos, expectedContainer, zoomOrNot) {
        function test(expectedOffset, scrollByX, scrollByY) {
            var hitPosition = { x: 15, y: 15 },
                range,
                doesContainerPass = function() { return range.startContainer === expectedContainer },
                doesOffsetPass = function() { return range.startOffset === expectedOffset };

            // Scroll relative to target.
            scrollRelativeToBaseline(scrollByX, scrollByY);

            range = document.caretRangeFromPoint(hitPosition.x, hitPosition.y);

            // shouldn't return null range on any of these tests
            if (range === null) {
                testFailed("null range was returned from document.caretRangeFromPoint(" + hitPosition.x + ", " + hitPosition.y + ") at window scroll position " + window.scrollX + "x" + window.scrollY);
                return;
            }

            // do an actual check
            function check(thunk, message) {
                if (thunk())
                    testPassed(message);
                else
                    testFailed(message);
            }
            check(doesContainerPass, "Range.startContainer check (got " + range.startContainer + ", expected " + expectedContainer + ")");
            check(doesOffsetPass, "Range.startOffset check (got " + range.startOffset + ", expected " + expectedOffset + ")");
        }

        function scrollRelativeToBaseline(x, y) {
            window.scrollTo(baselinePos.x + x, baselinePos.y + y);
        }

        if (zoomOrNot == "zoom") {
            test(0, 0, 0);
            test(6, 0, 25);
            test(4, 50, 0);
            test(10, 50, 25);
        } else {
            test(0, 0, 0);
            test(12, 0, 25);
            test(2, 25, 0);
            test(14, 25, 25);
        }

        debug(" ");
    }

    var rectTop = elementTop.getBoundingClientRect(),
        rectBottom = elementBottom.getBoundingClientRect(),
        // Subtract some distance so we aren't in the very top left of the target.
        topBaseline = { x: rectTop.left - 8, y: rectTop.top - 8 },
        bottomBaseline = { x: rectBottom.left - 8, y: rectBottom.top - 8 };

     // Testing inside initial containing block (top left)
    testsWithBaseline(topBaseline, elementTop.firstChild, "none");

    // Testing outside initial containing block (mid-page)
    testsWithBaseline(bottomBaseline, elementBottom.firstChild, "none");

    eventSender.zoomPageOut();
    testsWithBaseline(topBaseline, elementTop.firstChild, "zoom");

    if (window.testRunner) {
        var area = document.getElementById('testArea');
        area.parentNode.removeChild(area);
    }
</script>
<script src="../../../../resources/js-test-post.js"></script>
