inflation-explorer/shared/js/util.js (72 lines of code) (raw):

const $ = selector => document.querySelector(selector) const $$ = selector => [].slice.apply(document.querySelectorAll(selector)) // rounds value to exp digits (can be a negative number -> eg round(1234, -3) === 1000) const round = (value, exp) => { if (typeof exp === 'undefined' || +exp === 0) return Math.round(value); value = +value; exp = +exp; if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) return NaN; value = value.toString().split('e'); value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp))); value = value.toString().split('e'); return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)); } // inserts UK-style commas in numbers (1,300,000) const numberWithCommas = x => { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") } // returns a Promise that resolves after ms milliseconds const wait = ms => new Promise((resolve, reject) => setTimeout(() => resolve(), ms )) const getDimensions = el => { const width = el.clientWidth || el.getBoundingClientRect().width const height = el.clientHeight || el.getBoundingClientRect().height return [ width, height ] } const hashPattern = (patternId, pathClass, rectClass, a = 4) => { return ` <pattern id='${patternId}' patternUnits='userSpaceOnUse' width='${a}' height='${a}'> <rect width='${a}' height='${a}' class='${rectClass}'></rect> <path d='M-1,1 l2,-2 M0,${a} l${a},-${a} M${a-1},${a+1} l2,-2' class='${pathClass}'></path> </pattern> ` } function ordinal(i) { if(i === 1) { return 'first' } if(i === 2) { return 'second' } if(i === 3) { return 'third' } var j = i % 10, k = i % 100; if (j == 1 && k != 11) { return i + "st"; } if (j == 2 && k != 12) { return i + "nd"; } if (j == 3 && k != 13) { return i + "rd"; } return i + "th"; } const sum = (a, b) => a + b // duplicates a DOM element, inserts BEFORE original and adds a class name without deleting the old one. // Great for adding white outlines to SVG text elements const duplicate = ( el, className ) => { const clone = el.cloneNode(true) clone.classList.add(className) el.parentNode.insertBefore(clone, el) } // sequentially executes the (Promise-based) tasks in arr const pseq = (arr, lambda) => { return arr.reduce( (agg, cur, i, arr) => { return agg.then(res => lambda(cur, i, arr).then( res2 => res.concat(res2))) }, Promise.resolve([]) ) } const featureTest = (property, value, noPrefixes) => { var prop = property + ':', el = document.createElement('test'), mStyle = el.style; if (!noPrefixes) { mStyle.cssText = prop + ['-webkit-', '-moz-', '-ms-', '-o-', ''].join(value + ';' + prop) + value + ';'; } else { mStyle.cssText = prop + value; } return mStyle[property]; } const supportsSticky = () => (featureTest('position', 'sticky') || featureTest('position', '-webkit-sticky')) export { $, $$, round, numberWithCommas, wait, getDimensions, hashPattern, duplicate, pseq, sum, ordinal, featureTest, supportsSticky }