abspos-dialog-layout.html (4887B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset=utf-8> 5 <meta name="viewport" content="user-scalable=no"> 6 <title>Tests layout of absolutely positioned modal dialogs.</title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <style> 10 /* Remove body margin and dialog styles for easier positioning expected values */ 11 body { 12 height: 10000px; 13 margin: 0; 14 } 15 16 dialog { 17 border: 0; 18 padding: 0; 19 max-width: 100%; 20 max-height: 100%; 21 } 22 23 #absolute-div { 24 position: absolute; 25 top: 800px; 26 height: 50px; 27 width: 90%; 28 } 29 30 #relative-div { 31 position: relative; 32 top: 20px; 33 height: 30px; 34 } 35 </style> 36 </head> 37 <dialog >It is my dialog.</dialog> 38 <div id="absolute-div"> 39 <div id="relative-div"></div> 40 </div> 41 <script> 42 "use strict"; 43 44 function checkVerticallyCentered(dialog) { 45 var centeredTop = (document.documentElement.clientHeight - dialog.offsetHeight) / 2; 46 // Using approx equals because getBoundingClientRect() and centeredTop 47 // are calculated by different parts of the engine. Due to the loss 48 // of precision, the numbers might not equal exactly. 49 assert_approx_equals(dialog.getBoundingClientRect().top, centeredTop, 1); 50 } 51 52 function reset() { 53 document.body.style.width = "auto"; 54 dialog.style.top = null; 55 dialog.style.height = null; 56 if (dialog.open) 57 dialog.close(); 58 dialog.remove(); 59 document.body.appendChild(dialog); 60 window.scroll(0, 500); 61 } 62 63 var dialog = document.querySelector('dialog'); 64 var absoluteContainer = document.querySelector('#absolute-div'); 65 var relativeContainer = document.querySelector('#relative-div'); 66 reset(); 67 68 test(function() { 69 this.add_cleanup(reset); 70 71 dialog.showModal(); 72 checkVerticallyCentered(dialog); 73 }, "showModal() should center in the viewport"); 74 75 test(function() { 76 this.add_cleanup(reset); 77 78 dialog.showModal(); 79 dialog.close(); 80 window.scroll(0, 2 * window.scrollY); 81 dialog.showModal(); 82 checkVerticallyCentered(dialog); 83 }, "Dialog should be recentered if showModal() is called after close()"); 84 85 test(function() { 86 this.add_cleanup(reset); 87 88 dialog.showModal(); 89 var expectedTop = dialog.getBoundingClientRect().top; 90 window.scroll(0, window.scrollY * 2); 91 92 // Trigger relayout 93 document.body.offsetHeight; 94 95 window.scroll(0, window.scrollY / 2); 96 assert_equals(dialog.getBoundingClientRect().top, expectedTop); 97 }, "Dialog should not recenter on relayout."); 98 99 test(function() { 100 this.add_cleanup(reset); 101 102 dialog.style.height = '20000px'; 103 dialog.showModal(); 104 assert_equals(dialog.getBoundingClientRect().top, 0); 105 }, "A tall dialog should be positioned at the top of the viewport."); 106 107 test(function() { 108 this.add_cleanup(reset); 109 110 document.body.style.width = '4000px'; 111 dialog.showModal(); 112 checkVerticallyCentered(dialog); 113 114 }, "The dialog should be centered regardless of the presence of a horizontal scrollbar."); 115 116 test(function() { 117 this.add_cleanup(reset); 118 119 dialog.remove(); 120 absoluteContainer.appendChild(dialog); 121 dialog.showModal(); 122 checkVerticallyCentered(dialog); 123 dialog.close(); 124 125 dialog.remove(); 126 relativeContainer.appendChild(dialog); 127 dialog.showModal(); 128 checkVerticallyCentered(dialog); 129 }, "Centering should work when dialog is inside positioned containers."); 130 131 test(function() { 132 this.add_cleanup(reset); 133 134 dialog.showModal(); 135 var expectedTop = dialog.getBoundingClientRect().top; 136 relativeContainer.style.display = 'none'; 137 relativeContainer.style.display = 'block'; 138 assert_equals(dialog.getBoundingClientRect().top, expectedTop); 139 }, "A centered dialog's position should survive becoming display:none temporarily."); 140 141 test(function() { 142 this.add_cleanup(reset); 143 144 // Remove and reinsert so that the document position isn't changed by the second remove and reinsert 145 dialog.remove(); 146 relativeContainer.appendChild(dialog); 147 148 dialog.showModal(); 149 checkVerticallyCentered(dialog); 150 dialog.remove(); 151 152 relativeContainer.appendChild(dialog); 153 assert_equals(relativeContainer.getBoundingClientRect().top, dialog.getBoundingClientRect().top); 154 }, "Dialog should not still be centered when removed, and re-added to the document."); 155 156 test(function() { 157 this.add_cleanup(reset); 158 159 dialog.showModal(); 160 dialog.style.top = '0px'; 161 var expectedTop = dialog.getBoundingClientRect().top; 162 dialog.close(); 163 dialog.showModal(); 164 assert_equals(dialog.getBoundingClientRect().top, expectedTop); 165 }, "Dialog's specified position should survive after close() and showModal()."); 166 167 test(function() { 168 this.add_cleanup(reset); 169 170 dialog.showModal(); 171 dialog.removeAttribute('open'); 172 dialog.showModal(); 173 checkVerticallyCentered(dialog); 174 }, "Dialog should be recentered if showModal() is called after removing 'open'."); 175 </script>