<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test.js"></script>
<Script src="../../resources/ui-helper.js"></Script>
<script>
window.jsTestIsAsync = true;

let input;
let numberOfCharactersToOverflowFieldWhenCapsLockShown;

let tests = [
    // Test for caret selection
    // Empty field
    testFocusedEmptyFieldIsNotScrolled,
    testFieldDidNotScrollAfterCapsLockEnabled,
    testFieldDidNotScrollAfterCapsLockDisabled,

    // Non-empty field
    testFieldDidNotScrollAfterTyping,
    testFieldDidScrollAfterCapsLockEnabled,
    testFieldDidScrollAfterCapsLockDisabled,

    // Test for range selection
    // Select the first few characters
    testFieldDidNotScrollAfterSelectingPrefix,
    testFieldDidNotScrollAfterCapsLockEnabled,
    testFieldDidNotScrollAfterCapsLockDisabled,

    // Select the last few characters
    testFieldDidNotScrollAfterSelectingSuffix,
    testFieldDidScrollAfterCapsLockEnabled,
    testFieldDidScrollAfterCapsLockDisabled,
];

let currentTest = 0;

function runNextTest()
{
    if (currentTest >= tests.length) {
        done();
        return;
    }
    tests[currentTest++]();
}

function runTest()
{
    runNextTest();
}

function testFocusedEmptyFieldIsNotScrolled()
{
    debug("Case 1: Empty field:");
    function handleFocus() {
        shouldBeZero("document.getElementById('input').scrollLeft");
        runNextTest();
    }
    input.addEventListener("focus", handleFocus, { once: true });
    if (window.testRunner)
        UIHelper.activateElement(input);
    else
        input.focus();
}

function testFieldDidNotScrollAfterTyping()
{
    function checkFieldFilled(event) {
        console.assert(event.target === input);
        if (input.value.length < numberOfCharactersToOverflowFieldWhenCapsLockShown)
            return;
        input.oninput = null;
        shouldBeZero("document.getElementById('input').scrollLeft");
        runNextTest();
    }
    input.oninput = checkFieldFilled;

    debug("<br>Case 2: After typing into field:");
    if (window.testRunner) {
        for (let i = 0; i < numberOfCharactersToOverflowFieldWhenCapsLockShown; ++i)
            UIHelper.keyDown("a");
    }
}

function _toggleCapsLockWithCallbackAndRunNextTest(expectCapsLockEnabled, callback)
{
    if (window.internals)
        console.assert(internals.capsLockIsOn() != expectCapsLockEnabled);
    let newCapsLockStateDisplayName;
    let eventToListenFor;
    if (expectCapsLockEnabled) {
        newCapsLockStateDisplayName = "enabled";
        eventToListenFor = "keydown";
    } else {
        newCapsLockStateDisplayName = "disabled";
        eventToListenFor = "keyup";
    }

    let oldValue = document.getElementById("input").scrollLeft;
    function handleCapsLockChange(event) {
        console.assert(event.key === "CapsLock");
        callback(oldValue, document.getElementById("input").scrollLeft);
        runNextTest();
    }
    input.addEventListener(eventToListenFor, handleCapsLockChange, { once: true });
    debug(`<br>After caps lock ${newCapsLockStateDisplayName}:`);
    if (window.testRunner)
        UIHelper.toggleCapsLock();
}

function testFieldDidScrollAfterCapsLockEnabled()
{
    _toggleCapsLockWithCallbackAndRunNextTest(true, (oldValue, newValue) => {
        console.assert(oldValue != newValue);
        shouldBeNonZero("document.getElementById('input').scrollLeft");
    });
}

function testFieldDidScrollAfterCapsLockDisabled()
{
    _toggleCapsLockWithCallbackAndRunNextTest(false, (oldValue, newValue) => {
        console.assert(oldValue != newValue);
        shouldBeZero("document.getElementById('input').scrollLeft");
    });
}

function testFieldDidNotScrollAfterCapsLockEnabled()
{
    _toggleCapsLockWithCallbackAndRunNextTest(true, (oldValue, newValue) => {
        console.assert(oldValue == newValue);
        shouldBeZero("document.getElementById('input').scrollLeft");
    });
}

function testFieldDidNotScrollAfterCapsLockDisabled()
{
    _toggleCapsLockWithCallbackAndRunNextTest(false, (oldValue, newValue) => {
        console.assert(oldValue == newValue);
        shouldBeZero("document.getElementById('input').scrollLeft");
    });
}

function testFieldDidNotScrollAfterSelectingPrefix()
{
    let prefixLength = Math.floor(numberOfCharactersToOverflowFieldWhenCapsLockShown / 2);
    debug(`<br>Case 3: After selecting the first ${prefixLength} characters:`);
    input.setSelectionRange(0, prefixLength);
    shouldBeZero("document.getElementById('input').scrollLeft");
    runNextTest();
}

function testFieldDidNotScrollAfterSelectingSuffix()
{
    let suffixLength = Math.floor(numberOfCharactersToOverflowFieldWhenCapsLockShown / 2);
    debug(`<br>Case 4: After selecting the last ${suffixLength} characters:`);
    input.setSelectionRange(input.value.length - suffixLength, input.value.length);
    shouldBeZero("document.getElementById('input').scrollLeft");
    runNextTest();
}

function done()
{
    if (window.testRunner)
        document.body.removeChild(document.getElementById("input"));
    finishJSTest();
}
</script>
</head>
<body onload="runTest()">
<input type="password" id="input" size="5">
<script>
input = document.getElementById("input");
console.assert(input.hasAttribute("size"));
numberOfCharactersToOverflowFieldWhenCapsLockShown = input.size;

// FIXME: Find a way to compute the maximum number of visible characters the field can hold
// in a way that allows for running this test by hand.
let mayBeIOS = window.TouchEvent != undefined;
if (mayBeIOS) {
    // The look of the password field on iOS gives less space to the value than on Mac.
    --numberOfCharactersToOverflowFieldWhenCapsLockShown;
}
console.assert(numberOfCharactersToOverflowFieldWhenCapsLockShown >= 3);

description("Tests that the password field is scrolled when the caps lock indicator is toggled.");
</script>
</body>
</html>
