1<!DOCTYPE HTML>
2<meta name="timeout" content="long">
3<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
4<script src="/resources/testharness.js"></script>
5<script src="/resources/testharnessreport.js"></script>
6<script src="/resources/testdriver.js"></script>
7<script src="/resources/testdriver-actions.js"></script>
8<script src="/resources/testdriver-vendor.js"></script>
9<script src="scroll_support.js"></script>
10<style>
11html {
12  height: 3000px;
13  width: 3000px;
14}
15#targetDiv {
16  width: 200px;
17  height: 200px;
18  overflow: scroll;
19}
20
21#innerDiv {
22  width: 400px;
23  height: 400px;
24}
25</style>
26
27<body style="margin:0" onload=runTest()>
28<div id="targetDiv">
29  <div id="innerDiv">
30  </div>
31</div>
32</body>
33<script>
34var element_scrollend_arrived = false;
35var document_scrollend_arrived = false;
36
37function onElementScrollEnd(event) {
38  assert_false(event.cancelable);
39  assert_false(event.bubbles);
40  element_scrollend_arrived = true;
41}
42
43function onDocumentScrollEnd(event) {
44  assert_false(event.cancelable);
45  // scrollend events are bubbled when the target node is document.
46  assert_true(event.bubbles);
47  document_scrollend_arrived = true;
48}
49
50function callScrollFunction([scrollTarget, scrollFunction, args]) {
51  scrollTarget[scrollFunction](args);
52}
53
54function runTest() {
55  let root_element = document.scrollingElement;
56  let target_div = document.getElementById("targetDiv");
57
58  promise_test (async (t) => {
59    await waitForCompositorCommit();
60    target_div.addEventListener("scrollend", onElementScrollEnd);
61    document.addEventListener("scrollend", onDocumentScrollEnd);
62
63    let test_cases = [
64      [target_div, 200, 200, [target_div, "scrollTo", { top: 200, left: 200, behavior: "auto" }]],
65      [target_div, 0, 0, [target_div, "scrollTo", { top: 0, left: 0, behavior: "smooth" }]],
66      [root_element, 200, 200, [root_element, "scrollTo", { top: 200, left: 200, behavior: "auto" }]],
67      [root_element, 0, 0, [root_element, "scrollTo", { top: 0, left: 0, behavior: "smooth" }]],
68      [target_div, 200, 200, [target_div, "scrollBy", { top: 200, left: 200, behavior: "auto" }]],
69      [target_div, 0, 0, [target_div, "scrollBy", { top: -200, left: -200, behavior: "smooth" }]],
70      [root_element, 200, 200, [root_element, "scrollBy", { top: 200, left: 200, behavior: "auto" }]],
71      [root_element, 0, 0, [root_element, "scrollBy", { top: -200, left: -200, behavior: "smooth" }]]
72    ];
73
74    for(i = 0; i < test_cases.length; i++) {
75      let t = test_cases[i];
76      let target = t[0];
77      let expected_x = t[1];
78      let expected_y = t[2];
79      let scroll_datas = t[3];
80
81      callScrollFunction(scroll_datas);
82      await waitFor(() => { return element_scrollend_arrived || document_scrollend_arrived; }, target.tagName + "." + scroll_datas[1] + " did not receive scrollend event.");
83      if (target == root_element)
84        assert_false(element_scrollend_arrived);
85      else
86        assert_false(document_scrollend_arrived);
87      assert_equals(target.scrollLeft, expected_x, target.tagName + "." + scroll_datas[1] + " scrollLeft");
88      assert_equals(target.scrollTop, expected_y, target.tagName + "." + scroll_datas[1] + " scrollTop");
89
90      element_scrollend_arrived = false;
91      document_scrollend_arrived = false;
92    }
93  }, "Tests scrollend event for calling scroll functions.");
94
95  promise_test(async (t) => {
96    await waitForCompositorCommit();
97
98    let test_cases = [
99      [target_div, "scrollTop"],
100      [target_div, "scrollLeft"],
101      [root_element, "scrollTop"],
102      [root_element, "scrollLeft"]
103    ];
104    for (i = 0; i < test_cases.length; i++) {
105      let t = test_cases[i];
106      let target = t[0];
107      let attribute = t[1];
108      let position = 200;
109
110      target.style.scrollBehavior = "smooth";
111      target[attribute] = position;
112      await waitFor(() => { return element_scrollend_arrived || document_scrollend_arrived; }, target.tagName + "." + attribute + " did not receive scrollend event.");
113      if (target == root_element)
114        assert_false(element_scrollend_arrived);
115      else
116        assert_false(document_scrollend_arrived);
117      assert_equals(target[attribute], position, target.tagName + "." + attribute + " ");
118      element_scrollend_arrived = false;
119      document_scrollend_arrived = false;
120
121      await waitForCompositorCommit();
122      target.style.scrollBehavior = "auto";
123      target[attribute] = 0;
124      await waitFor(() => { return element_scrollend_arrived || document_scrollend_arrived; }, target.tagName + "." + attribute + " did not receive scrollend event.");
125      if (target == root_element)
126        assert_false(element_scrollend_arrived);
127      else
128        assert_false(document_scrollend_arrived);
129      assert_equals(target[attribute], 0, target.tagName + "." + attribute + " ");
130      element_scrollend_arrived = false;
131      document_scrollend_arrived = false;
132    }
133  }, "Tests scrollend event for changing scroll attributes.");
134}
135</script>
136