/** * Fizzy UI utils v3.0.0 * MIT license */ ( function( global, factory ) { // universal module definition if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( global ); } else { // browser global global.fizzyUIUtils = factory( global ); } }( this, function factory( global ) { let utils = {}; // ----- extend ----- // // extends objects utils.extend = function( a, b ) { return Object.assign( a, b ); }; // ----- modulo ----- // utils.modulo = function( num, div ) { return ( ( num % div ) + div ) % div; }; // ----- makeArray ----- // // turn element or nodeList into an array utils.makeArray = function( obj ) { // use object if already an array if ( Array.isArray( obj ) ) 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'; // convert nodeList to array if ( isArrayLike ) return [ ...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 ( elem.matches( 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 ); return elems // check that elem is an actual element .filter( ( elem ) => elem instanceof HTMLElement ) .reduce( ( ffElems, elem ) => { // add elem if no selector if ( !selector ) { ffElems.push( elem ); return ffElems; } // filter & find items if we have a selector // filter if ( elem.matches( selector ) ) { ffElems.push( elem ); } // find children let childElems = elem.querySelectorAll( selector ); // concat childElems to filterFound array ffElems = ffElems.concat( ...childElems ); return ffElems; }, [] ); }; // ----- debounceMethod ----- // utils.debounceMethod = function( _class, methodName, threshold ) { threshold = threshold || 100; // original method let method = _class.prototype[ methodName ]; let timeoutName = methodName + 'Timeout'; _class.prototype[ methodName ] = function() { clearTimeout( this[ timeoutName ] ); let args = arguments; this[ timeoutName ] = setTimeout( () => { method.apply( this, args ); delete this[ timeoutName ]; }, threshold ); }; }; // ----- docReady ----- // utils.docReady = function( onDocReady ) { let readyState = document.readyState; if ( readyState == 'complete' || readyState == 'interactive' ) { // do async to allow for other scripts to run. metafizzy/flickity#441 setTimeout( onDocReady ); } else { document.addEventListener( 'DOMContentLoaded', onDocReady ); } }; // ----- htmlInit ----- // // http://bit.ly/3oYLusc utils.toDashed = function( str ) { return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { return $1 + '-' + $2; } ).toLowerCase(); }; let console = global.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 ); let dataAttr = 'data-' + dashedNamespace; let dataAttrElems = document.querySelectorAll( `[${dataAttr}]` ); let jQuery = global.jQuery; [ ...dataAttrElems ].forEach( ( elem ) => { let attr = elem.getAttribute( dataAttr ); let 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 ); } } ); } ); }; // ----- ----- // return utils; } ) );