pruvodce/static/uboot.js

130 lines
3.4 KiB
JavaScript

// base javascript library
// protects programmer from javascript insanity, browser inconsitences and typing long strings
// (c) Severák 2019
// WTFPL licensed
// kudos to lua team for inspiration
// and http://bonsaiden.github.io/JavaScript-Garden/ for wonderful docs on insanities of JS
// guess type of x
function type(v) {
return Object.prototype.toString.call(v).slice(8, -1);
}
// issues error when v is false-y
function assert(v, message) {
if (!message) message = 'assertion failed';
if (!v) {
throw message;
}
}
// shorthand to throwing exceptions
function error(message) {
throw message;
}
// iterates over array calling fun(i, v)
function ipairs(arr, fun) {
for (var i = 0; i < arr.length; i++) {
fun(i, arr[v]);
}
}
// iterates over object calling fun(k, v)
function pairs(obj, fun) {
for(var k in obj) {
if (obj.hasOwnProperty(k)) {
fun(k,v);
}
}
}
function tostring(v) {
// TODO
}
function tonumber(v, base) {
if (!base) base = 10;
return parseFloat(v, base);
}
// and now some DOM stuff
// kudos to https://plainjs.com/
function gebi(id) {
return document.getElementById(id);
}
function makeElem(tag, attr, text) {
// TODO
}
var addEvent = function(el, type, handler) {
if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
};
// matches polyfill
this.Element && function(ElementPrototype) {
ElementPrototype.matches = ElementPrototype.matches ||
ElementPrototype.matchesSelector ||
ElementPrototype.webkitMatchesSelector ||
ElementPrototype.msMatchesSelector ||
function(selector) {
var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
while (nodes[++i] && nodes[i] != node);
return !!nodes[i];
}
}(Element.prototype);
function on(elem, eventName, fun, fun2) {
assert(arguments.length>2, 'Wrong number of arguments to function on.');
if (type(elem)=='String') elem = gebi(elem);
if (arguments.length==4) {
var selector = fun;
var context = elem;
addEvent(context || document, eventName, function(e) {
var found, el = e.target || e.srcElement;
while (el && el.matches && el !== context && !(found = el.matches(selector))) el = el.parentElement;
if (found) fun2.call(el, e);
});
} else {
addEvent(elem, eventName, fun);
}
}
// sub variant with on(elem, eventName, subselector, fun)
function hasClass(elem, className) {
if (type(elem)=='String') elem = gebi(elem);
return elem.classList ? elem.classList.contains(className) : new RegExp('\\b'+ className+'\\b').test(elem.className);
}
function addClass(elem, className) {
if (type(elem)=='String') elem = gebi(elem);
if (elem.classList) elem.classList.add(className);
else if (!hasClass(elem, className)) elem.className += ' ' + className;
}
function delClass(elem, className) {
if (type(elem)=='String') elem = gebi(elem);
if (elem.classList) elem.classList.remove(className);
else elem.className = elem.className.replace(new RegExp('\\b'+ className+'\\b', 'g'), '');
}
// jQuery-like DOM ready
function whenReady(fun) {
// in case the document is already rendered
if (document.readyState!='loading') fun();
// modern browsers
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', fun);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
if (document.readyState=='complete') fun();
});
}