UNPKG

@aidenlx/player

Version:

Headless web components that make integrating media on the a web a breeze.

132 lines (116 loc) 3.91 kB
import { FullscreenController, FullscreenControllerHost, listen, noop, ScreenOrientationController, } from '@vidstack/foundation'; import { VideoPresentationChangeEvent, VideoPresentationController } from '../presentation'; /** * Extends the base `FullscreenController` with additional logic for handling fullscreen * on iOS Safari where the native Fullscreen API is not available (in this case it falls back to * using the `VideoPresentationController`). * * @example * ```ts * import { LitElement } from 'lit'; * import { * FullscreenController, * ScreenOrientationController, * VideoPresentationController * } from '@vidstack/elements'; * * class MyElement extends LitElement { * get videoElement() { * return this.videoEl; * } * * fullscreenController = new VideoFullscreenController( * this, * new ScreenOrientationController(this), * new VideoPresentationController(this), * ); * * async requestFullscreen() { * if (this.fullscreenController.isRequestingNativeFullscreen) { * return super.requestFullscreen(); * } * * return this.fullscreenController.requestFullscreen(); * } * * async exitFullscreen() { * return this.fullscreenController.exitFullscreen(); * } * } * ``` */ export class VideoFullscreenController extends FullscreenController { constructor( host: FullscreenControllerHost, screenOrientationController: ScreenOrientationController, protected readonly _presentationController: VideoPresentationController, ) { super(host, screenOrientationController); } override get isFullscreen(): boolean { return this.isSupportedNatively ? this.isNativeFullscreen : this._presentationController.isFullscreenMode; } override get isSupported(): boolean { return this.isSupportedNatively || this.isSupportedOnSafari; } /** * Whether a fallback fullscreen API is available on Safari using presentation modes. This * is only used on iOS where the native fullscreen API is not available. * * @link https://developer.apple.com/documentation/webkitjs/htmlvideoelement/1631913-webkitpresentationmode */ get isSupportedOnSafari() { return this._presentationController.isSupported; } protected override async _makeEnterFullscreenRequest(): Promise<void> { return this.isSupportedNatively ? super._makeEnterFullscreenRequest() : this._makeFullscreenRequestOnSafari(); } protected async _makeFullscreenRequestOnSafari(): Promise<void> { return this._presentationController.setPresentationMode('fullscreen'); } protected override async _makeExitFullscreenRequest(): Promise<void> { return this.isSupportedNatively ? super._makeExitFullscreenRequest() : this._makeExitFullscreenRequestOnSafari(); } protected async _makeExitFullscreenRequestOnSafari(): Promise<void> { return this._presentationController.setPresentationMode('inline'); } protected override _addFullscreenChangeEventListener( handler: (this: HTMLElement, event: Event) => void, ): () => void { if (this.isSupportedNatively) { return super._addFullscreenChangeEventListener(handler); } if (this.isSupportedOnSafari) { if (__DEV__) { this._logger?.debug('adding `vds-video-presentation-change` listener'); } return listen( this._host, 'vds-video-presentation-change', this._handlePresentationModeChange.bind(this), ); } return noop; } protected _handlePresentationModeChange(event: VideoPresentationChangeEvent): void { this._handleFullscreenChange(event); } protected override _addFullscreenErrorEventListener( handler: (this: HTMLElement, event: Event) => void, ): () => void { if (!this.isSupportedNatively) return noop; return super._addFullscreenErrorEventListener(handler); } }