jellyfin-web/dashboard-ui/bower_components/fizzy-ui-utils/utils.js
2015-10-12 15:09:56 -04:00

271 lines
6.6 KiB
JavaScript

/**
* Fizzy UI utils v1.0.1
* MIT license
*/
/*jshint browser: true, undef: true, unused: true, strict: true */
( function( window, factory ) {
/*global define: false, module: false, require: false */
'use strict';
// universal module definition
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'doc-ready/doc-ready',
'matches-selector/matches-selector'
], function( docReady, matchesSelector ) {
return factory( window, docReady, matchesSelector );
});
} else if ( typeof exports == 'object' ) {
// CommonJS
module.exports = factory(
window,
require('doc-ready'),
require('desandro-matches-selector')
);
} else {
// browser global
window.fizzyUIUtils = factory(
window,
window.docReady,
window.matchesSelector
);
}
}( window, function factory( window, docReady, matchesSelector ) {
'use strict';
var utils = {};
// ----- extend ----- //
// extends objects
utils.extend = function( a, b ) {
for ( var prop in b ) {
a[ prop ] = b[ prop ];
}
return a;
};
// ----- modulo ----- //
utils.modulo = function( num, div ) {
return ( ( num % div ) + div ) % div;
};
// ----- isArray ----- //
var objToString = Object.prototype.toString;
utils.isArray = function( obj ) {
return objToString.call( obj ) == '[object Array]';
};
// ----- makeArray ----- //
// turn element or nodeList into an array
utils.makeArray = function( obj ) {
var ary = [];
if ( utils.isArray( obj ) ) {
// use object if already an array
ary = obj;
} else if ( obj && typeof obj.length == 'number' ) {
// convert nodeList to array
for ( var i=0, len = obj.length; i < len; i++ ) {
ary.push( obj[i] );
}
} else {
// array of single index
ary.push( obj );
}
return ary;
};
// ----- indexOf ----- //
// index of helper cause IE8
utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) {
return ary.indexOf( obj );
} : function( ary, obj ) {
for ( var i=0, len = ary.length; i < len; i++ ) {
if ( ary[i] === obj ) {
return i;
}
}
return -1;
};
// ----- removeFrom ----- //
utils.removeFrom = function( ary, obj ) {
var index = utils.indexOf( ary, obj );
if ( index != -1 ) {
ary.splice( index, 1 );
}
};
// ----- isElement ----- //
// http://stackoverflow.com/a/384380/182183
utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ?
function isElementDOM2( obj ) {
return obj instanceof HTMLElement;
} :
function isElementQuirky( obj ) {
return obj && typeof obj == 'object' &&
obj.nodeType == 1 && typeof obj.nodeName == 'string';
};
// ----- setText ----- //
utils.setText = ( function() {
var setTextProperty;
function setText( elem, text ) {
// only check setTextProperty once
setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' );
elem[ setTextProperty ] = text;
}
return setText;
})();
// ----- getParent ----- //
utils.getParent = function( elem, selector ) {
while ( 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 ) {
var 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 = [];
for ( var i=0, len = elems.length; i < len; i++ ) {
var elem = elems[i];
// check that elem is an actual element
if ( !utils.isElement( elem ) ) {
continue;
}
// filter & find items if we have a selector
if ( selector ) {
// filter siblings
if ( matchesSelector( elem, selector ) ) {
ffElems.push( elem );
}
// find children
var childElems = elem.querySelectorAll( selector );
// concat childElems to filterFound array
for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
ffElems.push( childElems[j] );
}
} else {
ffElems.push( elem );
}
}
return ffElems;
};
// ----- debounceMethod ----- //
utils.debounceMethod = function( _class, methodName, threshold ) {
// original method
var method = _class.prototype[ methodName ];
var timeoutName = methodName + 'Timeout';
_class.prototype[ methodName ] = function() {
var timeout = this[ timeoutName ];
if ( timeout ) {
clearTimeout( timeout );
}
var args = arguments;
var _this = this;
this[ timeoutName ] = setTimeout( function() {
method.apply( _this, args );
delete _this[ timeoutName ];
}, threshold || 100 );
};
};
// ----- 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();
};
var console = window.console;
/**
* allow user to initialize classes via .js-namespace class
* htmlInit( Widget, 'widgetName' )
* options are parsed from data-namespace-option attribute
*/
utils.htmlInit = function( WidgetClass, namespace ) {
docReady( function() {
var dashedNamespace = utils.toDashed( namespace );
var elems = document.querySelectorAll( '.js-' + dashedNamespace );
var dataAttr = 'data-' + dashedNamespace + '-options';
for ( var i=0, len = elems.length; i < len; i++ ) {
var elem = elems[i];
var attr = elem.getAttribute( dataAttr );
var options;
try {
options = attr && JSON.parse( attr );
} catch ( error ) {
// log error, do not initialize
if ( console ) {
console.error( 'Error parsing ' + dataAttr + ' on ' +
elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
error );
}
continue;
}
// initialize
var instance = new WidgetClass( elem, options );
// make available via $().data('layoutname')
var jQuery = window.jQuery;
if ( jQuery ) {
jQuery.data( elem, namespace, instance );
}
}
});
};
// ----- ----- //
return utils;
}));