File: development/js/utils/helpers.js
import {isString, isObject} from './type';
import {each} from './enums';
import {camelCase, dashCase} from './string';
/**
* Various uncategorised helpers
*
* @module Utils
* @class Utils.Helpers
* @static
*/
export const cssClass = (function () {
let support = (document.createElement('div')).classList != null;
if (support) {
return {
add(node, clnm) {
node.classList.add(clnm);
},
remove(node, clnm) {
node.classList.remove(clnm);
},
toggle(node, clnm) {
node.classList.toggle(clnm);
},
has(node, clnm) {
return node.classList.contains(clnm);
}
}
}
return {
add(node, clnm) {
if (!this.has(node, clnm)) {
node.className = node.
className.
split(/\s+/).
concat(clnm).
join(' ');
}
},
remove(node, clnm) {
if (this.has(node, clnm)) {
node.className = node.
className.
replace(new RegExp(`\\s?${clnm}\\b`, 'g'), '');
}
},
toggle(node, clnm) {
if (this.has(node, clnm)) {
return this.remove(node, clnm);
}
this.add(node, clnm);
},
has(node, clnm) {
return new RegExp(`\\s?${clnm}\\b`, 'g').test(node.className);
}
}
})();
/**
* Creates new nodes and allows to set attributes, styles and data- attributes
* directly on creation
*
* @method tag
* @for Utils.Helpers
* @param {string} nodeName Name of the node to create
* @param {object} attrs Key:value pairs to set as attributes or properties
* @return {Node} A node of the given type
*
* @example
* import {tag} from './utils/helpers';
*
* var div = tag('div', {
* className: 'myclass-1 myclass-2',
* innerHTML: 'This is the content of the div',
* data: {
* widget: 'MyWidget',
* defer: 'true'
* },
* style: {
* display: 'block',
* position: 'absolute',
* top: 0,
* left: 0
* zIndex: 100
* }
* });
*/
export const tag = function (nodeName, attrs) {
var elem;
if (!isString(nodeName)) {
throw new TypeError('Cannot create a <tag> of type ' + nodeName);
}
elem = document.createElement(nodeName);
if (isObject(attrs)) {
each(attrs, (val, key) => {
if (key === 'style') {
return each(val, (cssVal, cssRule) => {
elem.style[camelCase(cssRule)] = cssVal;
});
}
if (key === 'data') {
return each(val, (dataVal, dataKey) => {
if (elem.dataset) { elem.dataset[camelCase(dataKey)] = dataVal; }
else { elem.setAttribute(dashCase(dataKey), dataVal); }
});
}
elem[key] = val;
});
}
return elem;
}
/**
* Calculates the size of scrollbars in pixels and returns that
*
* @method getScrollBarSize
* @for Utils.Helpers
* @return {number} Size of scrollbars in pixels
*
* @example
* import {getScrollBarSize} from './utils/helpers';
*
* getScrollBarSize(); // -> Integer
*/
export const getScrollBarSize = (() => {
var div = document.createElement('div'),
w;
div.style.position = 'absolute';
div.style.top = '-9999px';
div.style.left = '-9999px';
div.style.width = '100px';
div.style.height = '100px';
div.style.overflow = 'scroll';
document.body.appendChild(div);
w = div.offsetWidth - div.clientWidth;
document.body.removeChild(div);
div = null;
return () => w;
})();
export default { cssClass, tag, getScrollBarSize };