pointerevent_pointercapture-not-lost-in-chorded-buttons.html (8609B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>Set/Release capture when using chorded buttons</title> 5 <meta name="viewport" content="width=device-width"> 6 <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1053385"> 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 13 <style> 14 .container { 15 height: 500px; 16 width: 500px; 17 border: 1px solid black; 18 overflow: hidden; 19 position: relative; 20 } 21 22 #box { 23 height: 50px; 24 width: 50px; 25 background: red; 26 position: absolute; 27 } 28 </style> 29 </head> 30 <body> 31 <h1>Pointer Events Capture Test - capture should not be lost early</h1> 32 <h4> 33 Test Description: This test checks if setCapture/pointerup functions 34 works properly. Complete the following actions: 35 <ol> 36 <li> Put your mouse over the red box 37 <li> Press and hold left mouse button. Box will call setPointerCapture 38 <li> Press right button and release 39 <li> Pointer capture should not be lost 40 <li> Press right button again and release 41 <li> Pointer capture should not be lost 42 <li> Release left mouse button. lostpointercapture is called 43 </ol> 44 </h4> 45 Test passes if the proper behavior of the events is observed. 46 <div class="container"> 47 <div id="box"></div> 48 </div> 49 <div id="log"></div> 50 </body> 51 <script> 52 var PhaseEnum = { 53 WaitingForDown: "down", 54 WaitingForUp: "up", 55 UpDone : "up_done" 56 }; 57 58 var origin = {x:0, y:0}; 59 var position = {x:0, y:0}; 60 var deltaX = 0; 61 var deltaY = 0; 62 var box = document.getElementById("box"); 63 var logDiv = document.getElementById("log"); 64 65 var currentPhase = PhaseEnum.WaitingForDown; 66 var events = []; 67 68 function slide(event){ 69 // move the target following the mouse 70 deltaX = event.clientX - origin.x 71 deltaY = event.clientY - origin.y 72 box.style.left = `${position.x + deltaX}px`; 73 box.style.top = `${position.y + deltaY}px`; 74 } 75 76 function addLog(message){ 77 var messageDiv = document.createElement("div"); 78 var textContent = document.createTextNode(message); 79 messageDiv.appendChild(textContent); 80 logDiv.appendChild(messageDiv); 81 } 82 83 function handle_pointerdown(e){ 84 box.setPointerCapture(e.pointerId); 85 if(window.promise_test){ 86 current_test.step(function(){ 87 // once receiving a pointer down and the pointer is captured, 88 // no other mousedown should send pointerdown events during the test 89 assert_equals(currentPhase, PhaseEnum.WaitingForDown, 90 "Current Phase should be " + PhaseEnum.WaitingForDown); 91 currentPhase = PhaseEnum.WaitingForUp; 92 events.push("target@pointerdown"); 93 }); 94 } 95 origin = { x: event.clientX, y: event.clientY }; 96 box.addEventListener("pointermove", slide); 97 } 98 99 function handle_pointerup(e){ 100 box.releasePointerCapture(e.pointerId); 101 if(window.promise_test){ 102 current_test.step(function(){ 103 assert_equals(event.buttons, 0, 104 'pointerup should happen when all buttons are released.'); 105 assert_equals(currentPhase, PhaseEnum.WaitingForUp, 106 "Current Phase should be " + PhaseEnum.WaitingForUp); 107 currentPhase = PhaseEnum.UpDone; 108 events.push("target@pointerup"); 109 }); 110 } 111 box.removeEventListener("pointermove", slide); 112 } 113 114 function handle_contextmenu(e){ 115 e.preventDefault(); 116 } 117 118 function handle_lostpointercapture(e){ 119 if(window.promise_test){ 120 current_test.step(function(){ 121 events.push("target@lostpointercapture"); 122 assert_equals(currentPhase, PhaseEnum.UpDone, 123 "Current Phase should be " + PhaseEnum.UpDone + "." + 124 'lostpointercapture should happen after pointerup event.'); 125 assert_equals(event.buttons, 0, 126 'lostpointercapture should happen when all buttons are released.'); 127 assert_array_equals(events, ["target@pointerdown", 128 "target@pointerup", "target@lostpointercapture"]); 129 resolve_test(); 130 current_test.done(); 131 }); 132 } 133 if(event.buttons === 0){ 134 addLog("Test Passed!"); 135 }else{ 136 addLog("Test Failed!"); 137 } 138 } 139 140 function removeEventListeners(){ 141 box.removeEventListener('pointerdown', handle_pointerdown); 142 box.removeEventListener('pointerup', handle_pointerup); 143 box.removeEventListener('contextmenu', handle_contextmenu); 144 box.removeEventListener('lostpointercapture', 145 handle_lostpointercapture); 146 } 147 148 function addEventListeners(){ 149 box.addEventListener('pointerdown', handle_pointerdown); 150 box.addEventListener('pointerup', handle_pointerup); 151 box.addEventListener('contextmenu', handle_contextmenu); 152 box.addEventListener('lostpointercapture', 153 handle_lostpointercapture); 154 } 155 156 var current_test = null; 157 var resolve_test = null; 158 var reject_test = null; 159 // window.promise_test is only defined when running the 160 // test using testharness.js 161 // if window.promise_test is not defined we'll run the manual testing 162 // path 163 if(!window.promise_test){ 164 addEventListeners(); 165 } 166 167 if(window.promise_test){ 168 promise_test(function(t){ 169 addEventListeners(); 170 t.add_cleanup(function(){ 171 removeEventListeners(); 172 currentPhase = PhaseEnum.WaitingForDown; 173 events = []; 174 }); 175 return new Promise(function(resolve, reject){ 176 current_test = t; 177 resolve_test = resolve; 178 reject_test = reject; 179 var actions = new test_driver.Actions(); 180 var actions_promise = actions 181 .pointerMove(0, 0, {origin: box}) 182 183 .pointerDown({button: actions.ButtonType.LEFT}) 184 // Ensure clicking other buttons while a first button has 185 // captured the pointer doesn't release the capture 186 .pointerDown({button: actions.ButtonType.RIGHT}) 187 .pointerUp({button: actions.ButtonType.RIGHT}) 188 .pointerDown({button: actions.ButtonType.RIGHT}) 189 .pointerUp({button: actions.ButtonType.RIGHT}) 190 .pointerUp({button: actions.ButtonType.LEFT}) 191 .send(); 192 }) 193 }, "Pointer Events Capture Test - capture not lost due to " + 194 "chorded buttons interaction"); 195 196 promise_test(function(t){ 197 addEventListeners(); 198 t.add_cleanup(function(){ 199 removeEventListeners(); 200 currentPhase = PhaseEnum.WaitingForDown; 201 events = []; 202 }); 203 return new Promise(function(resolve, reject){ 204 current_test = t; 205 resolve_test = resolve; 206 reject_test = reject; 207 var actions = new test_driver.Actions(); 208 var actions_promise = actions 209 .pointerMove(0, 0, {origin: box}) 210 211 .pointerDown({button: actions.ButtonType.LEFT}) 212 // Ensure clicking other buttons while a first button has 213 // captured the pointer doesn't release the capture 214 .pointerDown({button: actions.ButtonType.RIGHT}) 215 .pointerUp({button: actions.ButtonType.LEFT}) 216 .pointerDown({button: actions.ButtonType.LEFT}) 217 .pointerUp({button: actions.ButtonType.RIGHT}) 218 .pointerUp({button: actions.ButtonType.LEFT}) 219 .send(); 220 }) 221 }, "Pointer Events Capture Test - capture not lost " + 222 "due to combination of left and right chorded buttons interaction."); 223 } 224 </script> 225 </html>