<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.testRunner) {
        testRunner.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>
