121 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// ==========================================================================
 | 
						|
// Event utils
 | 
						|
// ==========================================================================
 | 
						|
 | 
						|
import is from './is';
 | 
						|
 | 
						|
// Check for passive event listener support
 | 
						|
// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
 | 
						|
// https://www.youtube.com/watch?v=NPM6172J22g
 | 
						|
const supportsPassiveListeners = (() => {
 | 
						|
    // Test via a getter in the options object to see if the passive property is accessed
 | 
						|
    let supported = false;
 | 
						|
    try {
 | 
						|
        const options = Object.defineProperty({}, 'passive', {
 | 
						|
            get() {
 | 
						|
                supported = true;
 | 
						|
                return null;
 | 
						|
            },
 | 
						|
        });
 | 
						|
        window.addEventListener('test', null, options);
 | 
						|
        window.removeEventListener('test', null, options);
 | 
						|
    } catch (e) {
 | 
						|
        // Do nothing
 | 
						|
    }
 | 
						|
 | 
						|
    return supported;
 | 
						|
})();
 | 
						|
 | 
						|
// Toggle event listener
 | 
						|
export function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {
 | 
						|
    // Bail if no element, event, or callback
 | 
						|
    if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // Allow multiple events
 | 
						|
    const events = event.split(' ');
 | 
						|
 | 
						|
    // Build options
 | 
						|
    // Default to just the capture boolean for browsers with no passive listener support
 | 
						|
    let options = capture;
 | 
						|
 | 
						|
    // If passive events listeners are supported
 | 
						|
    if (supportsPassiveListeners) {
 | 
						|
        options = {
 | 
						|
            // Whether the listener can be passive (i.e. default never prevented)
 | 
						|
            passive,
 | 
						|
            // Whether the listener is a capturing listener or not
 | 
						|
            capture,
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    // If a single node is passed, bind the event listener
 | 
						|
    events.forEach(type => {
 | 
						|
        if (this && this.eventListeners && toggle) {
 | 
						|
            // Cache event listener
 | 
						|
            this.eventListeners.push({ element, type, callback, options });
 | 
						|
        }
 | 
						|
 | 
						|
        element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
// Bind event handler
 | 
						|
export function on(element, events = '', callback, passive = true, capture = false) {
 | 
						|
    toggleListener.call(this, element, events, callback, true, passive, capture);
 | 
						|
}
 | 
						|
 | 
						|
// Unbind event handler
 | 
						|
export function off(element, events = '', callback, passive = true, capture = false) {
 | 
						|
    toggleListener.call(this, element, events, callback, false, passive, capture);
 | 
						|
}
 | 
						|
 | 
						|
// Bind once-only event handler
 | 
						|
export function once(element, events = '', callback, passive = true, capture = false) {
 | 
						|
    function onceCallback(...args) {
 | 
						|
        off(element, events, onceCallback, passive, capture);
 | 
						|
        callback.apply(this, args);
 | 
						|
    }
 | 
						|
 | 
						|
    toggleListener.call(this, element, events, onceCallback, true, passive, capture);
 | 
						|
}
 | 
						|
 | 
						|
// Trigger event
 | 
						|
export function triggerEvent(element, type = '', bubbles = false, detail = {}) {
 | 
						|
    // Bail if no element
 | 
						|
    if (!is.element(element) || is.empty(type)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // Create and dispatch the event
 | 
						|
    const event = new CustomEvent(type, {
 | 
						|
        bubbles,
 | 
						|
        detail: Object.assign({}, detail, {
 | 
						|
            plyr: this,
 | 
						|
        }),
 | 
						|
    });
 | 
						|
 | 
						|
    // Dispatch the event
 | 
						|
    element.dispatchEvent(event);
 | 
						|
}
 | 
						|
 | 
						|
// Unbind all cached event listeners
 | 
						|
export function unbindListeners() {
 | 
						|
    if (this && this.eventListeners) {
 | 
						|
        this.eventListeners.forEach(item => {
 | 
						|
            const { element, type, callback, options } = item;
 | 
						|
            element.removeEventListener(type, callback, options);
 | 
						|
        });
 | 
						|
 | 
						|
        this.eventListeners = [];
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Run method when / if player is ready
 | 
						|
export function ready() {
 | 
						|
    return new Promise(
 | 
						|
        resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),
 | 
						|
    ).then(() => {});
 | 
						|
}
 |