├── .editorconfig ├── .gitignore ├── .jsfmtrc ├── LICENSE ├── README.md ├── array ├── fillArray.js ├── getClosestNumber.js ├── shuffle.js └── toArray.js ├── date └── daysInMonth.js ├── detect ├── getOrientation.js ├── getPixelRatio.js ├── hasAppleColorEmoji.js ├── hasEmojiSupport.js ├── hasLocalStorageSupport.js ├── hasSvgSupport.js ├── hasTouchScreen.js ├── hasWebComponentSupport.js ├── isAndroid.js ├── isFireFoxOSApp.js ├── isIOS.js └── isModernBrowser.js ├── element ├── hasHorizontalScrollBar.js ├── hasVerticalScrollBar.js └── isHidden.js ├── function ├── debounce.js ├── delay.js ├── isEmpty.js ├── noop.js ├── once.js ├── poll.js └── selectContent.js ├── number ├── currencyFormat.js ├── pad.js └── random.js ├── object ├── extend.js ├── isFunction.js └── isString.js ├── package.json ├── string ├── removeLeadingSlash.js ├── slugify.js ├── stripEntities.js ├── stripTags.js └── ucfirst.js └── url ├── getAbsoluteUrl.js ├── getCurrentQueryString.js ├── getUrlHash.js └── getUrlVars.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | indent_style = space 11 | indent_size = 4 12 | 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | 18 | [*.md] 19 | trim_trailing_whitespace = false 20 | 21 | [*.json] 22 | indent_size = 2 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS files 2 | ._* 3 | .DS_Store 4 | Thumbs.db 5 | 6 | # Files that might appear on external disk 7 | .Spotlight-V100 8 | .Trashes 9 | 10 | # Always-ignore extensions 11 | *~ 12 | *.diff 13 | *.err 14 | *.log 15 | *.orig 16 | *.pyc 17 | *.rej 18 | *.sass-cache 19 | *.sw? 20 | *.vi 21 | *.cache 22 | *.idea 23 | *.sublime-* 24 | 25 | # Folders 26 | node_modules 27 | -------------------------------------------------------------------------------- /.jsfmtrc: -------------------------------------------------------------------------------- 1 | { 2 | "formatting": "https://github.com/ionutvmi/sublime-jsfmt#formatting-rules", 3 | "plugins": [ 4 | "esformatter-quotes", 5 | "esformatter-semicolons", 6 | "esformatter-braces" 7 | ], 8 | "quotes": { 9 | "type": "single", 10 | "avoidEscape": false 11 | }, 12 | "indent": { 13 | "value": " " // four spaces 14 | }, 15 | "whiteSpace": { 16 | "value" : " ", 17 | "removeTrailing" : 1, 18 | 19 | "before": { 20 | "ArgumentList": 0, 21 | "ArgumentListObjectExpression": 1, 22 | "ArgumentListFunctionExpression": 0, 23 | "ArgumentListArrayExpression": 1 24 | }, 25 | "after": { 26 | "ArgumentList": 0, 27 | "ArgumentListObjectExpression": 1, 28 | "ArgumentListFunctionExpression": 0, 29 | "ArgumentListArrayExpression": 1 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 André Ruffert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A collection of some JavaScript utility functions for everyday use. 2 | 3 | Take what you need! :v: 4 | 5 | ### array 6 | * [fillArray()](/array/fillArray.js) 7 | * [getClosestNumber()](/array/getClosestNumber.js) 8 | * [shuffle()](/array/shuffle.js) 9 | * [toArray()](/array/toArray.js) 10 | 11 | ### date 12 | * [daysInMonth()](/date/daysInMonth.js) 13 | 14 | ### detect 15 | * [getOrientation()](/detect/getOrientation.js) 16 | * [getPixelRatio()](/detect/getPixelRatio.js) 17 | * [hasAppleColorEmoji()](/detect/hasAppleColorEmoji.js) 18 | * [hasEmojiSupport()](/detect/hasEmojiSupport.js) 19 | * [hasLocalStorageSupport()](/detect/hasLocalStorageSupport.js) 20 | * [hasSvgSupport()](/detect/hasSvgSupport.js) 21 | * [hasTouchScreen()](/detect/hasTouchScreen.js) 22 | * [isAndroid()](/detect/isAndroid.js) 23 | * [isFireFoxOSApp()](/detect/isFireFoxOSApp.js) 24 | * [isIOS()](/detect/isIOS.js) 25 | * [isModernBrowser()](/detect/isModernBrowser.js) 26 | * [hasWebComponentSupport()](/detect/hasWebComponentSupport.js) 27 | 28 | ### element 29 | * [hasHorizontalScrollBar()](/element/hasHorizontalScrollBar.js) 30 | * [hasVerticalScrollBar()](/element/hasVerticalScrollBar.js) 31 | * [isHidden()](/element/isHidden.js) 32 | 33 | ### function 34 | * [debounce()](/function/debounce.js) 35 | * [delay()](/function/delay.js) 36 | * [isEmpty()](/function/isEmpty.js) 37 | * [noop()](/function/noop.js) 38 | * [once()](/function/once.js) 39 | * [poll()](/function/poll.js) 40 | * [selectContent()](/function/selectContent.js) 41 | 42 | ### number 43 | * [currencyFormat()](/number/currencyFormat.js) 44 | * [pad()](/number/pad.js) 45 | * [random()](/number/random.js) 46 | 47 | ### object 48 | * [extend()](/object/extend.js) 49 | * [isFunction()](/object/isFunction.js) 50 | * [isString()](/object/isString.js) 51 | 52 | ### string 53 | * [removeLeadingSlash()](/string/removeLeadingSlash.js) 54 | * [slugify()](/string/slugify.js) 55 | * [stripEntities()](/string/stripEntities.js) 56 | * [stripTags()](/string/stripTags.js) 57 | * [ucfirst()](/string/ucfirst.js) 58 | 59 | ### url 60 | * [getAbsoluteUrl()](/url/getAbsoluteUrl.js) 61 | * [getCurrentQueryString()](/url/getCurrentQueryString.js) 62 | * [getUrlHash()](/url/getUrlHash.js) 63 | * [getUrlVars()](/url/getUrlVars.js) 64 | 65 | 66 | ## License 67 | 68 | MIT © [André Ruffert](http://andreruffert.com) 69 | -------------------------------------------------------------------------------- /array/fillArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Create and fill an array 3 | * 4 | * @category Array 5 | * @param {Number} Length of the Array 6 | * @param {Function} Map function to call on every element of the array 7 | * @return {Array} 8 | * @example 9 | * 10 | * fillArray(5, (x, i) => i); 11 | * // => [0, 1, 2, 3, 4] 12 | */ 13 | 14 | const fillArray = (arrayLength, mapFn) => Array.from(new Array(arrayLength), mapFn); 15 | -------------------------------------------------------------------------------- /array/getClosestNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the closest number out of an array 3 | * 4 | * @category Array 5 | * @param {Array} arr 6 | * @param {Number} number 7 | * @return {Number} 8 | * @example 9 | * 10 | * getClosestNumber([10, 20, 30], 12); 11 | * // => 10 12 | */ 13 | function getClosestNumber(arr, number) { 14 | return arr.reduce(function (prev, curr) { 15 | return (Math.abs(curr - number) < Math.abs(prev - number) ? curr : prev); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /array/shuffle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Shuffle a given array (Fisher-Yates Shuffling Algorithm) 3 | * @param {Array} arr 4 | * @return {Array} 5 | */ 6 | function shuffle(arr) { 7 | var i, j, temp; 8 | for (i = arr.length - 1; i > 0; i--) { 9 | j = Math.floor(Math.random() * (i + 1)); 10 | temp = arr[i]; 11 | arr[i] = arr[j]; 12 | arr[j] = temp; 13 | } 14 | return arr; 15 | } 16 | -------------------------------------------------------------------------------- /array/toArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts a NodeList to Array 3 | * 4 | * @category Array 5 | * @param {NodeList} NodeList e.g. document.querySelectorAll('div') 6 | * @return {Array} Returns a new array of `NodeList` items. 7 | * @example 8 | * 9 | * toArray(document.querySelectorAll('div')); 10 | * // => [div, div, …] 11 | */ 12 | function toArray(nodeList) { 13 | return Array.prototype.slice.call(nodeList); 14 | } 15 | -------------------------------------------------------------------------------- /date/daysInMonth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the number of days in a month 3 | * 4 | * @category Date 5 | * @param {Integer} year The year 6 | * @param {Integer} month The month 7 | * @return {Integer} Returns the number of days in the given month 8 | * @example 9 | * 10 | * daysInMonth(2015, 2); 11 | * // => 28 12 | */ 13 | function daysInMonth(year, month) { 14 | return (new Date(year, month, 0)).getDate(); 15 | } 16 | -------------------------------------------------------------------------------- /detect/getOrientation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect the device screen orientation. 3 | * 4 | * @category Detect 5 | * @return {String} portrait or landscape 6 | * @example 7 | * 8 | * getOrientation(); 9 | * // => portrait|landscape 10 | */ 11 | function getOrientation() { 12 | var orientation = ['portrait', 'landscape']; 13 | if (typeof window.orientation !== 'undefined') { 14 | return (window.orientation === 0) ? orientation[0] : orientation[1]; 15 | } 16 | 17 | return (window.innerHeight > window.innerWidth) ? orientation[0] : orientation[1]; 18 | } 19 | -------------------------------------------------------------------------------- /detect/getPixelRatio.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect the device pixel ratio. 3 | * 4 | * @category Detect 5 | * @return {Number} 6 | * @example 7 | * 8 | * getPixelRatio(); 9 | * // => 1 10 | */ 11 | function getPixelRatio() { 12 | return Math.floor(window.devicePixelRatio) || 1; 13 | } 14 | -------------------------------------------------------------------------------- /detect/hasAppleColorEmoji.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check if a user's computer has the AppleColorEmoji font. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * hasAppleColorEmoji(); 9 | * // => true|false 10 | */ 11 | function hasAppleColorEmoji() { 12 | var widths = []; 13 | var tags = [ 14 | document.createElement('span'), 15 | document.createElement('span') 16 | ]; 17 | tags.forEach(function(tag, i) { 18 | tag.innerText = '☺'; 19 | tag.style.fontFamily = i === 1 ? 'thisisnotafont' : 'AppleColorEmoji'; 20 | document.body.appendChild(tag); 21 | widths.push(tag.offsetWidth); 22 | document.body.removeChild(tag); 23 | }); 24 | return widths[0] !== widths[1]; 25 | } 26 | -------------------------------------------------------------------------------- /detect/hasEmojiSupport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detects support for emoji character sets. 3 | * 4 | * Based on the Modernizr emoji detection. 5 | * https://github.com/Modernizr/Modernizr/blob/347ddb078116cee91b25b6e897e211b023f9dcb4/feature-detects/emoji.js 6 | * 7 | * @category Detect 8 | * @return {Boolean} true or false 9 | * @example 10 | * 11 | * hasEmojiSupport() 12 | * // => true|false 13 | */ 14 | function hasEmojiSupport() { 15 | var pixelRatio = window.devicePixelRatio || 1; 16 | var offset = 12 * pixelRatio; 17 | var node = document.createElement('canvas'); 18 | 19 | // canvastext support 20 | if (!node.getContext || 21 | !node.getContext('2d') || 22 | typeof node.getContext('2d').fillText !== 'function') { 23 | return false; 24 | } 25 | 26 | var ctx = node.getContext('2d'); 27 | 28 | ctx.fillStyle = '#f00'; 29 | ctx.textBaseline = 'top'; 30 | ctx.font = '32px Arial'; 31 | ctx.fillText('\ud83d\udc28', 0, 0); // U+1F428 KOALA 32 | return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0; 33 | } 34 | -------------------------------------------------------------------------------- /detect/hasLocalStorageSupport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect localStorage support. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * hasLocalStorageSupport(); 9 | * // => true|false 10 | */ 11 | function hasLocalStorageSupport() { 12 | var keyName = keyValue = 'js-utils'; 13 | 14 | try { 15 | localStorage.setItem(keyName, keyValue); 16 | localStorage.removeItem(keyName); 17 | return true; 18 | } catch (e) { 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /detect/hasSvgSupport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect native SVG support. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * hasSvgSupport(); 9 | * // => true|false 10 | */ 11 | function hasSvgSupport() { 12 | return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; 13 | } 14 | -------------------------------------------------------------------------------- /detect/hasTouchScreen.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect if the device has a Touchscreen. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * hasTouchScreen(); 9 | * // => true|false 10 | */ 11 | function hasTouchScreen() { 12 | return ('ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch) ? !0 : !1; 13 | } 14 | -------------------------------------------------------------------------------- /detect/hasWebComponentSupport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect native Web Component support. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * hasWebcomponentSupport(); 9 | * // => true|false 10 | */ 11 | function hasWebcomponentSupport() { 12 | if ('registerElement' in document && 13 | 'createShadowRoot' in HTMLElement.prototype && 14 | 'import' in document.createElement('link') && 15 | 'content' in document.createElement('template')) { 16 | 17 | // We're using a browser with native Web Component support. 18 | return true; 19 | } 20 | return false; 21 | } 22 | -------------------------------------------------------------------------------- /detect/isAndroid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect if we have a Android device. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * isAndroid(); 9 | * // => true|false 10 | */ 11 | function isAndroid() { 12 | return /Android/i.test(navigator.userAgent); 13 | } 14 | -------------------------------------------------------------------------------- /detect/isFireFoxOSApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect if we have a isFireFoxOSApp. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * isFireFoxOSApp(); 9 | * // => true|false 10 | */ 11 | function isFireFoxOSApp() { 12 | return navigator.mozApps && !window.locationbar.visible; 13 | } 14 | -------------------------------------------------------------------------------- /detect/isIOS.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect if we have a iOS device. 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * isIOS(); 9 | * // => true|false 10 | */ 11 | function isIOS() { 12 | return /(iPad|iPhone|iPod touch)/i.test(navigator.userAgent); 13 | } 14 | -------------------------------------------------------------------------------- /detect/isModernBrowser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple feature detection to identify HTML5 Browsers ([gt ie9]). 3 | * 4 | * @category Detect 5 | * @return {Boolean} true or false 6 | * @example 7 | * 8 | * isModernBrowser(); 9 | * // => true|false 10 | */ 11 | function isModernBrowser() { 12 | if ('querySelector' in document && 13 | 'localStorage' in window && 14 | 'addEventListener' in window) { 15 | 16 | return true; 17 | } 18 | return false; 19 | } 20 | -------------------------------------------------------------------------------- /element/hasHorizontalScrollBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect whether a DOM `element` has a visible horizontal scrollbar. 3 | * 4 | * @category Element 5 | * @param {Element} element 6 | * @return {Boolean} Returns `true` if `element` has a horizontal scrollbar, else `false`. 7 | * @example 8 | * 9 | * hasHorizontalScrollBar(document.querySelector('.element')); 10 | * // => true|false 11 | */ 12 | function hasHorizontalScrollBar(element) { 13 | return element ? element.scrollWidth > element.offsetWidth : false; 14 | } 15 | -------------------------------------------------------------------------------- /element/hasVerticalScrollBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect whether a DOM `element` has a visible vertical scrollbar. 3 | * 4 | * @category Element 5 | * @param {Element} element 6 | * @return {Boolean} Returns `true` if `element` has a vertical scrollbar, else `false`. 7 | * @example 8 | * 9 | * hasVerticalScrollBar(document.querySelector('.element')); 10 | * // => true|false 11 | */ 12 | function hasVerticalScrollBar(element) { 13 | return element ? element.scrollHeight > element.offsetHeight : false; 14 | } 15 | -------------------------------------------------------------------------------- /element/isHidden.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check if a `element` is visible in the DOM. 3 | * (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent) 4 | * 5 | * @category Element 6 | * @param {Element} element 7 | * @return {Boolean} Returns `true` if `element` is hidden, else `false`. 8 | * @example 9 | * 10 | * isHidden(document.querySelector('.element')); 11 | * // => true|false 12 | */ 13 | function isHidden(element) { 14 | return (element && element.offsetParent === null); 15 | } 16 | -------------------------------------------------------------------------------- /function/debounce.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a debounced function that will make sure 3 | * the given function is not triggered too much. 4 | * 5 | * @category Function 6 | * @param {Function} fn Function to debounce. 7 | * @param {Number} debounceDuration OPTIONAL (defaults to 100ms) 8 | * The amount of time in milliseconds for which we will debounce the function. 9 | * @return {Function} 10 | * @example 11 | * 12 | * // avoid costly calculations while the window size is in flux 13 | * jQuery(window).on('resize', debounce(calculateLayout, 150)); 14 | */ 15 | function debounce(fn, debounceDuration) { 16 | debounceDuration = debounceDuration || 100; 17 | return function() { 18 | if (!fn.debouncing) { 19 | var args = Array.prototype.slice.apply(arguments); 20 | fn.lastReturnVal = fn.apply(window, args); 21 | fn.debouncing = true; 22 | } 23 | clearTimeout(fn.debounceTimeout); 24 | fn.debounceTimeout = setTimeout(function() { 25 | fn.debouncing = false; 26 | }, debounceDuration); 27 | 28 | return fn.lastReturnVal; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /function/delay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Delays a function for the given number of milliseconds, 3 | * and then calls it with the arguments supplied. 4 | * 5 | * @category Function 6 | * @param {Function} fn 7 | * @param {Nmber} wait 8 | * @example 9 | * 10 | * delay(function() { 11 | * console.log('msg'); 12 | * }, 1000); 13 | * // => logs 'msg' after one second 14 | */ 15 | function delay(fn, wait) { 16 | var args = Array.prototype.slice.call(arguments, 2); 17 | return setTimeout(function() { 18 | return fn.apply(null, args); 19 | }, wait); 20 | } 21 | -------------------------------------------------------------------------------- /function/isEmpty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Works across strings, arrays & objects. 3 | * 4 | * @category Function 5 | * @example 6 | * 7 | * isEmpty(null); // => true 8 | * 9 | * isEmpty(''); // => true 10 | * isEmpty('helloha'); // => false 11 | * 12 | * isEmpty([]); // => true 13 | * isEmpty([1, 2, 3]); // => false 14 | * 15 | * isEmpty({}); // => true 16 | * isEmpty({ 'a': 1 }); // => false 17 | */ 18 | 19 | const isEmpty = (obj = {}) => obj ? !Object.keys(obj).length : true; 20 | -------------------------------------------------------------------------------- /function/noop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Function that does nothing. 3 | * 4 | * @category Function 5 | * @example 6 | * 7 | * noop(); 8 | * // => nothing 9 | */ 10 | function noop() {} 11 | -------------------------------------------------------------------------------- /function/once.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A wrapper for a function which you only want to run once. 3 | * 4 | * @category Function 5 | * @param {Function} fn 6 | * @param {[type]} context 7 | * @return {[type]} 8 | * @example 9 | * 10 | * var execOnce = once(function() { 11 | * console.log('executed!'); 12 | * }); 13 | * 14 | * execOnce(); 15 | * // => logs "executed!" 16 | * 17 | * execOnce(); 18 | * // => logs nothing 19 | */ 20 | function once(fn, context) { 21 | var result; 22 | 23 | return function() { 24 | if (fn) { 25 | result = fn.apply(context || this, arguments); 26 | fn = null; 27 | } 28 | 29 | return result; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /function/poll.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check for a desired state at intervals 3 | * @param {Function} fn 4 | * @param {Function} callback 5 | * @param {Function} errback 6 | * @param {Number} timeout 7 | * @param {Number} interval 8 | * @example 9 | * 10 | * // Ensure a element is visible 11 | * poll( 12 | * function() { 13 | * return document.getElementById('element').offsetWidth > 0; 14 | * }, 15 | * function() { 16 | * // Done, success callback 17 | * }, 18 | * function() { 19 | * // Error, failure callback 20 | * } 21 | * ); 22 | */ 23 | function poll(fn, callback, errback, timeout, interval) { 24 | var endTime = Number(new Date()) + (timeout || 2000); 25 | interval = interval || 100; 26 | 27 | (function p() { 28 | // If the condition is met, we're done! 29 | if(fn()) { 30 | callback(); 31 | } 32 | // If the condition isn't met but the timeout hasn't elapsed, go again 33 | else if (Number(new Date()) < endTime) { 34 | setTimeout(p, interval); 35 | } 36 | // Didn't match and too much time, reject! 37 | else { 38 | errback(new Error('timed out for ' + fn + ': ' + arguments)); 39 | } 40 | })(); 41 | } 42 | -------------------------------------------------------------------------------- /function/selectContent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Select all the content of an element. 3 | * 4 | * @category Function 5 | * @param {Element} 6 | * @example 7 | * 8 | * selectContent(document.querySelector('.element')); 9 | */ 10 | function selectContent(element) { 11 | var range = document.createRange(); 12 | var selection = window.getSelection(); 13 | range.selectNodeContents(element); 14 | selection.removeAllRanges(); 15 | selection.addRange(range); 16 | } 17 | -------------------------------------------------------------------------------- /number/currencyFormat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a number into currency format 3 | * @param {Number} amount 4 | * @param {String} options.thousand 5 | * @param {String} options.decimal 6 | * @param {Number} options.fractions 7 | * @return {String} 8 | */ 9 | function currencyFormat(amount, {thousand = ',', decimal = '.', fractions = 2} = {}) { 10 | const delimiter = {thousand, decimal}; 11 | return amount 12 | .toFixed(fractions) 13 | .replace('.', delimiter.decimal) 14 | .replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${delimiter.thousand}`); 15 | } 16 | -------------------------------------------------------------------------------- /number/pad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Pad a number with leading zeroes so the resulting string is "length" length. 3 | * If length is 2 and the passed in number is 5 the value returned is 05. 4 | * 5 | * @category Number 6 | * @param {Number} number 7 | * @param {Number} length 8 | * @return {String} 9 | * @example 10 | * 11 | * pad(1, 5); 12 | * // => 00001 13 | */ 14 | function pad(number, length) { 15 | var str = '' + number; 16 | while (str.length < length) { 17 | str = '0' + str; 18 | } 19 | return str; 20 | } 21 | -------------------------------------------------------------------------------- /number/random.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a random value between `min` and `max` 3 | * @param {Number} min 4 | * @param {NUmber} max 5 | * @param {Boolean} integer 6 | * @return {Number} 7 | * @example 8 | * 9 | * rand(2,5); // float random between 2 and 5 inclusive 10 | * rand(1,100,true); // integer random between 1 and 100 11 | */ 12 | function random(min, max, integer) { 13 | var r = Math.random() * (max - min) + min; 14 | return integer ? r|0 : r; 15 | } 16 | -------------------------------------------------------------------------------- /object/extend.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Extend a given object with all the properties in passed-in object(s). 3 | * 4 | * @category Object 5 | * @param {Object} obj 6 | * @return {Object} 7 | * @example 8 | * 9 | * extend({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); 10 | * // => { 'user': 'fred', 'age': 40 } 11 | */ 12 | function extend(obj) { 13 | var i, l, prop, source; 14 | for (i = 1, l = arguments.length; i < l; ++i) { 15 | source = arguments[i]; 16 | for (prop in source) { 17 | if (hasOwnProperty.call(source, prop)) { 18 | obj[prop] = source[prop]; 19 | } 20 | } 21 | } 22 | return obj; 23 | } 24 | -------------------------------------------------------------------------------- /object/isFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * isFunction 3 | * 4 | * @category Object 5 | * @param {Object} obj 6 | * @return {Boolean} Returns `true` if object is a Function, else `false`. 7 | * @example 8 | * 9 | * isFunction(obj); 10 | * // => true|false 11 | */ 12 | function isFunction(obj) { 13 | return typeof obj === 'function'; 14 | } 15 | -------------------------------------------------------------------------------- /object/isString.js: -------------------------------------------------------------------------------- 1 | /** 2 | * isString 3 | * 4 | * @category Object 5 | * @param {Object} obj 6 | * @return {Boolean} Returns `true` if object is a String, else `false`. 7 | * @example 8 | * 9 | * isString(obj); 10 | * // => true|false 11 | */ 12 | function isString(obj) { 13 | return typeof obj === 'string' || obj instanceof String; 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-utils", 3 | "version": "1.0.0", 4 | "description": "A collection of some JavaScript utility functions", 5 | "scripts": { 6 | "jsfmt": "node ./node_modules/jsfmt/bin/jsfmt -w **/*.js" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/andreruffert/js-utils.git" 11 | }, 12 | "author": "André Ruffert", 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com/andreruffert/js-utils/issues" 16 | }, 17 | "homepage": "https://github.com/andreruffert/js-utils", 18 | "devDependencies": { 19 | "esformatter-quotes": "^1.0.0", 20 | "esformatter-semicolons": "^1.0.3", 21 | "jsfmt": "^0.4.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /string/removeLeadingSlash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Remove leading slashes from a given string 3 | * 4 | * @category String 5 | * @param {String} str 6 | * @return {String} 7 | * * @example 8 | * 9 | * removeLeadingSlash('/some/path'); 10 | * // => "some/path" 11 | */ 12 | function removeLeadingSlash(str) { 13 | return str.replace(/^\/+/g, ''); 14 | } 15 | -------------------------------------------------------------------------------- /string/slugify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a string into a URL slug by removing non-URL friendly 3 | * characters and replacing spaces with dashes. 4 | * 5 | * @category String 6 | * @param {String} str 7 | * @return {String} URL slug 8 | * @example 9 | * 10 | * slugify('My Title'); 11 | * // => "my-title" 12 | */ 13 | function slugify(str) { 14 | str = (str || '') 15 | .toLowerCase() 16 | .replace(/[^\w ]+/g,'') 17 | .replace(/ +/g,'-'); 18 | 19 | return str; 20 | } 21 | -------------------------------------------------------------------------------- /string/stripEntities.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Strip HTML Entities 3 | * 4 | * @category String 5 | * @param {String} str 6 | * @return {String} 7 | * @example 8 | * 9 | * stripEntities(' Text'); 10 | * // => "Text" 11 | */ 12 | function stripEntities(str) { 13 | return str.replace(/&[^\s]*;/ig, ''); 14 | } 15 | -------------------------------------------------------------------------------- /string/stripTags.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Strip HTML Tags 3 | * 4 | * @category String 5 | * @param {String} str 6 | * @return {String} 7 | * @example 8 | * 9 | * stripTags('
Text
'); 10 | * // => "Text" 11 | */ 12 | function stripTags(str) { 13 | return str.replace(/<[^>]+>/ig, ''); 14 | 15 | // different approach (browser only) 16 | //var div = document.createElement('div'); 17 | //div.innerHTML = str; 18 | //return div.textContent; 19 | } 20 | -------------------------------------------------------------------------------- /string/ucfirst.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalize the first letter of string 3 | * 4 | * @category String 5 | * @param {String} str 6 | * @return {String} 7 | * @example 8 | * 9 | * ucfirst('yo!'); 10 | * // => "Yo!" 11 | */ 12 | function ucfirst(str) { 13 | return str.charAt(0).toUpperCase() + str.substr(1); 14 | } 15 | -------------------------------------------------------------------------------- /url/getAbsoluteUrl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * getAbsoluteUrl 3 | * 4 | * @category Url 5 | * @return {String} e.g. "https://example.com/path" 6 | * @example 7 | * 8 | * getAbsoluteUrl('path'); 9 | * // => "https://example.com/path" 10 | */ 11 | function getAbsoluteUrl(url) { 12 | var a; 13 | return (function(url) { 14 | if (!a) { 15 | a = document.createElement('a'); 16 | } 17 | a.href = url; 18 | return a.href; 19 | })(url); 20 | } 21 | -------------------------------------------------------------------------------- /url/getCurrentQueryString.js: -------------------------------------------------------------------------------- 1 | /** 2 | * getCurrentQueryString 3 | * 4 | * @category Url 5 | * @return {String} e.g. "foo=bar&fizz=buzz" (no ? symbol) 6 | * @example 7 | * 8 | * getCurrentQueryString(); 9 | * // => "foo=bar&fizz=buzz" 10 | */ 11 | function getCurrentQueryString() { 12 | return window.location.search.replace(/^\?/, ''); 13 | } 14 | -------------------------------------------------------------------------------- /url/getUrlHash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * getUrlHash 3 | * 4 | * @category Url 5 | * @return {String} (no # symbol) 6 | * @example 7 | * 8 | * getUrlHash(); 9 | * // => "string" 10 | */ 11 | function getUrlHash() { 12 | return location.hash.replace(/^#/, '') || false; 13 | } 14 | -------------------------------------------------------------------------------- /url/getUrlVars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * getUrlVars 3 | * 4 | * @category Url 5 | * @param {Object} options { query: 'foo=bar&fizz=buzz' } 6 | * @return {Object} A map of querystrings e.g. ?foo=bar&fizz=buzz returns x.foo = 'bar' and x.fizz = 'buzz' 7 | * @example 8 | * 9 | * getUrlVars({query: 'foo=bar&fizz=buzz'}); 10 | * // => Object {foo: "bar", fizz: "buzz"} 11 | */ 12 | function getUrlVars(options) { 13 | var opts = options || {}; 14 | var hashes = (opts.query || getCurrentQueryString()).split('&'); 15 | var hashLength = hashes.length; 16 | 17 | return hashes.reduce(function(o, v, i) { 18 | v = v.split('='); 19 | o[v[0]] = v[1]; 20 | return o; 21 | }, {}); 22 | } 23 | --------------------------------------------------------------------------------