summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/abspos-dialog-layout.html
blob: 77ed29ce56113fa733cb7e592a3e6c961590a6a8 (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
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name="viewport" content="user-scalable=no">
<title>Tests layout of absolutely positioned modal dialogs.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
/* Remove body margin and dialog styles for easier positioning expected values */
body {
    height: 10000px;
    margin: 0;
}

dialog {
    border: 0;
    padding: 0;
    max-width: 100%;
    max-height: 100%;
}

#absolute-div {
    position: absolute;
    top: 800px;
    height: 50px;
    width: 90%;
}

#relative-div {
    position: relative;
    top: 20px;
    height: 30px;
}
</style>
</head>
<dialog >It is my dialog.</dialog>
<div id="absolute-div">
    <div id="relative-div"></div>
</div>
<script>
"use strict";

function checkVerticallyCentered(dialog) {
    var centeredTop = (document.documentElement.clientHeight - dialog.offsetHeight) / 2;
    // Using approx equals because getBoundingClientRect() and centeredTop
    // are calculated by different parts of the engine. Due to the loss
    // of precision, the numbers might not equal exactly.
    assert_approx_equals(dialog.getBoundingClientRect().top, centeredTop, 1);
}

function reset() {
    document.body.style.width = "auto";
    dialog.style.top = null;
    dialog.style.height = null;
    if (dialog.open)
        dialog.close();
    dialog.remove();
    document.body.appendChild(dialog);
    window.scroll(0, 500);
}

var dialog = document.querySelector('dialog');
var absoluteContainer = document.querySelector('#absolute-div');
var relativeContainer = document.querySelector('#relative-div');
reset();

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    checkVerticallyCentered(dialog);
}, "showModal() should center in the viewport");

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    dialog.close();
    window.scroll(0, 2 * window.scrollY);
    dialog.showModal();
    checkVerticallyCentered(dialog);
}, "Dialog should be recentered if showModal() is called after close()");

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    var expectedTop = dialog.getBoundingClientRect().top;
    window.scroll(0, window.scrollY * 2);

    // Trigger relayout
    document.body.offsetHeight;

    window.scroll(0, window.scrollY / 2);
    assert_equals(dialog.getBoundingClientRect().top, expectedTop);
}, "Dialog should not recenter on relayout.");

test(function() {
    this.add_cleanup(reset);

    dialog.style.height = '20000px';
    dialog.showModal();
    assert_equals(dialog.getBoundingClientRect().top, 0);
}, "A tall dialog should be positioned at the top of the viewport.");

test(function() {
    this.add_cleanup(reset);

    document.body.style.width = '4000px';
    dialog.showModal();
    checkVerticallyCentered(dialog);

}, "The dialog should be centered regardless of the presence of a horizontal scrollbar.");

test(function() {
    this.add_cleanup(reset);

    dialog.remove();
    absoluteContainer.appendChild(dialog);
    dialog.showModal();
    checkVerticallyCentered(dialog);
    dialog.close();

    dialog.remove();
    relativeContainer.appendChild(dialog);
    dialog.showModal();
    checkVerticallyCentered(dialog);
}, "Centering should work when dialog is inside positioned containers.");

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    var expectedTop = dialog.getBoundingClientRect().top;
    relativeContainer.style.display = 'none';
    relativeContainer.style.display = 'block';
    assert_equals(dialog.getBoundingClientRect().top, expectedTop);
}, "A centered dialog's position should survive becoming display:none temporarily.");

test(function() {
    this.add_cleanup(reset);

    // Remove and reinsert so that the document position isn't changed by the second remove and reinsert
    dialog.remove();
    relativeContainer.appendChild(dialog);

    dialog.showModal();
    checkVerticallyCentered(dialog);
    dialog.remove();

    relativeContainer.appendChild(dialog);
    assert_equals(relativeContainer.getBoundingClientRect().top, dialog.getBoundingClientRect().top);
}, "Dialog should not still be centered when removed, and re-added to the document.");

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    dialog.style.top = '0px';
    var expectedTop = dialog.getBoundingClientRect().top;
    dialog.close();
    dialog.showModal();
    assert_equals(dialog.getBoundingClientRect().top, expectedTop);
}, "Dialog's specified position should survive after close() and showModal().");

test(function() {
    this.add_cleanup(reset);

    dialog.showModal();
    dialog.removeAttribute('open');
    dialog.showModal();
    checkVerticallyCentered(dialog);
}, "Dialog should be recentered if showModal() is called after removing 'open'.");
</script>