expo-av
Version:
Expo universal module for Audio and Video playback
114 lines • 4.79 kB
JavaScript
/**
* Detect if the browser supports the standard fullscreen API on the given
* element:
* https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
*/
const supportsFullscreenAPI = (element) => 'requestFullscreen' in element;
/**
* Detect if the browser supports the non-standard webkit fullscreen API on the
* given element (looking at you, Safari).
*/
const supportsWebkitFullscreenAPI = (element) => 'webkitEnterFullScreen' in element;
/**
* Detect if the browser supports the non-standard ms fullscreen API on the
* given element (looking at you, IE11).
*/
const supportsMsFullscreenAPI = (element) => 'msRequestFullscreen' in element;
/**
* Detect if the browser supports the `webkitFullscreenChange` event. This is
* a non-standard event added to Safari on macOS by Apple:
* https://developer.apple.com/documentation/webkitjs/document/1631998-onwebkitfullscreenchange
*/
const supportsWebkitFullscreenChangeEvent = () => supportsEvent('video', 'webkitfullscreenchange');
/**
* A helper that adds an event listener to an element. The key value-add over
* the native addEventListener is that it returns a function that will remove
* the event listener. This allows the setup and teardown logic for a listener
* to be easily colocated.
*/
function addEventListener(element, eventName, listener) {
element.addEventListener(eventName, listener);
return () => element.removeEventListener(eventName, listener);
}
/**
* Detect if the browser supports an event on a particular element type.
*/
const supportsEvent = (elementName, eventName) => {
// Detect if the browser supports the event by attempting to add a handler
// attribute for that event to the provided element. If the event is supported
// then the browser will accept the attribute and report the type of the
// attribute as "function". See: https://stackoverflow.com/a/4562426/2747759
const element = document.createElement(elementName);
element.setAttribute('on' + eventName, 'return;');
return typeof element['on' + eventName] === 'function';
};
/**
* Switches a video element into fullscreen.
*/
export async function requestFullscreen(element) {
if (supportsFullscreenAPI(element)) {
return element.requestFullscreen();
}
else if (supportsWebkitFullscreenAPI(element)) {
// This API is synchronous so no need to return the result
element['webkitEnterFullScreen']?.();
}
else if (supportsMsFullscreenAPI(element)) {
// This API is synchronous so no need to return the result
element['msRequestFullscreen']?.();
}
else {
throw new Error('Fullscreen not supported');
}
}
/**
* Switches a video element out of fullscreen.
*/
export async function exitFullscreen(element) {
if (supportsFullscreenAPI(element)) {
return document.exitFullscreen();
}
else if (supportsWebkitFullscreenAPI(element)) {
// This API is synchronous so no need to return the result
element['webkitExitFullScreen']?.();
}
else if (supportsMsFullscreenAPI(element)) {
// This API is synchronous so no need to return the result
document['msExitFullscreen']?.();
}
else {
throw new Error('Fullscreen not supported');
}
}
/**
* Listens for fullscreen change events on a video element. The provided
* callback will be called with `true` when the video is switched into
* fullscreen and `false` when the video is switched out of fullscreen.
*/
export function addFullscreenListener(element, callback) {
if (supportsFullscreenAPI(element)) {
// Used by browsers that support the official spec
return addEventListener(element, 'fullscreenchange', (event) => callback(document.fullscreenElement === event.target));
}
else if (supportsWebkitFullscreenAPI(element) && supportsWebkitFullscreenChangeEvent()) {
// Used by Safari on macOS
return addEventListener(element, 'webkitfullscreenchange', (event) => callback(document['webkitFullscreenElement'] === event.target));
}
else if (supportsWebkitFullscreenAPI(element)) {
// Used by Safari on iOS
const removeBeginListener = addEventListener(element, 'webkitbeginfullscreen', () => callback(true));
const removeEndListener = addEventListener(element, 'webkitendfullscreen', () => callback(false));
return () => {
removeBeginListener();
removeEndListener();
};
}
else if (supportsMsFullscreenAPI(element)) {
// Used by IE11
return addEventListener(document, 'MSFullscreenChange', (event) => callback(document['msFullscreenElement'] === event.target));
}
else {
return () => { };
}
}
//# sourceMappingURL=FullscreenUtils.web.js.map