UNPKG

bitmovin-player-ui

Version:
77 lines (63 loc) 2.24 kB
import { DOM } from '../DOM'; const FocusVisibleCssClassName = '{{PREFIX}}-focus-visible'; export class FocusVisibilityTracker { private readonly eventHandlerMap: { [eventName: string]: EventListenerOrEventListenerObject }; private lastInteractionWasKeyboard: boolean = true; private uiWrapperElement: DOM; constructor( private bitmovinUiPrefix: string, uiWrapperElement: DOM, ) { this.uiWrapperElement = uiWrapperElement; this.eventHandlerMap = { mousedown: this.onMouseOrPointerOrTouch, pointerdown: this.onMouseOrPointerOrTouch, touchstart: this.onMouseOrPointerOrTouch, keydown: this.onKeyDown, focus: this.onFocus, blur: this.onBlur, }; this.registerEventListeners(); } private onKeyDown = (e: KeyboardEvent) => { if (e.metaKey || e.altKey || e.ctrlKey) { return; } this.lastInteractionWasKeyboard = true; }; private onMouseOrPointerOrTouch = () => (this.lastInteractionWasKeyboard = false); private onFocus = ({ target: element }: FocusEvent) => { if ( this.lastInteractionWasKeyboard && isHtmlElement(element) && isBitmovinUi(element, this.bitmovinUiPrefix) && !element.classList.contains(FocusVisibleCssClassName) ) { element.classList.add(FocusVisibleCssClassName); } }; private onBlur = ({ target: element }: FocusEvent) => { if (isHtmlElement(element)) { element.classList.remove(FocusVisibleCssClassName); } }; private registerEventListeners(): void { for (const event in this.eventHandlerMap) { this.uiWrapperElement.on(event, this.eventHandlerMap[event], true); } } private unregisterEventListeners(): void { for (const event in this.eventHandlerMap) { this.uiWrapperElement.off(event, this.eventHandlerMap[event], true); } } public release(): void { this.unregisterEventListeners(); } } function isBitmovinUi(element: Element, bitmovinUiPrefix: string): boolean { return element.id.indexOf(bitmovinUiPrefix) === 0; } function isHtmlElement(element: unknown): element is HTMLElement & { classList: DOMTokenList } { return element instanceof HTMLElement && element.classList instanceof DOMTokenList; }