From 18f93d7e0b5d8d5576e65fcc29c1d1da861bd20f Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Fri, 13 Oct 2023 16:37:04 +0200 Subject: [PATCH] :rocket: lifecycle events, signals from attrs test --- dist/dde-with-signals.js | 374 +++++++++++++++------------- dist/dde.js | 247 +++++++++--------- dist/esm-with-signals.js | 374 +++++++++++++++------------- dist/esm.js | 247 +++++++++--------- examples/components/webComponent.js | 90 ++----- package.json | 7 +- src/events.js | 35 ++- src/signals-lib.js | 22 +- 8 files changed, 745 insertions(+), 651 deletions(-) diff --git a/dist/dde-with-signals.js b/dist/dde-with-signals.js index d590a55..5e989b1 100644 --- a/dist/dde-with-signals.js +++ b/dist/dde-with-signals.js @@ -1,7 +1,7 @@ //deka-dom-el library is available via global namespace `dde` (()=> { // src/signals-common.js - var E = { + var y = { isSignal(e) { return !1; }, @@ -9,22 +9,22 @@ return n; } }; - function C(e, t = !0) { - return t ? Object.assign(E, e) : (Object.setPrototypeOf(e, E), e); + function N(e, t = !0) { + return t ? Object.assign(y, e) : (Object.setPrototypeOf(e, y), e); } - function S(e) { - return E.isPrototypeOf(e) && e !== E ? e : E; + function _(e) { + return y.isPrototypeOf(e) && e !== y ? e : y; } // src/helpers.js - function m(e) { + function v(e) { return typeof e > "u"; } - function P(e) { + function j(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } - function L(e, t) { + function A(e, t) { if (!e || !(e instanceof AbortSignal)) return !0; if (!e.aborted) @@ -34,9 +34,9 @@ } // src/dom-common.js - var j = { setDeleteAttr: H }; + var W = { setDeleteAttr: H }; function H(e, t, n) { - if (Reflect.set(e, t, n), !!m(n)) { + if (Reflect.set(e, t, n), !!v(n)) { if (Reflect.deleteProperty(e, t), e instanceof HTMLElement && e.getAttribute(t) === "undefined") return e.removeAttribute(t); if (Reflect.get(e, t) === "undefined") @@ -45,12 +45,12 @@ } // src/dom.js - var w = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, O = { + var S = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], M = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, E = { get current() { - return w[w.length - 1]; + return S[S.length - 1]; }, get state() { - return [...w]; + return [...S]; }, get host() { return this.current.host; @@ -59,80 +59,80 @@ return this.current.namespace; }, set namespace(e) { - return this.current.namespace = W(e); + return this.current.namespace = M(e); }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return O.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return E.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = W(e.namespace)), w.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = M(e.namespace)), S.push(Object.assign({}, this.current, e)); }, pop() { - return w.pop(); + return S.pop(); } }; - function se(e, t, ...n) { - let r = this, o = S(this), { namespace: u } = O, a; + function ie(e, t, ...n) { + let r = this, o = _(this), { namespace: c } = E, a; switch ((Object(t) !== t || o.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - O.push({ scope: e, host: (s) => s ? (n.unshift(s), void 0) : a }), a = e(t || void 0), O.pop(); + E.push({ scope: e, host: (s) => s ? (n.unshift(s), void 0) : a }), a = e(t || void 0), E.pop(); break; } case e === "#text": - a = y.call(r, document.createTextNode(""), t); + a = O.call(r, document.createTextNode(""), t); break; case e === "<>": - a = y.call(r, document.createDocumentFragment(), t); + a = O.call(r, document.createDocumentFragment(), t); break; - case u !== "html": - a = y.call(r, document.createElementNS(u, e), t); + case c !== "html": + a = O.call(r, document.createElementNS(c, e), t); break; case !a: - a = y.call(r, document.createElement(e), t); + a = O.call(r, document.createElement(e), t); } return n.forEach((s) => s(a)), a; } - var { setDeleteAttr: F } = j; - function y(e, ...t) { - let n = this, r = S(this); + var { setDeleteAttr: k } = W; + function O(e, ...t) { + let n = this, r = _(this); if (!t.length) return e; - let u = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); + let c = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); return Object.entries(Object.assign({}, ...t)).forEach(function a([s, d]) { d = r.processReactiveAttribute(e, s, d, a); - let [b] = s; - if (b === "=") - return u(s.slice(1), d); - if (b === ".") - return M(e, s.slice(1), d); + let [m] = s; + if (m === "=") + return c(s.slice(1), d); + if (m === ".") + return F(e, s.slice(1), d); if (/(aria|data)([A-Z])/.test(s)) - return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), u(s, d); + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, d); switch (s === "className" && (s = "class"), s) { case "xlink:href": - return u(s, d, "http://www.w3.org/1999/xlink"); + return c(s, d, "http://www.w3.org/1999/xlink"); case "textContent": - return F(e, s, d); + return k(e, s, d); case "style": if (typeof d != "object") break; case "dataset": - return N(r, d, M.bind(null, e[s])); + return D(r, d, F.bind(null, e[s])); case "ariaset": - return N(r, d, (x, c) => u("aria-" + x, c)); + return D(r, d, (b, i) => c("aria-" + b, i)); case "classList": return B.call(n, e, d); } - return G(e, s) ? F(e, s, d) : u(s, d); + return G(e, s) ? k(e, s, d) : c(s, d); }), e; } function B(e, t) { - let n = S(this); - return N( + let n = _(this); + return D( n, t, (r, o) => e.classList.toggle(r, o === -1 ? void 0 : !!o) @@ -145,7 +145,7 @@ if (!Reflect.has(e, t)) return !1; let n = z(e, t); - return !m(n.set); + return !v(n.set); } function z(e, t) { if (e = Object.getPrototypeOf(e), !e) @@ -153,130 +153,149 @@ let n = Object.getOwnPropertyDescriptor(e, t); return n || z(e, t); } - function N(e, t, n) { + function D(e, t, n) { if (!(typeof t != "object" || t === null)) - return Object.entries(t).forEach(function([o, u]) { - o && (u = e.processReactiveAttribute(t, o, u, (a) => n(...a)), n(o, u)); + return Object.entries(t).forEach(function([o, c]) { + o && (c = e.processReactiveAttribute(t, o, c, (a) => n(...a)), n(o, c)); }); } function T(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } function I(e, t, n, r) { - return e[(m(r) ? "remove" : "set") + t](n, T(r)); + return e[(v(r) ? "remove" : "set") + t](n, T(r)); } function J(e, t, n, r, o = null) { - return e[(m(r) ? "remove" : "set") + t + "NS"](o, n, T(r)); + return e[(v(r) ? "remove" : "set") + t + "NS"](o, n, T(r)); } - function M(e, t, n) { - if (Reflect.set(e, t, n), !!m(n)) + function F(e, t, n) { + if (Reflect.set(e, t, n), !!v(n)) return Reflect.deleteProperty(e, t); } // src/events.js - function de(e, t, ...n) { + function le(e, t, ...n) { let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); return e.dispatchEvent(r); } - function U(e, t, n) { + function x(e, t, n) { return function(o) { return o.addEventListener(e, t, n), o; }; } - var _ = V(); - U.connected = function(e, t) { - return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:connected", e, t), typeof r.connectedCallback == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event("dde:connected")), r) : (L(t.signal, () => _.offConnected(r, e)) && _.onConnected(r, e), r); + var R = Z(), V = /* @__PURE__ */ new WeakSet(); + x.connected = function(e, t) { + let n = "connected"; + return typeof t != "object" && (t = {}), t.once = !0, function(o) { + let c = "dde:" + n; + return o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" ? o : o.isConnected ? (o.dispatchEvent(new Event(c)), o) : (A(t.signal, () => R.offConnected(o, e)) && R.onConnected(o, e), o); }; }; - U.disconnected = function(e, t) { - return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:disconnected", e, t), typeof r.disconnectedCallback == "function" || L(t.signal, () => _.offDisconnected(r, e)) && _.onDisconnected(r, e), r; + x.disconnected = function(e, t) { + let n = "disconnected"; + return typeof t != "object" && (t = {}), t.once = !0, function(o) { + let c = "dde:" + n; + return o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" || A(t.signal, () => R.offDisconnected(o, e)) && R.onDisconnected(o, e), o; }; }; - function V() { - let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let i of c) - if (i.type === "childList") { - if (b(i.addedNodes, !0)) { + x.attributeChanged = function(e, t) { + let n = "attributeChanged"; + return typeof t != "object" && (t = {}), function(o) { + let c = "dde:" + n; + if (o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" || V.has(o)) + return o; + let a = new MutationObserver(function(d) { + for (let { attributeName: m, target: b } of d) + b.dispatchEvent( + new CustomEvent(c, { detail: [m, b.getAttribute(m)] }) + ); + }); + return A(t.signal, () => a.disconnect()) && a.observe(o, { attributes: !0 }), o; + }; + }; + function Z() { + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(i) { + for (let u of i) + if (u.type === "childList") { + if (m(u.addedNodes, !0)) { a(); continue; } - x(i.removedNodes, !0) && a(); + b(u.removedNodes, !0) && a(); } }); return { - onConnected(c, i) { - u(); - let f = o(c); - f.connected.has(i) || (f.connected.add(i), f.length_c += 1); + onConnected(i, u) { + c(); + let f = o(i); + f.connected.has(u) || (f.connected.add(u), f.length_c += 1); }, - offConnected(c, i) { - if (!e.has(c)) + offConnected(i, u) { + if (!e.has(i)) return; - let f = e.get(c); - f.connected.has(i) && (f.connected.delete(i), f.length_c -= 1, r(c, f)); + let f = e.get(i); + f.connected.has(u) && (f.connected.delete(u), f.length_c -= 1, r(i, f)); }, - onDisconnected(c, i) { - u(); - let f = o(c); - f.disconnected.has(i) || (f.disconnected.add(i), f.length_d += 1); + onDisconnected(i, u) { + c(); + let f = o(i); + f.disconnected.has(u) || (f.disconnected.add(u), f.length_d += 1); }, - offDisconnected(c, i) { - if (!e.has(c)) + offDisconnected(i, u) { + if (!e.has(i)) return; - let f = e.get(c); - f.disconnected.has(i) && (f.disconnected.delete(i), f.length_d -= 1, r(c, f)); + let f = e.get(i); + f.disconnected.has(u) && (f.disconnected.delete(u), f.length_d -= 1, r(i, f)); } }; - function r(c, i) { - i.length_c || i.length_d || (e.delete(c), a()); + function r(i, u) { + u.length_c || u.length_d || (e.delete(i), a()); } - function o(c) { - if (e.has(c)) - return e.get(c); - let i = { + function o(i) { + if (e.has(i)) + return e.get(i); + let u = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(c, i), i; + return e.set(i, u), u; } - function u() { + function c() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } function a() { !t || e.size || (t = !1, n.disconnect()); } function s() { - return new Promise(function(c) { - (requestIdleCallback || requestAnimationFrame)(c); + return new Promise(function(i) { + (requestIdleCallback || requestAnimationFrame)(i); }); } - async function d(c) { + async function d(i) { e.size > 30 && await s(); - let i = []; - if (!(c instanceof Node)) - return i; + let u = []; + if (!(i instanceof Node)) + return u; for (let f of e.keys()) - f === c || !(f instanceof Node) || c.contains(f) && i.push(f); - return i; + f === i || !(f instanceof Node) || i.contains(f) && u.push(f); + return u; } - function b(c, i) { + function m(i, u) { let f = !1; - for (let l of c) { - if (i && d(l).then(b), !e.has(l)) + for (let p of i) { + if (u && d(p).then(m), !e.has(p)) continue; - let v = e.get(l); - v.length_c && (l.dispatchEvent(new Event("dde:connected")), v.connected = /* @__PURE__ */ new WeakSet(), v.length_c = 0, v.length_d || e.delete(l), f = !0); + let w = e.get(p); + w.length_c && (p.dispatchEvent(new Event("dde:connected")), w.connected = /* @__PURE__ */ new WeakSet(), w.length_c = 0, w.length_d || e.delete(p), f = !0); } return f; } - function x(c, i) { + function b(i, u) { let f = !1; - for (let l of c) - i && d(l).then(x), !(!e.has(l) || !e.get(l).length_d) && (l.dispatchEvent(new Event("dde:disconnected")), e.delete(l), f = !0); + for (let p of i) + u && d(p).then(b), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), f = !0); return f; } } @@ -290,64 +309,75 @@ }); // src/signals-lib.js - var p = Symbol.for("Signal"); - function R(e) { + var l = Symbol.for("Signal"); + function C(e) { try { - return Reflect.has(e, p); + return Reflect.has(e, l); } catch { return !1; } } - var h = /* @__PURE__ */ new WeakMap(); - function g(e, t) { + var g = /* @__PURE__ */ new WeakMap(); + function h(e, t) { if (typeof e != "function") - return $(e, t); - if (R(e)) + return U(e, t); + if (C(e)) return e; - let n = $(""), r = () => n(e()); - return h.set(r, /* @__PURE__ */ new Set([n])), Q(r), n; + let n = U(""), r = () => n(e()); + return g.set(r, /* @__PURE__ */ new Set([n])), X(r), n; } - g.action = function(e, t, ...n) { - let r = e[p], { actions: o } = r; + h.action = function(e, t, ...n) { + let r = e[l], { actions: o } = r; if (!o || !Reflect.has(o, t)) throw new Error(`'${e}' has no action with name '${t}'!`); if (o[t].apply(r, n), r.skip) return Reflect.deleteProperty(r, "skip"); - r.listeners.forEach((u) => u(r.value)); + r.listeners.forEach((c) => c(r.value)); }; - g.on = function e(t, n, r = {}) { + h.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) - return t.forEach((u) => e(u, n, r)); - D(t, n), o && o.addEventListener("abort", () => q(t, n)); + return t.forEach((c) => e(c, n, r)); + P(t, n), o && o.addEventListener("abort", () => q(t, n)); } }; - g.symbols = { - signal: p, + h.symbols = { + signal: l, onclear: Symbol.for("Signal.onclear") }; - g.clear = function(...e) { + h.attribute = function(e, t = void 0) { + let { host: n } = E, r = n() && n().hasAttribute(e) ? n().getAttribute(e) : t, o = new AbortController(), c = h(r, { + [h.symbols.onclear]() { + o.abort(); + } + }); + return E.host(x.attributeChanged(function({ detail: a }) { + let [s, d] = a; + s === e && c(d); + }, { signal: o.signal })), c; + }; + h.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[p], { onclear: o } = g.symbols; - r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, p); + let r = n[l], { onclear: o } = h.symbols; + r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, l); } function t(n, r) { r.listeners.forEach((o) => { - if (r.listeners.delete(o), !h.has(o)) + if (r.listeners.delete(o), !g.has(o)) return; - let u = h.get(o); - u.delete(n), !(u.size > 1) && (g.clear(...u), h.delete(o)); + let c = g.get(o); + c.delete(n), !(c.size > 1) && (h.clear(...c), g.delete(o)); }); } }; - g.el = function(e, t) { + h.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let u = (a) => { + let c = (a) => { if (!n.parentNode || !r.parentNode) - return q(e, u); + return q(e, c); let s = t(a); Array.isArray(s) || (s = [s]); let d = n; @@ -355,77 +385,77 @@ d.remove(); n.after(...s); }; - return D(e, u), u(e()), o; + return P(e, c), c(e()), o; }; - var k = { - isSignal: R, + var $ = { + isSignal: C, processReactiveAttribute(e, t, n, r) { - return R(n) ? (D(n, (o) => r([t, o])), n()) : n; + return C(n) ? (P(n, (o) => r([t, o])), n()) : n; } }; - function $(e, t) { - let n = (...r) => r.length ? ee(n, r[0]) : Y(n); - return K(n, e, t); + function U(e, t) { + let n = (...r) => r.length ? te(n, ...r) : ee(n); + return Q(n, e, t); } - var Z = Object.assign(/* @__PURE__ */ Object.create(null), { + var K = Object.assign(/* @__PURE__ */ Object.create(null), { stopPropagation() { this.skip = !0; } }); - function K(e, t, n) { - return P(n) !== "[object Object]" && (n = {}), e[p] = { + function Q(e, t, n) { + return j(n) !== "[object Object]" && (n = {}), e[l] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() - }, e.toJSON = () => e(), Object.setPrototypeOf(e[p], Z), e; + }, e.toJSON = () => e(), Object.setPrototypeOf(e[l], K), e; } - var A = []; - function Q(e) { + var L = []; + function X(e) { let t = function() { - A.push(t), e(), A.pop(); + L.push(t), e(), L.pop(); }; - h.has(e) && (h.set(t, h.get(e)), h.delete(e)), t(); + g.has(e) && (g.set(t, g.get(e)), g.delete(e)), t(); } - function X() { - return A[A.length - 1]; + function Y() { + return L[L.length - 1]; } - function Y(e) { - if (!e[p]) + function ee(e) { + if (!e[l]) return; - let { value: t, listeners: n } = e[p], r = X(); - return r && n.add(r), h.has(r) && h.get(r).add(e), t; + let { value: t, listeners: n } = e[l], r = Y(); + return r && n.add(r), g.has(r) && g.get(r).add(e), t; } - function ee(e, t) { - if (!e[p]) + function te(e, t, n) { + if (!e[l]) return; - let n = e[p]; - if (n.value !== t) - return n.value = t, n.listeners.forEach((r) => r(t)), t; + let r = e[l]; + if (!(!n && r.value === t)) + return r.value = t, r.listeners.forEach((o) => o(t)), t; } - function D(e, t) { - if (e[p]) - return e[p].listeners.add(t); + function P(e, t) { + if (e[l]) + return e[l].listeners.add(t); } function q(e, t) { - if (e[p]) - return e[p].listeners.delete(t); + if (e[l]) + return e[l].listeners.delete(t); } // signals.js - C(k); + N($); globalThis.dde= { - S: g, - assign: y, + S: h, + assign: O, classListDeclarative: B, - createElement: se, - dispatchEvent: de, - el: se, + createElement: ie, + dispatchEvent: le, + el: ie, empty: fe, - isSignal: R, - on: U, - registerReactivity: C, - scope: O + isSignal: C, + on: x, + registerReactivity: N, + scope: E }; })(); \ No newline at end of file diff --git a/dist/dde.js b/dist/dde.js index d3e2755..52ead9d 100644 --- a/dist/dde.js +++ b/dist/dde.js @@ -1,26 +1,26 @@ //deka-dom-el library is available via global namespace `dde` (()=> { // src/signals-common.js - var m = { + var b = { isSignal(e) { return !1; }, - processReactiveAttribute(e, t, n, r) { + processReactiveAttribute(e, t, n, s) { return n; } }; function P(e, t = !0) { - return t ? Object.assign(m, e) : (Object.setPrototypeOf(e, m), e); + return t ? Object.assign(b, e) : (Object.setPrototypeOf(e, b), e); } - function b(e) { - return m.isPrototypeOf(e) && e !== m ? e : m; + function E(e) { + return b.isPrototypeOf(e) && e !== b ? e : b; } // src/helpers.js - function l(e) { + function g(e) { return typeof e > "u"; } - function _(e, t) { + function w(e, t) { if (!e || !(e instanceof AbortSignal)) return !0; if (!e.aborted) @@ -30,9 +30,9 @@ } // src/dom-common.js - var R = { setDeleteAttr: j }; + var y = { setDeleteAttr: j }; function j(e, t, n) { - if (Reflect.set(e, t, n), !!l(n)) { + if (Reflect.set(e, t, n), !!g(n)) { if (Reflect.deleteProperty(e, t), e instanceof HTMLElement && e.getAttribute(t) === "undefined") return e.removeAttribute(t); if (Reflect.get(e, t) === "undefined") @@ -41,12 +41,12 @@ } // src/dom.js - var v = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], C = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { + var m = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, _ = { get current() { - return v[v.length - 1]; + return m[m.length - 1]; }, get state() { - return [...v]; + return [...m]; }, get host() { return this.current.host; @@ -55,93 +55,93 @@ return this.current.namespace; }, set namespace(e) { - return this.current.namespace = C(e); + return this.current.namespace = R(e); }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return x.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return _.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = C(e.namespace)), v.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = R(e.namespace)), m.push(Object.assign({}, this.current, e)); }, pop() { - return v.pop(); + return m.pop(); } }; - function I(e, t, ...n) { - let r = this, u = b(this), { namespace: d } = x, f; - switch ((Object(t) !== t || u.isSignal(t)) && (t = { textContent: t }), !0) { + function V(e, t, ...n) { + let s = this, r = E(this), { namespace: f } = _, a; + switch ((Object(t) !== t || r.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - x.push({ scope: e, host: (i) => i ? (n.unshift(i), void 0) : f }), f = e(t || void 0), x.pop(); + _.push({ scope: e, host: (u) => u ? (n.unshift(u), void 0) : a }), a = e(t || void 0), _.pop(); break; } case e === "#text": - f = w.call(r, document.createTextNode(""), t); + a = x.call(s, document.createTextNode(""), t); break; case e === "<>": - f = w.call(r, document.createDocumentFragment(), t); + a = x.call(s, document.createDocumentFragment(), t); break; - case d !== "html": - f = w.call(r, document.createElementNS(d, e), t); + case f !== "html": + a = x.call(s, document.createElementNS(f, e), t); break; - case !f: - f = w.call(r, document.createElement(e), t); + case !a: + a = x.call(s, document.createElement(e), t); } - return n.forEach((i) => i(f)), f; + return n.forEach((u) => u(a)), a; } - var { setDeleteAttr: S } = R; - function w(e, ...t) { - let n = this, r = b(this); + var { setDeleteAttr: S } = y; + function x(e, ...t) { + let n = this, s = E(this); if (!t.length) return e; - let d = (e instanceof SVGElement ? U : T).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function f([i, a]) { - a = r.processReactiveAttribute(e, i, a, f); - let [h] = i; + let f = (e instanceof SVGElement ? T : F).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([u, d]) { + d = s.processReactiveAttribute(e, u, d, a); + let [h] = u; if (h === "=") - return d(i.slice(1), a); + return f(u.slice(1), d); if (h === ".") - return y(e, i.slice(1), a); - if (/(aria|data)([A-Z])/.test(i)) - return i = i.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), d(i, a); - switch (i === "className" && (i = "class"), i) { + return L(e, u.slice(1), d); + if (/(aria|data)([A-Z])/.test(u)) + return u = u.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(u, d); + switch (u === "className" && (u = "class"), u) { case "xlink:href": - return d(i, a, "http://www.w3.org/1999/xlink"); + return f(u, d, "http://www.w3.org/1999/xlink"); case "textContent": - return S(e, i, a); + return S(e, u, d); case "style": - if (typeof a != "object") + if (typeof d != "object") break; case "dataset": - return O(r, a, y.bind(null, e[i])); + return C(s, d, L.bind(null, e[u])); case "ariaset": - return O(r, a, (E, c) => d("aria-" + E, c)); + return C(s, d, (l, c) => f("aria-" + l, c)); case "classList": - return F.call(n, e, a); + return M.call(n, e, d); } - return M(e, i) ? S(e, i, a) : d(i, a); + return W(e, u) ? S(e, u, d) : f(u, d); }), e; } - function F(e, t) { - let n = b(this); - return O( + function M(e, t) { + let n = E(this); + return C( n, t, - (r, u) => e.classList.toggle(r, u === -1 ? void 0 : !!u) + (s, r) => e.classList.toggle(s, r === -1 ? void 0 : !!r) ), e; } - function Z(e) { + function $(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } - function M(e, t) { + function W(e, t) { if (!Reflect.has(e, t)) return !1; let n = D(e, t); - return !l(n.set); + return !g(n.set); } function D(e, t) { if (e = Object.getPrototypeOf(e), !e) @@ -149,86 +149,105 @@ let n = Object.getOwnPropertyDescriptor(e, t); return n || D(e, t); } - function O(e, t, n) { + function C(e, t, n) { if (!(typeof t != "object" || t === null)) - return Object.entries(t).forEach(function([u, d]) { - u && (d = e.processReactiveAttribute(t, u, d, (f) => n(...f)), n(u, d)); + return Object.entries(t).forEach(function([r, f]) { + r && (f = e.processReactiveAttribute(t, r, f, (a) => n(...a)), n(r, f)); }); } - function L(e) { + function N(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } - function T(e, t, n, r) { - return e[(l(r) ? "remove" : "set") + t](n, L(r)); + function F(e, t, n, s) { + return e[(g(s) ? "remove" : "set") + t](n, N(s)); } - function U(e, t, n, r, u = null) { - return e[(l(r) ? "remove" : "set") + t + "NS"](u, n, L(r)); + function T(e, t, n, s, r = null) { + return e[(g(s) ? "remove" : "set") + t + "NS"](r, n, N(s)); } - function y(e, t, n) { - if (Reflect.set(e, t, n), !!l(n)) + function L(e, t, n) { + if (Reflect.set(e, t, n), !!g(n)) return Reflect.deleteProperty(e, t); } // src/events.js - function K(e, t, ...n) { - let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); - return e.dispatchEvent(r); + function Q(e, t, ...n) { + let s = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(s); } - function N(e, t, n) { - return function(u) { - return u.addEventListener(e, t, n), u; + function O(e, t, n) { + return function(r) { + return r.addEventListener(e, t, n), r; }; } - var A = W(); - N.connected = function(e, t) { + var A = q(), U = /* @__PURE__ */ new WeakSet(); + O.connected = function(e, t) { + let n = "connected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:connected", e, t), typeof r.connectedCallback == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event("dde:connected")), r) : (_(t.signal, () => A.offConnected(r, e)) && A.onConnected(r, e), r); + let f = "dde:" + n; + return r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event(f)), r) : (w(t.signal, () => A.offConnected(r, e)) && A.onConnected(r, e), r); }; }; - N.disconnected = function(e, t) { + O.disconnected = function(e, t) { + let n = "disconnected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:disconnected", e, t), typeof r.disconnectedCallback == "function" || _(t.signal, () => A.offDisconnected(r, e)) && A.onDisconnected(r, e), r; + let f = "dde:" + n; + return r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" || w(t.signal, () => A.offDisconnected(r, e)) && A.onDisconnected(r, e), r; }; }; - function W() { + O.attributeChanged = function(e, t) { + let n = "attributeChanged"; + return typeof t != "object" && (t = {}), function(r) { + let f = "dde:" + n; + if (r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" || U.has(r)) + return r; + let a = new MutationObserver(function(d) { + for (let { attributeName: h, target: l } of d) + l.dispatchEvent( + new CustomEvent(f, { detail: [h, l.getAttribute(h)] }) + ); + }); + return w(t.signal, () => a.disconnect()) && a.observe(r, { attributes: !0 }), r; + }; + }; + function q() { let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { for (let o of c) if (o.type === "childList") { if (h(o.addedNodes, !0)) { - f(); + a(); continue; } - E(o.removedNodes, !0) && f(); + l(o.removedNodes, !0) && a(); } }); return { onConnected(c, o) { - d(); - let s = u(c); - s.connected.has(o) || (s.connected.add(o), s.length_c += 1); + f(); + let i = r(c); + i.connected.has(o) || (i.connected.add(o), i.length_c += 1); }, offConnected(c, o) { if (!e.has(c)) return; - let s = e.get(c); - s.connected.has(o) && (s.connected.delete(o), s.length_c -= 1, r(c, s)); + let i = e.get(c); + i.connected.has(o) && (i.connected.delete(o), i.length_c -= 1, s(c, i)); }, onDisconnected(c, o) { - d(); - let s = u(c); - s.disconnected.has(o) || (s.disconnected.add(o), s.length_d += 1); + f(); + let i = r(c); + i.disconnected.has(o) || (i.disconnected.add(o), i.length_d += 1); }, offDisconnected(c, o) { if (!e.has(c)) return; - let s = e.get(c); - s.disconnected.has(o) && (s.disconnected.delete(o), s.length_d -= 1, r(c, s)); + let i = e.get(c); + i.disconnected.has(o) && (i.disconnected.delete(o), i.length_d -= 1, s(c, i)); } }; - function r(c, o) { - o.length_c || o.length_d || (e.delete(c), f()); + function s(c, o) { + o.length_c || o.length_d || (e.delete(c), a()); } - function u(c) { + function r(c) { if (e.has(c)) return e.get(c); let o = { @@ -239,41 +258,41 @@ }; return e.set(c, o), o; } - function d() { + function f() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function f() { + function a() { !t || e.size || (t = !1, n.disconnect()); } - function i() { + function u() { return new Promise(function(c) { (requestIdleCallback || requestAnimationFrame)(c); }); } - async function a(c) { - e.size > 30 && await i(); + async function d(c) { + e.size > 30 && await u(); let o = []; if (!(c instanceof Node)) return o; - for (let s of e.keys()) - s === c || !(s instanceof Node) || c.contains(s) && o.push(s); + for (let i of e.keys()) + i === c || !(i instanceof Node) || c.contains(i) && o.push(i); return o; } function h(c, o) { - let s = !1; + let i = !1; for (let p of c) { - if (o && a(p).then(h), !e.has(p)) + if (o && d(p).then(h), !e.has(p)) continue; - let g = e.get(p); - g.length_c && (p.dispatchEvent(new Event("dde:connected")), g.connected = /* @__PURE__ */ new WeakSet(), g.length_c = 0, g.length_d || e.delete(p), s = !0); + let v = e.get(p); + v.length_c && (p.dispatchEvent(new Event("dde:connected")), v.connected = /* @__PURE__ */ new WeakSet(), v.length_c = 0, v.length_d || e.delete(p), i = !0); } - return s; + return i; } - function E(c, o) { - let s = !1; + function l(c, o) { + let i = !1; for (let p of c) - o && a(p).then(E), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), s = !0); - return s; + o && d(p).then(l), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), i = !0); + return i; } } @@ -286,15 +305,15 @@ }); globalThis.dde= { - assign: w, - classListDeclarative: F, - createElement: I, - dispatchEvent: K, - el: I, - empty: Z, - on: N, + assign: x, + classListDeclarative: M, + createElement: V, + dispatchEvent: Q, + el: V, + empty: $, + on: O, registerReactivity: P, - scope: x + scope: _ }; })(); \ No newline at end of file diff --git a/dist/esm-with-signals.js b/dist/esm-with-signals.js index c357c62..8ec264f 100644 --- a/dist/esm-with-signals.js +++ b/dist/esm-with-signals.js @@ -1,5 +1,5 @@ // src/signals-common.js -var E = { +var y = { isSignal(e) { return !1; }, @@ -7,22 +7,22 @@ var E = { return n; } }; -function C(e, t = !0) { - return t ? Object.assign(E, e) : (Object.setPrototypeOf(e, E), e); +function N(e, t = !0) { + return t ? Object.assign(y, e) : (Object.setPrototypeOf(e, y), e); } -function S(e) { - return E.isPrototypeOf(e) && e !== E ? e : E; +function _(e) { + return y.isPrototypeOf(e) && e !== y ? e : y; } // src/helpers.js -function m(e) { +function v(e) { return typeof e > "u"; } -function P(e) { +function j(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } -function L(e, t) { +function A(e, t) { if (!e || !(e instanceof AbortSignal)) return !0; if (!e.aborted) @@ -32,9 +32,9 @@ function L(e, t) { } // src/dom-common.js -var j = { setDeleteAttr: H }; +var W = { setDeleteAttr: H }; function H(e, t, n) { - if (Reflect.set(e, t, n), !!m(n)) { + if (Reflect.set(e, t, n), !!v(n)) { if (Reflect.deleteProperty(e, t), e instanceof HTMLElement && e.getAttribute(t) === "undefined") return e.removeAttribute(t); if (Reflect.get(e, t) === "undefined") @@ -43,12 +43,12 @@ function H(e, t, n) { } // src/dom.js -var w = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, O = { +var S = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], M = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, E = { get current() { - return w[w.length - 1]; + return S[S.length - 1]; }, get state() { - return [...w]; + return [...S]; }, get host() { return this.current.host; @@ -57,80 +57,80 @@ var w = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document. return this.current.namespace; }, set namespace(e) { - return this.current.namespace = W(e); + return this.current.namespace = M(e); }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return O.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return E.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = W(e.namespace)), w.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = M(e.namespace)), S.push(Object.assign({}, this.current, e)); }, pop() { - return w.pop(); + return S.pop(); } }; -function se(e, t, ...n) { - let r = this, o = S(this), { namespace: u } = O, a; +function ie(e, t, ...n) { + let r = this, o = _(this), { namespace: c } = E, a; switch ((Object(t) !== t || o.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - O.push({ scope: e, host: (s) => s ? (n.unshift(s), void 0) : a }), a = e(t || void 0), O.pop(); + E.push({ scope: e, host: (s) => s ? (n.unshift(s), void 0) : a }), a = e(t || void 0), E.pop(); break; } case e === "#text": - a = y.call(r, document.createTextNode(""), t); + a = O.call(r, document.createTextNode(""), t); break; case e === "<>": - a = y.call(r, document.createDocumentFragment(), t); + a = O.call(r, document.createDocumentFragment(), t); break; - case u !== "html": - a = y.call(r, document.createElementNS(u, e), t); + case c !== "html": + a = O.call(r, document.createElementNS(c, e), t); break; case !a: - a = y.call(r, document.createElement(e), t); + a = O.call(r, document.createElement(e), t); } return n.forEach((s) => s(a)), a; } -var { setDeleteAttr: F } = j; -function y(e, ...t) { - let n = this, r = S(this); +var { setDeleteAttr: k } = W; +function O(e, ...t) { + let n = this, r = _(this); if (!t.length) return e; - let u = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); + let c = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); return Object.entries(Object.assign({}, ...t)).forEach(function a([s, d]) { d = r.processReactiveAttribute(e, s, d, a); - let [b] = s; - if (b === "=") - return u(s.slice(1), d); - if (b === ".") - return M(e, s.slice(1), d); + let [m] = s; + if (m === "=") + return c(s.slice(1), d); + if (m === ".") + return F(e, s.slice(1), d); if (/(aria|data)([A-Z])/.test(s)) - return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), u(s, d); + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, d); switch (s === "className" && (s = "class"), s) { case "xlink:href": - return u(s, d, "http://www.w3.org/1999/xlink"); + return c(s, d, "http://www.w3.org/1999/xlink"); case "textContent": - return F(e, s, d); + return k(e, s, d); case "style": if (typeof d != "object") break; case "dataset": - return N(r, d, M.bind(null, e[s])); + return D(r, d, F.bind(null, e[s])); case "ariaset": - return N(r, d, (x, c) => u("aria-" + x, c)); + return D(r, d, (b, i) => c("aria-" + b, i)); case "classList": return B.call(n, e, d); } - return G(e, s) ? F(e, s, d) : u(s, d); + return G(e, s) ? k(e, s, d) : c(s, d); }), e; } function B(e, t) { - let n = S(this); - return N( + let n = _(this); + return D( n, t, (r, o) => e.classList.toggle(r, o === -1 ? void 0 : !!o) @@ -143,7 +143,7 @@ function G(e, t) { if (!Reflect.has(e, t)) return !1; let n = z(e, t); - return !m(n.set); + return !v(n.set); } function z(e, t) { if (e = Object.getPrototypeOf(e), !e) @@ -151,130 +151,149 @@ function z(e, t) { let n = Object.getOwnPropertyDescriptor(e, t); return n || z(e, t); } -function N(e, t, n) { +function D(e, t, n) { if (!(typeof t != "object" || t === null)) - return Object.entries(t).forEach(function([o, u]) { - o && (u = e.processReactiveAttribute(t, o, u, (a) => n(...a)), n(o, u)); + return Object.entries(t).forEach(function([o, c]) { + o && (c = e.processReactiveAttribute(t, o, c, (a) => n(...a)), n(o, c)); }); } function T(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } function I(e, t, n, r) { - return e[(m(r) ? "remove" : "set") + t](n, T(r)); + return e[(v(r) ? "remove" : "set") + t](n, T(r)); } function J(e, t, n, r, o = null) { - return e[(m(r) ? "remove" : "set") + t + "NS"](o, n, T(r)); + return e[(v(r) ? "remove" : "set") + t + "NS"](o, n, T(r)); } -function M(e, t, n) { - if (Reflect.set(e, t, n), !!m(n)) +function F(e, t, n) { + if (Reflect.set(e, t, n), !!v(n)) return Reflect.deleteProperty(e, t); } // src/events.js -function de(e, t, ...n) { +function le(e, t, ...n) { let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); return e.dispatchEvent(r); } -function U(e, t, n) { +function x(e, t, n) { return function(o) { return o.addEventListener(e, t, n), o; }; } -var _ = V(); -U.connected = function(e, t) { - return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:connected", e, t), typeof r.connectedCallback == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event("dde:connected")), r) : (L(t.signal, () => _.offConnected(r, e)) && _.onConnected(r, e), r); +var R = Z(), V = /* @__PURE__ */ new WeakSet(); +x.connected = function(e, t) { + let n = "connected"; + return typeof t != "object" && (t = {}), t.once = !0, function(o) { + let c = "dde:" + n; + return o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" ? o : o.isConnected ? (o.dispatchEvent(new Event(c)), o) : (A(t.signal, () => R.offConnected(o, e)) && R.onConnected(o, e), o); }; }; -U.disconnected = function(e, t) { - return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:disconnected", e, t), typeof r.disconnectedCallback == "function" || L(t.signal, () => _.offDisconnected(r, e)) && _.onDisconnected(r, e), r; +x.disconnected = function(e, t) { + let n = "disconnected"; + return typeof t != "object" && (t = {}), t.once = !0, function(o) { + let c = "dde:" + n; + return o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" || A(t.signal, () => R.offDisconnected(o, e)) && R.onDisconnected(o, e), o; }; }; -function V() { - let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let i of c) - if (i.type === "childList") { - if (b(i.addedNodes, !0)) { +x.attributeChanged = function(e, t) { + let n = "attributeChanged"; + return typeof t != "object" && (t = {}), function(o) { + let c = "dde:" + n; + if (o.addEventListener(c, e, t), typeof o[n + "Callback"] == "function" || V.has(o)) + return o; + let a = new MutationObserver(function(d) { + for (let { attributeName: m, target: b } of d) + b.dispatchEvent( + new CustomEvent(c, { detail: [m, b.getAttribute(m)] }) + ); + }); + return A(t.signal, () => a.disconnect()) && a.observe(o, { attributes: !0 }), o; + }; +}; +function Z() { + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(i) { + for (let u of i) + if (u.type === "childList") { + if (m(u.addedNodes, !0)) { a(); continue; } - x(i.removedNodes, !0) && a(); + b(u.removedNodes, !0) && a(); } }); return { - onConnected(c, i) { - u(); - let f = o(c); - f.connected.has(i) || (f.connected.add(i), f.length_c += 1); + onConnected(i, u) { + c(); + let f = o(i); + f.connected.has(u) || (f.connected.add(u), f.length_c += 1); }, - offConnected(c, i) { - if (!e.has(c)) + offConnected(i, u) { + if (!e.has(i)) return; - let f = e.get(c); - f.connected.has(i) && (f.connected.delete(i), f.length_c -= 1, r(c, f)); + let f = e.get(i); + f.connected.has(u) && (f.connected.delete(u), f.length_c -= 1, r(i, f)); }, - onDisconnected(c, i) { - u(); - let f = o(c); - f.disconnected.has(i) || (f.disconnected.add(i), f.length_d += 1); + onDisconnected(i, u) { + c(); + let f = o(i); + f.disconnected.has(u) || (f.disconnected.add(u), f.length_d += 1); }, - offDisconnected(c, i) { - if (!e.has(c)) + offDisconnected(i, u) { + if (!e.has(i)) return; - let f = e.get(c); - f.disconnected.has(i) && (f.disconnected.delete(i), f.length_d -= 1, r(c, f)); + let f = e.get(i); + f.disconnected.has(u) && (f.disconnected.delete(u), f.length_d -= 1, r(i, f)); } }; - function r(c, i) { - i.length_c || i.length_d || (e.delete(c), a()); + function r(i, u) { + u.length_c || u.length_d || (e.delete(i), a()); } - function o(c) { - if (e.has(c)) - return e.get(c); - let i = { + function o(i) { + if (e.has(i)) + return e.get(i); + let u = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(c, i), i; + return e.set(i, u), u; } - function u() { + function c() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } function a() { !t || e.size || (t = !1, n.disconnect()); } function s() { - return new Promise(function(c) { - (requestIdleCallback || requestAnimationFrame)(c); + return new Promise(function(i) { + (requestIdleCallback || requestAnimationFrame)(i); }); } - async function d(c) { + async function d(i) { e.size > 30 && await s(); - let i = []; - if (!(c instanceof Node)) - return i; + let u = []; + if (!(i instanceof Node)) + return u; for (let f of e.keys()) - f === c || !(f instanceof Node) || c.contains(f) && i.push(f); - return i; + f === i || !(f instanceof Node) || i.contains(f) && u.push(f); + return u; } - function b(c, i) { + function m(i, u) { let f = !1; - for (let l of c) { - if (i && d(l).then(b), !e.has(l)) + for (let p of i) { + if (u && d(p).then(m), !e.has(p)) continue; - let v = e.get(l); - v.length_c && (l.dispatchEvent(new Event("dde:connected")), v.connected = /* @__PURE__ */ new WeakSet(), v.length_c = 0, v.length_d || e.delete(l), f = !0); + let w = e.get(p); + w.length_c && (p.dispatchEvent(new Event("dde:connected")), w.connected = /* @__PURE__ */ new WeakSet(), w.length_c = 0, w.length_d || e.delete(p), f = !0); } return f; } - function x(c, i) { + function b(i, u) { let f = !1; - for (let l of c) - i && d(l).then(x), !(!e.has(l) || !e.get(l).length_d) && (l.dispatchEvent(new Event("dde:disconnected")), e.delete(l), f = !0); + for (let p of i) + u && d(p).then(b), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), f = !0); return f; } } @@ -288,64 +307,75 @@ function V() { }); // src/signals-lib.js -var p = Symbol.for("Signal"); -function R(e) { +var l = Symbol.for("Signal"); +function C(e) { try { - return Reflect.has(e, p); + return Reflect.has(e, l); } catch { return !1; } } -var h = /* @__PURE__ */ new WeakMap(); -function g(e, t) { +var g = /* @__PURE__ */ new WeakMap(); +function h(e, t) { if (typeof e != "function") - return $(e, t); - if (R(e)) + return U(e, t); + if (C(e)) return e; - let n = $(""), r = () => n(e()); - return h.set(r, /* @__PURE__ */ new Set([n])), Q(r), n; + let n = U(""), r = () => n(e()); + return g.set(r, /* @__PURE__ */ new Set([n])), X(r), n; } -g.action = function(e, t, ...n) { - let r = e[p], { actions: o } = r; +h.action = function(e, t, ...n) { + let r = e[l], { actions: o } = r; if (!o || !Reflect.has(o, t)) throw new Error(`'${e}' has no action with name '${t}'!`); if (o[t].apply(r, n), r.skip) return Reflect.deleteProperty(r, "skip"); - r.listeners.forEach((u) => u(r.value)); + r.listeners.forEach((c) => c(r.value)); }; -g.on = function e(t, n, r = {}) { +h.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) - return t.forEach((u) => e(u, n, r)); - D(t, n), o && o.addEventListener("abort", () => q(t, n)); + return t.forEach((c) => e(c, n, r)); + P(t, n), o && o.addEventListener("abort", () => q(t, n)); } }; -g.symbols = { - signal: p, +h.symbols = { + signal: l, onclear: Symbol.for("Signal.onclear") }; -g.clear = function(...e) { +h.attribute = function(e, t = void 0) { + let { host: n } = E, r = n() && n().hasAttribute(e) ? n().getAttribute(e) : t, o = new AbortController(), c = h(r, { + [h.symbols.onclear]() { + o.abort(); + } + }); + return E.host(x.attributeChanged(function({ detail: a }) { + let [s, d] = a; + s === e && c(d); + }, { signal: o.signal })), c; +}; +h.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[p], { onclear: o } = g.symbols; - r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, p); + let r = n[l], { onclear: o } = h.symbols; + r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, l); } function t(n, r) { r.listeners.forEach((o) => { - if (r.listeners.delete(o), !h.has(o)) + if (r.listeners.delete(o), !g.has(o)) return; - let u = h.get(o); - u.delete(n), !(u.size > 1) && (g.clear(...u), h.delete(o)); + let c = g.get(o); + c.delete(n), !(c.size > 1) && (h.clear(...c), g.delete(o)); }); } }; -g.el = function(e, t) { +h.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let u = (a) => { + let c = (a) => { if (!n.parentNode || !r.parentNode) - return q(e, u); + return q(e, c); let s = t(a); Array.isArray(s) || (s = [s]); let d = n; @@ -353,74 +383,74 @@ g.el = function(e, t) { d.remove(); n.after(...s); }; - return D(e, u), u(e()), o; + return P(e, c), c(e()), o; }; -var k = { - isSignal: R, +var $ = { + isSignal: C, processReactiveAttribute(e, t, n, r) { - return R(n) ? (D(n, (o) => r([t, o])), n()) : n; + return C(n) ? (P(n, (o) => r([t, o])), n()) : n; } }; -function $(e, t) { - let n = (...r) => r.length ? ee(n, r[0]) : Y(n); - return K(n, e, t); +function U(e, t) { + let n = (...r) => r.length ? te(n, ...r) : ee(n); + return Q(n, e, t); } -var Z = Object.assign(/* @__PURE__ */ Object.create(null), { +var K = Object.assign(/* @__PURE__ */ Object.create(null), { stopPropagation() { this.skip = !0; } }); -function K(e, t, n) { - return P(n) !== "[object Object]" && (n = {}), e[p] = { +function Q(e, t, n) { + return j(n) !== "[object Object]" && (n = {}), e[l] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() - }, e.toJSON = () => e(), Object.setPrototypeOf(e[p], Z), e; + }, e.toJSON = () => e(), Object.setPrototypeOf(e[l], K), e; } -var A = []; -function Q(e) { +var L = []; +function X(e) { let t = function() { - A.push(t), e(), A.pop(); + L.push(t), e(), L.pop(); }; - h.has(e) && (h.set(t, h.get(e)), h.delete(e)), t(); + g.has(e) && (g.set(t, g.get(e)), g.delete(e)), t(); } -function X() { - return A[A.length - 1]; +function Y() { + return L[L.length - 1]; } -function Y(e) { - if (!e[p]) +function ee(e) { + if (!e[l]) return; - let { value: t, listeners: n } = e[p], r = X(); - return r && n.add(r), h.has(r) && h.get(r).add(e), t; + let { value: t, listeners: n } = e[l], r = Y(); + return r && n.add(r), g.has(r) && g.get(r).add(e), t; } -function ee(e, t) { - if (!e[p]) +function te(e, t, n) { + if (!e[l]) return; - let n = e[p]; - if (n.value !== t) - return n.value = t, n.listeners.forEach((r) => r(t)), t; + let r = e[l]; + if (!(!n && r.value === t)) + return r.value = t, r.listeners.forEach((o) => o(t)), t; } -function D(e, t) { - if (e[p]) - return e[p].listeners.add(t); +function P(e, t) { + if (e[l]) + return e[l].listeners.add(t); } function q(e, t) { - if (e[p]) - return e[p].listeners.delete(t); + if (e[l]) + return e[l].listeners.delete(t); } // signals.js -C(k); +N($); export { - g as S, - y as assign, + h as S, + O as assign, B as classListDeclarative, - se as createElement, - de as dispatchEvent, - se as el, + ie as createElement, + le as dispatchEvent, + ie as el, fe as empty, - R as isSignal, - U as on, - C as registerReactivity, - O as scope + C as isSignal, + x as on, + N as registerReactivity, + E as scope }; diff --git a/dist/esm.js b/dist/esm.js index 0950d81..557e690 100644 --- a/dist/esm.js +++ b/dist/esm.js @@ -1,24 +1,24 @@ // src/signals-common.js -var m = { +var b = { isSignal(e) { return !1; }, - processReactiveAttribute(e, t, n, r) { + processReactiveAttribute(e, t, n, s) { return n; } }; function P(e, t = !0) { - return t ? Object.assign(m, e) : (Object.setPrototypeOf(e, m), e); + return t ? Object.assign(b, e) : (Object.setPrototypeOf(e, b), e); } -function b(e) { - return m.isPrototypeOf(e) && e !== m ? e : m; +function E(e) { + return b.isPrototypeOf(e) && e !== b ? e : b; } // src/helpers.js -function l(e) { +function g(e) { return typeof e > "u"; } -function _(e, t) { +function w(e, t) { if (!e || !(e instanceof AbortSignal)) return !0; if (!e.aborted) @@ -28,9 +28,9 @@ function _(e, t) { } // src/dom-common.js -var R = { setDeleteAttr: j }; +var y = { setDeleteAttr: j }; function j(e, t, n) { - if (Reflect.set(e, t, n), !!l(n)) { + if (Reflect.set(e, t, n), !!g(n)) { if (Reflect.deleteProperty(e, t), e instanceof HTMLElement && e.getAttribute(t) === "undefined") return e.removeAttribute(t); if (Reflect.get(e, t) === "undefined") @@ -39,12 +39,12 @@ function j(e, t, n) { } // src/dom.js -var v = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], C = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { +var m = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, _ = { get current() { - return v[v.length - 1]; + return m[m.length - 1]; }, get state() { - return [...v]; + return [...m]; }, get host() { return this.current.host; @@ -53,93 +53,93 @@ var v = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document. return this.current.namespace; }, set namespace(e) { - return this.current.namespace = C(e); + return this.current.namespace = R(e); }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return x.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return _.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = C(e.namespace)), v.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = R(e.namespace)), m.push(Object.assign({}, this.current, e)); }, pop() { - return v.pop(); + return m.pop(); } }; -function I(e, t, ...n) { - let r = this, u = b(this), { namespace: d } = x, f; - switch ((Object(t) !== t || u.isSignal(t)) && (t = { textContent: t }), !0) { +function V(e, t, ...n) { + let s = this, r = E(this), { namespace: f } = _, a; + switch ((Object(t) !== t || r.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - x.push({ scope: e, host: (i) => i ? (n.unshift(i), void 0) : f }), f = e(t || void 0), x.pop(); + _.push({ scope: e, host: (u) => u ? (n.unshift(u), void 0) : a }), a = e(t || void 0), _.pop(); break; } case e === "#text": - f = w.call(r, document.createTextNode(""), t); + a = x.call(s, document.createTextNode(""), t); break; case e === "<>": - f = w.call(r, document.createDocumentFragment(), t); + a = x.call(s, document.createDocumentFragment(), t); break; - case d !== "html": - f = w.call(r, document.createElementNS(d, e), t); + case f !== "html": + a = x.call(s, document.createElementNS(f, e), t); break; - case !f: - f = w.call(r, document.createElement(e), t); + case !a: + a = x.call(s, document.createElement(e), t); } - return n.forEach((i) => i(f)), f; + return n.forEach((u) => u(a)), a; } -var { setDeleteAttr: S } = R; -function w(e, ...t) { - let n = this, r = b(this); +var { setDeleteAttr: S } = y; +function x(e, ...t) { + let n = this, s = E(this); if (!t.length) return e; - let d = (e instanceof SVGElement ? U : T).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function f([i, a]) { - a = r.processReactiveAttribute(e, i, a, f); - let [h] = i; + let f = (e instanceof SVGElement ? T : F).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([u, d]) { + d = s.processReactiveAttribute(e, u, d, a); + let [h] = u; if (h === "=") - return d(i.slice(1), a); + return f(u.slice(1), d); if (h === ".") - return y(e, i.slice(1), a); - if (/(aria|data)([A-Z])/.test(i)) - return i = i.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), d(i, a); - switch (i === "className" && (i = "class"), i) { + return L(e, u.slice(1), d); + if (/(aria|data)([A-Z])/.test(u)) + return u = u.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(u, d); + switch (u === "className" && (u = "class"), u) { case "xlink:href": - return d(i, a, "http://www.w3.org/1999/xlink"); + return f(u, d, "http://www.w3.org/1999/xlink"); case "textContent": - return S(e, i, a); + return S(e, u, d); case "style": - if (typeof a != "object") + if (typeof d != "object") break; case "dataset": - return O(r, a, y.bind(null, e[i])); + return C(s, d, L.bind(null, e[u])); case "ariaset": - return O(r, a, (E, c) => d("aria-" + E, c)); + return C(s, d, (l, c) => f("aria-" + l, c)); case "classList": - return F.call(n, e, a); + return M.call(n, e, d); } - return M(e, i) ? S(e, i, a) : d(i, a); + return W(e, u) ? S(e, u, d) : f(u, d); }), e; } -function F(e, t) { - let n = b(this); - return O( +function M(e, t) { + let n = E(this); + return C( n, t, - (r, u) => e.classList.toggle(r, u === -1 ? void 0 : !!u) + (s, r) => e.classList.toggle(s, r === -1 ? void 0 : !!r) ), e; } -function Z(e) { +function $(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } -function M(e, t) { +function W(e, t) { if (!Reflect.has(e, t)) return !1; let n = D(e, t); - return !l(n.set); + return !g(n.set); } function D(e, t) { if (e = Object.getPrototypeOf(e), !e) @@ -147,86 +147,105 @@ function D(e, t) { let n = Object.getOwnPropertyDescriptor(e, t); return n || D(e, t); } -function O(e, t, n) { +function C(e, t, n) { if (!(typeof t != "object" || t === null)) - return Object.entries(t).forEach(function([u, d]) { - u && (d = e.processReactiveAttribute(t, u, d, (f) => n(...f)), n(u, d)); + return Object.entries(t).forEach(function([r, f]) { + r && (f = e.processReactiveAttribute(t, r, f, (a) => n(...a)), n(r, f)); }); } -function L(e) { +function N(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } -function T(e, t, n, r) { - return e[(l(r) ? "remove" : "set") + t](n, L(r)); +function F(e, t, n, s) { + return e[(g(s) ? "remove" : "set") + t](n, N(s)); } -function U(e, t, n, r, u = null) { - return e[(l(r) ? "remove" : "set") + t + "NS"](u, n, L(r)); +function T(e, t, n, s, r = null) { + return e[(g(s) ? "remove" : "set") + t + "NS"](r, n, N(s)); } -function y(e, t, n) { - if (Reflect.set(e, t, n), !!l(n)) +function L(e, t, n) { + if (Reflect.set(e, t, n), !!g(n)) return Reflect.deleteProperty(e, t); } // src/events.js -function K(e, t, ...n) { - let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); - return e.dispatchEvent(r); +function Q(e, t, ...n) { + let s = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(s); } -function N(e, t, n) { - return function(u) { - return u.addEventListener(e, t, n), u; +function O(e, t, n) { + return function(r) { + return r.addEventListener(e, t, n), r; }; } -var A = W(); -N.connected = function(e, t) { +var A = q(), U = /* @__PURE__ */ new WeakSet(); +O.connected = function(e, t) { + let n = "connected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:connected", e, t), typeof r.connectedCallback == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event("dde:connected")), r) : (_(t.signal, () => A.offConnected(r, e)) && A.onConnected(r, e), r); + let f = "dde:" + n; + return r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" ? r : r.isConnected ? (r.dispatchEvent(new Event(f)), r) : (w(t.signal, () => A.offConnected(r, e)) && A.onConnected(r, e), r); }; }; -N.disconnected = function(e, t) { +O.disconnected = function(e, t) { + let n = "disconnected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { - return r.addEventListener("dde:disconnected", e, t), typeof r.disconnectedCallback == "function" || _(t.signal, () => A.offDisconnected(r, e)) && A.onDisconnected(r, e), r; + let f = "dde:" + n; + return r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" || w(t.signal, () => A.offDisconnected(r, e)) && A.onDisconnected(r, e), r; }; }; -function W() { +O.attributeChanged = function(e, t) { + let n = "attributeChanged"; + return typeof t != "object" && (t = {}), function(r) { + let f = "dde:" + n; + if (r.addEventListener(f, e, t), typeof r[n + "Callback"] == "function" || U.has(r)) + return r; + let a = new MutationObserver(function(d) { + for (let { attributeName: h, target: l } of d) + l.dispatchEvent( + new CustomEvent(f, { detail: [h, l.getAttribute(h)] }) + ); + }); + return w(t.signal, () => a.disconnect()) && a.observe(r, { attributes: !0 }), r; + }; +}; +function q() { let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { for (let o of c) if (o.type === "childList") { if (h(o.addedNodes, !0)) { - f(); + a(); continue; } - E(o.removedNodes, !0) && f(); + l(o.removedNodes, !0) && a(); } }); return { onConnected(c, o) { - d(); - let s = u(c); - s.connected.has(o) || (s.connected.add(o), s.length_c += 1); + f(); + let i = r(c); + i.connected.has(o) || (i.connected.add(o), i.length_c += 1); }, offConnected(c, o) { if (!e.has(c)) return; - let s = e.get(c); - s.connected.has(o) && (s.connected.delete(o), s.length_c -= 1, r(c, s)); + let i = e.get(c); + i.connected.has(o) && (i.connected.delete(o), i.length_c -= 1, s(c, i)); }, onDisconnected(c, o) { - d(); - let s = u(c); - s.disconnected.has(o) || (s.disconnected.add(o), s.length_d += 1); + f(); + let i = r(c); + i.disconnected.has(o) || (i.disconnected.add(o), i.length_d += 1); }, offDisconnected(c, o) { if (!e.has(c)) return; - let s = e.get(c); - s.disconnected.has(o) && (s.disconnected.delete(o), s.length_d -= 1, r(c, s)); + let i = e.get(c); + i.disconnected.has(o) && (i.disconnected.delete(o), i.length_d -= 1, s(c, i)); } }; - function r(c, o) { - o.length_c || o.length_d || (e.delete(c), f()); + function s(c, o) { + o.length_c || o.length_d || (e.delete(c), a()); } - function u(c) { + function r(c) { if (e.has(c)) return e.get(c); let o = { @@ -237,41 +256,41 @@ function W() { }; return e.set(c, o), o; } - function d() { + function f() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function f() { + function a() { !t || e.size || (t = !1, n.disconnect()); } - function i() { + function u() { return new Promise(function(c) { (requestIdleCallback || requestAnimationFrame)(c); }); } - async function a(c) { - e.size > 30 && await i(); + async function d(c) { + e.size > 30 && await u(); let o = []; if (!(c instanceof Node)) return o; - for (let s of e.keys()) - s === c || !(s instanceof Node) || c.contains(s) && o.push(s); + for (let i of e.keys()) + i === c || !(i instanceof Node) || c.contains(i) && o.push(i); return o; } function h(c, o) { - let s = !1; + let i = !1; for (let p of c) { - if (o && a(p).then(h), !e.has(p)) + if (o && d(p).then(h), !e.has(p)) continue; - let g = e.get(p); - g.length_c && (p.dispatchEvent(new Event("dde:connected")), g.connected = /* @__PURE__ */ new WeakSet(), g.length_c = 0, g.length_d || e.delete(p), s = !0); + let v = e.get(p); + v.length_c && (p.dispatchEvent(new Event("dde:connected")), v.connected = /* @__PURE__ */ new WeakSet(), v.length_c = 0, v.length_d || e.delete(p), i = !0); } - return s; + return i; } - function E(c, o) { - let s = !1; + function l(c, o) { + let i = !1; for (let p of c) - o && a(p).then(E), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), s = !0); - return s; + o && d(p).then(l), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), i = !0); + return i; } } @@ -283,13 +302,13 @@ function W() { }; }); export { - w as assign, - F as classListDeclarative, - I as createElement, - K as dispatchEvent, - I as el, - Z as empty, - N as on, + x as assign, + M as classListDeclarative, + V as createElement, + Q as dispatchEvent, + V as el, + $ as empty, + O as on, P as registerReactivity, - x as scope + _ as scope }; diff --git a/examples/components/webComponent.js b/examples/components/webComponent.js index 36c7d00..45104de 100644 --- a/examples/components/webComponent.js +++ b/examples/components/webComponent.js @@ -2,7 +2,6 @@ import { el, scope } from "../../index.js"; import { S } from "../../signals.js"; const { hasOwnProperty }= Object.prototype; -const store= attrsPropsToSignals([ "test" ]); /** * Compatible with `npx-wca test/components/webComponent.js` * */ @@ -12,14 +11,19 @@ export class CustomHTMLTestElement extends HTMLElement{ } connectedCallback(){ this.attachShadow({ mode: "open" }).append( - customElementRender(this, store.toRender(this), this.render) + customElementRender(this, this.render) ); } - render({ name, test, preName }){ + render({ test }){ console.log(scope.state); scope.host(on.connected(()=> console.log(CustomHTMLTestElement))); + scope.host(on.attributeChanged(e=> console.log(e))); scope.host(on.disconnected(()=> console.log(CustomHTMLTestElement))); + + const name= S.attribute("name"); + const preName= S.attribute("pre-name"); + console.log({ name, test, preName}); return el("p").append( el("#text", { textContent: name }), el("#text", { textContent: test }), @@ -31,14 +35,13 @@ export class CustomHTMLTestElement extends HTMLElement{ customElementsAssign( CustomHTMLTestElement, reflectObservedAttributes, - lifecycleToEvents(false), - store.connect + lifecycleToEvents, ); customElements.define("custom-test", CustomHTMLTestElement); -function customElementRender(_this, attrs, render){ +function customElementRender(_this, render){ scope.push({ scope: _this, host: (...a)=> a.length ? a[0](_this) : _this }); - const out= render(attrs); + const out= render(_this); scope.pop(); return out; } @@ -57,69 +60,20 @@ function reflectObservedAttributes(c){ }); } } -function lifecycleToEvents(is_attrs){ - return function(c){ - wrapMethod(c.prototype, "connectedCallback", function(target, thisArg, detail){ +function lifecycleToEvents(class_declaration){ + for (const name of [ "connected", "disconnected" ]) + wrapMethod(class_declaration.prototype, name+"Callback", function(target, thisArg, detail){ target.apply(thisArg, detail); - thisArg.dispatchEvent(new Event("dde:connected")); + thisArg.dispatchEvent(new Event("dde:"+name)); }); - wrapMethod(c.prototype, "disconnectedCallback", function(target, thisArg, detail){ - target.apply(thisArg, detail); - thisArg.dispatchEvent(new Event("dde:disconnected")); - }); - if(is_attrs) - wrapMethod(c.prototype, "attributeChangedCallback", function(target, thisArg, detail){ - thisArg.dispatchEvent(new CustomEvent("dde:attribute", { detail })); - target.apply(thisArg, detail); - }); - }; -} -function attrsPropsToSignals(props= []){ - const store_attrs= new WeakMap(); - const store_props= new WeakMap(); - return { - toRender(target){ - const out= {}; - const sattrs= get(store_attrs, target); - target.constructor.observedAttributes.forEach(function(name){ - const name_camel= name.replace(/([a-z])-([a-z])/g, (_, l, r)=> l+r.toUpperCase()); - if(!hasOwnProperty.call(sattrs, name)) sattrs[name]= S(undefined); - out[name_camel]= sattrs[name]; - }); - const sprops= get(store_props, target); - props.forEach(p=> !hasOwnProperty.call(sprops, p) && (sprops[p]= S(undefined))); - return Object.assign(out, sprops); - }, - connect(c){ - wrapMethod(c.prototype, "attributeChangedCallback", function(target, thisArg, detail){ - const [ name, _, value ]= detail; - const s= get(store_attrs, thisArg); - if(s[name]) s[name](value); - else s[name]= S(value); - - target.apply(thisArg, detail); - }); - for(const name of props){ - Reflect.defineProperty(c.prototype, name, { - get(){ - const s= get(store_props, this); - if(s[name]) return s[name](); - }, - set(value){ - const s= get(store_props, this); - if(s[name]) s[name](value); - else s[name]= S(value); - } - }); - } - } - }; - function get(store, t){ - if(store.has(t)) return store.get(t); - const s= {}; - store.set(t, s); - return s; - } + const name= "attributeChanged"; + wrapMethod(class_declaration.prototype, name+"Callback", function(target, thisArg, detail){ + const [ attribute, , value ]= detail; + thisArg.dispatchEvent(new CustomEvent("dde:"+name, { + detail: [ attribute, value ] + })); + target.apply(thisArg, detail); + }); } function wrapMethod(obj, method, apply){ obj[method]= new Proxy(obj[method] || (()=> {}), { apply }); diff --git a/package.json b/package.json index e73c92c..800cdd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deka-dom-el", - "version": "0.4.0", + "version": "0.5.0", "description": "A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks.", "author": "Jan Andrle ", "license": "MIT", @@ -51,6 +51,7 @@ "maxcomplexity": 10, "globals": { "requestIdleCallback": false, + "AbortController": false, "AbortSignal": false } }, @@ -62,12 +63,12 @@ }, { "path": "./signals.js", - "limit": "4 kB", + "limit": "7 kB", "gzip": false }, { "path": "./jsdom.js", - "limit": "8 kB", + "limit": "10 kB", "gzip": false }, { diff --git a/src/events.js b/src/events.js index bc5a9a6..5f45be8 100644 --- a/src/events.js +++ b/src/events.js @@ -12,17 +12,20 @@ export function on(event, listener, options){ } const c_ch_o= connectionsChangesObserverConstructor(); +const els_attribute_store= new WeakSet(); import { onAbort } from './helpers.js'; //TODO: cleanUp when event before abort? on.connected= function(listener, options){ + const name= "connected"; if(typeof options !== "object") options= {}; options.once= true; return function registerElement(element){ - element.addEventListener("dde:connected", listener, options); - if(typeof element.connectedCallback === "function") return element; + const event= "dde:"+name; + element.addEventListener(event, listener, options); + if(typeof element[name+"Callback"] === "function") return element; if(element.isConnected){ - element.dispatchEvent(new Event("dde:connected")); + element.dispatchEvent(new Event(event)); return element; } @@ -32,18 +35,40 @@ on.connected= function(listener, options){ }; }; on.disconnected= function(listener, options){ + const name= "disconnected"; if(typeof options !== "object") options= {}; options.once= true; return function registerElement(element){ - element.addEventListener("dde:disconnected", listener, options); - if(typeof element.disconnectedCallback === "function") return element; + const event= "dde:"+name; + element.addEventListener(event, listener, options); + if(typeof element[name+"Callback"] === "function") return element; const c= onAbort(options.signal, ()=> c_ch_o.offDisconnected(element, listener)); if(c) c_ch_o.onDisconnected(element, listener); return element; }; }; +on.attributeChanged= function(listener, options){ + const name= "attributeChanged"; + if(typeof options !== "object") + options= {}; + return function registerElement(element){ + const event= "dde:"+name; + element.addEventListener(event, listener, options); + if(typeof element[name+"Callback"] === "function") return element; + if(els_attribute_store.has(element)) return element; + + const observer= new MutationObserver(function(mutations){ + for(const { attributeName, target } of mutations) + target.dispatchEvent( + new CustomEvent(event, { detail: [ attributeName, target.getAttribute(attributeName) ] })); + }); + const c= onAbort(options.signal, ()=> observer.disconnect()); + if(c) observer.observe(element, { attributes: true }); + return element; + }; +}; function connectionsChangesObserverConstructor(){ const store= new Map(); diff --git a/src/signals-lib.js b/src/signals-lib.js index 82ab75b..4b1e120 100644 --- a/src/signals-lib.js +++ b/src/signals-lib.js @@ -37,6 +37,22 @@ S.symbols= { signal: mark, onclear: Symbol.for("Signal.onclear") }; +import { on } from "./events.js"; +import { scope } from "./dom.js"; +S.attribute= function(name, initial= undefined){ + const { host }= scope; + const value= host() && host().hasAttribute(name) ? host().getAttribute(name) : initial; + const ac= new AbortController(); + const out= S(value, { + [S.symbols.onclear](){ ac.abort(); } + }); + scope.host(on.attributeChanged(function({ detail }){ + const [ name_c, value ]= detail; + if(name_c!==name) return; + out(value); + }, { signal: ac.signal })); + return out; +}; S.clear= function(...signals){ for(const signal of signals){ Reflect.deleteProperty(signal, "toJSON"); @@ -95,7 +111,7 @@ export const signals_config= { function create(value, actions){ const signal= (...value)=> - value.length ? write(signal, value[0]) : read(signal); + value.length ? write(signal, ...value) : read(signal); return toSignal(signal, value, actions); } const protoSigal= Object.assign(Object.create(null), { @@ -138,10 +154,10 @@ function read(signal){ if(deps.has(context)) deps.get(context).add(signal); return value; } -function write(signal, value){ +function write(signal, value, force){ if(!signal[mark]) return; const s= signal[mark]; - if(s.value===value) return; + if(!force && s.value===value) return; s.value= value; s.listeners.forEach(l=> l(value)); return value;