@vime/core
Version:
Customizable, extensible, accessible and framework agnostic media player.
48 lines (47 loc) • 1.68 kB
JavaScript
import { getElement } from '@stencil/core';
import { fireEventAndRetry, listen } from '../../../utils/dom';
import { deferredPromise } from '../../../utils/promise';
import { createStencilHook } from '../../../utils/stencil';
import { isInstanceOf } from '../../../utils/unit';
export const FIND_PLAYER_EVENT = 'vmFindPlayer';
export function withFindPlayer(player) {
const el = getElement(player);
let off;
createStencilHook(player, () => {
off = listen(el, FIND_PLAYER_EVENT, (event) => {
event.stopPropagation();
event.detail(el);
});
}, () => {
off === null || off === void 0 ? void 0 : off();
});
}
/**
* Finds the closest ancestor player element by firing the `vmFindPlayer` event, and waiting
* for the player to catch it. This function retries finding the player (`maxRetries`) until it
* gives up and fails.
*
* @param ref - A HTMLElement that is within the player's subtree.
* @param interval - The length of the timeout before trying again in milliseconds.
* @param maxRetries - The number of times to retry firing the event.
*/
export const findPlayer = (ref, interval = 300, maxRetries = 10) => {
const el = (isInstanceOf(ref, HTMLElement)
? ref
: getElement(ref));
const search = deferredPromise();
// eslint-disable-next-line prefer-const
let stopFiring;
const event = new CustomEvent(FIND_PLAYER_EVENT, {
bubbles: true,
composed: true,
detail: player => {
search.resolve(player);
stopFiring();
},
});
stopFiring = fireEventAndRetry(el, event, () => {
search.reject(`Could not find player for ${el.nodeName}`);
}, interval, maxRetries);
return search.promise;
};