ajo
Version:
ajo is a JavaScript view library for building user interfaces
95 lines (94 loc) • 4.01 kB
JavaScript
import { Context as h, current as l } from "./context.js";
const u = Symbol.for("ajo.key"), p = Symbol.for("ajo.memo"), b = Symbol.for("ajo.ref"), w = Symbol.for("ajo.cache"), o = Symbol.for("ajo.generator"), c = Symbol.for("ajo.iterator"), y = Symbol.for("ajo.render"), a = Symbol.for("ajo.args"), M = (t) => t.children, U = (t, e, ...r) => ((e ??= {}).nodeName = t, !("children" in e) && r.length && (e.children = r.length == 1 ? r[0] : r), e), m = (t, e) => {
let r = e.firstChild;
for (t of g(t)) {
const i = k(t, e, r);
r == null ? e.appendChild(i) : i == r ? r = i.nextSibling : i == r.nextSibling ? (e.appendChild(r), r = i.nextSibling) : W(e, i, r);
}
for (; r; ) {
const i = r.nextSibling;
r.nodeType == 1 && j(r), e.removeChild(r), r = i;
}
}, g = function* (t) {
if (t == null) return;
const e = typeof t;
if (e != "boolean")
if (e == "string") yield t;
else if (e == "number" || e == "bigint") yield String(t);
else if (Symbol.iterator in t) for (t of t) yield* g(t);
else "nodeName" in t ? typeof t.nodeName == "function" ? yield* C(t) : yield t : yield String(t);
}, C = function* ({ nodeName: t, ...e }) {
t.constructor.name == "GeneratorFunction" ? yield N(t, e) : yield* g(t(e));
}, N = function(t, e) {
const r = { ...t.attrs }, i = { ...t.args };
for (const s in e)
s.startsWith("attr:") ? r[s.slice(5)] = e[s] : s == "key" || s == "skip" || s == "memo" || s == "ref" || s.startsWith("set:") ? r[s] = e[s] : i[s] = e[s];
return { ...r, nodeName: t.is ?? "div", [o]: t, [a]: i };
}, k = (t, e, r) => typeof t == "string" ? E(t, r) : G(t, e, r), E = (t, e) => {
for (; e && e.nodeType != 3; ) e = e.nextSibling;
return e ? e.data != t && (e.data = t) : e = document.createTextNode(t), e;
}, G = ({ nodeName: t, children: e, key: r, skip: i, memo: s, ref: S, [o]: f, [a]: A, ...x }, v, n) => {
for (; n && (n.localName != t || n[u] != null && n[u] != r || n[o] && n[o] != f); ) n = n.nextSibling;
return n ??= document.createElementNS(x.xmlns ?? v.namespaceURI, t), r != null && (n[u] = r), (s == null || R(n[p], n[p] = s)) && (O(n[w] ?? T(n), n[w] = x, n), i || (f ? B(f, A, n) : m(e, n)), typeof S == "function" && (n[b] = S)(n)), n;
}, O = (t, e, r) => {
for (const i in { ...t, ...e })
t[i] !== e[i] && (i.startsWith("set:") ? r[i.slice(4)] = e[i] : e[i] == null || e[i] === !1 ? r.removeAttribute(i) : r.setAttribute(i, e[i] === !0 ? "" : e[i]));
}, R = (t, e) => Array.isArray(t) && Array.isArray(e) ? t.some((r, i) => r !== e[i]) : t !== e, T = (t) => Array.from(t.attributes).reduce((e, r) => (e[r.name] = r.value, e), {}), W = (t, e, r) => {
if (e.contains(document.activeElement)) {
const i = e.nextSibling;
for (; r && r != e; ) {
const s = r.nextSibling;
t.insertBefore(r, i), r = s;
}
} else t.insertBefore(e, r);
}, j = (t) => {
for (const e of t.children) j(e);
typeof t.return == "function" && t.return(), t[b]?.(null);
}, B = (t, e, r) => {
r[o] ??= (F(r), t), Object.assign(r[a] ??= {}, e), r[y]();
}, F = (t) => {
Object.assign(t, I), t[h] = Object.create(l()?.[h] ?? null);
}, I = {
[y]() {
const t = l();
l(this);
try {
const { value: e, done: r } = (this[c] ??= this[o].call(this, this[a])).next();
m(e, this), this[b]?.(this), r && this.return();
} catch (e) {
this.throw(e);
} finally {
l(t);
}
},
next(t) {
if (typeof t == "function") try {
t.call(this, this[a]);
} catch (e) {
this.throw(e);
}
l()?.contains(this) || this[y]();
},
throw(t) {
for (let e = this; e; e = e.parentNode) if (typeof e[c]?.throw == "function") try {
return m(e[c].throw(t).value, e);
} catch (r) {
t = new Error(r instanceof Error ? r.message : r, { cause: t });
}
throw t;
},
return() {
try {
this[c]?.return();
} catch (t) {
this.throw(t);
} finally {
this[c] = null;
}
}
};
export {
M as Fragment,
U as h,
m as render
};