summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_touch_action_complex.html
blob: b8df34bfcae7582e3e7c230efa585792b92e69b3 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width; initial-scale=1.0">
  <title>Complex touch-action test</title>
  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
  <script type="application/javascript" src="apz_test_utils.js"></script>
  <script src="/tests/SimpleTest/paint_listener.js"></script>
  <script type="application/javascript">

function checkScroll(target, x, y, desc) {
  is(target.scrollLeft, x, desc + " - x axis");
  is(target.scrollTop, y, desc + " - y axis");
}

async function resetConfiguration(config) {
  // Cycle through all the configuration_X elements, setting them to display:none
  // except for when X == config, in which case set it to display:block
  var i = 0;
  while (true) {
    i++;
    var element = document.getElementById("configuration_" + i);
    if (element == null) {
      if (i <= config) {
        ok(false, "The configuration requested was not encountered!");
      }
      break;
    }

    if (i == config) {
      element.style.display = "block";
    } else {
      element.style.display = "none";
    }
  }

  // Also reset the scroll position on the scrollframe
  var s = document.getElementById("scrollframe");
  s.scrollLeft = 0;
  s.scrollTop = 0;

  await promiseAllPaintsDone();
  await promiseApzFlushedRepaints();
}

async function test() {
  var scrollframe = document.getElementById("scrollframe");

  // Helper function for the tests below.
  // Touch-pan configuration |configuration| towards scroll offset (dx, dy) with
  // the pan touching down at (x, y). Check that the final scroll offset is
  // (ex, ey). |desc| is some description string.
  async function scrollAndCheck(configuration, x, y, dx, dy, ex, ey, desc) {
    // Start with a clean slate
    await resetConfiguration(configuration);
    // Reverse the touch delta in order to scroll in the desired direction
    dx = -dx;
    dy = -dy;
    // Do the pan
    let touchEndPromise = promiseTouchEnd(document.body);
    ok(await synthesizeNativeTouchDrag(scrollframe, x, y, dx, dy),
        "Synthesized drag of (" + dx + ", " + dy + ") on configuration " + configuration);
    await touchEndPromise;
    await promiseAllPaintsDone();
    await promiseOnlyApzControllerFlushed();
    // Check for expected scroll position
    checkScroll(scrollframe, ex, ey, "configuration " + configuration + " " + desc);
  }

  // Test configuration_1, which contains two sibling elements that are
  // overlapping. The touch-action from the second sibling (which is on top)
  // should be used for the overlapping area.
  await scrollAndCheck(1, 25, 75, 20, 0, 20, 0, "first element horizontal scroll");
  await scrollAndCheck(1, 25, 75, 0, 50, 0, 0, "first element vertical scroll");
  await scrollAndCheck(1, 75, 75, 50, 0, 0, 0, "overlap horizontal scroll");
  await scrollAndCheck(1, 75, 75, 0, 50, 0, 50, "overlap vertical scroll");
  await scrollAndCheck(1, 125, 75, 20, 0, 0, 0, "second element horizontal scroll");
  await scrollAndCheck(1, 125, 75, 0, 50, 0, 50, "second element vertical scroll");

  // Test configuration_2, which contains two overlapping elements with a
  // parent/child relationship. The parent has pan-x and the child has pan-y,
  // which means that panning on the parent should work horizontally only, and
  // on the child no panning should occur at all.
  await scrollAndCheck(2, 125, 125, 50, 50, 0, 0, "child scroll");
  await scrollAndCheck(2, 75, 75, 50, 50, 0, 0, "overlap scroll");
  await scrollAndCheck(2, 25, 75, 0, 50, 0, 0, "parent vertical scroll");
  await scrollAndCheck(2, 75, 25, 50, 0, 50, 0, "parent horizontal scroll");

  // Test configuration_3, which is the same as configuration_2, except the child
  // has a rotation transform applied. This forces the event regions on the two
  // elements to be built separately and then get merged.
  await scrollAndCheck(3, 125, 125, 50, 50, 0, 0, "child scroll");
  await scrollAndCheck(3, 75, 75, 50, 50, 0, 0, "overlap scroll");
  await scrollAndCheck(3, 25, 75, 0, 50, 0, 0, "parent vertical scroll");
  await scrollAndCheck(3, 75, 25, 50, 0, 50, 0, "parent horizontal scroll");

  // Test configuration_4 has two elements, one above the other, not overlapping,
  // and the second element is a child of the first. The parent has pan-x, the
  // child has pan-y, but that means panning horizontally on the parent should
  // work and panning in any direction on the child should not do anything.
  await scrollAndCheck(4, 75, 75, 50, 50, 50, 0, "parent diagonal scroll");
  await scrollAndCheck(4, 75, 150, 50, 50, 0, 0, "child diagonal scroll");
}

waitUntilApzStable()
.then(test)
.then(subtestDone, subtestFailed);

  </script>
</head>
<body>
 <div id="scrollframe" style="width: 300px; height: 300px; overflow:scroll">
  <div id="scrolled_content" style="width: 1000px; height: 1000px; background-color: green">
  </div>
  <div id="configuration_1" style="display:none; position: relative; top: -1000px">
   <div style="touch-action: pan-x; width: 100px; height: 100px; background-color: blue"></div>
   <div style="touch-action: pan-y; width: 100px; height: 100px; position: relative; top: -100px; left: 50px; background-color: yellow"></div>
  </div>
  <div id="configuration_2" style="display:none; position: relative; top: -1000px">
   <div style="touch-action: pan-x; width: 100px; height: 100px; background-color: blue">
    <div style="touch-action: pan-y; width: 100px; height: 100px; position: relative; top: 50px; left: 50px; background-color: yellow"></div>
   </div>
  </div>
  <div id="configuration_3" style="display:none; position: relative; top: -1000px">
   <div style="touch-action: pan-x; width: 100px; height: 100px; background-color: blue">
    <div style="touch-action: pan-y; width: 100px; height: 100px; position: relative; top: 50px; left: 50px; background-color: yellow; transform: rotate(90deg)"></div>
   </div>
  </div>
  <div id="configuration_4" style="display:none; position: relative; top: -1000px">
   <div style="touch-action: pan-x; width: 100px; height: 100px; background-color: blue">
    <div style="touch-action: pan-y; width: 100px; height: 100px; position: relative; top: 125px; background-color: yellow"></div>
   </div>
  </div>
 </div>
</body>
</html>