Index: LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html |
diff --git a/LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html b/LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html |
index 9031641c55a3f900e822cfc798f65eb927b73449..6c8914f2f02e2fd548a45704c315f6875e9d6efb 100644 |
--- a/LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html |
+++ b/LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning.html |
@@ -5,6 +5,12 @@ |
.filler { |
height: 20000px; |
} |
+ |
+dialog { |
+ /* Remove border and padding to allow comparing dialog's position with that of plain span elements. */ |
+ border: 0; |
+ padding: 0; |
+} |
</style> |
<script src="../../js/resources/js-test-pre.js"></script> |
<script> |
@@ -19,6 +25,17 @@ 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> |
@@ -30,106 +47,142 @@ description("Tests default positioning of non-anchored dialogs."); |
dialog = document.getElementById('mydialog'); |
-// Dialog should be centered in the viewport. |
-dialog.show(); |
-checkCentered(dialog); |
-dialog.close(); |
+debug('Dialog should be centered in the viewport.'); |
+showAndTestDialog(dialog, function() { checkCentered(dialog) }); |
-// Dialog should still be centered if shown after window is scrolled. |
+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(); |
-// A tall dialog should be positioned at the top of the viewport. |
+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); |
-dialog.show(); |
-checkTopOfViewport(dialog); |
-dialog.close(); |
+showAndTestDialog(dialog, function() { checkTopOfViewport(dialog) }); |
dialog.removeChild(dialogInner); |
-// Add the horizontal scrollbar. The dialog should be centered regardless of the presence of scrollbars. |
+debug('<br>The dialog should be centered regardless of the presence of a horizontal scrollbar.'); |
var fillerDiv = document.getElementById('fillerDiv'); |
fillerDiv.style.width = '4000px'; |
-dialog.show(); |
-checkCentered(dialog); |
-dialog.close(); |
+showAndTestDialog(dialog, function() { checkCentered(dialog) }); |
fillerDiv.style.width = 'auto'; |
-// Test that centering works when dialog is inside positioned containers. |
-var container = document.createElement('div'); |
-container.style.position = 'absolute'; |
-container.style.top = '800px;' |
-container.style.height= '50px;' |
-container.style.width = '90%'; |
+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(container); |
-container.appendChild(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'; |
dialog.close(); |
-container.removeChild(dialog); |
- |
-var container2 = document.createElement('div'); |
-// FIXME: This test fails for position = 'relative'. |
-container2.style.position = 'absolute'; |
-container2.style.top = '20px'; |
-container2.style.height = '30px'; |
-container.appendChild(container2); |
-container2.appendChild(dialog); |
+dialog.show(); |
+var expectedTop = '0px'; |
+shouldBe('dialog.style.top', 'expectedTop'); |
+dialog.style.top = 'auto'; |
+ |
+debug("<br>Dialog is recentered if show() is called after removing 'open'"); |
+dialog.removeAttribute('open'); |
+window.scroll(0, 1000); |
dialog.show(); |
checkCentered(dialog); |
dialog.close(); |
+window.scroll(0, 500); |
-// Test that setting top manually is the same as for a plain div. |
-var plainDiv = document.createElement('div'); |
-container2.appendChild(plainDiv); |
-plainDiv.style.position = 'absolute'; |
-plainDiv.style.top = '50px'; |
-dialog.style.top = '50px'; |
+debug("<br>Dialog should not be centered if show() was called when an ancestor had display 'none'."); |
+var plainSpan = document.createElement('span'); |
+plainSpan.style.position = 'absolute'; |
+relativeContainer.appendChild(plainSpan); |
+expectedTop = plainSpan.getBoundingClientRect().top; |
+absoluteContainer.style.display = 'none'; |
dialog.show(); |
-shouldBe('dialog.offsetTop', 'plainDiv.offsetTop'); |
+absoluteContainer.style.display = 'block'; |
+shouldBe('dialog.getBoundingClientRect().top', 'expectedTop'); |
dialog.close(); |
-// Test that setting bottom manually is the same as for a plain div. |
+debug("<br>Test that setting 'top' on dialog results in the same position as for a plain, absolutely positioned span."); |
+plainSpan.style.top = '50px'; |
+dialog.style.top = '50px'; |
+showAndTestDialog(dialog, function() { shouldBe('dialog.offsetTop', 'plainSpan.offsetTop'); }); |
+ |
+debug("<br>Test that setting 'bottom' on dialog results in the same position as for a plain, absolutely positioned span."); |
dialog.style.top = 'auto'; |
-plainDiv.style.top = 'auto'; |
+plainSpan.style.top = 'auto'; |
dialog.style.bottom = '50px'; |
-plainDiv.style.bottom = '50px'; |
-dialog.show(); |
-shouldBe('dialog.offsetBottom', 'plainDiv.offsetBottom'); |
-dialog.close(); |
+plainSpan.style.bottom = '50px'; |
+showAndTestDialog(dialog, function() { shouldBe('dialog.offsetBottom', 'plainSpan.offsetBottom'); }); |
-// Test that fixed position has the usual behavior. |
-plainDiv.style.position = 'fixed'; |
-plainDiv.style.top = '50px'; |
+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'; |
-dialog.show(); |
-shouldBe('dialog.offsetTop', 'plainDiv.offsetTop'); |
-dialog.close(); |
+showAndTestDialog(dialog, function() { shouldBe('dialog.offsetTop', 'plainSpan.offsetTop'); }); |
-// Test that static position has the usual behavior. |
-plainDiv.style.position = 'static'; |
-plainDiv.style.top = 'auto'; |
-var expectedTop = plainDiv.offsetTop; |
-plainDiv.parentNode.removeChild(plainDiv); |
+debug('<br>Test that static position for a non-modal dialog has the same behavior as for a plain span.'); |
+// Just test non-modal since modal is covered by other tests (for modal, static computes to absolute) |
+plainSpan.style.position = 'static'; |
+var expectedTop = plainSpan.offsetTop; |
+plainSpan.parentNode.removeChild(plainSpan); |
dialog.style.position = 'static'; |
-dialog.style.top = 'auto'; |
dialog.show(); |
shouldBe('dialog.offsetTop', 'expectedTop'); |
dialog.close(); |
-dialog.parentNode.removeChild(dialog); |
-// Test that relative position has the usual behavior. |
-container2.appendChild(plainDiv); |
-plainDiv.style.position = 'relative'; |
-plainDiv.style.top = '50px'; |
-expectedTop = plainDiv.offsetTop; |
-plainDiv.parentNode.removeChild(plainDiv); |
-container2.appendChild(dialog); |
+debug('<br>Test that relative position for a non-modal dialog has the same behavior as for a plain span.'); |
+// Just test non-modal since modal is covered by other tests (for modal, relative computes to absolute) |
+relativeContainer.appendChild(plainSpan); |
+plainSpan.style.position = 'relative'; |
+plainSpan.style.top = '50px'; |
+expectedTop = plainSpan.offsetTop; |
+plainSpan.parentNode.removeChild(plainSpan); |
dialog.style.position = 'relative'; |
dialog.style.top = '50px'; |
dialog.show(); |