ziggurat.js
Version:
a tiny modular js library for templates and other shorthands
385 lines (341 loc) • 8.95 kB
JavaScript
// Generated by CoffeeScript 2.7.0
// contains all core logic (templates) as well as query
// note: requires imperative HTML to work
var create_math_function, fun, i, key, len, ref, zg;
if (typeof HTML === "undefined" || HTML === null) {
throw new Error("can't find HTML. did you forget to import imperative-html?");
}
zg = {};
// functions
// query
zg.query = function(selector) {
var result;
result = document.querySelectorAll(selector);
if (result.length === 1) {
return result[0];
} else {
return result;
}
};
zg.queryone = function(selector) {
return document.querySelector(selector);
};
zg.queryall = function(selector) {
return document.querySelectorAll(selector);
};
// misc
zg.deepfind = function(data, path) {
var i, index, len, node, ref;
path = path.trim();
ref = (function() {
var j, len, ref, results;
ref = path.split('.');
results = [];
for (j = 0, len = ref.length; j < len; j++) {
node = ref[j];
if (node !== "") {
results.push(node);
}
}
return results;
})();
for (i = 0, len = ref.length; i < len; i++) {
index = ref[i];
data = data[index];
if (data == null) {
throw new Error(`'${path}' not in data '${data}'`);
}
}
return data;
};
zg.VERSION = "0.5.0";
zg._INIT_LIST = [];
zg.init = function() {
var f, i, len, ref;
ref = zg._INIT_LIST;
for (i = 0, len = ref.length; i < len; i++) {
f = ref[i];
f();
}
return console.log(`%cZiggurat ${zg.VERSION} initialized.`, "color: orange; font-weight: bold");
};
zg.formdata = function(element) {
var data;
data = {};
// for each entry in the form,
// add a reference to it in data
(new FormData(element)).forEach(function(_, k) {
return Object.defineProperty(data, k, {
get: function() {
return element[k].value;
},
set: function(v) {
return element[k].value = v;
}
});
});
return data;
};
zg._INIT_LIST.push(function() {
var element, fn_name, i, len, ref, results;
ref = zg.queryall('form[zg-submit]');
results = [];
for (i = 0, len = ref.length; i < len; i++) {
element = ref[i];
fn_name = element.getAttribute("zg-submit");
results.push(element.onsubmit = function(event) {
var e;
try {
// fuck around and find out
window[fn_name](zg.formdata(element));
} catch (error) {
e = error;
console.error(e);
}
// prevent event default
event.preventDefault;
return false;
});
}
return results;
});
zg.mirror = class {
constructor(name1, _value, setters, options) {
this.name = name1;
Object.defineProperty(this, "v", {
get: function() {
return this._value;
},
set: function(val) {
// when V is set, also update the bound valus in HTML
this._value = val;
return this.update();
}
});
// also call the setter
this.setters = setters;
this.options = options;
this.v = _value;
}
update() {
var bind, i, j, len, len1, ref, ref1, results, setter;
ref = zg.queryall(`zg-bind[name=${this.name}]`);
// update DOM
for (i = 0, len = ref.length; i < len; i++) {
bind = ref[i];
bind.innerText = this._value;
}
ref1 = this.setters;
// call custom setters
results = [];
for (j = 0, len1 = ref1.length; j < len1; j++) {
setter = ref1[j];
results.push(setter(this._value, this.name, this.options));
}
return results;
}
};
zg.mirror_to_localstorage = function(value, name, options) {
return localStorage[name] = value;
};
zg.cookies = new Proxy({}, {
get: function(_, name) {
var cookie, cookies, i, len;
// extract cookie from document.cookie
cookies = (function() {
var i, len, ref, results;
ref = document.cookie.split('; ');
results = [];
for (i = 0, len = ref.length; i < len; i++) {
cookie = ref[i];
results.push(cookie.split('='));
}
return results;
})();
for (i = 0, len = cookies.length; i < len; i++) {
cookie = cookies[i];
if (cookie[0] === name) {
return cookie[1];
}
}
},
set: function(_, name, value) {
var cookie, k, v;
// build a statement to be put into document.cookie
if (typeof value === 'object') {
cookie = `${name}=${value.value}; `;
// add every property to cookie string
cookie += ((function() {
var results;
if (k !== 'value') {
results = [];
for (k in value) {
v = value[k];
results.push(v != null ? `${k} = ${v}` : `${k}`);
}
return results;
}
})()).join('; ');
} else {
cookie = `${name}=${value}`;
}
return document.cookie = cookie;
}
});
zg.load_json_cookie = function(name) {
var SyntaxError, val;
val = zg.cookies[name];
try {
return JSON.parse(val);
} catch (error) {
SyntaxError = error;
return null;
}
};
zg.mirror_to_cookie = function(value, name, options) {
return zg.cookies[name] = {
"value": JSON.stringify(value),
...options
};
};
Number.prototype.nanos = function() {
return this.micros() / 1000;
};
Number.prototype.micros = function() {
return this.millis() / 1000;
};
Number.prototype.millis = function() {
return this.seconds() / 1000;
};
Number.prototype.seconds = function() {
return this;
};
Number.prototype.minutes = function() {
return this.seconds() * 60;
};
Number.prototype.hours = function() {
return this.minutes() * 60;
};
Number.prototype.days = function() {
return this.hours() * 24;
};
Number.prototype.months = function() {
return this.days() * 30.43684914;
};
Number.prototype.years = function() {
return this.months() * 12;
};
Number.prototype.ago = function() {
return new Date(Date.now() - this * 1000);
};
Number.prototype.fromnow = function() {
return new Date(Date.now() + this * 1000);
};
create_math_function = function(name) {
return function() {
return this(Math[name]);
};
};
ref = Object.getOwnPropertyNames(Math);
for (i = 0, len = ref.length; i < len; i++) {
key = ref[i];
fun = Math[key];
if (fun.length === 1 && typeof fun === "function") {
eval(`Number.prototype.${key} = function() {return Math.${key}(this)}`);
}
}
zg.stream = {};
zg.HttpException = class HttpException extends Error {
constructor(status) {
super(`Recieved code ${status} from server`);
this.status = status;
}
};
// chunked fetch
// yields all data available
zg.stream.text = async function*(url, options) {
var data, decoder, reader, res, result;
res = (await fetch(url, options));
if (!res.ok) {
throw new zg.HttpException(res.statusCode);
}
reader = res.body.getReader();
decoder = new TextDecoder();
while (true) {
result = (await reader.read());
data = decoder.decode(result.value);
if (data.length > 0) {
yield data;
}
if (result.done) {
return;
}
}
};
// yields all lines as raw text
zg.stream.lines = async function*(url, options) {
var buffer, data, j, len1, line, lines, ref1, results;
buffer = "";
ref1 = zg.stream.text(url, options);
for await (data of ref1) {
buffer += data;
lines = buffer.split("\n");
if (lines.length > 1) {
yield lines[0];
lines = lines.slice(1);
buffer = lines.join("\n");
}
}
results = [];
for (j = 0, len1 = lines.length; j < len1; j++) {
line = lines[j];
if (line.length > 0) {
results.push((yield line));
} else {
results.push(void 0);
}
}
return results;
};
// yields all lines as JSON
zg.stream.jsonl = async function*(url, options) {
var line, ref1, results;
ref1 = zg.stream.lines(url, options);
results = [];
for await (line of ref1) {
try {
results.push((yield JSON.parse(line)));
} catch (error) {}
}
return results;
};
// template creation
zg.create = function(name, data) {
var build, template;
template = zg.queryone("zg-template#" + name);
if (template == null) {
throw new TypeError('no such template with name ' + name);
}
build = function(div, data) {
var child, elements, j, len1, new_elements, ref1;
elements = div.cloneNode(true);
new_elements = [];
ref1 = elements.childNodes;
// compile every child
for (j = 0, len1 = ref1.length; j < len1; j++) {
child = ref1[j];
// depending on tag, replace with something
switch (child.nodeName.toLowerCase()) {
case "zg-var":
child = document.createTextNode(zg.deepfind(data, child.innerHTML));
}
// if the child has more children, build the child
if (child.children != null) {
child.replaceChildren(...(build(child, data)));
}
new_elements.push(child);
}
return new_elements;
};
return HTML.div(build(template, data));
};