-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathscroll-initial-target-nested-container.tentative.html
219 lines (195 loc) · 8.59 KB
/
scroll-initial-target-nested-container.tentative.html
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> CSS Scroll Snap 2 Test: scroll-initial-target*</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-initial-target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/dom/events/scrolling/scroll_support.js"></script>
<script src="/css/css-animations/support/testcommon.js"></script>
</head>
<body>
<style>
/**
large-space divs are added to simplify scrolling calculations
(i.e. expected offsets are just distances from scroller border top to
scrollee border top).
*/
.large-space {
position: absolute;
height: 500vh;
width: 500vw;
}
#space-filler {
width: 500px;
height: 500px;
background-color: green;
}
#outer-container {
width: 400px;
height: 400px;
overflow: scroll;
position: relative;
background-color: yellow;
}
#inner-container {
top: 20px;
left: 20px;
width: 400px;
height: 400px;
overflow: visible;
position: relative;
background-color: blue;
}
#target {
width: 100px;
height: 100px;
background-color: pink;
scroll-initial-target: nearest;
}
</style>
<div id="outer-container">
<div class="large-space" id="large_space_outer"></div>
<div id="space-filler"></div>
<div id="inner-container">
<div class="large-space" id="large_space_inner"></div>
<div id="space-filler"></div>
<div id="target">
</div>
</div>
</div>
<script>
let outer_container = document.getElementById("outer-container");
let inner_container = document.getElementById("inner-container");
let space_filler = document.getElementById("space-filler");
let target = document.getElementById("target");
const inner_scroller_top_offset = 20;
const target_height = target.getBoundingClientRect().height;
const space_filler_height = space_filler.getBoundingClientRect().height;
const inner_content_height = target_height + space_filler_height;
const inner_container_height = inner_container.getBoundingClientRect().height;
let outer_to_target_scrolltop =
/*outer space-filler*/space_filler_height +
/* 20px top */ inner_scroller_top_offset +
/*inner space filler*/ space_filler_height;
let outer_to_inner_scrolltop =
/* outer space-filler*/ space_filler_height +
/* 20px top */ inner_scroller_top_offset;
let inner_to_target_scrolltop =
/*inner space filler*/ space_filler_height;
async function resetDisplay() {
outer_container.style.display = "block";
inner_container.style.display = "block";
target.style.display = "block";
return waitForAnimationFrames(2);
}
promise_test(async (t) => {
await resetDisplay();
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-container is scrolled to scroll-initial-target");
// Remove large_space_outer so we can observe outer-container adjust to
// its new content height.
large_space_outer.style.display = "none";
inner_container.style.display = "none";
await waitForAnimationFrames(2);
assert_equals(outer_container.scrollTop,
space_filler_height - outer_container.clientHeight,
"outer-container has only the outer space filler to scroll");
large_space_outer.style.display = "initial";
inner_container.style.display = "block";
await waitForAnimationFrames(2);
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-scroller is updated as scroll-initial-target reappears");
}, "display:none scroll-initial-target becomes display:block");
promise_test(async (t) => {
await waitForCompositorCommit();
await resetDisplay();
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-container is scrolled to scroll-initial-target");
// Remove large_space_outer so we can observe outer-container adjust to
// its new content height.
large_space_outer.style.display = "none";
inner_container.style.overflow = "scroll";
await waitForAnimationFrames(2);
// inner-container has become a scroller and should be scrolled to
// scroll-initial-target.
assert_equals(inner_container.scrollTop,
inner_to_target_scrolltop,
"inner-container is fully scrolled to target");
// outer-container should be adjusted to its new max scroll offset.
assert_equals(outer_container.scrollTop,
space_filler_height + inner_scroller_top_offset +
inner_container_height - outer_container.clientHeight,
"outer-container's overflowing content is only its direct " +
"children");
large_space_outer.style.display = "initial";
inner_container.style.overflow = "visible";
await waitForAnimationFrames(2);
assert_equals(inner_container.scrollTop, 0,
"inner-container is no longer a scroll container");
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-scroller is the scroll container for target once again");
}, "intermediate overflow:visible container becomes overflow:scroll");
promise_test(async (t) => {
// This test verifies that:
// 1. when both the child and grandchild are scroll-initial-targets, the
// first-in-tree-order (i.e. the child) wins/is scrolled to.
// 2. if/when the grandchild stops being a scroll-initial-target, the
// child (inner container) is scrolled to.
await waitForCompositorCommit();
await resetDisplay();
t.add_cleanup(async () => {
inner_container.style.scrollInitialTarget = "none";
await waitForAnimationFrames(2);
});
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-container is scrolled to scroll-initial-target");
// Make the inner container a scroll-initial-target.
inner_container.style.scrollInitialTarget = "nearest";
await waitForAnimationFrames(2);
// The inner container has overflow: visible, so it's not the scroll
// container of target.
assert_equals(outer_container.scrollTop,
outer_to_inner_scrolltop,
"outer-container is scrolled to inner-container (which is before the" +
"inner scroll-initial-target in tree order)");
}, "outer scroll-initial-target takes precedence over inner");
promise_test(async (t) => {
// This test verifies that a child which is a scroller, is a
// scroll-initial-target, and has a scroll-initial-target is scrolled to
// by its scrolling container, and also scrolls to its own
// scroll-initial-target.
await waitForCompositorCommit();
await resetDisplay();
t.add_cleanup(async () => {
inner_container.style.overflow = "visible";
inner_container.style.scrollInitialTarget = "none";
await waitForAnimationFrames(2);
});
assert_equals(outer_container.scrollTop, outer_to_target_scrolltop,
"outer-container is scrolled to scroll-initial-target");
// Make the inner container a scroll-initial-target.
inner_container.style.scrollInitialTarget = "nearest";
await waitForAnimationFrames(2);
assert_equals(outer_container.scrollTop,
outer_to_inner_scrolltop,
"outer-container is still scrolled to inner scroll-container" +
"as it is a scroll-initial-target and comes before #target in " +
"tree-order");
// Make the inner container a scroller.
inner_container.style.overflow = "scroll";
await waitForAnimationFrames(2);
assert_equals(outer_container.scrollTop,
outer_to_inner_scrolltop,
"outer-container is scrolled to the inner container");
assert_equals(inner_container.scrollTop,
inner_to_target_scrolltop,
"inner-container is scrolled to target");
}, "scroll containers can also be scroll-initial-targets");
</script>
</body>
</html>