import { ClassFlag } from "./ClassFlag"; import { ElementAttribute } from "./ElementAttribute"; import { ElementType } from "./ElementType"; export class Fullscreen { static readonly flag = new ClassFlag( "is-fullscreen" ); static _listensToChange = false; static setFlagOnChange() { if ( Fullscreen._listensToChange ) { return; } Fullscreen._listensToChange = true; document.addEventListener( "fullscreenchange", () => { Fullscreen.flag.setAs( document.body, Fullscreen.isFullscreen() ); } ); } static isFullscreen(): boolean { let anyDocument:any = document; if ( anyDocument.fullscreenElement != null ) { return true; } if ( anyDocument.webkitFullscreenElement != null ) { return true; } if ( anyDocument.mozFullScreenElement != null ) { return true; } if ( anyDocument.msFullscreenElement != null ) { return true; } return false; } protected static async enterFullscreen( element:HTMLElement ): Promise { let anyElement:any = element; if ( element.requestFullscreen != null ) { return element.requestFullscreen(); } if ( anyElement.webkitRequestFullscreen != null ) { return anyElement.webkitRequestFullscreen(); } if ( anyElement.mozRequestFullScreen != null ) { return anyElement.mozRequestFullScreen(); } if ( anyElement.msRequestFullscreen != null ) { return anyElement.msRequestFullscreen(); } return Promise.reject( new Error( "fullscreen api not supported" )); } static async exitFullscreen(): Promise { let anyDocument: any = document; if ( anyDocument.exitFullscreen != null ) { return anyDocument.exitFullscreen(); } if ( anyDocument.webkitExitFullscreen != null ) { return anyDocument.webkitExitFullscreen(); } if ( anyDocument.mozCancelFullScreen != null ) { return anyDocument.mozCancelFullScreen(); } if ( anyDocument.msExitFullscreen != null ) { return anyDocument.msExitFullscreen(); } return Promise.reject( new Error( "fullscreen exit not supported" )); } static async lockOrientation( orientation:string ): Promise { let anyScreen: any = ( screen as any ); let api: any = screen.orientation != null ? screen.orientation : anyScreen.orientation != null ? anyScreen.orientation : anyScreen.msOrientation; if ( api == null || typeof api.lock !== "function" ) { return; } try { await api.lock( orientation ); } catch { // fail quietly } } static unlockOrientation(): void { let anyScreen: any = ( screen as any ); let api: any = screen.orientation != null ? screen.orientation : anyScreen.orientation != null ? anyScreen.orientation : anyScreen.msOrientation; if ( api == null || typeof api.unlock !== "function" ) { return; } try { api.unlock(); } catch { // fail quietly } } static async toggleFullscreen( videoContainer:HTMLElement, handleOrientation:"auto"|"portrait"|"landscape"=null ): Promise { let videoElement = ElementType.video.query( videoContainer ); ElementAttribute.playsinline.to( videoContainer ); ( videoContainer as any ).playsInline = true; if ( Fullscreen.isFullscreen() ) { await Fullscreen.exitFullscreen(); if ( handleOrientation ) { Fullscreen.unlockOrientation(); } return Promise.resolve(); } let target:string = null; if ( handleOrientation !== null ) { if ( handleOrientation === "auto" ) { let vw = videoElement.videoWidth || videoElement.clientWidth || 16; let vh = videoElement.videoHeight || videoElement.clientHeight || 9; target = vw >= vh ? "landscape" : "portrait"; } else { target = handleOrientation; } } await Fullscreen.enterFullscreen( videoContainer ); if ( target != null ) { await Fullscreen.lockOrientation( target ); } return Promise.resolve(); } }