selection-start-end.html (7471B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title></title> 4 <script src=/resources/testharness.js></script> 5 <script src=/resources/testharnessreport.js></script> 6 <div id=log></div> 7 <script> 8 function createInputElement(value, append, suffix) { 9 var el = document.createElement("input"); 10 el.type = "text"; 11 el.value = value; 12 el.id = "input" + (append ? "-appended" : "-not-appended") + (suffix ? suffix : ""); 13 if (append) { 14 document.body.appendChild(el); 15 } 16 return el; 17 }; 18 19 function createTextareaElement(value, append, suffix) { 20 var el = document.createElement("textarea"); 21 el.value = value; 22 23 el.id = "textarea" + (append ? "-appended" : "-not-appended") + (suffix ? suffix : ""); 24 if (append) { 25 document.body.appendChild(el); 26 } 27 return el; 28 }; 29 30 function createPrefocusedInputElement(value, append) { 31 var el = createInputElement(value, append, "-prefocused"); 32 el.focus(); 33 el.blur(); 34 return el; 35 } 36 37 function createPrefocusedTextareaElement(value, append) { 38 var el = createTextareaElement(value, append, "-prefocused"); 39 el.focus(); 40 el.blur(); 41 return el; 42 } 43 44 function createClonedTextareaWithNoDirtyValueFlag(text) { 45 const textarea = document.createElement("textarea"); 46 textarea.textContent = text; 47 return textarea.cloneNode(true); 48 } 49 50 function createTestElements(value) { 51 return [ createInputElement(value, true), 52 createInputElement(value, false), 53 createPrefocusedInputElement(value, true), 54 createPrefocusedInputElement(value, false), 55 createTextareaElement(value, true), 56 createTextareaElement(value, false), 57 createPrefocusedTextareaElement(value, true), 58 createPrefocusedTextareaElement(value, false), 59 createClonedTextareaWithNoDirtyValueFlag(value) 60 ]; 61 } 62 63 var testValue = "abcdefghij"; 64 65 test(function() { 66 assert_equals(testValue.length, 10); 67 }, "Sanity check for testValue length; if this fails, variou absolute offsets in the test below need to be adjusted to be less than testValue.length"); 68 69 for (let prop of ["selectionStart", "selectionEnd"]) { 70 for (let el of createTestElements(testValue)) { 71 if (el.defaultValue !== el.value) { 72 test(function() { 73 assert_equals(el[prop], testValue.length); 74 }, `Initial .value set on ${el.id} should set ${prop} to end of value`); 75 } 76 } 77 } 78 79 test(function() { 80 for (let el of createTestElements(testValue)) { 81 var t = async_test(`onselect should fire when selectionStart is changed on ${el.id}`); 82 el.onselect = t.step_func_done(function(e) { 83 assert_equals(e.type, "select"); 84 el.remove(); 85 }); 86 el.selectionStart = 2; 87 } 88 }, "onselect should fire when selectionStart is changed"); 89 90 test(function() { 91 for (let el of createTestElements(testValue)) { 92 var t = async_test(`onselect should fire when selectionEnd is changed on ${el.id}`); 93 el.onselect = t.step_func_done(function(e) { 94 assert_equals(e.type, "select"); 95 el.remove(); 96 }); 97 el.selectionEnd = 2; 98 } 99 }, "onselect should fire when selectionEnd is changed"); 100 101 test(function() { 102 for (let el of createTestElements(testValue)) { 103 el.selectionStart = 0; 104 el.selectionEnd = 5; 105 el.selectionStart = 8; 106 assert_equals(el.selectionStart, 8, `selectionStart on ${el.id}`); 107 assert_equals(el.selectionEnd, 8, `selectionEnd on ${el.id}`); 108 el.remove(); 109 } 110 }, "Setting selectionStart to a value larger than selectionEnd should increase selectionEnd"); 111 112 test(function() { 113 for (let el of createTestElements(testValue)) { 114 el.selectionStart = 8; 115 el.selectionEnd = 5; 116 assert_equals(el.selectionStart, 5, `selectionStart on ${el.id}`); 117 assert_equals(el.selectionEnd, 5, `selectionEnd on ${el.id}`); 118 el.remove(); 119 } 120 }, "Setting selectionEnd to a value smaller than selectionStart should decrease selectionStart"); 121 122 test(function() { 123 for (let el of createTestElements(testValue)) { 124 el.selectionStart = 0; 125 assert_equals(el.selectionStart, 0, `We just set it on ${el.id}`); 126 el.selectionStart = -1; 127 assert_equals(el.selectionStart, testValue.length, 128 `selectionStart setter on ${el.id} should convert -1 to 2^32-1`); 129 el.selectionStart = Math.pow(2, 32); 130 assert_equals(el.selectionStart, 0, 131 `selectionStart setter on ${el.id} should convert 2^32 to 0`); 132 el.selectionStart = Math.pow(2, 32) - 1; 133 assert_equals(el.selectionStart, testValue.length, 134 `selectionStart setter on ${el.id} should leave 2^32-1 as-is`); 135 el.remove(); 136 } 137 }, "selectionStart edge-case values"); 138 139 test(function() { 140 for (let el of createTestElements(testValue)) { 141 el.selectionEnd = 0; 142 assert_equals(el.selectionEnd, 0, `We just set it on ${el.id}`); 143 el.selectionEnd = -1; 144 assert_equals(el.selectionEnd, testValue.length, 145 `selectionEnd setter on ${el.id} should convert -1 to 2^32-1`); 146 el.selectionEnd = Math.pow(2, 32); 147 assert_equals(el.selectionEnd, 0, 148 `selectionEnd setter on ${el.id} should convert 2^32 to 0`); 149 el.selectionEnd = Math.pow(2, 32) - 1; 150 assert_equals(el.selectionEnd, testValue.length, 151 `selectionEnd setter on ${el.id} should leave 2^32-1 as-is`); 152 el.remove(); 153 } 154 }, "selectionEnd edge-case values"); 155 156 test(() => { 157 for (const el of createTestElements(testValue)) { 158 el.selectionStart = 200; 159 assert_equals(el.selectionStart, testValue.length); 160 el.remove(); 161 } 162 }, "selectionStart should be clamped by the current value length"); 163 164 test(() => { 165 for (const el of createTestElements(testValue)) { 166 el.selectionStart = 300; 167 assert_equals(el.selectionEnd, testValue.length); 168 el.remove(); 169 } 170 }, "selectionEnd should be clamped by the current value length"); 171 172 test(() => { 173 for (const el of createTestElements(testValue)) { 174 el.setSelectionRange(200, 300); 175 assert_equals(el.selectionStart, testValue.length); 176 assert_equals(el.selectionEnd, testValue.length); 177 el.remove(); 178 } 179 }, "setSelectionRange should be clamped by the current value length"); 180 181 test(() => { 182 for (let el of createTestElements(testValue)) { 183 const start = 1; 184 const end = testValue.length - 1; 185 186 el.setSelectionRange(start, end); 187 188 assert_equals(el.selectionStart, start, `selectionStart on ${el.id}`); 189 assert_equals(el.selectionEnd, end, `selectionEnd on ${el.id}`); 190 191 el.selectionDirection = "backward"; 192 193 assert_equals(el.selectionStart, start, 194 `selectionStart on ${el.id} after setting selectionDirection to "backward"`); 195 assert_equals(el.selectionEnd, end, 196 `selectionEnd on ${el.id} after setting selectionDirection to "backward"`); 197 198 el.selectionDirection = "forward"; 199 200 assert_equals(el.selectionStart, start, 201 `selectionStart on ${el.id} after setting selectionDirection to "forward"`); 202 assert_equals(el.selectionEnd, end, 203 `selectionEnd on ${el.id} after setting selectionDirection to "forward"`); 204 } 205 }, "selectionStart and selectionEnd should remain the same when selectionDirection is changed"); 206 </script>