mirror of
https://gitlab.com/skysthelimit.dev/selenite.git
synced 2025-06-16 02:22:07 -05:00
244 lines
7.5 KiB
JavaScript
244 lines
7.5 KiB
JavaScript
/* toned.js */
|
|
// A mini-library I use for some short, useful functions
|
|
// Pass in true to give all the functions to window
|
|
|
|
function TonedJS(give_window) {
|
|
var toned = {
|
|
/* Object Shenanigans */
|
|
|
|
// Blindly hand all members of the donor variable to the recipient
|
|
// Ex: give(toned, window);
|
|
giveSup: function(donor, recipient) {
|
|
recipient = recipient || {};
|
|
for(var i in donor)
|
|
recipient[i] = donor[i];
|
|
return recipient
|
|
},
|
|
// Like giveSup/erior, but it doesn't override pre-existing members
|
|
giveSub: function(donor, recipient) {
|
|
recipient = recipient || {};
|
|
for(var i in donor)
|
|
if(!recipient[i])
|
|
recipient[i] = donor[i];
|
|
return recipient
|
|
},
|
|
|
|
// Proliferates all members of settings to the element recursively
|
|
proliferate: function(elem, settings, no_override) {
|
|
var setting, i;
|
|
for(i in settings) {
|
|
if(no_override && elem[i]) continue;
|
|
if(typeof(setting = settings[i]) == "object") {
|
|
if(!elem[i]) elem[i] = {};
|
|
proliferate(elem[i], setting, no_override);
|
|
}
|
|
else elem[i] = setting;
|
|
}
|
|
return elem;
|
|
},
|
|
|
|
// Blindly grabs the first key or value of the object, depending on grabkey
|
|
getFirst: function(obj, grabkey) {
|
|
for(var i in obj) return grabkey ? i : obj[i];
|
|
},
|
|
|
|
// Blindly grabs the last key or value of the object, depending on grabkey
|
|
getLast: function(obj, grabkey) {
|
|
for(var i in obj) {} return grabkey ? i : obj[i];
|
|
},
|
|
|
|
// Follows a path inside an object recursively
|
|
// Path is ["path", "to", "target"], where num is how far along the path it is
|
|
// Num must be given at start, for performance reasons
|
|
// To do: allow a function version?
|
|
followPath: function(obj, path, num) {
|
|
if(path[num] != null && obj[path[num]] != null)
|
|
return followPath(obj[path[num]], path, ++num);
|
|
return obj;
|
|
},
|
|
|
|
|
|
/* HTML Element Manipulations */
|
|
|
|
// Creates an element, and uses proliferate on all the other arguments
|
|
// * createElement() // (just returns a new div)
|
|
// * createElement("div", {width: "350px", style: {class: "Toned"}});
|
|
createElement: function(type) {
|
|
var elem = document.createElement(type || "div"),
|
|
i = arguments.length;
|
|
while(--i > 0) // because negative
|
|
proliferate(elem, arguments[i]);
|
|
return elem;
|
|
},
|
|
|
|
// Simple expressions to add/remove classes
|
|
classAdd: function(me, strin) { me.className += " " + strin; },
|
|
classRemove: function(me, strout) { me.className = me.className.replace(new RegExp(" " + strout, "gm"), ""); },
|
|
|
|
// Position changing
|
|
elementSetPosition: function(me, left, top) {
|
|
if(left == undefined) left = me.left;
|
|
if(top == undefined) top = me.top;
|
|
proliferate(me, {
|
|
left: left,
|
|
top: top,
|
|
style: {
|
|
marginLeft: left + "px",
|
|
marginTop: top + "px"
|
|
}
|
|
});
|
|
},
|
|
elementShiftLeft: function(me, left) {
|
|
if(!me.left) me.left = Number(me.style.marginLeft.replace("px", ""));
|
|
me.style.marginLeft = round(me.left += left) + "px";
|
|
},
|
|
elementShiftTop: function(me, top) {
|
|
if(!me.top) me.top = Number(me.style.marginLeft.replace("px", ""));
|
|
me.style.marginTop = round(me.top += top) + "px";
|
|
},
|
|
|
|
// Deletes an element if it's in its parent, or the body
|
|
removeChildSafe: function(child, container) {
|
|
if(!child) return;
|
|
container = container || document.body;
|
|
if(container.contains(child)) container.removeChild(child);
|
|
},
|
|
|
|
// Attempts to find the soonest parent with this tag
|
|
findParentOfType: function(child, type) {
|
|
var parent = child.parentElement;
|
|
if(!parent || parent.nodeName == type) return parent;
|
|
return findParentType(parent, type);
|
|
},
|
|
|
|
// Clears all timer events from setTimeout and setInterval
|
|
clearAllTimeouts: function() {
|
|
var id = setTimeout(function() {});
|
|
while(id--) clearTimeout(id);
|
|
},
|
|
|
|
/* String manipulations */
|
|
|
|
// Removes leading and trailing whitespace (thanks, IE<=8)
|
|
stringTrim: function(me) {
|
|
return me.replace(/^\s+|\s+$/g,'');
|
|
},
|
|
// Similar to arrayOf
|
|
stringOf: function(me, n) {
|
|
return (n == 0) ? '' : new Array(1 + (n || 1)).join(me);
|
|
},
|
|
// Checks if a haystack contains a needle
|
|
stringHas: function(haystack, needle) {
|
|
return haystack.indexOf(needle) != -1;
|
|
},
|
|
// Case insensitive version of stringHas
|
|
stringHasI: function(haystack, needle) {
|
|
return haystack.toLowerCase().indexOf(needle.toLowerCase()) != -1;
|
|
},
|
|
// Capitalizes only the first 1 or n charactacters of a string
|
|
capitalizeFirst: function(str, n) {
|
|
n = n || 1;
|
|
return str.substr(0,n).toUpperCase() + str.substr(n).toLowerCase();
|
|
},
|
|
|
|
/* Array manipulations */
|
|
|
|
// It's nice to have X-dimensional arrays
|
|
ArrayD: function(dim) {
|
|
// 1-dimensionals are easy
|
|
if(arguments.length == 1) return new Array(dim);
|
|
// Otherwise recurse
|
|
var rargs = arrayMake(arguments),
|
|
me = new Array(dim),
|
|
i;
|
|
rargs.shift();
|
|
for(i = dim - 1; i >= 0; --i) {
|
|
me[i]= ArrayD.apply(this, rargs);
|
|
}
|
|
return me;
|
|
},
|
|
// Similar to stringOf
|
|
arrayOf: function(me, n) {
|
|
n = n || 1;
|
|
var arr = new Array(n);
|
|
while(n--) arr[n] = me;
|
|
return arr;
|
|
},
|
|
// Looking at you, function arguments
|
|
arrayMake: function(me) {
|
|
return Array.prototype.slice.call(me);
|
|
},
|
|
// (7,10) = [7,8,9,10]
|
|
arrayRange: function(a, b) {
|
|
var len = 1 + b - a,
|
|
arr = new Array(len),
|
|
val = a, i = 0;
|
|
while(i < len) arr[i++] = val++;
|
|
return arr;
|
|
},
|
|
arrayShuffle: function(arr, start, end) {
|
|
start = start || 0;
|
|
end = end || arr.length;
|
|
for(var i = start, temp, sloc; i <= end; ++i) {
|
|
sloc = randInt(i+1);
|
|
temp = arr[i];
|
|
arr[i] = arr[sloc];
|
|
arr[sloc] = temp;
|
|
}
|
|
return arr;
|
|
},
|
|
// O(n^2) removal
|
|
removeDuplicates: function(arr) {
|
|
var output = [],
|
|
me, hasdup,
|
|
len, i, j;
|
|
for(i = 0, len = arr.length; i < len; ++i) {
|
|
me = arr[i];
|
|
hasdup = false;
|
|
for(j = 0; j < i; ++j) {
|
|
if(arr[j] == me) {
|
|
hasdup = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!hasdup) output.push(me);
|
|
}
|
|
return output;
|
|
},
|
|
|
|
/* Number manipulations */
|
|
|
|
// Converts ('7',3,1) to '117'
|
|
makeDigit: function(num, size, fill) {
|
|
num = String(num);
|
|
return stringOf(fill || 0, max(0, size - num.length)) + num;
|
|
},
|
|
roundDigit: function(n, d) { return Number(d ? ~~(0.5 + (n / d)) * d : round(n)); },
|
|
// It's often faster to store references to common Math functions
|
|
sign: function(n) { return n ? n < 0 ? -1 : 1 : 0; },
|
|
round: function(n) { return ~~(0.5 + n); },
|
|
max: Math.max,
|
|
min: Math.min,
|
|
abs: Math.abs,
|
|
pow: Math.pow,
|
|
ceil: Math.ceil,
|
|
floor: Math.floor,
|
|
random: Math.random,
|
|
// Returns a number between [0, n)
|
|
randInt: function(n) { return floor(Math.random() * (n || 1)); },
|
|
// Positives are true, negatives are false
|
|
signBool: function(n) { return n > 0 ? true : false; },
|
|
|
|
/* Etcetera */
|
|
|
|
// It's nice being able log without going through console.. hopefully it gets optimized!
|
|
log: console.log.bind(console),
|
|
|
|
// Timing
|
|
now: Date.now
|
|
};
|
|
|
|
if(give_window) toned.giveSub(toned, window);
|
|
|
|
return toned;
|
|
} |