pointerevent-drag-interaction.html (4372B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <meta name="viewport" content="width=device-width"> 4 <meta name="timeout" content="long"> 5 <title>Pointer Events interaction with drag and drop</title> 6 <link rel="author" href="mailto:zhoupeng.1996@bytedance.com"> 7 <link rel="help" href="https://w3c.github.io/pointerevents/"> 8 <link rel="stylesheet" type="text/css" href="pointerevent_styles.css"> 9 <script src="/resources/testharness.js"></script> 10 <script src="/resources/testharnessreport.js"></script> 11 <script src="/resources/testdriver.js"></script> 12 <script src="/resources/testdriver-actions.js"></script> 13 <script src="/resources/testdriver-vendor.js"></script> 14 <script src="pointerevent_support.js"></script> 15 16 <div id="testContainer"> 17 <div draggable="true" id="target0"></div> 18 <div id="target1"></div> 19 </div> 20 21 <script> 22 let received_events = []; 23 24 function reset() { 25 received_events = []; 26 // Use ESC to cancel drag session. 27 const Escape = '\uE00C'; 28 return new test_driver.Actions() 29 .keyDown(Escape) 30 .keyUp(Escape) 31 .send(); 32 } 33 34 function performDrag() { 35 return new test_driver.Actions() 36 .addPointer('pointer-drag', 'mouse') 37 .pointerMove(0, 0, { origin: target0 }) 38 .pointerDown() 39 .pointerMove(10, 10, { origin: target0 }) 40 .pointerMove(0, 0, { origin: target1 }) 41 .pause(100) 42 .pointerUp() 43 .send(); 44 } 45 46 function on(t, target, eventName, handler) { 47 target.addEventListener(eventName, handler); 48 t.add_cleanup(() => target.removeEventListener(eventName, handler)); 49 } 50 51 function trackEvents(t, target, eventNames) { 52 eventNames.forEach(name => { 53 on(t, target, name, e => received_events.push(e.type + '@' + target.id)); 54 }); 55 } 56 57 promise_test(async t => { 58 t.add_cleanup(reset); 59 60 trackEvents(t, target0, ['pointerdown', 'mousedown', 'dragstart', 'pointercancel']); 61 const pointerCancelPromise = new Promise(resolve => { 62 on(t, target0, 'pointercancel', resolve); 63 }); 64 65 await performDrag(); 66 await pointerCancelPromise; 67 68 assert_equals(received_events.join(', '), 69 'pointerdown@target0, mousedown@target0, dragstart@target0, pointercancel@target0'); 70 }, 'Pointercancel should be fired with the expected order when drag operation starts'); 71 72 promise_test(async t => { 73 t.add_cleanup(reset); 74 75 trackEvents(t, target0, ['pointerdown', 'mousedown', 'gotpointercapture', 'dragstart', 'pointercancel', 'lostpointercapture']); 76 on(t, target0, 'pointerdown', e => target0.setPointerCapture(e.pointerId)); 77 const lostCapturePromise = new Promise(resolve => { 78 on(t, target0, 'lostpointercapture', resolve); 79 }); 80 81 await performDrag(); 82 await lostCapturePromise; 83 84 assert_equals( 85 received_events.join(', '), 86 'pointerdown@target0, mousedown@target0, gotpointercapture@target0, dragstart@target0, pointercancel@target0, lostpointercapture@target0'); 87 }, 'Pointercancel and lostpointercapture should be fired with the expected order when drag operation starts (capture on pointerdown)'); 88 89 promise_test(async t => { 90 t.add_cleanup(reset); 91 let pointerId = -1; 92 93 trackEvents(t, target0, ['pointerdown', 'mousedown', 'gotpointercapture', 'dragstart', 'pointercancel', 'lostpointercapture']); 94 on(t, target0, 'pointerdown', e => { pointerId = e.pointerId; }); 95 on(t, target0, 'mousedown', e => { target0.setPointerCapture(pointerId); }); 96 const lostCapturePromise = new Promise(resolve => { 97 on(t, target0, 'lostpointercapture', resolve); 98 }); 99 100 await performDrag(); 101 await lostCapturePromise; 102 103 assert_equals(received_events.join(', '), 104 'pointerdown@target0, mousedown@target0, gotpointercapture@target0, dragstart@target0, pointercancel@target0, lostpointercapture@target0'); 105 }, 'Pointercancel and lostpointercapture should be fired with the expected order when drag operation starts (capture on mousedown)'); 106 107 promise_test(async t => { 108 t.add_cleanup(reset); 109 110 trackEvents(t, target0, ['pointerdown', 'mousedown', 'dragstart']); 111 trackEvents(t, target1, ['pointerup']); 112 on(t, target0, 'dragstart', e => e.preventDefault()); 113 const pointerUpPromise = new Promise(resolve => { 114 on(t, target1, 'pointerup', resolve); 115 }); 116 117 await performDrag(); 118 await pointerUpPromise; 119 120 assert_equals(received_events.join(', '), 121 'pointerdown@target0, mousedown@target0, dragstart@target0, pointerup@target1'); 122 }, 'Pointerevent stream should not get interrupted when drag is prevented.'); 123 </script>