chromium/third_party/blink/web_tests/editing/selection/caret-bidi-first-and-last-letters.html

<!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>