<!DOCTYPE html>
<html>
<head>
    <title>Touch Adjustment : Testing that a drag/drop will start on a long press - bug 92914</title>
    <script src="../resources/js-test-pre.js"></script>
    <script src="resources/touchadjustment.js"></script>
    <style>
        #sandbox {
            position: absolute;
            left: 0px;
            top: 0px;
        }
    </style>
</head>

<body>

<div id="sandbox">
<p><a href="" id="link1">I</a> propose to consider <a href="" id="link2">the question</a>, "Can machines think?"<br>This should begin with definitions of the meaning of the terms "machine" and <a href="" id="link3">"think."</a></p>
</div>

<p id='description'></p>
<div id='console'></div>

<script>
    var element;
    var adjustedNode;
    // Set up shortcut access to elements
    var e = {};
    ['sandbox', 'link1', 'link2', 'link3'].forEach(function(a) {
        e[a] = document.getElementById(a);
    });

    document.ondragstart = function(e) { debug("PASS"); e.preventDefault();}

    function testLongPress(touchpoint)
    {
        if (eventSender.gestureLongPress)
            eventSender.gestureLongPress(touchpoint.x, touchpoint.y, touchpoint.width, touchpoint.height);
        else
            debug("gestureLongPress not implemented by this platform.");
    }

    function testDirectTouch(element)
    {
        // Touch directly in the center of the element.
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'center', 0, 20, 30);
        if (document.elementFromPoint(touchpoint.x, touchpoint.y) != element)
            testFailed('Direct touch ended up on some other element');
        testLongPress(touchpoint);
    }

    function testIndirectTouch(element)
    {
        // Touch just right of the element.
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'right', 10, 30, 20);
        if (isDescendantOf(element, document.elementFromPoint(touchpoint.x, touchpoint.y)))
            testFailed('Indirect touch ended up still on top of the element');
        testLongPress(touchpoint);
    }

    function isDescendantOf(parent, child)
    {
        var n = child;
        while(n) {
            if(n==parent)
                return true;
            n = n.parentNode;
        }
        return false;
    }

    function testDirectTouches()
    {
        debug('Testing direct hits.');
        testDirectTouch(e.link1);
        testDirectTouch(e.link2);
        testDirectTouch(e.link3);
    }

    function testIndirectTouches()
    {
        debug('Testing indirect hits.');
        testIndirectTouch(e.link1);
        testIndirectTouch(e.link2);
        testIndirectTouch(e.link3);
    }

    function runTests()
    {
        if (window.testRunner && window.internals && internals.touchNodeAdjustedToBestClickableNode) {
            internals.settings.setTouchDragDropEnabled(true);
            description('Tests if a long press gesture on links will trigger a drag/drop when touch adjustment is used.');
            testDirectTouches();
            testIndirectTouches();
            e.sandbox.style.display = 'none';
        }
    }
    runTests();
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
