diff --git a/packages/install-site.js b/packages/install-site.js index 626a7e0..2e2628b 100644 --- a/packages/install-site.js +++ b/packages/install-site.js @@ -1,9 +1,9 @@ import { inject } from 'vue' -import { Screen } from './plugins' +import { Fullscreen, Screen } from './plugins' const BaseKey = Symbol('Site') -const defaultPlugins = [Screen] +const defaultPlugins = [Fullscreen, Screen] function install (app, options = {}) { const $site = { diff --git a/packages/plugins/fullscreen/index.js b/packages/plugins/fullscreen/index.js index cecbe33..2b6e205 100644 --- a/packages/plugins/fullscreen/index.js +++ b/packages/plugins/fullscreen/index.js @@ -1,4 +1,71 @@ import { createReactivePlugin } from '../../utils/create' +const native = { + request: ['requestFullscreen', 'msRequestFullscreen', 'mozRequestFullScreen', 'webkitRequestFullscreen'].find((request) => !!document.documentElement[request]), + exit: ['exitFullscreen', 'msExitFullscreen', 'mozCancelFullScreen', 'webkitExitFullscreen'].find((exit) => !!document[exit]) +} + +function getFullElement () { + return (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement || null) +} + +function promisify (target, event) { + try { + const result = target[event]() + return result || Promise.resolve() + } catch (err) { + return Promise.reject(err) + } +} + +export default createReactivePlugin({ + isActive: false, + activeEl: null +}, { + request (target) { + const el = target || document.documentElement + if (this.activeEl === el) return Promise.resolve() + // -- + const result = this.activeEl !== null && el.contains(this.activeEl) === true + ? this.exit() + : Promise.resolve() + + return result.finally(() => promisify(el, native.request)) + }, + exit () { + return this.isActive === true + ? promisify(document, native.exit) + : Promise.resolve() + }, + toggle (target) { + return this.isActive === true + ? this.exit() + : this.request(target) + }, + install (app, options, $site) { + $site && ($site.fullscreen = this) + + const onUpdateActiveEl = () => { + this.activeEl = this.isActive === false ? null : getFullElement() + } + + const onChange = () => { + this.isActive = this.isActive === false + onUpdateActiveEl() + } + + this.isActive = !!getFullElement() + this.isActive === true && onUpdateActiveEl() + + // ;['fullscreenchange', 'MSFullscreenChange', 'mozfullscreenchange', 'webkitfullscreenchange'].forEach((type) => { + // addEvt(document, type, onChange) + // }) + + ;['onfullscreenchange', 'onmsfullscreenchange', 'onmozfullscreenchange', 'onwebkitfullscreenchange'].forEach((event) => { + document[event] = onChange + }) + } +}) + diff --git a/packages/plugins/index.js b/packages/plugins/index.js index 49d23dd..33fe241 100644 --- a/packages/plugins/index.js +++ b/packages/plugins/index.js @@ -1,5 +1,7 @@ +import Fullscreen from './fullscreen' import Screen from './screen' export { + Fullscreen, Screen } diff --git a/src/layout/components/fullscreen/index.jsx b/src/layout/components/fullscreen/index.jsx index 940cbbd..e554274 100644 --- a/src/layout/components/fullscreen/index.jsx +++ b/src/layout/components/fullscreen/index.jsx @@ -1,7 +1,6 @@ -import { defineComponent, onBeforeUnmount, onMounted, ref, unref } from 'vue' +import { computed, defineComponent, unref } from 'vue' import { ExitFullscreenOutlined, FullscreenOutlined } from '@/components/icon' -import native from './screenfull' -import { addEvt, cleanEvt } from '@site/utils/event' +import { useSite } from '@site' import { useConfigInject } from '@site/utils/extend' import useStyle from './style' @@ -10,41 +9,19 @@ export default defineComponent({ setup (props, { attrs }) { const { prefixCls } = useConfigInject('pro-fullscreen', props) const [wrapSSR, hashId] = useStyle(prefixCls) + const $site = useSite() - const { fullscreenElement, exitFullscreen, requestFullscreen, fullscreenchange } = native + const isActive = computed(() => $site.fullscreen.isActive) - const fullest = ref(false) - - function onChange () { - fullest.value = !unref(fullest) - } - - function isFullscreen () { - return fullscreenElement && !!(document[fullscreenElement]) + function onClick () { + $site.fullscreen.toggle() } - function handleFullscreen () { - if (unref(fullest)) { - exitFullscreen && document[exitFullscreen]() - } else { - requestFullscreen && document.body[requestFullscreen]() - } - } - - onMounted(() => { - fullest.value = isFullscreen() - fullscreenchange && addEvt(document, fullscreenchange, onChange, false) - }) - - onBeforeUnmount(() => { - fullscreenchange && cleanEvt(document, fullscreenchange, onChange, false) - }) - return () => { return wrapSSR(