API Docs for:
Show:

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 };