test_css_visibility_propagation.xhtml (7970B)
1 <?xml version="1.0"?> 2 <?xml-stylesheet type="text/css" href="chrome://global/skin"?> 3 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> 4 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 5 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> 6 <body xmlns="http://www.w3.org/1999/xhtml"></body> 7 <script> 8 <![CDATA[ 9 const baseURL = "chrome://mochitests/content/chrome/layout/base/tests/chrome/"; 10 11 function checkHiddenEmbeddederState(window1, window2, expected1, expected2) 12 { 13 ok(!window1.browsingContext.isUnderHiddenEmbedderElement, "window1 visible state"); 14 ok(!window2.browsingContext.isUnderHiddenEmbedderElement, "window2 visible state"); 15 is(window1.document.querySelector("browser").contentWindow.browsingContext.isUnderHiddenEmbedderElement, !expected1, 16 "window1 child visible state"); 17 is(window2.document.querySelector("browser").contentWindow.browsingContext.isUnderHiddenEmbedderElement, !expected2, 18 "window2 child visible state"); 19 } 20 21 // Tests that browser visibility is updated when it's swapped. 22 add_task(async () => { 23 // Open two new windows to swap iframes. 24 const window1 = window.browsingContext.topChromeWindow.open( 25 baseURL + "window_css_visibility_propagation-1.xhtml", 26 "_blank", "chrome"); 27 const window2 = window.browsingContext.topChromeWindow.open( 28 baseURL + "window_css_visibility_propagation-2.xhtml", 29 "_blank", "chrome"); 30 31 const loadWindow1 = 32 new Promise(resolve => window1.addEventListener("load", resolve)); 33 const loadWindow2 = 34 new Promise(resolve => window2.addEventListener("load", resolve)); 35 36 await Promise.all([ loadWindow1, loadWindow2 ]); 37 38 checkHiddenEmbeddederState(window1, window2, false, true); 39 40 // Hide the parent of browser2. 41 let parent = window2.document.getElementById("parent"); 42 parent.style.visibility = "hidden"; 43 parent.getBoundingClientRect(); 44 45 checkHiddenEmbeddederState(window1, window2, false, false); 46 47 const browser2 = window2.document.querySelector("browser"); 48 let target = browser2.contentDocument.getElementById("button"); 49 target.focus(); 50 51 // browser2 is now in a visibility:hidden element in window2, 52 // so that Element.focus() shouldn't work. 53 isnot(browser2.contentDocument.activeElement, target, 54 "Element.focus() shouldn't work in invisible browser"); 55 56 // Make the parent visible. 57 parent.style.visibility = ""; 58 parent.getBoundingClientRect(); 59 60 checkHiddenEmbeddederState(window1, window2, false, true); 61 62 target.focus(); 63 64 // browser2 is visible now, so focus() should work. 65 is(browser2.contentDocument.activeElement, target, 66 "Element.focus() should work in visible browser"); 67 68 target.blur(); 69 isnot(browser2.contentDocument.activeElement, target, 70 "The target element shouldn't be activeElement"); 71 72 // Swap the content in browser1 for the content in browser2. 73 const browser1 = window1.document.querySelector("browser"); 74 browser1.swapFrameLoaders(browser2); 75 await new Promise(resolve => setTimeout(resolve, 0)); 76 77 target = browser1.contentDocument.getElementById("button"); 78 target.focus(); 79 80 // browser1 is in a visibility:hidden element in window1, 81 // so that Element.focus() shouldn't work. 82 isnot(browser1.contentDocument.activeElement, target, 83 "Element.focus() shouldn't work in invisible browser"); 84 85 checkHiddenEmbeddederState(window1, window2, false, true); 86 87 parent = window1.document.getElementById("parent"); 88 parent.style.visibility = "visible"; 89 parent.getBoundingClientRect(); 90 91 checkHiddenEmbeddederState(window1, window2, true, true); 92 93 target.focus(); 94 95 // Now browser1 is in a visibility:visible element, so that 96 // Element.focus() should just work. 97 is(browser1.contentDocument.activeElement, target, 98 "Element.focus() should work in visible browser"); 99 100 window1.close(); 101 window2.close(); 102 }); 103 104 // Tests that ancestor's visibility change doesn't clobber child 105 // iframe's visibility if the child iframe is hidden by an 106 // element in the ancestor document. 107 add_task(async () => { 108 const tabReady = new Promise(resolve => { 109 window.addEventListener("message", event => { 110 if (event.data == "ready") { 111 resolve(); 112 } 113 }, { once: true }); 114 }); 115 const tabWindow = 116 window.open(baseURL + "window_css_visibility_propagation-3.html"); 117 await tabReady; 118 119 const childIFrame = tabWindow.document.querySelector("iframe"); 120 121 const grandChildBrowser = 122 childIFrame.contentDocument.querySelector("browser"); 123 let target = grandChildBrowser.contentDocument.getElementById("button"); 124 target.focus(); 125 126 ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); 127 ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); 128 ok(!grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is visible"); 129 130 is(grandChildBrowser.contentDocument.activeElement, target, 131 "Element.focus() should work in visible browser"); 132 target.blur(); 133 134 // Hide the parent element of the grand child browser. 135 let parent = childIFrame.contentDocument.getElementById("parent"); 136 parent.style.visibility = "hidden"; 137 parent.getBoundingClientRect(); 138 139 ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); 140 ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); 141 ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); 142 143 target.focus(); 144 145 isnot(grandChildBrowser.contentDocument.activeElement, target, 146 "Element.focus() shouldn't work in invisible browser"); 147 148 // Hide the parent element of the child iframe. 149 parent = tabWindow.document.getElementById("parent"); 150 parent.style.visibility = "hidden"; 151 parent.getBoundingClientRect(); 152 153 target.focus(); 154 155 ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); 156 ok(childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is not visible"); 157 ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); 158 159 isnot(grandChildBrowser.contentDocument.activeElement, target, 160 "Element.focus() shouldn't work in invisible iframe"); 161 162 // Make the parent element of the child iframe visible. 163 parent.style.visibility = "visible"; 164 parent.getBoundingClientRect(); 165 166 ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); 167 ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); 168 ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); 169 170 target.focus(); 171 172 // Even if the child iframe is visible, but still the grand child is 173 // hidden by the parent element of the grand child browser so that 174 // we can't focus to the element in the grand child browser. 175 isnot(grandChildBrowser.contentDocument.activeElement, target, 176 "Element.focus() shouldn't work in invisible browser"); 177 178 tabWindow.close(); 179 }); 180 181 // Tests that an iframe is initially hidden by a visibility:hidden element in 182 // the parent document. 183 add_task(async () => { 184 const tabReady = new Promise(resolve => { 185 window.addEventListener("message", event => { 186 if (event.data == "ready") { 187 resolve(); 188 } 189 }, { once: true }); 190 }); 191 const tabWindow = 192 window.open(baseURL + "window_css_visibility_propagation-4.html"); 193 await tabReady; 194 195 const iframe = tabWindow.document.querySelector("iframe"); 196 let target = iframe.contentDocument.getElementById("button"); 197 target.focus(); 198 199 ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); 200 ok(iframe.browsingContext.isUnderHiddenEmbedderElement, "iframe is not visible"); 201 202 isnot(iframe.contentDocument.activeElement, target, 203 "Element.focus() shouldn't work in invisible iframe"); 204 205 tabWindow.close(); 206 }); 207 ]]> 208 </script> 209 </window>