onion/js/utils/general_utils.js

180 lines
4.8 KiB
JavaScript

'use strict';
/**
* Takes an object and deletes all keys that are
*
* tagged as false by the passed in filter function
*
* @param {object} obj regular javascript object
* @return {object} regular javascript object without null values or empty strings
*/
export function sanitize(obj, filterFn) {
if(!filterFn) {
// By matching null with a double equal, we can match undefined and null
// http://stackoverflow.com/a/15992131
filterFn = (val) => val == null || val === '';
}
Object
.keys(obj)
.map((key) => {
if(filterFn(obj[key])) {
delete obj[key];
}
});
return obj;
}
/**
* Sums up a list of numbers. Like a Epsilon-math-kinda-sum...
*/
export function sumNumList(l) {
let sum = 0;
l.forEach((num) => sum += parseFloat(num) || 0);
return sum;
}
/*
Taken from http://stackoverflow.com/a/4795914/1263876
Behaves like C's format string function
*/
export function formatText() {
let args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, (m) => {
// m is the matched format, e.g. %s, %d
let val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// A switch statement so that the formatter can be extended. Default is %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}
/*
Checks a list of objects for key duplicates and returns a boolean
*/
function _doesObjectListHaveDuplicates(l) {
let mergedList = [];
l = l.map((obj) => {
if(!obj) {
throw new Error('The object you are trying to merge is null instead of an empty object');
}
return Object.keys(obj);
});
// Taken from: http://stackoverflow.com/a/10865042
// How to flatten an array of arrays in javascript.
// If two objects contain the same key, then these two keys
// will actually be represented in the merged array
mergedList = mergedList.concat.apply(mergedList, l);
// Taken from: http://stackoverflow.com/a/7376645/1263876
// By casting the array to a set, and then checking if the size of the array
// shrunk in the process of casting, we can check if there were any duplicates
return (new Set(mergedList)).size !== mergedList.length;
}
/**
* Takes a list of object and merges their keys to one object.
* Uses mergeOptions for two objects.
* @param {[type]} l [description]
* @return {[type]} [description]
*/
export function mergeOptions(...l) {
// If the objects submitted in the list have duplicates,in their key names,
// abort the merge and tell the function's user to check his objects.
if(_doesObjectListHaveDuplicates(l)) {
throw new Error('The objects you submitted for merging have duplicates. Merge aborted.');
}
let newObj = {};
for(let i = 1; i < l.length; i++) {
newObj = _mergeOptions(newObj, _mergeOptions(l[i - 1], l[i]));
}
return newObj;
}
/**
* Merges a number of objects even if there're having duplicates.
*
* DOES NOT RETURN AN ERROR!
*
* Takes a list of object and merges their keys to one object.
* Uses mergeOptions for two objects.
* @param {[type]} l [description]
* @return {[type]} [description]
*/
export function mergeOptionsWithDuplicates(...l) {
// If the objects submitted in the list have duplicates,in their key names,
// abort the merge and tell the function's user to check his objects.
let newObj = {};
for(let i = 1; i < l.length; i++) {
newObj = _mergeOptions(newObj, _mergeOptions(l[i - 1], l[i]));
}
return newObj;
}
/**
* In place update of a dictionary
*/
export function update(a, ...l) {
for(let i = 0; i < l.length; i++) {
for (let attrname in l[i]) {
a[attrname] = l[i][attrname];
}
}
return a;
}
/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
* Taken from: http://stackoverflow.com/a/171256/1263876
*/
function _mergeOptions(obj1, obj2) {
let obj3 = {};
for (let attrname in obj1) {
obj3[attrname] = obj1[attrname];
}
for (let attrname in obj2) {
obj3[attrname] = obj2[attrname];
}
return obj3;
}
/**
* Escape HTML in a string so it can be injected safely using
* React's `dangerouslySetInnerHTML`
*
* @param s the string to be sanitized
*
* Taken from: http://stackoverflow.com/a/17546215/597097
*/
export function escapeHTML(s) {
return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
}