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
|
function checkSnapEventSupport(event_type) {
if (event_type == "snapchanged") {
assert_true(window.onsnapchanged !== undefined, "snapchanged not supported");
} else if (event_type == "snapchanging") {
assert_true(window.onsnapchanging !== undefined, "snapchanging not supported");
} else {
assert_unreached(`Unknown snap event type selected: ${event_type}`);
}
}
// This function is deprecated. It tests a deprecated SnapEvent interface.
function assertSnapEventDeprecated(evt, expected_ids) {
assert_equals(evt.bubbles, false, "snap events don't bubble");
assert_false(evt.cancelable, "snap events are not cancelable.");
const actual = Array.from(evt.snapTargets, el => el.id).join(",");
const expected = expected_ids.join(",");
assert_equals(actual, expected, "snap event supplied expected targets");
}
// This function is deprecated. It tests a deprecated SnapEvent interface.
// This function holds logic intended to be used by tests for scroll snap
// events.
// |test_data| should contain:
// - |scroller|: the snap container being scrolled (or
// document.scrollingElement)
// - |scrolling_function|: this function should trigger the desired snap event
// when executed.
// - |expected_snap_targets|: a list of element ids which the triggered snap
// event should supply in SnapEvent.snapTargets.
// - |expected_scroll_offsets|: the scroll offsets at which the snap container
// should be after scrolling function has been
// executed.
// |event_type|: should be "snapchanged" or "snapchanging".
async function test_snap_event_deprecated(test, test_data, event_type) {
checkSnapEventSupport(event_type);
await waitForScrollReset(test, test_data.scroller);
let listener = test_data.scroller ==
document.scrollingElement ? document : test_data.scroller;
const event_promise = waitForSnapEvent(listener, event_type);
await test_data.scrolling_function();
let evt = await event_promise;
assertSnapEventDeprecated(evt, test_data.expected_snap_targets);
assert_approx_equals(test_data.scroller.scrollTop,
test_data.expected_scroll_offsets.y, 1,
"vertical scroll offset mismatch.");
assert_approx_equals(test_data.scroller.scrollLeft,
test_data.expected_scroll_offsets.x, 1,
"horizontal scroll offset mismatch.");
}
async function test_snapchanged(test, test_data) {
await test_snap_event_deprecated(test, test_data, "snapchanged");
}
function waitForEventUntil(event_target, event_type, wait_until) {
return new Promise(resolve => {
let result = null;
const listener = (evt) => {
result = evt;
};
event_target.addEventListener(event_type, listener);
wait_until.then(() => {
event_target.removeEventListener(event_type, listener);
resolve(result);
});
});
}
function waitForEventsUntil(event_target, event_type, wait_until) {
return new Promise(resolve => {
let result = [];
const listener = (evt) => {
result.push(evt);
};
event_target.addEventListener(event_type, listener);
wait_until.then(() => {
event_target.removeEventListener(event_type, listener);
resolve(result);
});
});
}
// Proxy a wait for a snap event. We want to avoid having a test
// timeout in the event of an expected snap event not firing in a particular
// test case as that would cause the entire file to fail.
// Snap events should fire before scrollend, so if a scroll should happen, wait
// for a scrollend event. Otherwise, just do a rAF-based wait.
function waitForSnapEvent(event_target, event_type, scroll_happens = true) {
return scroll_happens ? waitForEventUntil(event_target, event_type,
waitForScrollendEventNoTimeout(event_target))
: waitForEventUntil(event_target, event_type,
waitForAnimationFrames(2));
}
function waitForSnapChangedEvent(event_target, scroll_happens = true) {
return waitForSnapEvent(event_target, "snapchanged", scroll_happens);
}
function getScrollbarToScrollerRatio(scroller) {
// Ideally we'd subtract the length of the scrollbar thumb from
// the dividend but there isn't currently a way to get the
// scrollbar thumb length.
return scroller.clientHeight /
(scroller.scrollHeight - scroller.clientHeight);
}
|