blob: e5453d73ee86f1d3ccacbb6a84562c402df10d28 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<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 checkNotVerticallyCentered(dialog) {
var centeredTop = (document.documentElement.clientHeight - dialog.offsetHeight) / 2;
assert_not_equals(dialog.getBoundingClientRect().top, centeredTop);
}
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";
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);
// Set back original value to 'height'.
dialog.style.height = 'fit-content';
}, "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);
checkVerticallyCentered(dialog);
}, "Dialog should 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);
// Set back original value to 'top'.
dialog.style.top = '0';
}, "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>