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