library-ts/browser/dom/Fullscreen.ts

203 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-09-06 11:33:04 +00:00
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<void>
{
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<void>
{
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<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.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<void>
{
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();
}
}