selection-after-content-change.html (5967B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title>Selection indices after content change</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 7 <input id="i1" type="text" value="hello"> 8 <textarea id="t1">hello</textarea> 9 10 <script> 11 "use strict"; 12 13 // This helper ensures that when the selection direction is reset, it always is reset to the same value consistently 14 // (which must be one of either "none" or "forward"). This helps catch bugs like one observed in Chrome, where textareas 15 // reset to "none" but inputs reset to "forward". 16 let observedResetSelectionDirection; 17 function assertSelectionDirectionIsReset(element) { 18 if (!observedResetSelectionDirection) { 19 assert_in_array(element.selectionDirection, ["none", "forward"], 20 "selectionDirection must be set to either none or forward"); 21 observedResetSelectionDirection = element.selectionDirection; 22 } else { 23 assert_equals(element.selectionDirection, observedResetSelectionDirection, 24 `selectionDirection must be reset to ${observedResetSelectionDirection} (which was previously observed to be ` + 25 `the value after resetting the selection direction)`); 26 } 27 } 28 29 runInputTest("input out of document", () => { 30 const input = document.createElement("input"); 31 input.value = "hello"; 32 return input; 33 }); 34 35 runInputTest("input in document", () => { 36 const input = document.querySelector("#i1"); 37 input.value = "hello"; 38 return input; 39 }); 40 41 runInputTest("input in document, with focus", () => { 42 const input = document.querySelector("#i1"); 43 input.value = "hello"; 44 input.focus(); 45 return input; 46 }); 47 48 runTextareaTest("textarea out of document", () => { 49 const textarea = document.createElement("textarea"); 50 textarea.value = "hello"; 51 return textarea; 52 }); 53 54 runTextareaTest("textarea in document", () => { 55 const textarea = document.querySelector("#t1"); 56 textarea.value = "hello"; 57 return textarea; 58 }); 59 60 runTextareaTest("textarea in document, with focus", () => { 61 const textarea = document.querySelector("#t1"); 62 textarea.value = "hello"; 63 textarea.focus(); 64 return textarea; 65 }); 66 67 function runTest(descriptor, elementFactory) { 68 test(() => { 69 const element = elementFactory(); 70 element.setSelectionRange(1, 3, "backward"); 71 72 assert_equals(element.selectionStart, 1, "Sanity check: selectionStart was set correctly"); 73 assert_equals(element.selectionEnd, 3, "Sanity check: selectionEnd was set correctly"); 74 assert_equals(element.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly"); 75 76 element.value = "hello"; 77 78 assert_equals(element.selectionStart, 1, "selectionStart must not change"); 79 assert_equals(element.selectionEnd, 3, "selectionEnd must not change"); 80 assert_equals(element.selectionDirection, "backward", "selectionDirection must not change"); 81 }, `${descriptor}: selection must not change when setting the same value`); 82 83 test(() => { 84 const element = elementFactory(); 85 element.setSelectionRange(1, 3, "backward"); 86 87 assert_equals(element.selectionStart, 1, "Sanity check: selectionStart was set correctly"); 88 assert_equals(element.selectionEnd, 3, "Sanity check: selectionEnd was set correctly"); 89 assert_equals(element.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly"); 90 91 element.value = "hello2"; 92 93 assert_equals(element.selectionStart, element.value.length, "selectionStart must be reset to the end"); 94 assert_equals(element.selectionEnd, element.value.length, "selectionEnd must be reset to the end"); 95 assertSelectionDirectionIsReset(element); 96 }, `${descriptor}: selection must change when setting a different value`); 97 } 98 99 function runInputTest(descriptor, elementFactory) { 100 runTest(descriptor, elementFactory); 101 102 test(() => { 103 const input = elementFactory(); 104 input.setSelectionRange(1, 3, "backward"); 105 106 assert_equals(input.selectionStart, 1, "Sanity check: selectionStart was set correctly"); 107 assert_equals(input.selectionEnd, 3, "Sanity check: selectionEnd was set correctly"); 108 assert_equals(input.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly"); 109 110 input.value = "he\nllo"; 111 112 assert_equals(input.selectionStart, 1, "selectionStart must not change"); 113 assert_equals(input.selectionEnd, 3, "selectionEnd must not change"); 114 assert_equals(input.selectionDirection, "backward", "selectionDirection must not change"); 115 }, `${descriptor}: selection must not change when setting a value that becomes the same after the value ` + 116 `sanitization algorithm`); 117 } 118 119 function runTextareaTest(descriptor, elementFactory) { 120 runTest(descriptor, elementFactory); 121 122 test(() => { 123 const textarea = elementFactory(); 124 textarea.value = "hell\no"; 125 textarea.setSelectionRange(1, 3, "backward"); 126 127 assert_equals(textarea.selectionStart, 1, "Sanity check: selectionStart was set correctly"); 128 assert_equals(textarea.selectionEnd, 3, "Sanity check: selectionEnd was set correctly"); 129 assert_equals(textarea.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly"); 130 131 textarea.value = "hell\r\no"; 132 133 assert_equals(textarea.selectionStart, 1, "selectionStart must not change when setting to CRLF"); 134 assert_equals(textarea.selectionEnd, 3, "selectionEnd must not change when setting to CRLF"); 135 assert_equals(textarea.selectionDirection, "backward", "selectionDirection must not change when setting to CRLF"); 136 137 textarea.value = "hell\ro"; 138 139 assert_equals(textarea.selectionStart, 1, "selectionStart must not change when setting to CR"); 140 assert_equals(textarea.selectionEnd, 3, "selectionEnd must not change when setting to CR"); 141 assert_equals(textarea.selectionDirection, "backward", "selectionDirection must not change when setting to CR"); 142 }, `${descriptor}: selection must not change when setting the same normalized value`); 143 } 144 </script>