caret-navigation-around-line-break.html (5454B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Caret navigation around line break</title> 4 <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> 5 <meta name="assert" content="This test checks that caret navigation works well around various kinds of line breaks." /> 6 <meta name="timeout" content="long"> 7 <style> 8 .test { 9 font-size: 16px; 10 line-height: 20px; 11 padding: 4px; 12 width: 5.5ch; 13 padding: 5px; 14 font-family: monospace; 15 word-wrap: break-word; 16 } 17 </style> 18 19 <div class="test" contenteditable data-title="no separator" 20 >line1line2</div> 21 <div class="test" contenteditable data-title="<br> separator" 22 >line1<br>line2</div> 23 <div class="test" contenteditable data-title="<wbr> separator" 24 >line1<wbr>line2</div> 25 <div class="test" contenteditable data-title="<span> separator" 26 >line1<span></span>line2</div> 27 <div class="test" contenteditable data-title="two <span> separators" 28 >line1<span></span><span></span>line2</div> 29 30 <script src="/resources/testharness.js"></script> 31 <script src="/resources/testharnessreport.js"></script> 32 <script src="/resources/testdriver.js"></script> 33 <script src="/resources/testdriver-vendor.js"></script> 34 <script src="/resources/testdriver-actions.js"></script> 35 <script> 36 const KEY_CODE_MAP = { 37 'ArrowLeft': '\uE012', 38 'ArrowUp': '\uE013', 39 'ArrowRight': '\uE014', 40 'ArrowDown': '\uE015', 41 }; 42 43 function click(target, x, y) { 44 return new test_driver.Actions() 45 .pointerMove(x, y, {origin: target}) 46 .pointerDown() 47 .pointerUp() 48 .send(); 49 } 50 51 const s = getSelection(); 52 for (const test of document.querySelectorAll(".test")) { 53 const padding = 4; 54 const halfLineWidth = Math.floor((test.offsetWidth - padding) / 2); 55 const halfLineHeight = Math.floor(20 / 2); 56 const hasSeparator = test.firstChild !== test.lastChild; 57 const line1 = { 58 node: test.firstChild, 59 start: 0, 60 end: "line1".length, 61 }; 62 const line2 = { 63 node: test.lastChild, 64 start: hasSeparator ? 0 : "line1".length, 65 end: hasSeparator ? "line2".length : "line1line2".length, 66 }; 67 68 promise_test(async t => { 69 // Click at the start of line 1 70 await click(test, -halfLineWidth, -halfLineHeight); 71 assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); 72 assert_equals(s.anchorOffset, line1.start, "Caret is at the start of line 1"); 73 74 // Move down, expect start of line 2 75 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown); 76 assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); 77 assert_equals(s.anchorOffset, line2.start, "Caret moved to the start of line 2"); 78 79 // Click at the end of line 1 80 await click(test, +halfLineWidth, -halfLineHeight); 81 range = getSelection().getRangeAt(0); 82 assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); 83 assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1"); 84 85 // Move down, expect end of line 2 86 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown); 87 assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); 88 assert_equals(s.anchorOffset, line2.end, "Caret moved to the end of line 2"); 89 }, test.dataset.title + " - move down"); 90 91 promise_test(async t => { 92 // Click at the start of line 2 93 await click(test, -halfLineWidth, +halfLineHeight); 94 assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); 95 assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2"); 96 97 // Move up, expect start of line 1 98 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp); 99 assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); 100 assert_equals(s.anchorOffset, line1.start, "Caret moved to the start of line 1"); 101 102 // Click at the end of line 2 103 await click(test, +halfLineWidth, +halfLineHeight); 104 assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); 105 assert_equals(s.anchorOffset, line2.end, "Caret is at the end of line 2"); 106 107 // Move up, expect end of line 1 108 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp); 109 assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); 110 assert_equals(s.anchorOffset, line1.end, "Caret moved to the end of line 1"); 111 }, test.dataset.title + " - move up"); 112 113 promise_test(async t => { 114 // Click at the end of line 1 115 await click(test, +halfLineWidth, -halfLineHeight); 116 assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); 117 assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1"); 118 119 // Move right, expect start or start+1 of line 2 120 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowRight); 121 assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); 122 assert_in_array(s.anchorOffset, [line2.start, line2.start + 1], "Caret moved to the start or start+1 of line 2"); 123 }, test.dataset.title + " - move right"); 124 125 promise_test(async t => { 126 // Click at the start of line 2 127 await click(test, -halfLineWidth, +halfLineHeight); 128 assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); 129 assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2"); 130 131 // Move left, expect end or end-1 of line 1 132 await test_driver.send_keys(test, KEY_CODE_MAP.ArrowLeft); 133 assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); 134 assert_in_array(s.anchorOffset, [line1.end, line1.end - 1], "Caret moved to the end or end-1 of line 1"); 135 }, test.dataset.title + " - move left"); 136 } 137 </script>