<!DOCTYPE html>
<html>
<body>
<p>
This tests that clicking in a contenteditable div will set the caret in the right position for LTR/RTL text in a RTL/LTR block.
</p>
<dl>
    <dt>Clicking the first letter of RTL text in a LTR block</dt>
    <dd><div id="rtl-in-ltr-first" style="font-size: 70px; width: 20ex; border: solid thin black; padding: 10px;" contenteditable>&#x05e9;&#x05d3;&#x05d4; &#x05d1;&#x05d5;&#x05e8;</div></dd>
    <dt>Clicking the last letter of RTL text in a LTR block</dt>
    <dd><div id="rtl-in-ltr-last" style="font-size: 70px; width: 20ex; border: solid thin black; padding: 10px;" contenteditable>&#x05e9;&#x05d3;&#x05d4; &#x05d1;&#x05d5;&#x05e8;</div></dd>
    <dt>Clicking the first letter of LTR text in a RTL block</dt>
    <dd><div id="ltr-in-rtl-first" style="direction: rtl; font-size: 70px; width: 20ex; border: solid thin black; padding: 10px;" contenteditable>WebKitW</div></dd>
    <dt>Clicking the last letter of LTR text in a RTL block</dt>
    <dd><div id="ltr-in-rtl-last" style="direction: rtl; font-size: 70px; width: 20ex; border: solid thin black; padding: 10px;" contenteditable>WebKitW</div></dd>
</dl>
<script src="resources/caret-edge-shared.js"></script>
<script>

if (window.testRunner)
    testRunner.dumpAsText();

function runTest(div, clickOn, expectedOffset) {
    var elementToCalulateTextWidth = document.createElement('span');
    elementToCalulateTextWidth.appendChild(div.firstChild.cloneNode());
    document.body.appendChild(elementToCalulateTextWidth);
    elementToCalulateTextWidth.style.fontSize = '70px';

    var inRTLBlock = div.style.direction == 'rtl';
    var x = 20;
    if ((!inRTLBlock && clickOn == 'last') || (inRTLBlock && clickOn == 'first'))
        x = elementToCalulateTextWidth.offsetWidth;
    if (inRTLBlock)
        x = div.offsetWidth - x;

    document.body.removeChild(elementToCalulateTextWidth);

    var verify = function() {
        if (!window.getSelection().isCollapsed)
            return log(div, 'FAIL: selection not collapsed');

        var range = window.getSelection().getRangeAt(0);
        if (range.startContainer != div.firstChild)
            return log(div, 'FAIL: wrong container');
        if (range.startOffset != expectedOffset)
            return log(div, 'FAIL: wrong offset ' + range.startOffset + ', expected ' + expectedOffset);

        return log(div, 'PASS');
    }

    if (!window.testRunner) {
        div.addEventListener('mouseup', verify);
        return;
    }

    eventSender.mouseMoveTo(div.offsetLeft + x, div.offsetTop + div.offsetHeight / 2);
    eventSender.leapForward(200);
    eventSender.mouseDown();
    eventSender.leapForward(200);
    eventSender.mouseUp();
    verify({target: div});
}

function log(div, message) {
    div.innerHTML = message;
}

const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled;
runTest(document.getElementById('rtl-in-ltr-first'), 'first', usesBidiAffinity ? 7 : 0);
runTest(document.getElementById('rtl-in-ltr-last'), 'last', usesBidiAffinity ? 0 : 7);
runTest(document.getElementById('ltr-in-rtl-first'), 'first', usesBidiAffinity ? 0 : 7);
runTest(document.getElementById('ltr-in-rtl-last'), 'last', usesBidiAffinity ? 7 : 0);

</script>
</body>
</html>
