All files / src util.js

70.58% Statements 36/51
78.94% Branches 15/19
71.42% Functions 15/21
66.66% Lines 28/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102  8x 8x 8x         1x 1x   1x 1x 1x 1x 1x           8x     69x 68x 67x 312x 67x       8x         3x       3x       1x         1x 1x       4x 4x     8x 8x 8x 8x                                                                              
// Grab the prefers reduced media query.
const reducedMotion = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)') : false;
const shouldReduce = (!reducedMotion || reducedMotion.matches);
export const ANIMATION_SPEED = shouldReduce ? 0 : 200;
 
 
// native js animation
export function animate (el, from, to, _options = {}) {
	const dflt = { duration: ANIMATION_SPEED, easing: 'ease-out', fill: 'forwards' };
	const opts = Object.assign({}, dflt, _options);
 
	return new Promise(resolve => {
		requestAnimationFrame(() => {
			const anim = el.animate([from, to], opts);
			anim.oncancel = resolve;
			anim.onfinish = resolve;
		});
	});
}
 
 
const pluckOne = (obj, key) => obj[key];
 
export function pluck (obj, keys) {
	if (!obj) return {};
	if (!Array.isArray(keys)) return pluckOne(obj, keys);
	const newObj = {};
	keys.forEach(key => newObj[key] = obj[key]);
	return newObj;
}
 
 
export const FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),iframe:not([disabled]),input:not([disabled]),' +
	'select:not([disabled]),textarea:not([disabled]),[contentEditable],[tabindex]';
 
 
export function getMouseX (e) {
	return (e.type.includes('touch')) ? e.touches[0].clientX : e.clientX;
}
 
export function getMouseY (e) {
	return (e.type.includes('touch')) ? e.touches[0].clientY : e.clientY;
}
 
export function getMouseXY (e) {
	return [getMouseX(e), getMouseY(e)];
}
 
 
export function getFlexFlow (el) {
	const css = getComputedStyle(el);
	return css.flexDirection.replace('-reverse', '');
}
 
export function getCSSvalueInPx (el, name) {
	const css = getComputedStyle(el);
	return parseFloat(css[name]);
}
 
export const minWidth = (el) => getCSSvalueInPx(el, 'minWidth');
export const minHeight = (el) => getCSSvalueInPx(el, 'minHeight');
export const maxWidth = (el) => getCSSvalueInPx(el, 'maxWidth');
export const maxHeight = (el) => getCSSvalueInPx(el, 'maxHeight');
 
 
export function innerWidth (el) {
	const css = getComputedStyle(el);
	const borders = parseFloat(css.borderLeftWidth) + parseFloat(css.borderRightWidth);
	const padding = parseFloat(css.paddingLeft) + parseFloat(css.paddingRight);
	return el.getBoundingClientRect().width - borders - padding;
}
 
 
export function innerHeight (el) {
	const css = getComputedStyle(el);
	const borders = parseFloat(css.borderTopWidth) + parseFloat(css.borderBottomWidth);
	const padding = parseFloat(css.paddingTop) + parseFloat(css.paddingBottom);
	return el.getBoundingClientRect().height - borders - padding;
}
 
export function uuid () {
	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
		const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
		return v.toString(16);
	});
}
 
 
export function roundAmount (val, precision = 2) {
	const multiplier = Math.pow(10, precision);
	return Math.round(val * multiplier) / multiplier;
}
 
 
export function blink (el, duration = 160) {
	return animate(el,
		{ opacity: 1 },
		{ opacity: 0.5 },
		{ duration: duration / 2, fill: 'backwards' }
	);
}