diff --git a/ui/dev/src/pages/other/app-fullscreen-portals.vue b/ui/dev/src/pages/other/app-fullscreen-portals.vue index 7e6499ab92a..69d368911bd 100644 --- a/ui/dev/src/pages/other/app-fullscreen-portals.vue +++ b/ui/dev/src/pages/other/app-fullscreen-portals.vue @@ -1,5 +1,5 @@ + + diff --git a/ui/dev/src/pages/other/app-fullscreen.vue b/ui/dev/src/pages/other/app-fullscreen.vue index 8595eda70f7..316507e240f 100644 --- a/ui/dev/src/pages/other/app-fullscreen.vue +++ b/ui/dev/src/pages/other/app-fullscreen.vue @@ -8,6 +8,9 @@

Is fullscreen: {{ $q.fullscreen.isActive }}
+
+ Fullscreen el: {{ $q.fullscreen.activeEl.tagName }} - {{ $q.fullscreen.activeEl.className }} +

{ - setTimeout(() => { - console.log(AppFullscreen.isActive) - }, 1000) + console.log('toggle', { isActive: AppFullscreen.isActive, activeEl: AppFullscreen.activeEl }) }) .catch(err => { console.error(err) diff --git a/ui/src/mixins/portal.js b/ui/src/mixins/portal.js index 0372da4fb96..c28fde01de8 100644 --- a/ui/src/mixins/portal.js +++ b/ui/src/mixins/portal.js @@ -3,6 +3,7 @@ import Vue from 'vue' import { isSSR } from '../plugins/Platform.js' import { getBodyFullscreenElement } from '../utils/dom.js' import { addFocusWaitFlag, removeFocusWaitFlag } from '../utils/focus-manager.js' +import debounce from '../utils/debounce.js' export function closePortalMenus (vm, evt) { do { @@ -88,15 +89,12 @@ const Portal = { addFocusWaitFlag(this.focusObj) if (this.$q.fullscreen !== void 0 && this.$q.fullscreen.isCapable === true) { - const append = isFullscreen => { + const append = () => { if (this.__portal === void 0) { return } - const newParent = getBodyFullscreenElement( - isFullscreen, - this.$q.fullscreen.activeEl - ) + const newParent = getBodyFullscreenElement(this.$q.fullscreen.activeEl) if ( this.__portal.$el.parentElement !== newParent && @@ -106,12 +104,10 @@ const Portal = { } } - this.unwatchFullscreen = this.$watch('$q.fullscreen.isActive', append) + this.unwatchFullscreen = this.$watch('$q.fullscreen.activeEl', debounce(append, 50)) - const isActive = this.$q.fullscreen.isActive - - if (this.__onGlobalDialog === false || isActive === true) { - append(isActive) + if (this.__onGlobalDialog === false || this.$q.fullscreen.isActive === true) { + append() } } else if (this.__portal !== void 0 && this.__onGlobalDialog === false) { diff --git a/ui/src/plugins/AppFullscreen.js b/ui/src/plugins/AppFullscreen.js index 7fc1224aca2..849dd01e575 100644 --- a/ui/src/plugins/AppFullscreen.js +++ b/ui/src/plugins/AppFullscreen.js @@ -1,6 +1,6 @@ import Vue from 'vue' -import { isSSR } from './Platform.js' +import { isSSR, client } from './Platform.js' const prefixes = {} @@ -18,17 +18,42 @@ function promisify (target, fn) { } } +function checkActive (plugin) { + plugin.activeEl = document.fullscreenElement || + document.mozFullScreenElement || + document.webkitFullscreenElement || + document.msFullscreenElement || + null + + plugin.isActive = plugin.activeEl !== null +} + export default { isCapable: false, isActive: false, activeEl: null, request (target) { - if (this.isCapable === true && this.isActive === false) { + if (this.isCapable === true) { const el = target || document.documentElement - return promisify(el, prefixes.request).then(() => { - this.activeEl = el - }) + + if (el !== this.activeEl) { + const q = client.is.ie === true && this.activeEl !== null && el.contains(this.activeEl) + ? this.exit() + : Promise.resolve() + + return q + .then(() => promisify(el, prefixes.request)) + .catch(error => ( + this.activeEl !== null + ? this.exit().then(() => promisify(el, prefixes.request)) + : Promise.reject(error) + )) + .then(res => { + checkActive(this) + return res + }) + } } return this.__getErr() @@ -36,21 +61,26 @@ export default { exit () { return this.isCapable === true && this.isActive === true - ? promisify(document, prefixes.exit).then(() => { - this.activeEl = null + ? promisify(document, prefixes.exit).then(res => { + checkActive(this) + return this.isActive ? this.exit() : res }) : this.__getErr() }, toggle (target) { - return this.isActive === true + const el = target || document.documentElement + + return this.activeEl === el ? this.exit() - : this.request(target) + : this.request(el) }, install ({ $q }) { $q.fullscreen = this + this.__getErr = () => Promise.resolve() + if (isSSR === true) { return } prefixes.request = [ @@ -66,24 +96,19 @@ export default { return } - this.__getErr = () => Promise.resolve() - prefixes.exit = [ 'exitFullscreen', 'msExitFullscreen', 'mozCancelFullScreen', 'webkitExitFullscreen' ].find(exit => document[exit]) - this.isActive = !!(document.fullscreenElement || - document.mozFullScreenElement || - document.webkitFullscreenElement || - document.msFullscreenElement) + checkActive(this) ;[ 'onfullscreenchange', 'onmsfullscreenchange', 'onwebkitfullscreenchange' ].forEach(evt => { document[evt] = () => { - this.isActive = this.isActive === false + checkActive(this) } }) diff --git a/ui/src/plugins/Notify.js b/ui/src/plugins/Notify.js index afb93767603..13743b10fc8 100644 --- a/ui/src/plugins/Notify.js +++ b/ui/src/plugins/Notify.js @@ -7,6 +7,7 @@ import QSpinner from '../components/spinner/QSpinner.js' import { noop } from '../utils/event.js' import { getBodyFullscreenElement } from '../utils/dom.js' +import debounce from '../utils/debounce.js' import { isSSR } from './Platform.js' let uid = 0 @@ -500,21 +501,18 @@ const Notifications = { mounted () { if (this.$q.fullscreen !== void 0 && this.$q.fullscreen.isCapable === true) { - const append = isFullscreen => { - const newParent = getBodyFullscreenElement( - isFullscreen, - this.$q.fullscreen.activeEl - ) + const append = () => { + const newParent = getBodyFullscreenElement(this.$q.fullscreen.activeEl) if (this.$el.parentElement !== newParent) { newParent.appendChild(this.$el) } } - this.unwatchFullscreen = this.$watch('$q.fullscreen.isActive', append) + this.unwatchFullscreen = this.$watch('$q.fullscreen.activeEl', debounce(append, 50)) if (this.$q.fullscreen.isActive === true) { - append(true) + append() } } }, diff --git a/ui/src/utils/dom.js b/ui/src/utils/dom.js index 18865b11385..5380ae04147 100644 --- a/ui/src/utils/dom.js +++ b/ui/src/utils/dom.js @@ -62,15 +62,10 @@ export function childHasFocus (el, focusedEl) { } // internal -export function getBodyFullscreenElement (isFullscreen, activeEl) { - return isFullscreen === true - ? ( - // when a video tag enters fullscreen activeEl is null - activeEl === document.documentElement || activeEl === null - ? document.body - : activeEl - ) - : document.body +export function getBodyFullscreenElement (activeEl) { + return activeEl === document.documentElement || activeEl === null + ? document.body + : activeEl } export default {