save-iframe-scroll-offset-when-display-none.html (2816B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title>Ensure that the scroll position isn't lost when the iframe is set to display:none and shown again</title> 4 <link rel="author" href="mailto:perryuwang@gmail.com"> 5 <link rel="help" href="https://issues.chromium.org/issues/41368291"> 6 <script src="scroll_support.js"></script> 7 <script src="/common/get-host-info.sub.js"></script> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 11 <div> 12 <iframe id="frame"></iframe> 13 </div> 14 15 <script> 16 const IFRAME_PATH = '/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.sub.html'; 17 18 function waitForFrameLoadAsync(frame) { 19 return new Promise(async (resolve) => { 20 frame.addEventListener('load', resolve, { once: true }); 21 }); 22 } 23 24 function waitForMessageAsync(expected_frame_id, expected_command) { 25 return new Promise((resolve) => { 26 window.addEventListener('message', (event) => { 27 assert_equals(event.data.command, expected_command); 28 assert_equals(event.data.frame_id, expected_frame_id); 29 resolve({scrollX: event.data.scrollX, scrollY: event.data.scrollY}); 30 }, { once: true }); 31 }); 32 } 33 34 function iframeScrollTo(frame, x, y) { 35 return new Promise(async (resolve) => { 36 const scroll_ack_waiter = waitForMessageAsync(frame.id, 'scrollTo'); 37 await frame.contentWindow.postMessage({ 38 command: 'scrollTo', 39 frame_id: frame.id, 40 scrollX: x, 41 scrollY: y, 42 }, '*'); 43 const ret = await scroll_ack_waiter; 44 resolve(ret); 45 }); 46 } 47 48 function iframeGetScroll(frame) { 49 return new Promise(async (resolve) => { 50 const scroll_ack_waiter = waitForMessageAsync(frame.id, 'getScroll'); 51 await frame.contentWindow.postMessage({ 52 command: 'getScroll', 53 frame_id: frame.id, 54 }, '*'); 55 const ret = await scroll_ack_waiter; 56 resolve(ret); 57 }); 58 } 59 60 async function testIFrame(src) { 61 const frame = document.getElementById('frame'); 62 frame.src = src; 63 await waitForFrameLoadAsync(frame); 64 let ret = await iframeScrollTo(frame, 1000, 2000); 65 assert_equals(ret.scrollX, 1000); 66 assert_equals(ret.scrollY, 2000); 67 frame.style.display = 'none'; 68 await waitForCompositorCommit(); 69 frame.style.display = ''; 70 await waitForCompositorCommit(); 71 ret = await iframeGetScroll(frame); 72 assert_equals(ret.scrollX, 1000); 73 assert_equals(ret.scrollY, 2000); 74 } 75 76 window.onload = async () => { 77 promise_test(async () => { 78 await testIFrame(IFRAME_PATH); 79 }, 'Ensure that the scroll position is not lost when the local iframe is set to display:none and shown again.'); 80 81 promise_test(async () => { 82 await testIFrame(get_host_info().HTTP_NOTSAMESITE_ORIGIN + IFRAME_PATH); 83 }, 'Ensure that the scroll position is not lost when the remote iframe is set to display:none and shown again.'); 84 } 85 </script>