blob: 7f601fb3b2a36572a7f4c2e037a26e4368bb37c5 [file] [log] [blame]
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
div.test {
font-size: 20px;
width: 120px;
}
</style>
<body>
<script>
// This file tests the consistency between hit test and caret displaying that,
// caret must be displayed at the exact location where mouse is clicked.
const kErrorThreshold = 2;
function computeExpectedCaretRect(container, characterIndex, side) {
const range = container.ownerDocument.createRange();
range.setStart(container.firstChild, characterIndex);
range.setEnd(container.firstChild, characterIndex + 1);
const rect = range.getBoundingClientRect();
if (side == 'left')
return {x: rect.left, top: rect.top, height: rect.height};
return {x: rect.right, top: rect.top, height: rect.height};
}
function clickAt(container, characterIndex, side) {
const caretRect = computeExpectedCaretRect(container, characterIndex, side);
const xDelta = side === 'left' ? kErrorThreshold : -kErrorThreshold;
const x = caretRect.x + xDelta;
const y = caretRect.top + caretRect.height / 2;
return new Promise((resolve, reject) => {
assert_own_property(window, 'chrome');
assert_own_property(window.chrome, 'gpuBenchmarking');
chrome.gpuBenchmarking.pointerActionSequence([{
source: 'mouse',
actions: [
{name: 'pointerDown', x: x, y: y},
{name: 'pointerUp'}
]}], resolve);
});
}
function assertCaretLocation(container, characterIndex, side) {
const expectedCaretRect = computeExpectedCaretRect(container, characterIndex, side);
const actualCaretRect = internals.absoluteCaretBounds();
assert_approx_equals(actualCaretRect.x, expectedCaretRect.x, kErrorThreshold);
assert_approx_equals(actualCaretRect.top, expectedCaretRect.top, kErrorThreshold);
}
tests = [
// Rendered as "foo CBA" in LTR block. Click the right edge of "A".
{html: 'foo \u05D0\u05D1\u05D2', dir: 'ltr', index: 5, side: 'right', name: 'Bidi after collapsed space LTR'},
// Rendered as "foo CBA" in RTL block. Click the left edge of "f".
{html: '\u05D0\u05D1\u05D2 foo', dir: 'rtl', index: 5, side: 'left', name: 'Bidi after collapsed space RTL'},
// Rendered as two lines in LTR block:
// "foo CBA"
// "LKJIHGFED"
// Click the left edge of "L".
{html: 'foo \u05D0\u05D1\u05D2 \u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB',
dir: 'ltr', index: 16, side: 'left', name: 'End of RTL text in LTR block after line wrap'},
// Same sample as above. Click the left edge of "C".
{html: 'foo \u05D0\u05D1\u05D2 \u05D3\u05D4\u05D5\u05D6\u05D7\u05D8\u05D9\u05DA\u05DB',
dir: 'ltr', index: 7, side: 'left', name: 'Logical line end in LTR block before line wrap'},
// Rendered as two lines in RTL block:
// "foo CBA"
// "abcdefghijklmn"
// Click the right edge of "n".
{html: '\u05D0\u05D1\u05D2 foo abcdefghijklmn',
dir: 'rtl', index: 22, side: 'right', name: 'End of LTR text in RTL block after line wrap'},
// Same sample as above. Click the right edge of "foo".
{html: '\u05D0\u05D1\u05D2 foo abcdefghijklmn',
dir: 'rtl', index: 7, side: 'right', name: 'Logical line end in RTL block before line wrap'},
];
function runTest(testCase) {
const html = testCase.html;
const dir = testCase.dir;
const index = testCase.index;
const side = testCase.side;
const name = testCase.name;
promise_test(async () => {
const container = document.createElement('div');
container.classList.add('test');
container.contentEditable = 'true';
container.dir = dir;
container.innerHTML = html;
document.body.appendChild(container);
await clickAt(container, index, side);
assertCaretLocation(container, index, side);
}, name);
}
tests.forEach(runTest);
</script>
</body>