Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<meta charset="utf-8">
<title>Caret navigation around line break</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<meta name="assert" content="This test checks that caret navigation works well around various kinds of line breaks." />
<meta name="timeout" content="long">
<style>
.test {
font-size: 16px;
line-height: 20px;
padding: 4px;
width: 5.5ch;
padding: 5px;
font-family: monospace;
word-wrap: break-word;
}
</style>
<div class="test" contenteditable data-title="no separator"
>line1line2</div>
<div class="test" contenteditable data-title="<br> separator"
>line1<br>line2</div>
<div class="test" contenteditable data-title="<wbr> separator"
>line1<wbr>line2</div>
<div class="test" contenteditable data-title="<span> separator"
>line1<span></span>line2</div>
<div class="test" contenteditable data-title="two <span> separators"
>line1<span></span><span></span>line2</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script>
const KEY_CODE_MAP = {
'ArrowLeft': '\uE012',
'ArrowUp': '\uE013',
'ArrowRight': '\uE014',
'ArrowDown': '\uE015',
};
function click(target, x, y) {
return new test_driver.Actions()
.pointerMove(x, y, {origin: target})
.pointerDown()
.pointerUp()
.send();
}
const s = getSelection();
for (const test of document.querySelectorAll(".test")) {
const padding = 4;
const halfLineWidth = Math.floor((test.offsetWidth - padding) / 2);
const halfLineHeight = Math.floor(20 / 2);
const hasSeparator = test.firstChild !== test.lastChild;
const line1 = {
node: test.firstChild,
start: 0,
end: "line1".length,
};
const line2 = {
node: test.lastChild,
start: hasSeparator ? 0 : "line1".length,
end: hasSeparator ? "line2".length : "line1line2".length,
};
promise_test(async t => {
// Click at the start of line 1
await click(test, -halfLineWidth, -halfLineHeight);
assert_equals(s.anchorNode, line1.node, "Caret is in line 1");
assert_equals(s.anchorOffset, line1.start, "Caret is at the start of line 1");
// Move down, expect start of line 2
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown);
assert_equals(s.anchorNode, line2.node, "Caret moved to line 2");
assert_equals(s.anchorOffset, line2.start, "Caret moved to the start of line 2");
// Click at the end of line 1
await click(test, +halfLineWidth, -halfLineHeight);
range = getSelection().getRangeAt(0);
assert_equals(s.anchorNode, line1.node, "Caret is in line 1");
assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1");
// Move down, expect end of line 2
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown);
assert_equals(s.anchorNode, line2.node, "Caret moved to line 2");
assert_equals(s.anchorOffset, line2.end, "Caret moved to the end of line 2");
}, test.dataset.title + " - move down");
promise_test(async t => {
// Click at the start of line 2
await click(test, -halfLineWidth, +halfLineHeight);
assert_equals(s.anchorNode, line2.node, "Caret is in line 2");
assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2");
// Move up, expect start of line 1
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp);
assert_equals(s.anchorNode, line1.node, "Caret moved to line 1");
assert_equals(s.anchorOffset, line1.start, "Caret moved to the start of line 1");
// Click at the end of line 2
await click(test, +halfLineWidth, +halfLineHeight);
assert_equals(s.anchorNode, line2.node, "Caret is in line 2");
assert_equals(s.anchorOffset, line2.end, "Caret is at the end of line 2");
// Move up, expect end of line 1
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp);
assert_equals(s.anchorNode, line1.node, "Caret moved to line 1");
assert_equals(s.anchorOffset, line1.end, "Caret moved to the end of line 1");
}, test.dataset.title + " - move up");
promise_test(async t => {
// Click at the end of line 1
await click(test, +halfLineWidth, -halfLineHeight);
assert_equals(s.anchorNode, line1.node, "Caret is in line 1");
assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1");
// Move right, expect start or start+1 of line 2
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowRight);
assert_equals(s.anchorNode, line2.node, "Caret moved to line 2");
assert_in_array(s.anchorOffset, [line2.start, line2.start + 1], "Caret moved to the start or start+1 of line 2");
}, test.dataset.title + " - move right");
promise_test(async t => {
// Click at the start of line 2
await click(test, -halfLineWidth, +halfLineHeight);
assert_equals(s.anchorNode, line2.node, "Caret is in line 2");
assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2");
// Move left, expect end or end-1 of line 1
await test_driver.send_keys(test, KEY_CODE_MAP.ArrowLeft);
assert_equals(s.anchorNode, line1.node, "Caret moved to line 1");
assert_in_array(s.anchorOffset, [line1.end, line1.end - 1], "Caret moved to the end or end-1 of line 1");
}, test.dataset.title + " - move left");
}
</script>