selection.html (7265B)
1 <!DOCTYPE HTML> 2 <title>test if select() API returns correct attributes</title> 3 <meta charset="UTF-8"> 4 <meta name="timeout" content="long"> 5 <link rel="author" title="Koji Tashiro" href="mailto:koji.tashiro@gmail.com"> 6 <link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/association-of-controls-and-forms.html#textFieldSelection"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 10 <div id="log"></div> 11 12 <script> 13 var body = document.getElementsByTagName("body").item(0); 14 var dirs = ['forward', 'backward', 'none']; 15 var sampleText = "0123456789"; 16 17 var createInputElement = function(value, append = true) { 18 var el = document.createElement("input"); 19 el.type = "text"; 20 el.value = value; 21 el.id = "input" + (append ? "-appended" : "-not-appended"); 22 if (append) { 23 body.appendChild(el); 24 } 25 return el; 26 }; 27 28 var createTextareaElement = function(value, append = true) { 29 var el = document.createElement("textarea"); 30 el.value = value; 31 el.id = "textarea" + (append ? "-appended" : "-not-appended"); 32 if (append) { 33 body.appendChild(el); 34 } 35 return el; 36 }; 37 38 39 test(function() { 40 var text = 'a'; 41 for (var i=0; i<255; i++) { 42 var el = createInputElement(text); 43 el.select(); 44 var selectionText = el.value.substring(el.selectionStart, el.selectionEnd); 45 assert_equals(selectionText, text, "Selection text mismatched"); 46 el.parentNode.removeChild(el); 47 text += 'a'; 48 } 49 }, "test if selection text is correct for input"); 50 51 52 test(function() { 53 var text = 'a'; 54 for (var i=0; i<255; i++) { 55 var el = createTextareaElement(text); 56 el.select(); 57 var selectionText = el.value.substring(el.selectionStart, el.selectionEnd); 58 assert_equals(selectionText, text, "Selection text mismatched"); 59 el.parentNode.removeChild(el); 60 text += 'a'; 61 } 62 }, "test if selection text is correct for textarea"); 63 64 65 test(function() { 66 var text = 'あ'; 67 for (var i=0; i<255; i++) { 68 var el = createInputElement(text); 69 el.select(); 70 var selectionText = el.value.substring(el.selectionStart, el.selectionEnd); 71 assert_equals(selectionText, text, "Selection text mismatched"); 72 el.parentNode.removeChild(el); 73 text += 'あ'; 74 } 75 }, "test if non-ascii selection text is correct for input"); 76 77 78 test(function() { 79 var text = 'あ'; 80 for (var i=0; i<255; i++) { 81 var el = createTextareaElement(text); 82 el.select(); 83 var selectionText = el.value.substring(el.selectionStart, el.selectionEnd); 84 assert_equals(selectionText, text, "Selection text mismatched"); 85 el.parentNode.removeChild(el); 86 text += 'あ'; 87 } 88 }, "test if non-ascii selection text is correct for textarea"); 89 90 91 for (var append of [true, false]) { 92 test(function() { 93 var el = createInputElement(sampleText, append); 94 // If there is no selection, then it must return the offset(in logical order) 95 // to the character that immediately follows the text entry cursor. 96 assert_equals(el.selectionStart, el.value.length, 97 "SelectionStart offset without selection in " + el.id); 98 el.select(); 99 assert_equals(el.selectionStart, 0, "SelectionStart offset"); 100 el.remove(); 101 }, "test SelectionStart offset for input that is " + 102 (append ? "appended" : " not appended")); 103 } 104 105 for (var append of [true, false]) { 106 test(function() { 107 var el = createTextareaElement(sampleText, append); 108 // If there is no selection, then it must return the offset(in logical order) 109 // to the character that immediately follows the text entry cursor. 110 assert_equals(el.selectionStart, el.value.length, 111 "SelectionStart offset without selection in " + el.id); 112 el.select(); 113 assert_equals(el.selectionStart, 0, "SelectionStart offset"); 114 el.remove(); 115 }, "test SelectionStart offset for textarea that is " + 116 (append ? "appended" : " not appended")); 117 } 118 119 for (var append of [true, false]) { 120 test(function() { 121 var el = createInputElement(sampleText, append); 122 // If there is no selection, then it must return the offset(in logical order) 123 // to the character that immediately follows the text entry cursor. 124 assert_equals(el.selectionEnd, el.value.length, 125 "SelectionEnd offset without selection in " + el.id); 126 el.select(); 127 assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset"); 128 el.remove(); 129 }, "test SelectionEnd offset for input that is " + 130 (append ? "appended" : " not appended")); 131 } 132 133 134 for (var append of [true, false]) { 135 test(function() { 136 var el = createTextareaElement(sampleText, append); 137 // If there is no selection, then it must return the offset(in logical order) 138 // to the character that immediately follows the text entry cursor. 139 assert_equals(el.selectionEnd, el.value.length, 140 "SelectionEnd offset without selection in " + el.id); 141 el.select(); 142 assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset"); 143 el.remove(); 144 }, "test SelectionEnd offset for textarea that is " + 145 (append ? "appended" : " not appended")); 146 } 147 148 test(function() { 149 var el = createInputElement(sampleText); 150 assert_in_array(el.selectionDirection, dirs, "SelectionDirection"); 151 el.select(); 152 assert_in_array(el.selectionDirection, dirs, "SelectionDirection"); 153 el.parentNode.removeChild(el); 154 }, "test SelectionDirection for input"); 155 156 157 test(function() { 158 var el = createTextareaElement(sampleText); 159 assert_in_array(el.selectionDirection, dirs, "SelectionDirection"); 160 el.select(); 161 assert_in_array(el.selectionDirection, dirs, "SelectionDirection"); 162 el.parentNode.removeChild(el); 163 }, "test SelectionDirection for textarea"); 164 165 promise_test(async () => { 166 // cause a layout overflow 167 const el = createInputElement(sampleText.repeat(100)); 168 el.selectionEnd = 0; 169 await new Promise(requestAnimationFrame); 170 assert_equals(el.scrollLeft, 0); 171 172 el.select(); 173 await new Promise(requestAnimationFrame); 174 assert_equals(el.scrollLeft, 0); 175 el.remove(); 176 }, `test scrollLeft for input`); 177 178 promise_test(async () => { 179 // cause a layout overflow 180 const el = createInputElement(sampleText.repeat(100)); 181 el.scrollLeft = 33; 182 183 el.select(); 184 await new Promise(requestAnimationFrame); 185 assert_equals(el.scrollLeft, 33); 186 el.remove(); 187 }, `test scrollLeft preservation for input`); 188 189 for (const localName of ["input", "textarea"]) { 190 promise_test(async () => { 191 const container = document.createElement("div"); 192 container.style.height = "100px"; 193 container.style.overflow = "scroll"; 194 const element = document.createElement(localName); 195 element.style.marginTop = "120px"; 196 container.append(element); 197 document.body.append(container); 198 199 element.select(); 200 await new Promise(requestAnimationFrame); 201 assert_equals(container.scrollTop, 0); 202 203 container.remove(); 204 }, `test container.scrollTop for ${localName}`); 205 } 206 </script>