9e79010371e7813460eb426a747c5665602cd042
[WebKit-https.git] / LayoutTests / tiled-drawing / scrolling / latched-div-with-scroll-snap.html
1 <!DOCTYPE html>
2 <html>
3     <head>
4         <style>
5             .gallery {
6                 width: 200px;
7                 height: 200px;
8                 overflow-y: hidden;
9                 overflow-x: auto;
10                 margin-bottom: 2px;
11                 -webkit-scroll-snap-points-x: repeat(100%);
12                 -webkit-scroll-snap-type: mandatory;
13             }
14             .galleryDrawer {
15                 width: 1200px;
16                 height: 200px;
17             }
18             .colorBox {
19                 height: 200px;
20                 width: 200px;
21                 float: left;
22             }
23             #itemH0, #itemV0 { background-color: red; }
24             #itemH1, #itemV1 { background-color: green; }
25             #itemH2, #itemV2 { background-color: blue; }
26             #itemH3, #itemV3 { background-color: aqua; }
27             #itemH4, #itemV4 { background-color: yellow; }
28             #itemH5, #itemV5 { background-color: fuchsia; }
29         </style>
30         <script src="../../resources/js-test.js"></script>
31         <script>
32         window.jsTestIsAsync = true;
33
34         var divScrollPositionBeforeGlide;
35         var divScrollPositionBeforeSnap;
36         var divScrollPositionBeforeSecondaryMove;
37         var bottomDivScrollPositionBeforeSecondaryMove;
38
39         function locationInWindowCoordinates(element)
40         {
41             var position = {};
42             position.x = element.offsetLeft;
43             position.y = element.offsetTop;
44
45             while (element.offsetParent) {
46                 position.x = position.x + element.offsetParent.offsetLeft;
47                 position.y = position.y + element.offsetParent.offsetTop;
48                 if (element == document.getElementsByTagName("body")[0])
49                     break;
50
51                 element = element.offsetParent;
52             }
53
54             return position;
55         }
56
57
58         function checkForSecondaryScrollGlide(targetLabel)
59         {
60             var topDivTarget = document.getElementById("topTarget");
61
62             var actualTopPosition = topDivTarget.scrollLeft;
63             var expectedTopPosition = divScrollPositionBeforeSecondaryMove;
64
65             // The top div should NOT have scrolled (glided) to the next snap point.
66             if (actualTopPosition == expectedTopPosition)
67                 testPassed("top div did not move.");
68             else
69                 testFailed("top div was improperly latched. Expected " + expectedTopPosition + ", but got " + actualTopPosition);
70
71             var divTarget = document.getElementById("bottomTarget");
72
73             var actualPosition = divTarget.scrollLeft;
74             var expectedPosition = divTarget.clientWidth;
75
76             // The div should have scrolled (glided) to the next snap point.
77             if (actualPosition == expectedPosition)
78                 testPassed("div scrolled to next window.");
79             else
80                 testFailed("div did not honor snap points. Expected " + expectedPosition + ", but got " + actualPosition);
81
82             finishJSTest();
83         }
84
85         function performSwipeGestureOnElementEnd()
86         {
87             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'none', 'begin');
88             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'none', 'continue');
89             eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
90         }
91
92         function performSwipeGestureOnElement(divTarget)
93         {
94             var windowPosition = locationInWindowCoordinates(divTarget);
95             var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
96             var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
97
98             eventSender.monitorWheelEvents();
99             eventSender.mouseMoveTo(startPosX, startPosY);
100             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'began', 'none');
101             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
102             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
103             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
104             eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
105         }
106
107         function scrollInSecondDiv()
108         {
109             debug("Testing that latch moves to bottom div:");
110             var topDivTarget = document.getElementById("topTarget");
111             divScrollPositionBeforeSecondaryMove = topDivTarget.scrollLeft;
112
113             var divTarget = document.getElementById("bottomTarget");
114
115             performSwipeGestureOnElement(divTarget);
116
117             eventSender.callAfterScrollingCompletes(function() { 
118                 performSwipeGestureOnElementEnd();
119                 eventSender.callAfterScrollingCompletes(function() {
120                     setTimeout(function() { checkForSecondaryScrollGlide(); }, 10); 
121                 });
122             });           
123         }
124
125         function checkForScrollSnap()
126         {
127             var divTarget = document.getElementById("topTarget");
128
129             var actualPosition = divTarget.scrollLeft;
130
131             // The div should have snapped back to the previous position
132             if (actualPosition != divScrollPositionBeforeSnap) {
133                 testFailed("div did not snap back to proper location for " + divTarget +". Expected " + divScrollPositionBeforeSnap + ", but got " + actualPosition);
134                 finishJSTest();
135                 return;
136             } else
137                 testPassed("div honored snap points.");
138             scrollInSecondDiv();
139         }
140
141         function scrollSnapTest()
142         {
143             var divTarget = document.getElementById("topTarget");
144  
145             divScrollPositionBeforeSnap = divTarget.scrollLeft;
146
147             var windowPosition = locationInWindowCoordinates(divTarget);
148             var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
149             var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
150
151             eventSender.monitorWheelEvents();
152             eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
153             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'began', 'none');
154             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
155             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
156             eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
157             eventSender.callAfterScrollingCompletes(function() { checkForScrollSnap(); });
158         }
159
160         function checkForScrollGlide(targetLabel)
161         {
162             var divTarget = document.getElementById("topTarget");
163
164             var actualPosition = divTarget.scrollLeft;
165             var expectedPosition = divTarget.clientWidth;
166
167             // The div should have scrolled (glided) to the next snap point.
168             if (actualPosition == expectedPosition)
169                 testPassed("div scrolled to next window.");
170             else {
171                 testFailed("div did not honor snap points. Expected " + expectedPosition + ", but got " + actualPosition);
172                 finishJSTest();
173                 return;
174             }
175             scrollSnapTest();
176         }
177
178         function scrollGlideTest()
179         {
180             var divTarget = document.getElementById("topTarget");
181  
182             divScrollPositionBeforeGlide = divTarget.scrollLeft;
183
184             performSwipeGestureOnElement(divTarget);
185             eventSender.callAfterScrollingCompletes(function() { 
186                 performSwipeGestureOnElementEnd();
187                 eventSender.callAfterScrollingCompletes(function() {
188                     setTimeout(function() { checkForScrollGlide(); }, 10); 
189                 });
190             });           
191         }
192
193         function onLoad()
194         {
195             if (window.eventSender) {
196                 testRunner.dumpAsText();
197                 scrollGlideTest();
198             } else {
199                 var messageLocationH = document.getElementById('itemH0');
200                 var message = document.createElement('div');
201                 message.innerHTML = "<p>This test is better run under WebKitTestRunner.<br/>To manually test it, place the mouse pointer<br/>"
202                     + "inside the red region at the top of the page,<br/>and then use the mouse wheel or a two-finger<br/>swipe to make a"
203                     + "small swipe gesture with<br/>some momentum.<br/><br/>"
204                     + "The region should scroll to show a green region.<br/><br/>"
205                     + "Next, perform a small scroll gesture that does<br/>not involve momentum. You should begin to<br/>see one of the colors "
206                     + "to the side of the current<br/>green box. When you release the wheel, the<br/>region should scroll back to a single color.";
207                 messageLocationH.appendChild(message);
208
209                 var messageLocationV = document.getElementById('itemV0');
210                 var message = document.createElement('div');
211                 message.innerHTML = "<p>You should also be able to repeat these tests steps for this vertical region.<br/>"
212                 messageLocationV.appendChild(message);
213             }
214         }
215         </script>
216     </head>
217     <body onload="onLoad();">
218         <div style="position: relative; width: 200px">
219             <div>Tests that the scroll-snap feature works properly in overflow regions.</div>
220             <div class="gallery" id="topTarget">
221                 <div class="galleryDrawer">
222                     <div id="itemH0" class="colorBox"></div>
223                     <div id="itemH1" class="colorBox"></div>
224                     <div id="itemH2" class="colorBox"></div>
225                     <div id="itemH3" class="colorBox"></div>
226                     <div id="itemH4" class="colorBox"></div>
227                     <div id="itemH5" class="colorBox"></div>
228                 </div>
229             </div>
230             <div class="gallery" id="bottomTarget">
231                 <div class="galleryDrawer">
232                     <div id="itemV0" class="colorBox"></div>
233                     <div id="itemV1" class="colorBox"></div>
234                     <div id="itemV2" class="colorBox"></div>
235                     <div id="itemV3" class="colorBox"></div>
236                     <div id="itemV4" class="colorBox"></div>
237                     <div id="itemV5" class="colorBox"></div>
238                 </div>
239             </div>
240             <div id="console"></div>
241         </div>
242     </body>
243 </html>