mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-20 20:21:20 -08:00
88 lines
2.4 KiB
TypeScript
88 lines
2.4 KiB
TypeScript
import type { FullscreenHost } from './types'
|
|
import { getScope, isClosing } from '../lifecycle/instance'
|
|
import { listen } from '../lifecycle/resources'
|
|
import { abandonVideo, clearAbandonedVideo, isAbandonedVideo, videoIsFullscreen } from './video-fullscreen-state'
|
|
|
|
export function videoFullscreen(art: FullscreenHost): PropertyDescriptor {
|
|
const { $video } = art.template
|
|
const scope = getScope(art).child()
|
|
let observed = false
|
|
let last = videoIsFullscreen($video)
|
|
let desired = last
|
|
let pending = false
|
|
let revision = 0
|
|
|
|
const active = () => videoIsFullscreen($video, observed)
|
|
function changed(hint?: boolean) {
|
|
if (isClosing(art) || isAbandonedVideo($video))
|
|
return
|
|
if (typeof hint === 'boolean')
|
|
observed = hint
|
|
const value = active()
|
|
if (value)
|
|
pending = false
|
|
if (value === last)
|
|
return
|
|
last = value
|
|
const current = revision
|
|
const stale = () => isClosing(art) || active() !== value || (current !== revision && desired !== value)
|
|
art.emit('fullscreen', value)
|
|
if (stale())
|
|
return
|
|
if (value)
|
|
art.state = 'fullscreen'
|
|
if (!stale())
|
|
art.emit('resize')
|
|
}
|
|
|
|
scope.add(() => {
|
|
revision++
|
|
desired = false
|
|
if (pending)
|
|
abandonVideo($video)
|
|
if (active())
|
|
$video.webkitExitFullscreen?.()
|
|
})
|
|
listen(scope, $video, 'webkitbeginfullscreen', () => changed(true))
|
|
listen(scope, $video, 'webkitendfullscreen', () => changed(false))
|
|
listen(scope, $video, 'webkitpresentationmodechanged', () => changed())
|
|
const documentChanged = () => changed()
|
|
art.on('document:webkitfullscreenchange', documentChanged)
|
|
scope.add(() => {
|
|
art.off('document:webkitfullscreenchange', documentChanged)
|
|
})
|
|
|
|
return {
|
|
get: () => !isClosing(art) && active(),
|
|
set(value: boolean): void {
|
|
if (isClosing(art))
|
|
return
|
|
const current = ++revision
|
|
desired = Boolean(value)
|
|
if (value) {
|
|
clearAbandonedVideo($video)
|
|
art.state = 'fullscreen'
|
|
if (isClosing(art) || current !== revision)
|
|
return
|
|
pending = true
|
|
try {
|
|
$video.webkitEnterFullscreen!()
|
|
}
|
|
catch (error) {
|
|
if (current === revision)
|
|
pending = false
|
|
throw error
|
|
}
|
|
}
|
|
else {
|
|
if (pending) {
|
|
pending = false
|
|
abandonVideo($video)
|
|
}
|
|
if (active())
|
|
$video.webkitExitFullscreen!()
|
|
}
|
|
},
|
|
}
|
|
}
|