import { CLASS_PLAYER , EVENT } from '../constants' ; import { Player } from '../player' ; import { Disposable } from '../types' ; import { addClass , addDisposable , addDisposableListener , dispose , isFunction , isIOS , removeClass , } from '../utils' ; const CLASS_FULL = '-full' ; export class Fullscreen implements Disposable { private target ! : HTMLElement ; private readonly prefix = this . getPrefix ( ) ; constructor ( private player ) { addDisposableListener ( this , document , this . prefix === 'ms' ? 'MSFullscreenChange' : `${ this . prefix }fullscreenchange` as any , ( ) => { let evt = '' ; if ( this . isActive ) { this . addClass ( ) ; evt = EVENT . ENTER_FULLSCREEN ; } else { this . removeClass ( ) ; evt = EVENT . EXIT_FULLSCREEN ; } this . player . emit ( evt ) ; this . player . emit ( EVENT . UPDATE_SIZE ) ; } ) ; addDisposable ( this , player . on ( EVENT . UPDATE_OPTIONS , ( ) => { this . disableDblclick ( ) ; } ) ) ; this . setTarget ( ) ; if ( this . isActive ) this . addClass ( ) ; if ( ! player . opts . isTouch ) { this . enableDblclick ( ) ; } } private getPrefix ( ) { if ( isFunction ( document . exitFullscreen ) ) return '' ; let prefix = '' ; [ 'webkit' , 'moz' , 'ms' ] . forEach ( ( p ) => { if ( isFunction ( ( document as any ) [ `${ p }ExitFullscreen` ] ) || isFunction ( ( document as any ) [ `${ p }CancelFullScreen` ] ) ) { prefix = p ; } } ) ; return prefix ; } get requestFullscreen ( ) : Element [ 'requestFullscreen' ] { return ( HTMLElement . prototype . requestFullscreen || ( HTMLElement . prototype as any ) . webkitRequestFullscreen || ( HTMLElement . prototype as any ) . mozRequestFullScreen || ( HTMLElement . prototype as any ) . msRequestFullscreen ) ; } get exitFullscreen ( ) : Document [ 'exitFullscreen' ] { return ( HTMLDocument . prototype . exitFullscreen || ( HTMLDocument . prototype as any ) . webkitExitFullscreen || ( HTMLDocument . prototype as any ) . cancelFullScreen || ( HTMLDocument . prototype as any ) . mozCancelFullScreen || ( HTMLDocument . prototype as any ) . msExitFullscreen ) ; } get fullscreenElement ( ) : HTMLElement { return ( document . fullscreenElement || ( document as any ) . mozFullScreenElement || ( document as any ) . msFullscreenElement || ( document as any ) . webkitFullscreenElement ) ; } get isActive ( ) : boolean { return this . fullscreenElement === this . target ; } private addClass ( ) { addClass ( this . player . el , CLASS_FULL , CLASS_PLAYER ) ; } private removeClass ( ) { removeClass ( this . player . el , CLASS_FULL , CLASS_PLAYER ) ; } enableDblclick ( ) { this . player . video . addEventListener ( 'dblclick' , this . toggle ) ; } disableDblclick ( ) { this . player . video . removeEventListener ( 'dblclick' , this . toggle ) ; } setTarget ( dom ? , video ? ) { this . target = ( dom && isIOS ? video : dom ) || ( isIOS ? this . player . video : this . player . el ) ; if ( this . isActive ) this . enter ( ) ; } enter ( ) { if ( isIOS ) { ( this . target as any ) . webkitEnterFullscreen ( ) ; } else { this . requestFullscreen . call ( this . target , { navigationUI : 'hide' } ) ; this . player . emit ( EVENT . UPDATE_SIZE ) ; } } exit ( ) { if ( ! this . isActive ) return false ; if ( isIOS ) { ( this . target as any ) . webkitExitFullscreen ( ) ; } else { this . exitFullscreen . call ( document ) ; this . player . emit ( EVENT . UPDATE_SIZE ) ; } return true ; } toggle = ( ) : void => { if ( this . isActive ) { this . exit ( ) ; } else { this . enter ( ) ; } } ; dispose ( ) { if ( ! this . player ) return ; this . player . off ( EVENT . ENTER_FULLSCREEN ) ; this . player . off ( EVENT . EXIT_FULLSCREEN ) ; this . disableDblclick ( ) ; this . player = null ! ; dispose ( this ) ; } }