Repository URL to install this package:
|
Version:
1.0.2 ▾
|
const matchesSelector = require('./matches-selector')
var utils = {}
// ----- extend ----- //
// extends objects
utils.extend = function(a, b) {
for (let prop in b) {
a[prop] = b[prop]
}
return a
}
// ----- modulo ----- //
utils.modulo = function(num, div) {
return (num % div + div) % div
}
// ----- makeArray ----- //
let arraySlice = Array.prototype.slice
// turn element or nodeList into an array
utils.makeArray = function(obj) {
if (Array.isArray(obj)) {
// use object if already an array
return obj
}
// return empty array if undefined or null. #6
if (obj === null || obj === undefined) {
return []
}
let isArrayLike = typeof obj === 'object' && typeof obj.length === 'number'
if (isArrayLike) {
// convert nodeList to array
return arraySlice.call(obj)
}
// array of single index
return [obj]
}
// ----- removeFrom ----- //
utils.removeFrom = function(ary, obj) {
let index = ary.indexOf(obj)
if (index != -1) {
ary.splice(index, 1)
}
}
// ----- getParent ----- //
utils.getParent = function(elem, selector) {
while (elem.parentNode && elem != document.body) {
elem = elem.parentNode
if (matchesSelector(elem, selector)) {
return elem
}
}
}
// ----- getQueryElement ----- //
// use element as selector string
utils.getQueryElement = function(elem) {
if (typeof elem === 'string') {
return document.querySelector(elem)
}
return elem
}
// ----- handleEvent ----- //
// enable .ontype to trigger from .addEventListener( elem, 'type' )
utils.handleEvent = function(event) {
let method = 'on' + event.type
if (this[method]) {
this[method](event)
}
}
// ----- filterFindElements ----- //
utils.filterFindElements = function(elems, selector) {
// make array of elems
elems = utils.makeArray(elems)
var ffElems = []
elems.forEach(function(elem) {
// check that elem is an actual element
if (!(elem instanceof HTMLElement)) {
return
}
// add elem if no selector
if (!selector) {
ffElems.push(elem)
return
}
// filter & find items if we have a selector
// filter
if (matchesSelector(elem, selector)) {
ffElems.push(elem)
}
// find children
let childElems = elem.querySelectorAll(selector)
// concat childElems to filterFound array
for (let i = 0; i < childElems.length; i++) {
ffElems.push(childElems[i])
}
})
return ffElems
}
// ----- debounceMethod ----- //
utils.debounceMethod = function(_class, methodName, threshold) {
threshold = threshold || 100
// original method
var method = _class.prototype[methodName]
var timeoutName = methodName + 'Timeout'
_class.prototype[methodName] = function() {
let timeout = this[timeoutName]
clearTimeout(timeout)
var args = arguments
var _this = this
this[timeoutName] = setTimeout(function() {
method.apply(_this, args)
delete _this[timeoutName]
}, threshold)
}
}
// ----- docReady ----- //
utils.docReady = function(callback) {
let readyState = document.readyState
if (readyState == 'complete' || readyState == 'interactive') {
// do async to allow for other scripts to run. metafizzy/flickity#441
setTimeout(callback)
} else {
document.addEventListener('DOMContentLoaded', callback)
}
}
// ----- htmlInit ----- //
// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
utils.toDashed = function(str) {
return str
.replace(/(.)([A-Z])/g, function(match, $1, $2) {
return $1 + '-' + $2
})
.toLowerCase()
}
let console = window.console
/**
* allow user to initialize classes via [data-namespace] or .js-namespace class
* htmlInit( Widget, 'widgetName' )
* options are parsed from data-namespace-options
*/
utils.htmlInit = function(WidgetClass, namespace) {
utils.docReady(function() {
let dashedNamespace = utils.toDashed(namespace)
var dataAttr = 'data-' + dashedNamespace
var dataAttrElems = document.querySelectorAll('[' + dataAttr + ']')
var jsDashElems = document.querySelectorAll('.js-' + dashedNamespace)
var elems = utils
.makeArray(dataAttrElems)
.concat(utils.makeArray(jsDashElems))
var dataOptionsAttr = dataAttr + '-options'
var jQuery = window.jQuery
elems.forEach(function(elem) {
let attr =
elem.getAttribute(dataAttr) || elem.getAttribute(dataOptionsAttr)
var options
try {
options = attr && JSON.parse(attr)
} catch (error) {
// log error, do not initialize
if (console) {
console.error(
'Error parsing ' + dataAttr + ' on ' + elem.className + ': ' + error
)
}
return
}
// initialize
let instance = new WidgetClass(elem, options)
// make available via $().data('namespace')
if (jQuery) {
jQuery.data(elem, namespace, instance)
}
})
})
}
module.exports = utils