test_input_range_key_events.html (5830B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=843725 5 --> 6 <head> 7 <title>Test key events for range</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 <meta charset="UTF-8"> 12 </head> 13 <body> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=843725">Mozilla Bug 843725</a> 15 <p id="display"></p> 16 <div id="content"> 17 </div> 18 <pre id="test"> 19 <script type="application/javascript"> 20 21 /** 22 * Test for Bug 843725 23 * This test checks how the value of <input type=range> changes in response to 24 * various key events while it is in various states. 25 */ 26 SimpleTest.waitForExplicitFinish(); 27 28 SimpleTest.waitForFocus(function() { 29 test(); 30 SimpleTest.finish(); 31 }); 32 33 const defaultMinimum = 0; 34 const defaultMaximum = 100; 35 const defaultStep = 1; 36 37 // Helpers: 38 // For the sake of simplicity, we do not currently support fractional value, 39 // step, etc. 40 41 function minimum(element) { 42 return Number(element.min || defaultMinimum); 43 } 44 45 function maximum(element) { 46 return Number(element.max || defaultMaximum); 47 } 48 49 function range(element) { 50 var max = maximum(element); 51 var min = minimum(element); 52 if (max < min) { 53 return 0; 54 } 55 return max - min; 56 } 57 58 function defaultValue(element) { 59 return minimum(element) + range(element)/2; 60 } 61 62 function value(element) { 63 return Number(element.value || defaultValue(element)); 64 } 65 66 function step(element) { 67 var stepSize = Number(element.step || defaultStep); 68 return stepSize <= 0 ? defaultStep : stepSize; 69 } 70 71 function clampToRange(val, element) { 72 var min = minimum(element); 73 var max = maximum(element); 74 if (max < min) { 75 return min; 76 } 77 if (val < min) { 78 return min; 79 } 80 if (val > max) { 81 return max; 82 } 83 return val; 84 } 85 86 // Functions used to specify expected test results: 87 88 function valuePlusStep(element) { 89 return clampToRange(value(element) + step(element), element); 90 } 91 92 function valueMinusStep(element) { 93 return clampToRange(value(element) - step(element), element); 94 } 95 96 /** 97 * Returns the current value of the range plus whichever is greater of either 98 * 10% of the range or its current step value, clamped to the range's minimum/ 99 * maximum. The reason for using the step if it is greater than 10% of the 100 * range is because otherwise the PgUp/PgDn keys would do nothing in that case. 101 */ 102 function valuePlusTenPctOrStep(element) { 103 var tenPct = range(element)/10; 104 var stp = step(element); 105 return clampToRange(value(element) + Math.max(tenPct, stp), element); 106 } 107 108 function valueMinusTenPctOrStep(element) { 109 var tenPct = range(element)/10; 110 var stp = step(element); 111 return clampToRange(value(element) - Math.max(tenPct, stp), element); 112 } 113 114 // Test table: 115 116 const LTR = "ltr"; 117 const RTL = "rtl"; 118 119 var testTable = [ 120 ["KEY_ArrowLeft", LTR, valueMinusStep], 121 ["KEY_ArrowLeft", RTL, valuePlusStep], 122 ["KEY_ArrowRight", LTR, valuePlusStep], 123 ["KEY_ArrowRight", RTL, valueMinusStep], 124 ["KEY_ArrowUp", LTR, valuePlusStep], 125 ["KEY_ArrowUp", RTL, valuePlusStep], 126 ["KEY_ArrowDown", LTR, valueMinusStep], 127 ["KEY_ArrowDown", RTL, valueMinusStep], 128 ["KEY_PageUp", LTR, valuePlusTenPctOrStep], 129 ["KEY_PageUp", RTL, valuePlusTenPctOrStep], 130 ["KEY_PageDown", LTR, valueMinusTenPctOrStep], 131 ["KEY_PageDown", RTL, valueMinusTenPctOrStep], 132 ["KEY_Home", LTR, minimum], 133 ["KEY_Home", RTL, minimum], 134 ["KEY_End", LTR, maximum], 135 ["KEY_End", RTL, maximum], 136 ] 137 138 function test() { 139 var elem = document.createElement("input"); 140 elem.type = "range"; 141 142 var content = document.getElementById("content"); 143 content.appendChild(elem); 144 elem.focus(); 145 146 for (test of testTable) { 147 var [key, dir, expectedFunc] = test; 148 var oldVal, expectedVal; 149 150 elem.step = "2"; 151 elem.style.direction = dir; 152 var flush = document.body.clientWidth; 153 154 // Start at middle: 155 elem.value = oldVal = defaultValue(elem); 156 expectedVal = expectedFunc(elem); 157 synthesizeKey(key); 158 is(elem.value, String(expectedVal), "Test " + key + " for " + dir + " range with value set to the midpoint (" + oldVal + ")"); 159 160 // Same again: 161 expectedVal = expectedFunc(elem); 162 synthesizeKey(key); 163 is(elem.value, String(expectedVal), "Test repeat of " + key + " for " + dir + " range"); 164 165 // Start at maximum: 166 elem.value = oldVal = maximum(elem); 167 expectedVal = expectedFunc(elem); 168 synthesizeKey(key); 169 is(elem.value, String(expectedVal), "Test " + key + " for " + dir + " range with value set to the maximum (" + oldVal + ")"); 170 171 // Same again: 172 expectedVal = expectedFunc(elem); 173 synthesizeKey(key); 174 is(elem.value, String(expectedVal), "Test repeat of " + key + " for " + dir + " range"); 175 176 // Start at minimum: 177 elem.value = oldVal = minimum(elem); 178 expectedVal = expectedFunc(elem); 179 synthesizeKey(key); 180 is(elem.value, String(expectedVal), "Test " + key + " for " + dir + " range with value set to the minimum (" + oldVal + ")"); 181 182 // Same again: 183 expectedVal = expectedFunc(elem); 184 synthesizeKey(key); 185 is(elem.value, String(expectedVal), "Test repeat of " + key + " for " + dir + " range"); 186 187 // Test for a step value that is greater than 10% of the range: 188 elem.step = 20; 189 elem.value = 60; 190 expectedVal = expectedFunc(elem); 191 synthesizeKey(key); 192 is(elem.value, String(expectedVal), "Test " + key + " for " + dir + " range with a step that is greater than 10% of the range (step=" + elem.step + ")"); 193 194 // Same again: 195 expectedVal = expectedFunc(elem); 196 synthesizeKey(key); 197 is(elem.value, String(expectedVal), "Test repeat of " + key + " for " + dir + " range"); 198 199 // reset step: 200 elem.step = 2; 201 } 202 } 203 204 </script> 205 </pre> 206 </body> 207 </html>