<html>
<style>
body {
background-color: white;
}

iframe {
border: 2px solid black;
}
</style>
<script>
function log(msg)
{
    document.getElementById('log').appendChild(document.createTextNode(msg + '\n'));
}

function windowFocused(win, name)
{
    return function() {
        win.document.body.style.background = "green";
        log(name + ': window focused');
    }
}

function windowBlurred(win, name)
{
    return function() {
        win.document.body.style.background = "red";
        log(name + ': window blurred');
    }
}

function logTabbedElement(event, elem, i, name)
{
    log(name + ': ' + elem.tagName + ' #' + i + ' (tabindex=' + elem.tabIndex + ') ' + event);
}

var lastFocusedElement = null;
function elementFocused(elem, i, name)
{
    return function() {
        logTabbedElement('focused', elem, i, name);
        lastFocusedElement = elem;
    }
}

function elementBlurred(elem, i, name)
{
    return function() {
        logTabbedElement('blurred', elem, i, name);
    }
}

function setupElements(win, name, tag)
{
    var elems = win.document.getElementsByTagName(tag);
    for (var i = 0; i < elems.length; ++i) {
        elems[i].onfocus = elementFocused(elems[i], i, name);
        elems[i].onblur = elementBlurred(elems[i], i, name);
    }
}

function setupBodyFunc(win, name)
{
    return function() {
        setupElements(win, name, 'a');
        setupElements(win, name, 'input');
        setupElements(win, name, 'iframe');
    }
}

function setupWindow(win)
{
    var name;
    if (win.frameElement) {
        name = win.frameElement.id;
    } else {
        name = 'main window';
    }

    win.setupWindow = setupWindow;
    win.setupBody = setupBodyFunc(win, name);

    win.onfocus = windowFocused(win, name);
    win.onblur = windowBlurred(win, name);
}

function dispatchTabPress(element, shiftKey, altKey)
{
    var event = document.createEvent('KeyboardEvents');
    var tabKeyIdentifier = 'U+0009';
    event.initKeyboardEvent('keydown', true, true, document.defaultView, tabKeyIdentifier, 0, false, altKey, shiftKey, false, false);
    element.dispatchEvent(event);
}

function test()
{
    if (window.layoutTestController) {
        layoutTestController.dumpAsText();
    }

    log('Tabbing forward...\n');
    document.getElementById('first').focus();
    for (var i = 0; i < 7; ++i) {
        dispatchTabPress(document, false, false);
    }

    lastFocusedElement.blur();

    log('\nTabbing backward...\n');
    for (var i = 0; i < 8; ++i) {
        dispatchTabPress(document, true, false);
    }

    lastFocusedElement.blur();

    log('\nOption-tabbing forward...\n');
    for (var i = 0; i < 12; ++i) {
        dispatchTabPress(document, false, true);
    }

    lastFocusedElement.blur();

    log('\nOption-tabbing backward...\n');
    for (var i = 0; i < 12; ++i) {
        dispatchTabPress(document, true, true);
    }

    lastFocusedElement.blur();

    log('\nTest finished\n');
}

setupWindow(window);
</script>
<body onload="window.setupBody(); test();">
    <p>This page tests tabbing between subframes. To test, click on this text
    to focus the main window. Then press Tab 7 times, then Shift-Tab 7 times,
    which should move focus forward and backward through all inputs and frames.
    Then press Option-Tab 11 times and Shift-Option-Tab 11 times, which should
    move focus forward and backward through all inputs, frames, and links.</p>

    <input type="text">
    <iframe id="empty-middle" src="resources/frame-tab-focus-empty-middle.html" width="400" height="200"></iframe>
    <input type="text" tabindex="3">
    <input type="text" tabindex="2" id="first">
    <iframe id="upper" src="resources/frame-tab-focus-upper.html" height="300"></iframe>
    <iframe id="child" tabindex="4" src="resources/frame-tab-focus-child.html"></iframe>
    <input type="text">
    <a tabindex="1" href="#">[tabindex of one]</a>
    <a tabindex="3" href="#">[tabindex of three]</a>
    <a tabindex="2" href="#">[tabindex of two]</a>
    <a tabindex="3" href="#">[tabindex of three]</a>
    <pre id="log"></pre>
</body>
</html>
