test_change_event.html (13207B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=722599 5 --> 6 <head> 7 <title>Test for Bug 722599</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script src="/tests/SimpleTest/EventUtils.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=722599">Mozilla Bug 722599</a> 14 <p id="display"></p> 15 <div id="content"> 16 <input type="file" id="fileInput"></input> 17 <textarea id="textarea" onchange="++textareaChange;"></textarea> 18 <input type="text" id="input_text" onchange="++textInputChange[0];"></input> 19 <input type="email" id="input_email" onchange="++textInputChange[1];"></input> 20 <input type="search" id="input_search" onchange="++textInputChange[2];"></input> 21 <input type="tel" id="input_tel" onchange="++textInputChange[3];"></input> 22 <input type="url" id="input_url" onchange="++textInputChange[4];"></input> 23 <input type="password" id="input_password" onchange="++textInputChange[5];"></input> 24 25 <!-- "Non-text" inputs--> 26 <input type="button" id="input_button" onchange="++NonTextInputChange[0];"></input> 27 <input type="submit" id="input_submit" onchange="++NonTextInputChange[1];"></input> 28 <input type="image" id="input_image" onchange="++NonTextInputChange[2];"></input> 29 <input type="reset" id="input_reset" onchange="++NonTextInputChange[3];"></input> 30 <input type="radio" id="input_radio" onchange="++NonTextInputChange[4];"></input> 31 <input type="checkbox" id="input_checkbox" onchange="++NonTextInputChange[5];"></input> 32 <input type="number" id="input_number" onchange="++numberChange;"></input> 33 <input type="range" id="input_range" onchange="++rangeChange;"></input> 34 35 <!-- Input text with default value and blurs on focus--> 36 <input type="text" id="input_text_value" onchange="++textInputValueChange" 37 onfocus="this.blur();" value="foo"></input> 38 39 </div> 40 <pre id="test"> 41 <script class="testbody" type="text/javascript"> 42 43 /** Test for Bug 722599 */ 44 45 const isDesktop = !/Mobile|Tablet/.test(navigator.userAgent); 46 47 var textareaChange = 0; 48 var fileInputChange = 0; 49 var textInputValueChange = 0; 50 51 var textInputTypes = ["text", "email", "search", "tel", "url", "password"]; 52 var textInputChange = [0, 0, 0, 0, 0, 0]; 53 54 var NonTextInputTypes = ["button", "submit", "image", "reset", "radio", "checkbox"]; 55 var NonTextInputChange = [0, 0, 0, 0, 0, 0]; 56 57 var numberChange = 0; 58 var rangeChange = 0; 59 60 var blurTestCalled = false; //Sentinel to prevent infinite loop. 61 62 SimpleTest.waitForExplicitFinish(); 63 var MockFilePicker = SpecialPowers.MockFilePicker; 64 MockFilePicker.init(SpecialPowers.wrap(window).browsingContext); 65 66 function fileInputBlurTest() { 67 var btn = document.getElementById('fileInput'); 68 btn.focus() 69 btn.blur(); 70 is(fileInputChange, 1, "change event shouldn't be dispatched on blur for file input element(1)"); 71 } 72 73 function testUserInput() { 74 //Simulating an OK click and with a file name return. 75 MockFilePicker.useBlobFile(); 76 MockFilePicker.returnValue = MockFilePicker.returnOK; 77 var input = document.getElementById('fileInput'); 78 input.focus(); 79 80 input.addEventListener("change", function (aEvent) { 81 ++fileInputChange; 82 if (!blurTestCalled) { 83 is(fileInputChange, 1, "change event should have been dispatched on file input."); 84 blurTestCalled = true; 85 fileInputBlurTest(); 86 } 87 else { 88 is(fileInputChange, 1, "change event shouldn't be dispatched on blur for file input element (2)"); 89 } 90 }); 91 92 SpecialPowers.wrap(document).notifyUserGestureActivation(); 93 input.click(); 94 95 // blur the file input, we can't use blur() because of bug 760283 96 document.getElementById('input_text').focus(); 97 setTimeout(testUserInput2, 0); 98 } 99 100 function testUserInput2() { 101 var input = document.getElementById('fileInput'); 102 // remove it, otherwise cleanup() opens a native file picker! 103 input.remove(); 104 MockFilePicker.cleanup(); 105 106 //text, email, search, telephone, url & password input tests 107 for (var i = 0; i < textInputTypes.length; ++i) { 108 input = document.getElementById("input_" + textInputTypes[i]); 109 input.focus(); 110 synthesizeKey("KEY_Enter"); 111 is(textInputChange[i], 0, "Change event shouldn't be dispatched on " + textInputTypes[i] + " input element"); 112 113 sendString("m"); 114 synthesizeKey("KEY_Enter"); 115 is(textInputChange[i], 1, textInputTypes[i] + " input element should have dispatched change event."); 116 } 117 118 //focus and blur text input 119 input = document.getElementById("input_text"); 120 input.focus(); 121 sendString("f"); 122 input.blur(); 123 is(textInputChange[0], 2, "text input element should have dispatched change event (2)."); 124 125 // value being set while focused 126 input.focus(); 127 input.value = 'foo'; 128 input.blur(); 129 is(textInputChange[0], 2, "text input element should not have dispatched change event (2)."); 130 131 // value being set while focused after being modified manually 132 input.focus(); 133 sendString("f"); 134 input.value = 'bar'; 135 input.blur(); 136 is(textInputChange[0], 3, "text input element should have dispatched change event (3)."); 137 138 //focus and blur textarea 139 var textarea = document.getElementById("textarea"); 140 textarea.focus(); 141 sendString("f"); 142 textarea.blur(); 143 is(textareaChange, 1, "Textarea element should have dispatched change event."); 144 145 // value being set while focused 146 textarea.focus(); 147 textarea.value = 'foo'; 148 textarea.blur(); 149 is(textareaChange, 1, "textarea should not have dispatched change event (1)."); 150 151 // value being set while focused after being modified manually 152 textarea.focus(); 153 sendString("f"); 154 textarea.value = 'bar'; 155 textarea.blur(); 156 is(textareaChange, 2, "textearea should have dispatched change event (2)."); 157 158 //Non-text input tests: 159 for (var i = 0; i < NonTextInputTypes.length; ++i) { 160 //button, submit, image and reset input type tests. 161 if (i < 4) { 162 input = document.getElementById("input_" + NonTextInputTypes[i]); 163 input.focus(); 164 input.click(); 165 is(NonTextInputChange[i], 0, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element"); 166 input.blur(); 167 is(NonTextInputChange[i], 0, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element(2)"); 168 } 169 //for radio and and checkboxes, we require that change event should ONLY be dispatched on setting the value. 170 else { 171 input = document.getElementById("input_" + NonTextInputTypes[i]); 172 input.focus(); 173 input.click(); 174 is(NonTextInputChange[i], 1, NonTextInputTypes[i] + " input element should have dispatched change event."); 175 input.blur(); 176 is(NonTextInputChange[i], 1, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element"); 177 178 // Test that change event is not dispatched if click event is cancelled. 179 function preventDefault(e) { 180 e.preventDefault(); 181 } 182 input.addEventListener("click", preventDefault); 183 input.click(); 184 is(NonTextInputChange[i], 1, "Change event shouldn't be dispatched if click event is cancelled"); 185 input.removeEventListener("click", preventDefault); 186 } 187 } 188 189 // Special case type=number 190 var number = document.getElementById("input_number"); 191 number.focus(); 192 sendString("a"); 193 number.blur(); 194 is(numberChange, 0, "Change event shouldn't be dispatched on number input element for key changes that don't change its value"); 195 number.value = ""; 196 number.focus(); 197 sendString("12"); 198 is(numberChange, 0, "Change event shouldn't be dispatched on number input element for keyboard input until it loses focus"); 199 number.blur(); 200 is(numberChange, 1, "Change event should be dispatched on number input element on blur"); 201 is(number.value, "12", "Sanity check that number keys were actually handled"); 202 if (isDesktop) { // up/down arrow keys not supported on android/b2g 203 number.value = ""; 204 number.focus(); 205 synthesizeKey("KEY_ArrowUp"); 206 synthesizeKey("KEY_ArrowUp"); 207 synthesizeKey("KEY_ArrowDown"); 208 is(numberChange, 4, "Change event should be dispatched on number input element for up/down arrow keys (a special case)"); 209 is(number.value, "1", "Sanity check that number and arrow keys were actually handled"); 210 } 211 212 // Special case type=range 213 var range = document.getElementById("input_range"); 214 range.focus(); 215 sendString("a"); 216 range.blur(); 217 is(rangeChange, 0, "Change event shouldn't be dispatched on range input element for key changes that don't change its value"); 218 range.focus(); 219 synthesizeKey("VK_HOME"); 220 is(rangeChange, 1, "Change event should be dispatched on range input element for key changes"); 221 range.blur(); 222 is(rangeChange, 1, "Change event shouldn't be dispatched on range input element on blur"); 223 range.focus(); 224 var bcr = range.getBoundingClientRect(); 225 var centerOfRangeX = bcr.width / 2; 226 var centerOfRangeY = bcr.height / 2; 227 synthesizeMouse(range, centerOfRangeX - 10, centerOfRangeY, { type: "mousedown" }); 228 is(rangeChange, 1, "Change event shouldn't be dispatched on range input element for mousedown"); 229 synthesizeMouse(range, centerOfRangeX - 5, centerOfRangeY, { type: "mousemove" }); 230 is(rangeChange, 1, "Change event shouldn't be dispatched on range input element during drag of thumb"); 231 synthesizeMouse(range, centerOfRangeX, centerOfRangeY, { type: "mouseup" }); 232 is(rangeChange, 2, "Change event should be dispatched on range input element at end of drag"); 233 range.blur(); 234 is(rangeChange, 2, "Change event shouldn't be dispatched on range input element when range loses focus after a drag"); 235 synthesizeMouse(range, centerOfRangeX - 10, centerOfRangeY, {}); 236 is(rangeChange, 3, "Change event should be dispatched on range input element for a click that gives the range focus"); 237 238 if (isDesktop) { // up/down arrow keys not supported on android/b2g 239 synthesizeKey("KEY_ArrowUp"); 240 is(rangeChange, 4, "Change event should be dispatched on range input element for key changes that change its value (KEY_ArrowUp)"); 241 synthesizeKey("KEY_ArrowDown"); 242 is(rangeChange, 5, "Change event should be dispatched on range input element for key changes that change its value (KEY_ArrowDown)"); 243 synthesizeKey("KEY_ArrowRight"); 244 is(rangeChange, 6, "Change event should be dispatched on range input element for key changes that change its value (KEY_ArrowRight)"); 245 synthesizeKey("KEY_ArrowLeft"); 246 is(rangeChange, 7, "Change event should be dispatched on range input element for key changes that change its value (KEY_ArrowLeft)"); 247 synthesizeKey("KEY_ArrowUp", {shiftKey: true}); 248 is(rangeChange, 8, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_ArrowUp)"); 249 synthesizeKey("KEY_ArrowDown", {shiftKey: true}); 250 is(rangeChange, 9, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_ArrowDown)"); 251 synthesizeKey("KEY_ArrowRight", {shiftKey: true}); 252 is(rangeChange, 10, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_ArrowRight)"); 253 synthesizeKey("KEY_ArrowLeft", {shiftKey: true}); 254 is(rangeChange, 11, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_ArrowLeft)"); 255 synthesizeKey("KEY_PageUp"); 256 is(rangeChange, 12, "Change event should be dispatched on range input element for key changes that change its value (KEY_PageUp)"); 257 synthesizeKey("KEY_PageDown"); 258 is(rangeChange, 13, "Change event should be dispatched on range input element for key changes that change its value (KEY_PageDown"); 259 synthesizeKey("KEY_ArrowRight", {shiftKey: true}); 260 is(rangeChange, 14, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_PageUp)"); 261 synthesizeKey("KEY_ArrowLeft", {shiftKey: true}); 262 is(rangeChange, 15, "Change event should be dispatched on range input element for key changes that change its value (Shift+KEY_PageDown)"); 263 } 264 //Input type change test. 265 input = document.getElementById("input_checkbox"); 266 input.type = "text"; 267 input.focus(); 268 input.click(); 269 input.blur(); 270 is(NonTextInputChange[5], 1, "Change event shouldn't be dispatched for checkbox ---> text input type change"); 271 272 setTimeout(testInputWithDefaultValue, 0); 273 } 274 275 function testInputWithDefaultValue() { 276 // focus and blur an input text should not trigger change event if content hasn't changed. 277 var input = document.getElementById('input_text_value'); 278 input.focus(); 279 is(textInputValueChange, 0, "change event shouldn't be dispatched on input text with default value"); 280 281 SimpleTest.finish(); 282 } 283 284 addLoadEvent(testUserInput); 285 286 </script> 287 </pre> 288 </body> 289 </html>