2012-10-09 02:21:57 +04:00
|
|
|
// Returns true if the window occupies the entire screen.
|
|
|
|
// Note this only returns true once the transition from normal to
|
|
|
|
// fullscreen mode is complete.
|
2015-10-10 04:19:23 +03:00
|
|
|
function inFullscreenMode(win) {
|
2016-01-11 01:38:53 +03:00
|
|
|
return (
|
|
|
|
win.innerWidth == win.screen.width && win.innerHeight == win.screen.height
|
|
|
|
);
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns true if the window is in normal mode, i.e. non fullscreen mode.
|
|
|
|
// Note this only returns true once the transition from fullscreen back to
|
|
|
|
// normal mode is complete.
|
2015-10-10 04:19:23 +03:00
|
|
|
function inNormalMode(win) {
|
2016-01-11 01:38:53 +03:00
|
|
|
return (
|
|
|
|
win.innerWidth == win.normalSize.w && win.innerHeight == win.normalSize.h
|
|
|
|
);
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Adds a listener that will be called once a fullscreen transition
|
|
|
|
// is complete. When type==='enter', callback is called when we've
|
|
|
|
// received a fullscreenchange event, and the fullscreen transition is
|
|
|
|
// complete. When type==='exit', callback is called when we've
|
|
|
|
// received a fullscreenchange event and the window dimensions match
|
|
|
|
// the window dimensions when the window opened (so don't resize the
|
|
|
|
// window while running your test!). inDoc is the document which
|
|
|
|
// the listeners are added on, if absent, the listeners are added to
|
|
|
|
// the current document.
|
|
|
|
function addFullscreenChangeContinuation(type, callback, inDoc) {
|
|
|
|
var doc = inDoc || document;
|
2015-10-10 04:19:23 +03:00
|
|
|
var topWin = doc.defaultView.top;
|
|
|
|
// Remember the window size in non-fullscreen mode.
|
|
|
|
if (!topWin.normalSize) {
|
|
|
|
topWin.normalSize = {
|
2016-01-11 01:38:53 +03:00
|
|
|
w: window.innerWidth,
|
|
|
|
h: window.innerHeight,
|
2015-10-10 04:19:23 +03:00
|
|
|
};
|
|
|
|
}
|
2015-05-21 00:52:26 +03:00
|
|
|
function checkCondition() {
|
|
|
|
if (type == "enter") {
|
2015-10-10 04:19:23 +03:00
|
|
|
return inFullscreenMode(topWin);
|
2015-05-21 00:52:26 +03:00
|
|
|
} else if (type == "exit") {
|
|
|
|
// If we just revert the state to a previous fullscreen state,
|
|
|
|
// the window won't back to the normal mode. Hence we check
|
2016-02-17 03:47:11 +03:00
|
|
|
// fullscreenElement first here. Note that we need to check
|
2015-10-08 09:47:39 +03:00
|
|
|
// the fullscreen element of the outmost document here instead
|
|
|
|
// of the current one.
|
2016-02-17 03:47:11 +03:00
|
|
|
return topWin.document.fullscreenElement || inNormalMode(topWin);
|
2015-05-21 00:52:26 +03:00
|
|
|
} else {
|
|
|
|
throw "'type' must be either 'enter', or 'exit'.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function invokeCallback(event) {
|
|
|
|
// Use async call after a paint to workaround unfinished fullscreen
|
|
|
|
// change even when the window size has changed on Linux.
|
|
|
|
requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
|
|
|
|
}
|
|
|
|
function onFullscreenChange(event) {
|
2017-01-17 13:50:25 +03:00
|
|
|
doc.removeEventListener("fullscreenchange", onFullscreenChange);
|
2015-05-21 00:52:26 +03:00
|
|
|
if (checkCondition()) {
|
|
|
|
invokeCallback(event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
function onResize() {
|
|
|
|
if (checkCondition()) {
|
2017-01-17 13:50:25 +03:00
|
|
|
topWin.removeEventListener("resize", onResize);
|
2015-05-21 00:52:26 +03:00
|
|
|
invokeCallback(event);
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
2015-05-21 00:52:26 +03:00
|
|
|
}
|
2017-01-17 13:50:25 +03:00
|
|
|
topWin.addEventListener("resize", onResize);
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
2017-01-17 13:50:25 +03:00
|
|
|
doc.addEventListener("fullscreenchange", onFullscreenChange);
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Calls |callback| when the next fullscreenerror is dispatched to inDoc||document.
|
|
|
|
function addFullscreenErrorContinuation(callback, inDoc) {
|
2019-05-22 22:16:31 +03:00
|
|
|
return new Promise(resolve => {
|
|
|
|
let doc = inDoc || document;
|
|
|
|
let listener = function(event) {
|
|
|
|
doc.removeEventListener("fullscreenerror", listener);
|
|
|
|
setTimeout(function() {
|
|
|
|
if (callback) {
|
|
|
|
callback(event);
|
|
|
|
}
|
|
|
|
resolve();
|
|
|
|
}, 0);
|
|
|
|
};
|
|
|
|
doc.addEventListener("fullscreenerror", listener);
|
|
|
|
});
|
2012-10-09 02:21:57 +04:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:33:25 +03:00
|
|
|
// Waits until the window has both the load event and a MozAfterPaint called on
|
|
|
|
// it, and then invokes the callback
|
|
|
|
function waitForLoadAndPaint(win, callback) {
|
|
|
|
win.addEventListener(
|
|
|
|
"MozAfterPaint",
|
|
|
|
function() {
|
|
|
|
// The load event may have fired before the MozAfterPaint, in which case
|
|
|
|
// listening for it now will hang. Instead we check the readyState to see if
|
|
|
|
// it already fired, and if so, invoke the callback right away.
|
|
|
|
if (win.document.readyState == "complete") {
|
|
|
|
callback();
|
|
|
|
} else {
|
|
|
|
win.addEventListener("load", callback, { once: true });
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ once: true }
|
|
|
|
);
|
|
|
|
}
|