select-multiple-keyboard-selection.optional.html (3333B)
1 <!doctype html> 2 <link rel="author" title="Aditya Keerthi" href="https://github.com/pxlcoder"> 3 <link rel="help" href="https://html.spec.whatwg.org/#the-select-element"> 4 <link rel="help" href="https://drafts.csswg.org/css-writing-modes-4/#block-flow"> 5 <title>Test <select> multiple keyboard selection</title> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/resources/testdriver.js"></script> 9 <script src="/resources/testdriver-actions.js"></script> 10 <script src="/resources/testdriver-vendor.js"></script> 11 12 <select multiple size="4"></select> 13 <script> 14 const select = document.querySelector("select"); 15 for (let i = 0; i < 5; i++) { 16 const option = document.createElement("option"); 17 option.textContent = `Option ${i + 1}`; 18 select.appendChild(option); 19 } 20 21 const arrow_left = "\uE012"; 22 const arrow_up = "\uE013"; 23 const arrow_right = "\uE014"; 24 const arrow_down = "\uE015"; 25 26 async function sendKeyEventAndWait(key) { 27 await test_driver.send_keys(document.activeElement, key); 28 // Engines differ in when the scrolling is applied so wait for a frame to be 29 // rendered. 30 await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))); 31 } 32 33 for (const writingMode of ["horizontal-tb", "vertical-lr", "vertical-rl", "sideways-lr", "sideways-rl"]) { 34 if (!CSS.supports(`writing-mode: ${writingMode}`)) 35 continue; 36 37 const isHorizontal = writingMode === "horizontal-tb"; 38 const isReversedBlockFlowDirection = writingMode.endsWith("-rl"); 39 const scrollBlockAxis = isHorizontal ? "scrollTop" : "scrollLeft"; 40 41 let nextKey = isHorizontal ? arrow_down : arrow_right; 42 let previousKey = isHorizontal ? arrow_up : arrow_left; 43 44 if (isReversedBlockFlowDirection) { 45 [nextKey, previousKey] = [previousKey, nextKey]; 46 } 47 48 promise_test(async function() { 49 select.selectedIndex = 0; 50 select.style.writingMode = writingMode; 51 this.add_cleanup(() => { 52 select.scrollTop = 0; 53 select.scrollLeft = 0; 54 select.removeAttribute("style"); 55 }); 56 57 assert_equals(select.value, "Option 1"); 58 assert_equals(select[scrollBlockAxis], 0); 59 60 select.focus(); 61 62 assert_equals(document.activeElement, select); 63 64 await sendKeyEventAndWait(previousKey); 65 assert_equals(select.value, "Option 1"); 66 assert_equals(select[scrollBlockAxis], 0); 67 68 await sendKeyEventAndWait(nextKey); 69 assert_equals(select.value, "Option 2"); 70 assert_equals(select[scrollBlockAxis], 0); 71 72 for (let i = 0; i < select.size - 1; i++) { 73 await sendKeyEventAndWait(nextKey); 74 } 75 76 assert_equals(select.value, "Option 5"); 77 78 if (!isReversedBlockFlowDirection) { 79 assert_true(select[scrollBlockAxis] > 0); 80 } else { 81 assert_true(select[scrollBlockAxis] < 0); 82 } 83 84 await sendKeyEventAndWait(previousKey); 85 assert_equals(select.value, "Option 4"); 86 87 if (!isReversedBlockFlowDirection) { 88 assert_true(select[scrollBlockAxis] > 0); 89 } else { 90 assert_true(select[scrollBlockAxis] < 0); 91 } 92 }, `select[multiple][style="writing-mode: ${writingMode}"] supports keyboard navigation`); 93 }; 94 </script>