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
content / test / data / iframe_out_of_view.html [blame]
<!DOCTYPE html>
<html>
<body>
<style>
body {
width: 100%;
height: 100%;
margin: 0;
}
iframe {
width: 400px;
height: 400px;
margin: 300%;
border: 0;
padding: 0;
overflow: scroll;
}
input {
margin: 0;
padding: 0;
border: 0;
height: 1px;
font-size: 1px;
}
</style>
<p> Single <iframe> which is positioned out of view. </p>
<iframe id="test_iframe">
</iframe>
<p> Iframe should be positioned way above </p>
<script>
window.loaded = false;
window.notifyBrowser = null;
const kInfinity = 1000000;
const kMarginOfError = 1;
const tinyTimeout = 50;
window.addEventListener("load", () => {
document.scrollingElement.scrollTop = kInfinity;
document.scrollingElement.scrollLeft = kInfinity;
window.loaded = true;
if (window.notifyBrowser) {
window.notifyBrowser("LOADED");
window.notifyBrowser = null;
}
});
function notifyWhenLoaded() {
return new Promise(resolve => {
if (loaded)
resolve("LOADED");
else
window.notifyBrowser = resolve;
});
}
// Waits until the |visualViewport| reaches the given size (approximately).
// Notifies the browser when this happens.
function notifyVisualViewportChanged(width, height) {
if ((Math.abs(visualViewport.width - width) < kMarginOfError) &&
(Math.abs(visualViewport.height - height) < kMarginOfError)) {
return window.domAutomationController.send("SIZED");
}
window.setTimeout(() => {
notifyVisualViewportChanged(width, height);
}, tinyTimeout);
}
function isEmptyRect(rect) {
return (rect.width * rect.height) === 0;
}
function intersect(rect1, rect2) {
let minX1 = rect1.x, maxX1 = minX1 + rect1.width
minY1 = rect1.y, maxY1 = minY1 + rect1.height,
minX2 = rect2.x, maxX2 = minX2 + rect2.width,
minY2 = rect2.y, maxY2 = minY2 + rect2.height;
return !(isEmptyRect(rect1) ||
isEmptyRect(rect2) ||
(minX1 > maxX2) ||
(minX2 > maxX1) ||
(minY1 > maxY2) ||
(minY2 > maxY1));
}
function visualViewportAsRect() {
return {
x: visualViewport.offsetLeft,
y: visualViewport.offsetTop,
width: Math.round(visualViewport.width),
height: Math.round(visualViewport.height)
};
}
function rectAsString(rect) {
return `${rect.x},${rect.y},${rect.width},${rect.height}`;
}
function addFocusedInputField() {
var input = document.createElement("input");
input.value="some text";
document.body.insertBefore(input, document.body.firstChild);
input.focus();
}
// Waits until the given element is inside the |visualViewport|.
async function notifyWhenVisible(el) {
while (!intersect(el.getBoundingClientRect(), visualViewportAsRect())) {
await new Promise(resolve => {
window.setTimeout(resolve, tinyTimeout);
});
}
return "VISIBLE";
}
</script>
</body>
</html>