pointerevent_pointerId_scope.html (6298B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>Pointer Events pointerdown tests</title> 5 <meta name="viewport" content="width=device-width"> 6 <link rel="stylesheet" type="text/css" href="pointerevent_styles.css"> 7 <link rel="help" href="https://w3c.github.io/pointerevents/#dom-pointerevent-pointerid"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/resources/testdriver.js"></script> 11 <script src="/resources/testdriver-actions.js"></script> 12 <script src="/resources/testdriver-vendor.js"></script> 13 <!-- Additional helper script for common checks across event types --> 14 <script type="text/javascript" src="pointerevent_support.js"></script> 15 <script> 16 "use strict" 17 18 function loadFrame() { 19 return new Promise(resolve => { 20 const innerframe = document.getElementById("innerframe"); 21 innerframe.onload = resolve; 22 innerframe.src = 23 "resources/pointerevent_pointerId_scope-iframe.html"; 24 }); 25 } 26 27 const eventList = [ 28 'pointerenter', 29 'pointerover', 30 'pointermove', 31 'pointerout', 32 'pointerleave' 33 ]; 34 35 function recordEvents(test) { 36 const target0 = document.getElementById("target0"); 37 const innerframe = document.getElementById("innerframe"); 38 let activePointerId = undefined; 39 let activePointerType = undefined; 40 const eventsReceived = { 41 'inner': {}, 42 'outer': {}, 43 }; 44 45 // Records the last event of a given type in the case of multiple 46 // events. 47 const recordEvent = (event, context) => { 48 if (activePointerId === undefined) { 49 activePointerId = event.pointerId; 50 } 51 if (activePointerType == undefined) { 52 activePointerType= event.pointerType; 53 } 54 eventsReceived[context][event.type] = { 55 pointerId: event.pointerId, 56 pointerType: event.pointerType 57 }; 58 } 59 60 const listener = (event) => { 61 recordEvent(event, 'outer'); 62 }; 63 eventList.forEach(eventType => { 64 target0.addEventListener(eventType, listener); 65 }); 66 67 const messageListener = (event) => { 68 if (event.source != innerframe.contentWindow) { 69 return; 70 } 71 recordEvent(event.data, 'inner'); 72 }; 73 window.addEventListener('message', messageListener); 74 75 test.add_cleanup(() => { 76 eventList.forEach(eventType => { 77 target0.removeEventListener(eventType, listener); 78 }); 79 window.removeEventListener('message', messageListener); 80 }); 81 82 return new Promise(resolve => { 83 document.addEventListener('pointerup', () => { 84 // As pointer events for the inner frame are routed via a post 85 // message, the outer frame won't see the event until the following 86 // event processing loop. Allow 2 additional animation frames to 87 // ensure adequate time to receive the events. 88 waitForAnimationFrames(2).then(() => { 89 eventsReceived.activePointerId = activePointerId; 90 eventsReceived.activePointerType = activePointerType; 91 resolve(eventsReceived); 92 }); 93 }, { once: true }); 94 }); 95 96 }; 97 98 async function run() { 99 await loadFrame(); 100 101 const target0 = document.getElementById("target0"); 102 const innerframe = document.getElementById("innerframe"); 103 const target1 = 104 innerframe.contentWindow.document.getElementsByTagName("div")[0]; 105 106 promise_test(async t => { 107 const results = recordEvents(t); 108 // Move from the target in the outer-frame to a target in the inner- 109 // frame, click on second target, move back to the first and click. 110 // The inner target is not centered in the iframe, thus its position 111 // needs to be calculated. 112 const iframeRect = innerframe.getClientRects()[0]; 113 const rect = target1.getClientRects()[0]; 114 const center_x = 115 Math.round(iframeRect.left + (rect.left + rect.right) / 2); 116 const center_y = 117 Math.round(iframeRect.top + (rect.top + rect.bottom) / 2); 118 119 await new test_driver.Actions() 120 .pointerMove(0, 0, { origin: target0 }) 121 .pointerMove(center_x, center_y) 122 .pointerDown() 123 .pointerUp() 124 .pointerMove(0, 0, { origin: target0 }) 125 .pointerDown() 126 .pointerUp() 127 .send(); 128 129 const events = await results; 130 131 assert_equals( 132 Object.keys(events.outer).length, eventList.length, 133 "Missing events for outer target"); 134 assert_equals( 135 Object.keys(events.inner).length, eventList.length, 136 "Missing events for inner target"); 137 138 const activePointerId = events.activePointerId; 139 const activePointerType = events.activePointerType; 140 eventList.forEach(eventName => { 141 assert_equals( 142 events.inner[eventName].pointerId, activePointerId, 143 `PointerId of ${eventName} in the inner frame is not correct`); 144 assert_equals( 145 events.outer[eventName].pointerId, activePointerId, 146 `PointerId of ${eventName} in the outer frame is not correct`); 147 assert_equals( 148 events.inner[eventName].pointerType, activePointerType, 149 `PointerType of ${eventName} in the inner frame is not correct`); 150 assert_equals( 151 events.outer[eventName].pointerType, activePointerType, 152 `PointerType of ${eventName} in the outer frame is not correct`); 153 }); 154 }, 'pointerId of an active pointer is the same across same origin ' + 155 'frames'); 156 } 157 </script> 158 </head> 159 <body onload="run()"> 160 <h1>Pointer Events pointer ID tests</h1> 161 <div id="target0" class="touchActionNone"></div> 162 <!-- Document onload does not guarantee that child iframes have loaded. 163 Force synchronization by deferring setting the iframe's source 164 until a promise is set up to capture its load event. The root 165 document will load first, then the iframe. This ordering ensures 166 deterministic behavior. 167 --> 168 <iframe id="innerframe"></iframe> 169 </body> 170 </html>