File: new-scroll-event-dispatched-at-next-updating-rendering-time.html

package info (click to toggle)
thunderbird 1%3A140.4.0esr-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie-proposed-updates
  • size: 4,609,412 kB
  • sloc: cpp: 7,672,442; javascript: 5,901,613; ansic: 3,898,954; python: 1,413,343; xml: 653,997; asm: 462,286; java: 180,927; sh: 113,489; makefile: 20,460; perl: 14,288; objc: 13,059; yacc: 4,583; pascal: 3,352; lex: 1,720; ruby: 1,222; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 70; csh: 10
file content (116 lines) | stat: -rw-r--r-- 4,080 bytes parent folder | download | duplicates (10)
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
109
110
111
112
113
114
115
116
<!doctype html>
<meta charset="utf-8">
<link rel="help" href="https://html.spec.whatwg.org/#event-loop-processing-model">
<link rel="help" href="https://issues.chromium.org/issues/397737222">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
</style>
<iframe width="300" height="300" srcdoc="
  <style>
    html {
      transition: color 1s step-start;
    }
    .scroller {
      overflow: auto;
      width: 100%;
      height: 100px;
    }
    .spacer {
      height: 500px;
    }
  </style>
  <div class='scroller'>
    <div class='spacer'></div>
  </div>
  <div class='scroller'>
    <div class='spacer'></div>
  </div>
  "></iframe>
<script>
promise_test(async function() {
  await new Promise(resolve => window.addEventListener("load", resolve, { once: true }));

  const iframe = document.querySelector("iframe");
  const mql = iframe.contentWindow.matchMedia("(max-width: 300px)");
  assert_true(mql.matches, "");

  // Set up a MQL change event listener to receive the event in between
  // scroll and transitionrun events.
  let timeOnMQLChange = null;
  iframe.width = "400";
  const mqlChangeEvent = new Promise(resolve => {
    mql.addEventListener("change", () => {
      timeOnMQLChange = performance.now();
      resolve();
    }, { once: true });
  });

  // There are two scroll containers, setup a scroll event listener for one
  // of them.
  const scrollers = iframe.contentDocument.querySelectorAll(".scroller");
  let timeOnScrollEventOnAnotherScroller = null;
  scrollers[1].addEventListener("scroll", () => {
    timeOnScrollEventOnAnotherScroller = performance.now();
  }, { once: true });

  // Setup another scroll event listener for the other scroll container.
  const scrollEventPromise = new Promise(resolve => {
    scrollers[0].addEventListener("scroll", resolve, { once: true });
  });
  // And scroll the scroller.
  scrollers[0].scrollTop = 10;

  // Await the scroll event.
  await scrollEventPromise;

  const timeOnScrollEvent = performance.now();

  // Scroll the other scroller.
  scrollers[1].scrollTop = 10;

  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    "The new scroll event should not yet have been dispatched");

  // Trigger a CSS transition.
  let timeOnTransitionRun = null;
  const transitionrunEventPromise = new Promise(resolve => {
    iframe.contentDocument.documentElement.addEventListener("transitionrun", () => {
      timeOnTransitionRun = performance.now();
      resolve();
    }, { once: true });
  });
  iframe.contentDocument.documentElement.style.color = "blue";
  getComputedStyle(iframe.contentDocument.documentElement).color;

  // Now it's time to receive the MQL change event.
  await mqlChangeEvent;
  assert_less_than(timeOnScrollEvent, timeOnMQLChange,
    "The MQL change event should have been dispatched after the first scroll event");
  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    "The new scroll event should not yet have been dispatched");

  // Await the transitionrun event.
  await transitionrunEventPromise;

  assert_less_than(timeOnScrollEvent, timeOnTransitionRun,
    "The transitionrun event should have been dispatched after the first scroll event");
  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    "The new scroll event should not yet have been dispatched");

  // Await a requestAnimationFrame callback.
  await new Promise(resolve => requestAnimationFrame(resolve));

  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    "The new scroll event should not yet have been dispatched");

  // Await one more requestAnimationFrame callback.
  await new Promise(resolve => requestAnimationFrame(resolve));

  assert_not_equals(timeOnScrollEventOnAnotherScroller, null,
    "The new scroll event should now have been dispatched");
  assert_less_than(timeOnTransitionRun, timeOnScrollEventOnAnotherScroller,
    "The new scroll event should have been dispatched after the transitionrun event");
});
</script>