pointerevent_range_input.html (6772B)
1 <!DOCTYPE html> 2 <!-- TODO(crbug.com/40275057) Fix test for pointer-event-range-input.html?pen. 3 --> 4 <title>Pointer dragging behavior on input type='range' </title> 5 <meta name="variant" content="?touch"> 6 <meta name="variant" content="?mouse"> 7 <script src='/resources/testharness.js'></script> 8 <script src='/resources/testharnessreport.js'></script> 9 <script src='/resources/testdriver.js'></script> 10 <script src='/resources/testdriver-actions.js'></script> 11 <script src='/resources/testdriver-vendor.js'></script> 12 <style type='text/css'> 13 body { 14 margin: 0; 15 } 16 </style> 17 18 <div><input type='range' id='slider1' min='0' max='100' step='10'></div> 19 <div><input type='range' id='slider2' min='0' max='100' step='10' style='touch-action:none;'></div> 20 <div><input type='range' id='slider3' min='0' max='100' step='10' style='writing-mode:vertical-lr; direction:rtl;'></div> 21 22 <script> 23 "use strict"; 24 const pointerType = location.search.substring(1); 25 26 function isMouse() { 27 return pointerType === 'mouse'; 28 } 29 function isTouch() { 30 return pointerType === 'touch'; 31 } 32 33 // Verify that a point is on screen. 34 // (x,y) is relative to the center of the origin element. 35 function assert_point_within_viewport(x, y, origin) { 36 const rect = origin.getBoundingClientRect(); 37 const center_point = { 38 x: rect.x + rect.width / 2, 39 y: rect.y + rect.height / 2 40 }; 41 const viewport_point = { 42 x: (center_point.x - visualViewport.offsetLeft) * visualViewport.scale, 43 y: (center_point.y - visualViewport.offsetTop) * visualViewport.scale 44 }; 45 x += viewport_point.x; 46 y += viewport_point.y; 47 assert_true(x >= 0 && x <= window.innerWidth, 48 'x coordinate outside viewport'); 49 assert_true(y >= 0 && y <= window.innerHeight, 50 'y coordinate outside viewport'); 51 } 52 53 // The deltas are relative to the center of the target. 54 function smoothDrag(delta_x, delta_y, target) { 55 const eventTarget = document; 56 const prevent_fling_pause_ms = isTouch() ? 100 : 0; 57 58 const x = 0; 59 const y = 0; 60 const end_x = Math.round(delta_x); 61 const end_y = Math.round(delta_y); 62 assert_point_within_viewport(end_x, end_y, target); 63 64 // Expect a pointerup or pointercancel event depending on whether scrolling 65 // actually took place. 66 return new Promise(resolve => { 67 const pointerPromise = new Promise(resolve => { 68 const pointerListener = (event) => { 69 eventTarget.removeEventListener('pointerup', pointerListener); 70 eventTarget.removeEventListener('pointercancel', pointerListener); 71 resolve(event.type); 72 }; 73 eventTarget.addEventListener('pointerup', pointerListener); 74 eventTarget.addEventListener('pointercancel', pointerListener); 75 }); 76 const actionPromise = new test_driver.Actions() 77 .addPointer("pointer1", pointerType) 78 .pointerMove(x, y, { origin: target }) 79 .pointerDown({button: 0/*Left*/}) 80 .pointerMove(end_x, end_y, { origin: target }) 81 .pause(prevent_fling_pause_ms) 82 .pointerUp({button: 0 /*Left*/}) 83 .send(); 84 Promise.all([actionPromise, pointerPromise]).then(responses => { 85 resolve(responses[1]); 86 }); 87 }); 88 } 89 90 function forceLayoutUpdate() { 91 document.body.offsetTop; 92 } 93 94 const slider1 = document.getElementById('slider1'); 95 const slider2 = document.getElementById('slider2'); 96 const slider3 = document.getElementById('slider3'); 97 98 function resetPage() { 99 slider1.value = 50; 100 slider2.value = 50; 101 slider3.value = 50; 102 } 103 104 const isMac = navigator.platform.indexOf('Mac') == 0; 105 if (isMac && isTouch()) { 106 // Mac devices do not support touch. 107 testNothing(); 108 } else { 109 forceLayoutUpdate(); 110 111 promise_test(async t => { 112 resetPage(); 113 assert_equals(parseInt(slider1.value), 50, "Slider1's initial value"); 114 // Perform a left drag from the center of the slider. 115 const gestureCompletionEventType = 116 await smoothDrag(-slider1.clientWidth / 2, 0, slider1); 117 assert_equals(gestureCompletionEventType, 'pointerup', 118 "The gesture is completed with 'pointerup'"); 119 assert_equals(parseInt(slider1.value), 0, 120 "Should set slider1's value to 0"); 121 }, 'Horizontal drag on a horizontal slider.'); 122 123 promise_test(async t => { 124 resetPage(); 125 assert_equals(parseInt(slider1.value), 50, "Slider1's initial value"); 126 // Perform a down drag from the center of the slider. 127 const gestureCompletionEventType = 128 await smoothDrag(0, slider1.clientWidth, slider1); 129 assert_equals(parseInt(slider1.value), 50, 130 "Should not change slider1's value."); 131 // Don't assert gestureCompletionEventType value. Depending on the UA, the 132 // gesture may result in scroll. In this case gestureCompletionEventType 133 // is 'pointercancel'. 134 }, 'Vertical drag on a horizontal slider.'); 135 136 promise_test(async t => { 137 resetPage(); 138 assert_equals(parseInt(slider2.value), 50, "Slider2's initial value"); 139 // Perform a down drag from the center of the slider. 140 const gestureCompletionEventType = 141 await smoothDrag(0, slider2.clientWidth, slider2); 142 assert_equals(gestureCompletionEventType, 'pointerup', 143 "The gesture is completed with 'pointerup'"); 144 assert_equals(parseInt(slider2.value), 50, 145 "Should not change slider2's value."); 146 147 }, 'Vertical drag on a horizontal slider with touch-action:none.'); 148 149 promise_test(async t => { 150 resetPage(); 151 assert_equals(parseInt(slider3.value), 50, "Slider3's initial value."); 152 // Perform an up drag from the center of the slider. 153 const gestureCompletionEventType = 154 await smoothDrag(0, -slider3.clientHeight / 2, slider3); 155 assert_equals(gestureCompletionEventType, 'pointerup', 156 "The gesture is completed with 'pointerup'"); 157 assert_equals(parseInt(slider3.value), 100, 158 "Should set slider3' value to 100."); 159 }, 'Vertical drag on a vertical slider.'); 160 161 promise_test(async t => { 162 resetPage(); 163 assert_equals(parseInt(slider3.value), 50, "Slider3's initial value."); 164 // Perform a right drag from the center of the slider. 165 const gestureCompletionEventType = 166 await smoothDrag(slider3.clientHeight, 0, slider3); 167 assert_equals(parseInt(slider3.value), 50, 168 "Should not change slider3' value."); 169 // Don't assert gestureCompletionEventType value. Depending on the UA, the 170 // gesture may result in scroll. In this case gestureCompletionEventType 171 // is 'pointercancel'. 172 }, 'Horizontal drag on a vertical slider.'); 173 } 174 175 function testNothing() { 176 test(() => {}, 'Empty test for MacOS.'); 177 } 178 </script>