summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_scroll_linked_effect_detector.html
blob: aaa4b43829dafd7e156028bbd9c15a503bc0a55c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<script src="/tests/SimpleTest/paint_listener.js"></script>
<script src="apz_test_utils.js"></script>
<script src="apz_test_native_event_utils.js"></script>
<title>ScrollLinkedEffectDetector tests</title>
<style>
html, body { margin: 0; }
body {
  height: 1000vh;
}
#target {
  position: absolute;
  height: 800px;
  background-color: #cc00cc;
  top: 0;
  left: 0;
  right: 0;
}
</style>
<div id="target"></div>
<script>
async function test() {
  let eventTimeStamp;
  // Utility function to synthesize a scroll and call the given function
  // in the event listener.
  async function promiseScrollAndEvent(fn) {
    let scrollEventPromise = new Promise(resolve => {
      window.addEventListener("scroll", () => {
        fn();
        resolve();
      }, { once: true });
    });
    await scrollEventPromise;
    // Wait a rAF to make sure we are outside of the micro tasks for the scroll
    // event callback so that we can ensure our stack based
    // ScrollLinkedEffectDetector has been scoped out from the function firing
    // scroll events.
    await promiseFrame();
  }

  let intervalId = setInterval(async () => {
    await synthesizeNativeWheel(window, 50, 50, 0, -10);
  }, 0);
  await promiseScrollAndEvent(() => {
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(!SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "No scroll-linked effect found yet");

  // Setup a scroll-linked effect callback.
  await promiseScrollAndEvent(() => {
    isnot(window.scrollY, 0, "we've already scrolled some amount");
    target.style.top = window.scrollY + "px";
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "Scroll-linked effect found");

  // A no-op again.
  await promiseScrollAndEvent(() => {
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(!SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "No scroll-linked effect found");

  // Setup a non-effective scroll-linked effect callback.
  await promiseScrollAndEvent(() => {
    target.style.top = getComputedStyle(target).top;
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(!SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "No scroll-linked effect found");

  // Setup a callback to remove the style.
  await promiseScrollAndEvent(() => {
    target.style.top = "";
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "Scroll-linked effect found");

  // Setup a no-op callback.
  await promiseScrollAndEvent(() => {
    eventTimeStamp = document.timeline.currentTime;
  });
  is(eventTimeStamp, document.timeline.currentTime,
     `We are in same time frame where we got a scroll event at ${eventTimeStamp}`);
  ok(!SpecialPowers.DOMWindowUtils.hasScrollLinkedEffect,
     "No scroll-linked effect found this time");
  clearInterval(intervalId);
}

waitUntilApzStable()
.then(test)
.then(subtestDone, subtestFailed);
</script>