-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
pagewide-play-pause-offscreen-animations.html
150 lines (126 loc) · 5.43 KB
/
pagewide-play-pause-offscreen-animations.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
<!-- webkit-test-runner [ runSingly=true ] -->
<!-- Always run this test in a clean testing environment with runSingly=true. Without doing this, state preserved between
each run can cause repeated iterations of this test to fail. -->
<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test.js"></script>
<style>
#css-background-svg-container {
width: 100px;
height: 60px;
background: url('data:image/svg+xml;utf8,<svg id="css-background-svg" xmlns="http://www.w3.org/2000/svg"><rect id="background-image-svg-rect" width="30" height="30" fill="green"><animate attributeName="x" from="0" to="200" dur="5s" repeatCount="indefinite"/></rect></svg>');
}
</style>
</head>
<body>
<div id="margin-bottom-anchor"></div>
<svg id="inline-svg" xmlns="http://www.w3.org/2000/svg">
<rect id="svg-rect" width="30" height="30" fill="green">
<animate attributeName="x" from="0" to="30" dur="5s" repeatCount="indefinite"/>
</rect>
</svg>
<div id="css-background-svg-container"></div>
<img id="img-src-svg-container" src=
'data:image/svg+xml;utf8,
<svg id="img-src-svg" xmlns="http://www.w3.org/2000/svg">
<rect width="30" height="30" fill="green">
<animate attributeName="x" from="0" to="30" dur="5s" repeatCount="indefinite"/>
</rect>
</svg>
'>
<iframe id="iframe-srcdoc-svg-container" srcdoc='
<svg id="iframe-srcdoc-svg" xmlns="http://www.w3.org/2000/svg">
<rect width="30" height="30" fill="green">
<animate attributeName="x" from="0" to="30" dur="5s" repeatCount="indefinite"/>
</rect>
</svg>
'></iframe>
<img id="gif-element" src="resources/animation.gif" />
<script>
var testOutput = "This test ensures that animations resumed off-screen don't start playing until they become visible in the viewport.\n\n";
window.jsTestIsAsync = true;
window.onload = function() {
if (!window.internals)
return;
internals.settings.setImageAnimationControlEnabled(true);
setTimeout(async () => {
testOutput += "Verifying animations are initially playing.\n\n";
await verifyAnimationsArePaused(false);
testOutput += "Pausing animations page-wide.\n\n";
internals.setImageAnimationEnabled(false);
await verifyAnimationsArePaused(true);
testOutput += "Moving animations off-screen and enabling page-wide animation (which should have no effect for off-screen animations).\n\n";
document.getElementById("margin-bottom-anchor").style.marginBottom = "2000px";
// Wait for the page to update.
await new Promise(resolve => setTimeout(resolve, 10));
internals.setImageAnimationEnabled(true);
internals.settings.setImageAnimationControlEnabled(false);
await verifyAnimationsArePaused(true);
testOutput += "Scrolling to make animations visible again. They should resume automatically because page-wide animation is enabled.\n\n";
window.scrollBy(0, 2000);
await verifyAnimationsArePaused(false);
debug(testOutput);
internals.clearMemoryCache();
finishJSTest();
});
};
var gifElement = document.getElementById("gif-element");
var svgSvgElement;
async function verifyAnimationsArePaused(expectPaused) {
for (const element of internals.allSVGSVGElements())
element.setCurrentTime(0);
// Allow time to pass to see if the animations progress.
await new Promise(resolve => setTimeout(resolve, 50));
for (const element of sortedSVGSVGElements()) {
svgSvgElement = element;
testOutput += `Testing #${svgSvgElement.id}.\n`;
if (!(svgSvgElement.children[0] instanceof SVGRectElement))
testOutput += `FAIL: 'children[0]' of ${svgSvgElement.id} should've been an SVGRectElement but wasn't, so this test won't behave as expected.\n`;
testOutput += expect(`svgSvgElement.children[0].x.animVal.value ${expectPaused ? "===" : "!=="} 0`, "true");
}
testOutput += `Testing #${gifElement.id}.\n`;
await waitFor(() => internals.isImageAnimating(gifElement) === !expectPaused);
testOutput += expect("internals.isImageAnimating(gifElement)", `${!expectPaused}`);
testOutput += "\n";
}
// IntersectionObserver is not necessary for this test, but the output is helpful when reading the -expected.txt file.
let hadFirstObservation = false;
const viewportVisibilityObserver = new IntersectionObserver(function (entries) {
if (!hadFirstObservation) {
hadFirstObservation = true;
return;
}
for (const entry of entries) {
if (entry.isIntersecting)
testOutput += `#${entry.target.id} is now visible in the viewport.\n`;
else
testOutput += `#${entry.target.id} is no longer visible in the viewport.\n`;
}
testOutput += "\n";
});
for (const id of ["inline-svg", "css-background-svg-container", "img-src-svg-container", "iframe-srcdoc-svg-container", gifElement.id])
viewportVisibilityObserver.observe(document.getElementById(id));
function sortedSVGSVGElements() {
// Sort the SVG elements by ID so the test output is consistent from run to run.
return internals.allSVGSVGElements().sort((elementA, elementB) => elementA.id.localeCompare(elementB.id));
}
function expect(expression, expectedValue) {
const evalExpression = `${expression} === ${expectedValue}`;
if (eval(evalExpression))
return `PASS: ${expression} is ${expectedValue}\n`;
return `FAIL: ${expression} didn't equal ${expectedValue}; was ${eval(expression)}\n`;
}
function waitFor(condition) {
return new Promise(resolve => {
const interval = setInterval(() => {
if (condition()) {
clearInterval(interval);
resolve();
}
}, 5);
});
}
</script>
</body>
</html>