blob: 3f573bcd88ff1781e03be03f1adeccfab8e5ba84 [file] [log] [blame]
Xiaoming Shi73dfa202020-03-12 11:31:35 -07001<!DOCTYPE html>
2<meta name="viewport" content="width=device-width,initial-scale=1">
3<script src="/resources/testharness.js"></script>
4<script src="/resources/testharnessreport.js"></script>
5<script src="./resources/intersection-observer-test-utils.js"></script>
6
7<style>
8pre, #log {
9 position: absolute;
10 top: 0;
11 left: 200px;
12}
13.spacer {
14 height: calc(100vh + 100px);
15}
16
17</style>
18<div id="leading-space" class="spacer"></div>
19<div id="trailing-space" class="spacer"></div>
20
21<script>
22// Pick this number to be comfortably greater than the length of two frames at 60Hz.
23var timeSkew = 40;
24
25var topWindowEntries = [];
26var iframeWindowEntries = [];
27var targetIframe;
28var topWindowTimeBeforeNotification;
29var iframeWindowTimeBeforeNotification;
30
31async_test(function(t) {
32 t.step_timeout(function() {
33 targetIframe = document.createElement("iframe");
34 assert_true(!!targetIframe, "iframe exists");
35 targetIframe.src = "resources/timestamp-subframe.html";
36 var trailingSpace = document.getElementById("trailing-space");
37 assert_true(!!trailingSpace, "trailing-space exists");
38 trailingSpace.parentNode.insertBefore(targetIframe, trailingSpace);
39 targetIframe.onload = function() {
40 var target = targetIframe.contentDocument.getElementById("target");
41 var iframeScroller = targetIframe.contentDocument.scrollingElement;
42
43 // Observer created here, callback created in iframe context. Timestamps should be
44 // from this window.
45 var observer = new IntersectionObserver(
46 targetIframe.contentDocument.createObserverCallback(topWindowEntries), {});
47 assert_true(!!observer, "Observer exists");
48 observer.observe(target);
49
50 // Callback created here, observer created in iframe. Timestamps should be
51 // from iframe window.
52 observer = targetIframe.contentDocument.createObserver(function(newEntries) {
53 iframeWindowEntries = iframeWindowEntries.concat(newEntries);
54 });
55 observer.observe(target);
56 runTestCycle(step1, "First rAF after iframe is loaded.");
57 t.done();
58 };
59 }, timeSkew);
60}, "Check that timestamps correspond to the to execution context that created the observer.");
61
62function step1() {
63 document.scrollingElement.scrollTop = 200;
64 targetIframe.contentDocument.scrollingElement.scrollTop = 250;
65 topWindowTimeBeforeNotification = performance.now();
66 iframeWindowTimeBeforeNotification = targetIframe.contentWindow.performance.now();
67 runTestCycle(step2, "Generate notifications.");
68 assert_equals(topWindowEntries.length, 1, "One notification to top window observer.");
69 assert_equals(iframeWindowEntries.length, 1, "One notification to iframe observer.");
70}
71
72function step2() {
73 document.scrollingElement.scrollTop = 0;
74 var topWindowTimeAfterNotification = performance.now();
75 var iframeWindowTimeAfterNotification = targetIframe.contentWindow.performance.now();
76
77 assert_approx_equals(
78 topWindowEntries[1].time - topWindowTimeBeforeNotification,
79 iframeWindowEntries[1].time - iframeWindowTimeBeforeNotification,
80 // Since all intersections are computed in a tight loop between 2 frames,
81 // an epsilon of 16ms (the length of one frame at 60Hz) turned out to be
82 // reliable, even at slow frame rates.
83 16,
84 "Notification times are relative to the expected time origins");
85
86 assert_equals(topWindowEntries.length, 2, "Top window observer has two notifications.");
87 assert_between_inclusive(
88 topWindowEntries[1].time,
89 topWindowTimeBeforeNotification,
90 topWindowTimeAfterNotification,
91 "Notification to top window observer is within the expected range.");
92
93 assert_equals(iframeWindowEntries.length, 2, "Iframe observer has two notifications.");
94 assert_between_inclusive(
95 iframeWindowEntries[1].time,
96 iframeWindowTimeBeforeNotification,
97 iframeWindowTimeAfterNotification,
98 "Notification to iframe observer is within the expected range.");
99}
100</script>