fullscreen_helpers.js (6172B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TEST_URLS = [ 7 // all frames are in different process. 8 `data:text/html, 9 <div name="div" id="div" style="width: 100px; height: 100px; background: red;"> 10 <iframe id="iframe" allowfullscreen="yes" 11 src="https://example.com/browser/dom/base/test/fullscreen/file_fullscreen-iframe-middle.html"></iframe> 12 </div>`, 13 // toplevel and inner most iframe are in same process, and middle iframe is 14 // in a different process. 15 `https://example.org/browser/dom/base/test/fullscreen/file_fullscreen-iframe-top.html`, 16 // toplevel and middle iframe are in same process, and inner most iframe is 17 // in a different process. 18 `https://example.com/browser/dom/base/test/fullscreen/file_fullscreen-iframe-top.html`, 19 ]; 20 21 function waitRemoteFullscreenEnterEvents(aBrowsingContexts) { 22 let promises = []; 23 aBrowsingContexts.forEach(([aBrowsingContext, aName]) => { 24 promises.push( 25 SpecialPowers.spawn(aBrowsingContext, [aName], async name => { 26 return new Promise(resolve => { 27 let document = content.document; 28 document.addEventListener( 29 "fullscreenchange", 30 function changeHandler() { 31 info(`received fullscreenchange event on ${name}`); 32 ok( 33 !!document.fullscreenElement, 34 `check remote DOM fullscreen event` 35 ); 36 document.removeEventListener("fullscreenchange", changeHandler); 37 resolve(); 38 } 39 ); 40 }); 41 }) 42 ); 43 }); 44 return Promise.all(promises); 45 } 46 47 function waitRemoteFullscreenExitEvents(aBrowsingContexts) { 48 let promises = []; 49 aBrowsingContexts.forEach(([aBrowsingContext, aName]) => { 50 promises.push( 51 SpecialPowers.spawn(aBrowsingContext, [aName], async name => { 52 return new Promise(resolve => { 53 let document = content.document; 54 document.addEventListener( 55 "fullscreenchange", 56 function changeHandler() { 57 if (document.fullscreenElement) { 58 return; 59 } 60 61 info(`received fullscreenchange event on ${name}`); 62 ok(true, `check remote DOM fullscreen event (${name})`); 63 document.removeEventListener("fullscreenchange", changeHandler); 64 resolve(); 65 } 66 ); 67 }); 68 }) 69 ); 70 }); 71 return Promise.all(promises); 72 } 73 74 function waitDOMFullscreenEvent( 75 aDocument, 76 aIsInFullscreen, 77 aWaitUntil = false 78 ) { 79 return new Promise(resolve => { 80 function errorHandler() { 81 ok(false, "should not get fullscreenerror event"); 82 aDocument.removeEventListener("fullscreenchange", changeHandler); 83 aDocument.removeEventListener("fullscreenerror", errorHandler); 84 resolve(); 85 } 86 87 function changeHandler() { 88 if (aWaitUntil && aIsInFullscreen != !!aDocument.fullscreenElement) { 89 return; 90 } 91 92 is( 93 aIsInFullscreen, 94 !!aDocument.fullscreenElement, 95 "check DOM fullscreen (event)" 96 ); 97 aDocument.removeEventListener("fullscreenchange", changeHandler); 98 aDocument.removeEventListener("fullscreenerror", errorHandler); 99 resolve(); 100 } 101 102 aDocument.addEventListener("fullscreenchange", changeHandler); 103 aDocument.addEventListener("fullscreenerror", errorHandler); 104 }); 105 } 106 107 function waitWidgetFullscreenEvent( 108 aWindow, 109 aIsInFullscreen, 110 aWaitUntil = false 111 ) { 112 return BrowserTestUtils.waitForEvent(aWindow, "fullscreen", false, () => { 113 if ( 114 aWaitUntil && 115 aIsInFullscreen != 116 aWindow.document.documentElement.hasAttribute("inFullscreen") 117 ) { 118 return false; 119 } 120 121 is( 122 aIsInFullscreen, 123 aWindow.document.documentElement.hasAttribute("inFullscreen"), 124 "check widget fullscreen (event)" 125 ); 126 return true; 127 }); 128 } 129 130 function waitForFullScreenObserver( 131 aDocument, 132 aIsInFullscreen, 133 aWaitUntil = false 134 ) { 135 return TestUtils.topicObserved("fullscreen-painted", () => { 136 if ( 137 aWaitUntil && 138 aIsInFullscreen != 139 aDocument.documentElement.hasAttribute("inDOMFullscreen") 140 ) { 141 return false; 142 } 143 144 is( 145 aIsInFullscreen, 146 aDocument.documentElement.hasAttribute("inDOMFullscreen"), 147 "check fullscreen (observer)" 148 ); 149 return true; 150 }); 151 } 152 153 function waitForFullscreenState( 154 aDocument, 155 aIsInFullscreen, 156 aWaitUntil = false 157 ) { 158 return Promise.all([ 159 waitWidgetFullscreenEvent( 160 aDocument.defaultView, 161 aIsInFullscreen, 162 aWaitUntil 163 ), 164 waitDOMFullscreenEvent(aDocument, aIsInFullscreen, aWaitUntil), 165 waitForFullScreenObserver(aDocument, aIsInFullscreen, aWaitUntil), 166 ]); 167 } 168 169 // Wait for fullscreenchange event for fullscreen exit. And wait for 170 // fullscreen-painted observed conditionally. 171 async function waitForFullscreenExit(aDocument) { 172 info(`waitForFullscreenExit`); 173 let promiseFsObserver = null; 174 let observer = function () { 175 if (aDocument.documentElement.hasAttribute("inDOMFullscreen")) { 176 info(`waitForFullscreenExit, fullscreen-painted, inDOMFullscreen`); 177 Services.obs.removeObserver(observer, "fullscreen-painted"); 178 promiseFsObserver = waitForFullScreenObserver(aDocument, false); 179 } 180 }; 181 Services.obs.addObserver(observer, "fullscreen-painted"); 182 183 await waitDOMFullscreenEvent(aDocument, false, true); 184 // If there is a fullscreen-painted observer notified for inDOMFullscreen set, 185 // we expect to have a subsequent fullscreen-painted observer notified with 186 // inDOMFullscreen unset. 187 if (promiseFsObserver) { 188 info(`waitForFullscreenExit, promiseFsObserver`); 189 await promiseFsObserver; 190 return; 191 } 192 193 Services.obs.removeObserver(observer, "fullscreen-painted"); 194 // If inDOMFullscreen is set we expect to have a subsequent fullscreen-painted 195 // observer notified with inDOMFullscreen unset. 196 if (aDocument.documentElement.hasAttribute("inDOMFullscreen")) { 197 info(`waitForFullscreenExit, inDOMFullscreen`); 198 await waitForFullScreenObserver(aDocument, false, true); 199 } 200 }