/**
* this module contains all the helper methods for dom manipulation or access
* @module utils/dom
* @author Aamir khan
*/
import assign from "lodash/assign";
import isElement from "lodash/isElement";
import split from "lodash/split";
import { yell } from "./common";
/**
* a jquery like css dom selector which returns dom node
* @param {string} selector - css selector
* @returns {DOMElement} dom node
*/
export const select = document.querySelector.bind(document);
/**
* creates a new dom element
* @param {string} tagName - tag name of the element
* @returns {DOMElement} dom node
*/
export const newElement = document.createElement.bind(document);
/**
* add an even listener to an element given by the selector
* @param {String} selector a css selector along with the event name seperated by a colon
* @param {Function} handler function to be called when the event is triggered
* @returns {Function} function to remove the event listener
* @example
* // specify the css selector followed by the event name with semilcolon in between
const removePlayClick = on('#play:click', () => player.play());
// to add listener on gloal document
on(':keydown', (e) => {{);
*
*/
export const on = (selector, handler, node) => {
if(isElement(node)){
node.addEventListener(selector, handler);
return () => node.removeEventListener(selector, handler);
}
const [s, event] = split(selector, ':');
const el = s ? select(s) : document;
el.addEventListener(event, handler);
return () => el.removeEventListener(event, handler);
}
/**
* dispatch a custom event on document object
* @param {String} evtName - custom event name
* @param {Object} data - data thay you want to pass to the event listener
* @param {Object} options - options to pass while creating the custom event
*/
export const dispatchCustomEvent = (evtName, data, options) => {
const opt = options || { bubbles: false };
const evt = new CustomEvent(evtName,
assign({}, opt, { detail: data }));
document.dispatchEvent(evt);
};
/**
* load a script from the given url
* @author Aamir Khan
* @param {String} src - url of the script
* @param {Function} onload - callback function to be called when the script is loaded
*/
export const addScript = (src, onload) => {
const script = newElement('script');
script.src = src;
script.type = 'text/javascript';
script.onerror = yell(`Failed to load ${src}`);
script.async = false;
script.onload = onload;
select('head').appendChild(script);
}