summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html
blob: 0a6264932fe9a4b99b3ce92996f9fde6ae6dfa7c (plain)
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
<!DOCTYPE html>
<html>
<head>
<style>
/* Remove body margin and dialog styles to allow comparing dialog's position with that of plain span elements. */
body {
    margin: 0;
}

dialog {
    border: 0;
    padding: 0;
    height: auto;
    width: auto;
}

.filler {
    height: 20000px;
}

</style>
<script src="../../js/resources/js-test-pre.js"></script>
<script>
function checkTopOfViewport(dialog) {
    shouldBe('dialog.getBoundingClientRect().top', '0');
}

function checkCentered(dialog) {
    expectedTop = (window.innerHeight - dialog.offsetHeight) / 2;
    shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
}

// Helper to test both a non-modal and modal dialog.
function showAndTestDialog(dialog, checker) {
    dialog.show();
    checker();
    dialog.close();

    dialog.showModal();
    checker();
    dialog.close();
}
</script>
</head>
<body>
    <dialog id="mydialog">It is my dialog.</dialog>
    <div class="filler" id="fillerDiv"></div>
</body>
<script>
description("Tests positioning of non-anchored dialogs.");

dialog = document.getElementById('mydialog');

debug('Dialog should be centered in the viewport.');
showAndTestDialog(dialog, function() { checkCentered(dialog) });

debug('<br>The computed top and bottom of a centered dialog should still have position auto');
shouldBeEqualToString('window.getComputedStyle(dialog).top', 'auto');
shouldBeEqualToString('window.getComputedStyle(dialog).bottom', 'auto');

debug('<br>Dialog should be recentered if show() is called after close().');
window.scroll(0, 500);
dialog.show();
checkCentered(dialog);

debug('<br>Dialog should not be recentered on a relayout.');
var expectedTop = dialog.getBoundingClientRect().top;
window.scroll(0, 1000);
var forceRelayoutDiv = document.createElement('div');
forceRelayoutDiv.style.width = '100px';
forceRelayoutDiv.style.height = '100px';
forceRelayoutDiv.style.border = 'solid';
document.body.appendChild(forceRelayoutDiv);
window.scroll(0, 500);
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
document.body.removeChild(forceRelayoutDiv);
dialog.close();

debug('<br>A tall dialog should be positioned at the top of the viewport.');
var dialogInner = document.createElement('div');
dialogInner.className = 'filler';
dialog.appendChild(dialogInner);
showAndTestDialog(dialog, function() { checkTopOfViewport(dialog) });
dialog.removeChild(dialogInner);

debug('<br>The dialog should be centered regardless of the presence of a horizontal scrollbar.');
var fillerDiv = document.getElementById('fillerDiv');
fillerDiv.style.width = '4000px';
showAndTestDialog(dialog, function() { checkCentered(dialog) });
fillerDiv.style.width = 'auto';

debug('<br>Test that centering works when dialog is inside positioned containers.');
var absoluteContainer = document.createElement('div');
absoluteContainer.style.position = 'absolute';
absoluteContainer.style.top = '800px;'
absoluteContainer.style.height = '50px;'
absoluteContainer.style.width = '90%';
dialog.parentNode.removeChild(dialog);
document.body.appendChild(absoluteContainer);
absoluteContainer.appendChild(dialog);
showAndTestDialog(dialog, function() { checkCentered(dialog) });
absoluteContainer.removeChild(dialog);

var relativeContainer = document.createElement('div');
relativeContainer.style.position = 'relative';
relativeContainer.style.top = '20px';
relativeContainer.style.height = '30px';
absoluteContainer.appendChild(relativeContainer);
relativeContainer.appendChild(dialog);
dialog.show();
checkCentered(dialog);

debug("<br>Dialog's position should survive after becoming display:none temporarily.");
expectedTop = dialog.getBoundingClientRect().top;
window.scroll(0, 1000);
relativeContainer.style.display = 'none';
relativeContainer.style.display = 'block';
window.scroll(0, 500);
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');

debug("<br>Dialog's position should survive after being re-added to document without another call to show().");
expectedTop = dialog.getBoundingClientRect().top;
window.scroll(0, 1000);
relativeContainer.removeChild(dialog);
relativeContainer.appendChild(dialog);
window.scroll(0, 500);
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.close();

debug("<br>Dialog's position should survive after close() and show().");
dialog.show();
dialog.style.top = '0px';
expectedTop = dialog.getBoundingClientRect().top;
dialog.close();
dialog.show();
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.style.top = 'auto';

debug("<br>Dialog's position should survive after close() and manually reopen.");
dialog.show();
expectedTop = dialog.getBoundingClientRect().top;
dialog.close();
document.body.offsetHeight;
dialog.open = true;
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.close();

debug("<br>Dialog is recentered if show() is called after removing 'open'");
dialog.show();
dialog.removeAttribute('open');
window.scroll(0, 1000);
dialog.show();
checkCentered(dialog);
dialog.close();
window.scroll(0, 500);

debug("<br>Dialog should not be centered if show() was called when an ancestor had display 'none'.");
absoluteContainer.style.display = 'none';
dialog.show();
absoluteContainer.style.display = 'block';
// Since dialog's containing block is the ICB, it's statically positioned after <body>.
expectedTop = document.body.getBoundingClientRect().bottom;
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.close();

debug("<br>Test that setting 'top' on dialog results in the same position as for a plain, absolutely positioned span.");
var plainSpan = document.createElement('span');
plainSpan.style.position = 'absolute';
document.body.appendChild(plainSpan);
plainSpan.style.top = '50px';
dialog.style.top = '50px';
expectedTop = plainSpan.getBoundingClientRect().top;
showAndTestDialog(dialog, function() { shouldBe('dialog.getBoundingClientRect().top', 'expectedTop'); });

debug("<br>Test that setting 'bottom' on dialog results in the same position as for a plain, absolutely positioned span.");
dialog.style.top = 'auto';
plainSpan.style.top = 'auto';
dialog.style.bottom = '50px';
plainSpan.style.bottom = '50px';
showAndTestDialog(dialog, function() { shouldBe('dialog.getBoundingClientRect().bottom', 'plainSpan.getBoundingClientRect().bottom'); });

debug('<br>Test that fixed positioning for dialog has same behavior as for a plain span.');
plainSpan.style.position = 'fixed';
plainSpan.style.top = '50px';
dialog.style.position = 'fixed';
dialog.style.top = '50px';
showAndTestDialog(dialog, function() { shouldBe('dialog.getBoundingClientRect().top', 'plainSpan.getBoundingClientRect().top'); });

debug('<br>Test that static position for a non-modal dialog has the same behavior as for a plain span.');
plainSpan.parentNode.removeChild(plainSpan);
relativeContainer.appendChild(plainSpan);
plainSpan.style.position = 'static';
expectedTop = plainSpan.getBoundingClientRect().top;
plainSpan.parentNode.removeChild(plainSpan);
dialog.style.position = 'static';
// Just test non-modal since modal is covered by other tests (for modal, static computes to absolute)
dialog.show();
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.close();

debug('<br>Test that relative position for a non-modal dialog has the same behavior as for a plain span.');
relativeContainer.appendChild(plainSpan);
plainSpan.style.position = 'relative';
plainSpan.style.top = '50px';
expectedTop = plainSpan.getBoundingClientRect().top;
plainSpan.parentNode.removeChild(plainSpan);
dialog.style.position = 'relative';
dialog.style.top = '50px';
// Just test non-modal since modal is covered by other tests (for modal, relative computes to absolute)
dialog.show();
shouldBe('dialog.getBoundingClientRect().top', 'expectedTop');
dialog.close();
</script>
</body>
</html>