<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<meta name="viewport" content="width=device-width">
<script src="../../../resources/js-test.js"></script>
<script src="../../../resources/ui-helper.js"></script>
</head>
<body>
<script>
window.jsTestIsAsync = true;

description("This tests that DOM keypress events are dispatched to a non-editable &lt;body&gt; on iOS when pressing special keys on a hardware keyboard. This test can only be run in DumpRenderTree/WebKitTestRunner.");

class TestKeyPressDispatchedFor {
    constructor(key) {
        this.key = key;
        this.shouldDispatchKeyPress = true;
    }
}

class TestKeyPressNotDispatchedFor {
    constructor(key) {
        this.key = key;
        this.shouldDispatchKeyPress = false;
    }
}

var lastKeyPressEvent = null;
var currentTestIndex = -1;

// Non-special keys: KeyPress should be dispatched.
var tests = "abcdefghijklmnopqrstuvwxyz0123456789-=[]\\;',./".split("").map((key) => new TestKeyPressDispatchedFor(key));
if (UIHelper.isWebKit2())
    tests.push(new TestKeyPressNotDispatchedFor(" ")); // Spacebar scrolls the page.
else
    tests.push(new TestKeyPressDispatchedFor(" "));
// Special keys: KeyPress should be dispatched.
tests.push(new TestKeyPressDispatchedFor("delete"));
tests.push(new TestKeyPressDispatchedFor("enter"));
tests.push(new TestKeyPressDispatchedFor("escape"));
tests.push(new TestKeyPressDispatchedFor("return"));

// Special keys: KeyPress should not be dispatched.
tests.push(new TestKeyPressNotDispatchedFor("forwardDelete"));
tests.push(new TestKeyPressNotDispatchedFor("upArrow"));
tests.push(new TestKeyPressNotDispatchedFor("downArrow"));
tests.push(new TestKeyPressNotDispatchedFor("leftArrow"));
tests.push(new TestKeyPressNotDispatchedFor("rightArrow"));
tests.push(new TestKeyPressNotDispatchedFor("clear"));
tests.push(new TestKeyPressNotDispatchedFor("end"));
tests.push(new TestKeyPressNotDispatchedFor("home"));
// FIXME: Test that keypress is not dispatched for "insert" once <rdar://problem/47128940> is fixed.
tests.push(new TestKeyPressNotDispatchedFor("leftAlt"));
tests.push(new TestKeyPressNotDispatchedFor("leftCommand"));
tests.push(new TestKeyPressNotDispatchedFor("leftControl"));
tests.push(new TestKeyPressNotDispatchedFor("leftShift"));
tests.push(new TestKeyPressNotDispatchedFor("pageDown"));
tests.push(new TestKeyPressNotDispatchedFor("pageUp"));
tests.push(new TestKeyPressNotDispatchedFor("rightAlt"));
tests.push(new TestKeyPressNotDispatchedFor("rightCommand"));
tests.push(new TestKeyPressNotDispatchedFor("rightControl"));
tests.push(new TestKeyPressNotDispatchedFor("rightShift"));
// FIXME: Check function keys up to F24 once <rdar://problem/47128940> is fixed.
for (let i = 1; i <= 16; ++i)
    tests.push(new TestKeyPressNotDispatchedFor("F" + i));

function nextKeyPress()
{
    function actualNextKeyPress() {
        ++currentTestIndex;
        if (currentTestIndex >= tests.length) {
            finishJSTest();
            return;
        }
        let nextTest = tests[currentTestIndex];
        UIHelper.typeCharacter(nextTest.key);
    }
    // In WebKit Legacy typing a key performs a synchronous DOM dispatch. Schedule the key press
    // on the next turn of the event loop to avoid blowing out the stack given that we call this
    // function from an onkeyup handler.
    window.setTimeout(actualNextKeyPress, 0);
}

function handleKeyPress(event)
{
    lastKeyPressEvent = event;
}

function checkResult(event)
{
    let currentTest = tests[currentTestIndex];
    if (lastKeyPressEvent && currentTest.shouldDispatchKeyPress)
        testPassed(`${currentTest.key} did dispatch a keypress event.`);
    else if (lastKeyPressEvent)
        testFailed(`${currentTest.key} should not have dispatched a keypress event. It did dispatch one.`);
    else if (currentTest.shouldDispatchKeyPress)
        testFailed(`${currentTest.key} should have dispatched a keypress event. It did not dispatch one.`);
    else
        testPassed(`${currentTest.key} did not dispatch a keypress event.`);
    lastKeyPressEvent = null;
    nextKeyPress();
}

function runTest()
{
    if (!window.testRunner){
        testFailed("Must be run in DumpRenderTree/WebKitTestRunner");
        finishJSTest();
        return;
    }
    document.body.onkeypress = handleKeyPress;
    document.body.onkeyup = checkResult;
    nextKeyPress();
}

runTest();
</script>
</body>
</html>
