| <!DOCTYPE html> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="./resources/intersection-observer-test-utils.js"></script> | |
| <style> | |
| pre, #log { | |
| position: absolute; | |
| top: 0; | |
| left: 200px; | |
| } | |
| .spacer { | |
| height: calc(100vh + 100px); | |
| } | |
| </style> | |
| <div id="leading-space" class="spacer"></div> | |
| <div id="trailing-space" class="spacer"></div> | |
| <script> | |
| // Pick this number to be comfortably greater than the length of two frames at 60Hz. | |
| var timeSkew = 40; | |
| var topWindowEntries = []; | |
| var iframeWindowEntries = []; | |
| var targetIframe; | |
| var topWindowTimeBeforeNotification; | |
| var iframeWindowTimeBeforeNotification; | |
| async_test(function(t) { | |
| t.step_timeout(function() { | |
| targetIframe = document.createElement("iframe"); | |
| assert_true(!!targetIframe, "iframe exists"); | |
| targetIframe.src = "resources/timestamp-subframe.html"; | |
| var trailingSpace = document.getElementById("trailing-space"); | |
| assert_true(!!trailingSpace, "trailing-space exists"); | |
| trailingSpace.parentNode.insertBefore(targetIframe, trailingSpace); | |
| targetIframe.onload = function() { | |
| var target = targetIframe.contentDocument.getElementById("target"); | |
| var iframeScroller = targetIframe.contentDocument.scrollingElement; | |
| // Observer created here, callback created in iframe context. Timestamps should be | |
| // from this window. | |
| var observer = new IntersectionObserver( | |
| targetIframe.contentDocument.createObserverCallback(topWindowEntries), {}); | |
| assert_true(!!observer, "Observer exists"); | |
| observer.observe(target); | |
| // Callback created here, observer created in iframe. Timestamps should be | |
| // from iframe window. | |
| observer = targetIframe.contentDocument.createObserver(function(newEntries) { | |
| iframeWindowEntries = iframeWindowEntries.concat(newEntries); | |
| }); | |
| observer.observe(target); | |
| runTestCycle(step1, "First rAF after iframe is loaded."); | |
| t.done(); | |
| }; | |
| }, timeSkew); | |
| }, "Check that timestamps correspond to the to execution context that created the observer."); | |
| function step1() { | |
| document.scrollingElement.scrollTop = 200; | |
| targetIframe.contentDocument.scrollingElement.scrollTop = 250; | |
| topWindowTimeBeforeNotification = performance.now(); | |
| iframeWindowTimeBeforeNotification = targetIframe.contentWindow.performance.now(); | |
| runTestCycle(step2, "Generate notifications."); | |
| assert_equals(topWindowEntries.length, 1, "One notification to top window observer."); | |
| assert_equals(iframeWindowEntries.length, 1, "One notification to iframe observer."); | |
| } | |
| function step2() { | |
| document.scrollingElement.scrollTop = 0; | |
| var topWindowTimeAfterNotification = performance.now(); | |
| var iframeWindowTimeAfterNotification = targetIframe.contentWindow.performance.now(); | |
| assert_approx_equals( | |
| topWindowEntries[1].time - topWindowTimeBeforeNotification, | |
| iframeWindowEntries[1].time - iframeWindowTimeBeforeNotification, | |
| // Since all intersections are computed in a tight loop between 2 frames, | |
| // an epsilon of 16ms (the length of one frame at 60Hz) turned out to be | |
| // reliable, even at slow frame rates. | |
| 16, | |
| "Notification times are relative to the expected time origins"); | |
| assert_equals(topWindowEntries.length, 2, "Top window observer has two notifications."); | |
| assert_between_inclusive( | |
| topWindowEntries[1].time, | |
| topWindowTimeBeforeNotification, | |
| topWindowTimeAfterNotification, | |
| "Notification to top window observer is within the expected range."); | |
| assert_equals(iframeWindowEntries.length, 2, "Iframe observer has two notifications."); | |
| assert_between_inclusive( | |
| iframeWindowEntries[1].time, | |
| iframeWindowTimeBeforeNotification, | |
| iframeWindowTimeAfterNotification, | |
| "Notification to iframe observer is within the expected range."); | |
| } | |
| </script> |