<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="resources/js-test-selection-shared.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>

<div id="test"> 
    <div id="regular-div">
        line 1<br>
        line 2<br>
        line 3
    </div> 
    <div contenteditable="true" id="editable-div">
         line 1<br>
         line 2<br>
         line 3
    </div> 
    <textarea id="text-area" cols="60" rows="7">
line 1
line 2
line 3</textarea>
    <input type="text" id="text-input" value="line 2"/>
</div>

<script>
if (window.internals)
    internals.setContinuousSpellCheckingEnabled(false); // For performance.

description("This test ensures that programmatically set selections are directionless on mac, and that they are not on other platforms.");

function selectLine(node) {
    var selection = window.getSelection();
    selection.empty();

    if (node.localName == 'div') {
        var container = node.childNodes[2];
        var range = document.createRange();
        range.setStart(container, container.data.search('ine 2'));
        range.setEnd(container, range.startOffset + 'in'.length);
        selection.addRange(range);
    } else {
       node.selectionDirection = 'none';
       node.selectionStart = node.value.search('ine 2');
       node.selectionEnd = node.selectionStart + 'in'.length;
    }
}

function runTestsAndVerify(node, selectionModifier, expectedDirection, expectedText) {
    var currentTest = makeTest(node, selectionModifier, expectedDirection, expectedText);

    currentTest('no action');
    currentTest('delete');
    currentTest('forwardDelete');
    currentTest('cut');
    currentTest('bold');
    currentTest('insertText');
}

function makeTest(node, selectionModifier, expectedDirection, expectedText) {
    return function (action) {
        selectLine(node);
        var actionString = '';

        if (action != 'no action') {
            document.execCommand(action, false, 'word');
            document.execCommand('undo');
            actionString = ', after undoing ' + action;
        }

        var description = selectionModifier() + ' in ' + node.id + actionString;
        var selection = window.getSelection();
        var actualDirection = selection.baseOffset < selection.extentOffset ? 'forward' : (selection.baseOffset > selection.extentOffset ? 'backward' : 'none');
        var actualText = selection.toString();
        if (node.localName != 'div') {
            actualDirection = node.selectionDirection;
            actualText = node.value.substring(node.selectionStart, node.selectionEnd);
        }
        if (actualText != expectedText)
            testFailed(description + ', expected "' + expectedText + '" but got "' + actualText + '"');
        else if (description.split(' ')[4] == 'div' && expectedDirection != actualDirection)
            testFailed(description + ', expected ' + expectedDirection + ' direction but got ' + actualDirection);
        else
            testPassed(description);
    }
}

function makeSelectionModifier(direction, granularity) {
    return function() {
        window.getSelection().modify('extend', direction, granularity);
        var testDescription = direction + ' by ' + granularity;
        return testDescription;
    }
}

function runTestsOn(platform, node) {
    var macOrNonMac = platform == 'mac' ? 'mac' : 'non-mac';
    var backwardOnMacAndForwardOtherwise = {'mac': 'backward', 'non-mac': 'forward'}[macOrNonMac];

    var extendSelectionLeftByCharacter = makeSelectionModifier('left', 'character');
    var extendSelectionRightByCharacter = makeSelectionModifier('right', 'character');
    var extendSelectionLeftByLine = makeSelectionModifier('left', 'line');
    var extendSelectionRightByLine = makeSelectionModifier('right', 'line');

    runTestsAndVerify(node, extendSelectionLeftByCharacter, backwardOnMacAndForwardOtherwise, {'mac': 'lin', 'non-mac': 'i'}[macOrNonMac]);
    runTestsAndVerify(node, extendSelectionRightByCharacter, 'forward', 'ine');

    if (node.localName == 'input')
        expectedResult = {'mac': 'lin', 'non-mac': 'l'};
    else if (node.localName == 'textarea')
        expectedResult = {'mac': 'ine 1\nlin', 'non-mac': 'e 1\nl'}
    else if (node.localName == 'div')
        expectedResult = {'mac': 'ine 1\nlin', 'non-mac': 'e 1\nl'}

    runTestsAndVerify(node, extendSelectionLeftByLine, backwardOnMacAndForwardOtherwise, expectedResult[macOrNonMac]);

    if (node.localName == 'input')
        expectedResult = 'ine 2';
    else if (node.localName == 'textarea')
        expectedResult = 'ine 2\nlin';
    else if (node.localName == 'div')
        expectedResult = 'ine 2\nlin';

    runTestsAndVerify(node, extendSelectionRightByLine, 'forward', expectedResult);
}

function runTestsFor(platform) {
    debug(platform + ':');
    internals.settings.setEditingBehavior(platform);
    var listOfTestNodes = document.getElementById('test').childNodes;

    for (var i = 0; i < listOfTestNodes.length; i++) {
        if (listOfTestNodes[i].nodeName != '#text')
            runTestsOn(platform, listOfTestNodes[i]);
    }
}

if (window.internals) {
    runTestsFor('mac');
    runTestsFor('windows');
    runTestsFor('unix');

    document.getElementById('test').innerHTML = '';
}

</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
