<!DOCTYPE html>
<html>
<head>
    <title>Touch Adjustment : Event triggered widgets - bug 78801</title>
    <script src="../resources/js-test-pre.js"></script>
    <script src="resources/touchadjustment.js"></script>
    <style>
        .box { border: 1px solid black; border-radius: 5px 5px; margin: 1em; width: 40em; }
    </style>
</head>

<body>

<div id=sandbox>
    <script>
        function triggerInput() {
            var element = event.srcElement;
            if (!element.open) {
                element.innerHTML = '<input type=text style="width: 100%"></input>'
                element.open = true;
            }
            element.firstChild.focus();
        }
    </script>

    <div id=test1 class=box tabindex=1 onfocus='triggerInput()'>
    Focus here should give a text input-field.
    </div>

    <div id=test2 class=box onmouseover='triggerInput()'> 
    Mouse-over here should give a text input-field.
    </div>

    <style>
        .box:not(:hover) .hovertriggered { visibility: hidden;}
        .box:hover .hoverfallback { display: none; }  
    </style>

    <div id=test3 class=box> 
        <span class=hoverfallback>Hovering here should give a text input-field.</span>
        <input type=text class=hovertriggered></input>
    </div>

    <div id=test4 class=box onfocus='triggerInput()'>
        <span tabindex=1> Focusing here should only give focus outline to this inner text.
        </span>
    </div>

    <div class=box>
        <span id=test5 tabindex=1> Focusing here should give a text input-field.
        </span>
    </div>

    <script>
        var element = document.getElementById('test5');
        element.addEventListener('DOMFocusIn', triggerInput, false);
    </script>
</div>

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

<script>
    var element;
    var adjustedNode;
    function findAbsolutePosition(node) {
        var pos = new Object();
        pos.left = 0; pos.top = 0;
        do {
            pos.left += node.offsetLeft;
            pos.top += node.offsetTop;
        } while (node = node.offsetParent);
        return pos;
    }

    function findBestClickableNode(x, y, width, height)
    {
        var adjustedNode = internals.touchNodeAdjustedToBestClickableNode(x, y, width, height);
        if (adjustedNode && adjustedNode.nodeType == 3) // TEXT node
            adjustedNode = adjustedNode.parentNode;
        return adjustedNode;
    }

    function testDirectTouch(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'center', 0, 2, 2);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testDirectFatFinger(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'top', -5, element.clientHeight/2, (element.clientHeight+10)/2);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testIndirectFatFinger(element)
    {
        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), 'top', 3, 5, 5);
        adjustedNode = findBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    }

    function testTouchHit(elementid, touchType) {
        element = document.getElementById(elementid);
        touchType(element);
        shouldBe('adjustedNode.id', 'element.id');
    }

    function testTouchMiss(elementid, touchType) {
        element = document.getElementById(elementid);
        touchType(element);
        shouldNotBe('adjustedNode.id', 'element.id');
    }

    function testDirectTouches()
    {
        debug('Testing small direct hits');
        testTouchHit('test1', testDirectTouch);
        testTouchHit('test2', testDirectTouch);
        testTouchHit('test3', testDirectTouch);
        testTouchMiss('test4', testDirectTouch);
        testTouchHit('test5', testDirectTouch);
    }

    function testDirectFatFingers()
    {
        debug('Testing large direct hits');
        testTouchHit('test1', testDirectFatFinger);
        testTouchHit('test2', testDirectFatFinger);
        testTouchHit('test3', testDirectFatFinger);
        testTouchMiss('test4', testDirectFatFinger);
        testTouchHit('test5', testDirectFatFinger);
    }

    function testIndirectFatFingers()
    {
        debug('Testing large direct hits');
        testTouchHit('test1', testIndirectFatFinger);
        testTouchHit('test2', testIndirectFatFinger);
        testTouchHit('test3', testIndirectFatFinger);
        testTouchMiss('test4', testIndirectFatFinger);
        testTouchHit('test5', testIndirectFatFinger);
    }

    function runTests()
    {
        if (window.testRunner && window.internals && internals.touchNodeAdjustedToBestClickableNode) {
            description('Test various ways to trigger input-widgets. On a touch interface, all the actions should be triggerable with either a touch down or a touch tap.');
            testDirectTouches();
            testDirectFatFingers();
            testIndirectFatFingers();
            document.getElementById('sandbox').style.display = 'none';
        }
    }
    runTests();
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
