1<!DOCTYPE HTML>
2<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
3<script src="/resources/testharness.js"></script>
4<script src="/resources/testharnessreport.js"></script>
5<script src="/resources/testdriver.js"></script>
6<script src="/resources/testdriver-actions.js"></script>
7<script src="/resources/testdriver-vendor.js"></script>
8<script src="scroll_support.js"></script>
9<style>
10#rootDiv {
11  width: 500px;
12  height: 500px;
13}
14
15#targetDiv {
16  width: 200px;
17  height: 200px;
18  overflow: scroll;
19}
20
21#innerDiv {
22  width: 500px;
23  height: 4000px;
24}
25</style>
26
27<body style="margin:0" onload=runTest()>
28</body>
29
30<script>
31let scrollend_arrived = false;
32
33async function setupHtmlAndScrollAndRemoveElement(element_to_remove_id) {
34  document.body.innerHTML=`
35    <div id="rootDiv">
36      <div id="targetDiv">
37        <div id="innerDiv">
38        </div>
39      </div>
40    </div>
41  `;
42  await waitForCompositorCommit();
43
44  const target_div = document.getElementById('targetDiv');
45  const element_to_remove = document.getElementById(element_to_remove_id);
46  let reached_half_scroll = false;
47  scrollend_arrived = false;
48
49  target_div.addEventListener("scrollend", () => {
50    scrollend_arrived = true;
51  });
52
53  target_div.onscroll = () => {
54    // Remove the element after reached half of the scroll offset,
55    if(target_div.scrollTop >= 1000) {
56      reached_half_scroll = true;
57      element_to_remove.remove();
58    }
59  };
60
61  target_div.scrollTo({top:2000, left:0, behavior:"smooth"});
62  await waitFor(() => {return reached_half_scroll; },
63    "target_div never reached scroll offset of 1000");
64  await waitForCompositorCommit();
65}
66
67function runTest() {
68  promise_test (async (t) => {
69    await setupHtmlAndScrollAndRemoveElement("rootDiv");
70    await conditionHolds(() => { return !scrollend_arrived; });
71  }, "No scrollend is received after removing parent div");
72
73  promise_test (async (t) => {
74    await setupHtmlAndScrollAndRemoveElement("targetDiv");
75    await conditionHolds(() => { return !scrollend_arrived; });
76  }, "No scrollend is received after removing scrolling element");
77
78  promise_test (async (t) => {
79    await setupHtmlAndScrollAndRemoveElement("innerDiv");
80    await waitFor(() => { return scrollend_arrived; },
81        'target_div did not receive scrollend event after vertical scroll.');
82  }, "scrollend is received after removing descendant div");
83}
84</script>
85